34
35:- module(pce_unclip, []). 36:- use_module(library(pce)). 37
38
55
56:- pce_extend_class(graphical).
57
58clipped_by_window(Gr) :->
59 ::
60 get(Gr, window, Window),
61 get(Window, visible, Visible),
62 get(Gr, absolute_position, Window, point(X,Y)),
63 get(Gr, area, area(_,_,W,H)),
64 \+ send(Visible, inside, area(X,Y,W,H)).
65
66:- pce_end_class(graphical).
67
68
69 72
73:- pce_global(@unclip_window, new(pce_unclip_window)).
74
75:- pce_begin_class(pce_unclip_window, window).
76
77variable(handler, handler, get, ).
78variable(busy, bool := @off, none, ).
79
80class_variable(background, colour, azure).
81
82initialise(W) :->
83 send_super(W, initialise),
84 get(W, frame, Fr),
85 send(Fr, kind, popup),
86 send(Fr, sensitive, @off),
87 send(W, pen, 0),
88 send(Fr, border, 1),
89 send(Fr?tile, border, 0),
90 send(W, slot, handler,
91 handler(any, message(W, unclipped_event, @event))).
92
93attach(W, To:graphical) :->
94 ::
95 ( get(W, slot, busy, @off)
96 -> send(W, slot, busy, @on),
97 call_cleanup(attach(W, To),
98 send(W, slot, busy, @off))
99 ; true
100 ).
101
102attach(W, To) :-
103 get(To, window, ToWindow),
104 ( get(W, hypered, mirroring, Old)
105 -> send(W, delete_hypers, mirroring),
106 ( get(Old, window, ToWindow)
107 -> true
108 ; send(Old, grab_pointer, @off),
109 send(ToWindow, grab_pointer, @on)
110 )
111 ; get(W, handler, H),
112 send(ToWindow, grab_pointer, @on),
113 send(@display?inspect_handlers, prepend, H)
114 ),
115 new(_, hyper(To, W, mirror, mirroring)),
116 send(W, update),
117 get(To, display_position, point(X,Y)),
118 ( get(@pce, window_system, windows)
119 -> Border = 0 120 ; get(W, border, Border)
121 ),
122 send(W, open, point(X-Border,Y-Border)),
123 send(W, expose).
124
125update(W) :->
126 ::
127 send(W, clear),
128 ( get(W, hypered, mirroring, Gr)
129 -> get(Gr, clone, Clone),
130 ( get(@pce, window_system, windows)
131 -> get(Clone, size, size(W0, H0)),
132 send(W, size, size(W0+1, H0+1))
133 ; get(Clone, size, Size),
134 send(W, size, Size)
135 ),
136 send(Clone, set, 0, 0),
137 send(W, display, Clone)
138 ; true
139 ).
140
141
142detach(W) :->
143 ::
144 ( get(W, slot, busy, @off)
145 -> send(W, slot, busy, @on),
146 call_cleanup(detach(W),
147 send(W, slot, busy, @off))
148 ; true
149 ).
150
151detach(W) :-
152 ( get(W, hypered, mirroring, Gr)
153 -> send(W, delete_hypers, mirroring),
154 send(W, clear),
155 send(W, show, @off),
156 get(W, handler, H),
157 send(Gr?window, grab_pointer, @off),
158 send(@display?inspect_handlers, delete, H)
159 ; true
160 ).
161
162
163unclipped_event(W, Ev:event) :->
164 ( send(Ev, is_a, loc_move),
165 ( \+ send(Ev, inside, W)
166 ; get(W, hypered, mirroring, Gr),
167 \+ send(Ev, inside, Gr?window)
168 )
169 -> send(W, detach)
170 ; ( send(Ev, is_a, button)
171 ; send(Ev, is_a, keyboard)
172 ; send(Ev, is_a, wheel)
173 )
174 -> send(W, detach),
175 fail 176 ).
177
178:- pce_end_class(pce_unclip_window)