author | Claus Gittinger <cg@exept.de> |
Sat, 27 Jan 1996 16:35:09 +0100 | |
changeset 385 | 15fd1c806d2a |
parent 373 | 79d3a565ca9f |
child 488 | 97f384f5e2aa |
permissions | -rw-r--r-- |
0 | 1 |
" |
6 | 2 |
COPYRIGHT (c) 1992 by Claus Gittinger |
72 | 3 |
All Rights Reserved |
0 | 4 |
|
5 |
This software is furnished under a license and may be used |
|
6 |
only in accordance with the terms of that license and with the |
|
7 |
inclusion of the above copyright notice. This software may not |
|
8 |
be provided or otherwise made available to, or used by, any |
|
9 |
other person. No title to or ownership of the software is |
|
10 |
hereby transferred. |
|
11 |
" |
|
12 |
||
13 |
DeviceDrawable subclass:#PseudoView |
|
316 | 14 |
instanceVariableNames:'viewBackground cursor eventMask middleButtonMenu keyCommands |
15 |
gotExpose exposePending backed saveUnder delegate' |
|
16 |
classVariableNames:'' |
|
17 |
poolDictionaries:'' |
|
18 |
category:'Views-Basic' |
|
0 | 19 |
! |
20 |
||
40 | 21 |
!PseudoView class methodsFor:'documentation'! |
22 |
||
46 | 23 |
copyright |
24 |
" |
|
25 |
COPYRIGHT (c) 1992 by Claus Gittinger |
|
72 | 26 |
All Rights Reserved |
46 | 27 |
|
28 |
This software is furnished under a license and may be used |
|
29 |
only in accordance with the terms of that license and with the |
|
30 |
inclusion of the above copyright notice. This software may not |
|
31 |
be provided or otherwise made available to, or used by, any |
|
32 |
other person. No title to or ownership of the software is |
|
33 |
hereby transferred. |
|
34 |
" |
|
35 |
! |
|
36 |
||
40 | 37 |
documentation |
38 |
" |
|
59 | 39 |
this abstract class describes stuff common to any Window on a display |
40 |
device. i.e. RootWindow, TopWindows, PopUps and Subwindows. |
|
41 |
That is, they have a viewBackground, cursor etc. and especially events. |
|
42 |
A special feature is the delegate field, which allows key- and button |
|
43 |
events to be stolen from a view. |
|
44 |
If the delegate is non-nil, these events will be sent to it instead. |
|
45 |
So you can change a views behavior even if it was not initially designed |
|
46 |
for it. Also, controller functionality could be simulated using delegates. |
|
47 |
||
48 |
instance variables: |
|
49 |
||
72 | 50 |
viewBackground <Color|Form|Image> the views background |
59 | 51 |
|
72 | 52 |
cursor <Cursor> the cursor |
59 | 53 |
|
72 | 54 |
eventMask mask specifying the enabled |
59 | 55 |
events. |
56 |
||
72 | 57 |
middleButtonMenu a popup menu for the middle |
59 | 58 |
button. |
59 |
||
72 | 60 |
keyCommands not yet supported |
59 | 61 |
|
72 | 62 |
gotExpose for exposure handling after |
63 |
exposePending after a scroll |
|
59 | 64 |
|
72 | 65 |
backed true if backing store for that |
59 | 66 |
view is enabled |
67 |
||
72 | 68 |
saveUnder true if saveunder store for |
59 | 69 |
that view is enabled |
70 |
||
72 | 71 |
delegate for event delegation |
40 | 72 |
" |
73 |
! ! |
|
74 |
||
0 | 75 |
!PseudoView methodsFor:'accessing'! |
76 |
||
77 |
depth |
|
40 | 78 |
"return the depth in pixels of the view. |
79 |
Notice, that this is currently the devices depth, |
|
80 |
but support for mixed depth views is being prepared. |
|
81 |
(especially useful on SGI, with 24bit view)" |
|
0 | 82 |
|
83 |
^ device depth |
|
84 |
! |
|
85 |
||
269 | 86 |
insideColor:aColor |
87 |
"set the views background color - ST-80 compatibility" |
|
0 | 88 |
|
269 | 89 |
self viewBackground:aColor. |
90 |
self background:aColor |
|
40 | 91 |
! |
92 |
||
93 |
setViewBackground |
|
94 |
"install the viewBackground for the receiver on the device" |
|
0 | 95 |
|
96 |
|id devBgPixmap bgPixmap w h colors| |
|
97 |
||
98 |
drawableId notNil ifTrue:[ |
|
72 | 99 |
viewBackground isColor ifTrue:[ |
100 |
viewBackground := viewBackground on:device. |
|
101 |
id := viewBackground colorId. |
|
102 |
" |
|
103 |
a real color (i.e. one supported by the device) ? |
|
104 |
" |
|
105 |
id notNil ifTrue:[ |
|
106 |
device setWindowBackground:id in:drawableId. |
|
107 |
^ self |
|
108 |
]. |
|
109 |
" |
|
110 |
no, a dithered one - must have a dither-pattern |
|
111 |
(which is ready for the device, since viewBackground |
|
112 |
is already assigned to the device) |
|
113 |
" |
|
114 |
bgPixmap := viewBackground ditherForm. |
|
115 |
] ifFalse:[ |
|
116 |
" |
|
117 |
assume, it can convert itself to a form |
|
118 |
" |
|
119 |
bgPixmap := viewBackground asFormOn:device |
|
120 |
]. |
|
0 | 121 |
|
72 | 122 |
" |
123 |
must now have: |
|
124 |
a dithered color or bitmap or pixmap |
|
125 |
" |
|
126 |
bgPixmap isNil ifTrue:[ |
|
145 | 127 |
'PSEUDOVIEW: background not convertable - ignored' errorPrintNL. |
72 | 128 |
^ self |
129 |
]. |
|
40 | 130 |
|
72 | 131 |
w := bgPixmap width. |
132 |
h := bgPixmap height. |
|
40 | 133 |
|
72 | 134 |
(bgPixmap depth ~~ device depth) ifTrue:[ |
135 |
(bgPixmap depth ~~ 1) ifTrue:[ |
|
136 |
self error:'bad dither depth'. |
|
137 |
^ self |
|
138 |
]. |
|
139 |
" |
|
140 |
convert it into a deep form |
|
141 |
" |
|
142 |
colors := bgPixmap colorMap. |
|
143 |
devBgPixmap := Form width:w height:h depth:(device depth) on:device. |
|
144 |
devBgPixmap paint:(colors at:1). |
|
145 |
devBgPixmap fillRectangleX:0 y:0 width:w height:h. |
|
146 |
devBgPixmap foreground:(colors at:2) background:(colors at:1). |
|
147 |
devBgPixmap copyPlaneFrom:bgPixmap x:0 y:0 toX:0 y:0 width:w height:h. |
|
148 |
bgPixmap := devBgPixmap. |
|
149 |
] ifFalse:[ |
|
150 |
(bgPixmap depth == 1) ifTrue:[ |
|
151 |
" |
|
152 |
although depth matches, |
|
153 |
values in the dither are to be interpreted via the ditherForms |
|
154 |
colormap, which is not always the same as blackpixel/whitepixel ... |
|
155 |
" |
|
156 |
(bgPixmap colorMap at:1) colorId == device whitepixel ifTrue:[ |
|
157 |
(bgPixmap colorMap at:2) colorId == device blackpixel ifTrue:[ |
|
158 |
" |
|
159 |
ok, can use it |
|
160 |
" |
|
161 |
device setWindowBackgroundPixmap:(bgPixmap id) in:drawableId. |
|
162 |
^ self |
|
163 |
] |
|
164 |
]. |
|
40 | 165 |
|
72 | 166 |
" |
167 |
no, must invert it |
|
168 |
" |
|
169 |
devBgPixmap := Form width:w height:h depth:(device depth) on:device. |
|
170 |
devBgPixmap paint:(bgPixmap colorMap at:2) on:(bgPixmap colorMap at:1). |
|
171 |
devBgPixmap copyPlaneFrom:bgPixmap x:0 y:0 toX:0 y:0 width:w height:h. |
|
172 |
bgPixmap := devBgPixmap. |
|
173 |
] |
|
174 |
]. |
|
175 |
device setWindowBackgroundPixmap:(bgPixmap id) in:drawableId. |
|
0 | 176 |
] |
177 |
! |
|
178 |
||
269 | 179 |
viewBackground |
180 |
"return the viewBackground" |
|
181 |
||
182 |
^ viewBackground |
|
183 |
! |
|
184 |
||
185 |
viewBackground:something |
|
186 |
"set the viewBackground to something, a color, image or form. |
|
187 |
The viewBackground is the color or pattern with which exposed |
|
188 |
regions are filled - do not confuse this with the drawing background |
|
189 |
color, which is used with opaque drawing." |
|
0 | 190 |
|
269 | 191 |
viewBackground ~~ something ifTrue:[ |
192 |
viewBackground := something. |
|
193 |
drawableId notNil ifTrue:[ |
|
194 |
self setViewBackground |
|
195 |
] |
|
196 |
] |
|
197 |
! |
|
198 |
||
199 |
viewGravity |
|
200 |
"return the views gravity" |
|
201 |
||
202 |
^ #NorthWest |
|
203 |
! |
|
204 |
||
205 |
viewOrigin |
|
206 |
"0@0 here, since by default we cannot be scrolled" |
|
207 |
||
208 |
^ 0 @ 0 |
|
209 |
! |
|
210 |
||
211 |
widget |
|
212 |
"ST-80 compatibility" |
|
213 |
||
214 |
^ self |
|
40 | 215 |
! ! |
216 |
||
217 |
!PseudoView methodsFor:'accessing-cursor'! |
|
0 | 218 |
|
219 |
cursor |
|
220 |
"return the views cursor" |
|
221 |
||
222 |
^ cursor |
|
223 |
! |
|
224 |
||
225 |
cursor:aCursor |
|
141 | 226 |
"set the views cursor. This cursor will be automatically displayed whenever |
227 |
the mouse-pointer enters the receiver. |
|
228 |
Cursors are typically set at view creation time and left as installed." |
|
0 | 229 |
|
316 | 230 |
self cursor:aCursor now:true |
231 |
||
232 |
" |
|
233 |
|v| |
|
234 |
||
235 |
v := View new. |
|
236 |
v cursor:(Cursor wait). |
|
237 |
v open. |
|
238 |
[v shown] whileFalse:[Processor yield]. |
|
239 |
[v shown] whileTrue:[ |
|
385
15fd1c806d2a
pass info if focus change was explicit (i.e. Tab-key) or by window manager.
Claus Gittinger <cg@exept.de>
parents:
373
diff
changeset
|
240 |
(Delay forSeconds:1) wait. |
15fd1c806d2a
pass info if focus change was explicit (i.e. Tab-key) or by window manager.
Claus Gittinger <cg@exept.de>
parents:
373
diff
changeset
|
241 |
v cursor:(Cursor normal). |
15fd1c806d2a
pass info if focus change was explicit (i.e. Tab-key) or by window manager.
Claus Gittinger <cg@exept.de>
parents:
373
diff
changeset
|
242 |
(Delay forSeconds:1) wait. |
15fd1c806d2a
pass info if focus change was explicit (i.e. Tab-key) or by window manager.
Claus Gittinger <cg@exept.de>
parents:
373
diff
changeset
|
243 |
v cursor:(Cursor wait). |
316 | 244 |
] |
245 |
" |
|
246 |
||
247 |
"Modified: 14.12.1995 / 21:28:14 / cg" |
|
248 |
! |
|
249 |
||
250 |
cursor:aCursor now:showImmediately |
|
251 |
"set the views cursor. This cursor will be automatically displayed whenever |
|
252 |
the mouse-pointer enters the receiver. |
|
253 |
Cursors are typically set at view creation time and left as installed." |
|
254 |
||
2 | 255 |
|id| |
256 |
||
0 | 257 |
aCursor notNil ifTrue:[ |
385
15fd1c806d2a
pass info if focus change was explicit (i.e. Tab-key) or by window manager.
Claus Gittinger <cg@exept.de>
parents:
373
diff
changeset
|
258 |
(aCursor ~~ cursor) ifTrue:[ |
15fd1c806d2a
pass info if focus change was explicit (i.e. Tab-key) or by window manager.
Claus Gittinger <cg@exept.de>
parents:
373
diff
changeset
|
259 |
cursor := aCursor. |
15fd1c806d2a
pass info if focus change was explicit (i.e. Tab-key) or by window manager.
Claus Gittinger <cg@exept.de>
parents:
373
diff
changeset
|
260 |
drawableId notNil ifTrue:[ |
15fd1c806d2a
pass info if focus change was explicit (i.e. Tab-key) or by window manager.
Claus Gittinger <cg@exept.de>
parents:
373
diff
changeset
|
261 |
cursor := cursor on:device. |
343 | 262 |
cursor isNil ifTrue:[ ^ self]. |
385
15fd1c806d2a
pass info if focus change was explicit (i.e. Tab-key) or by window manager.
Claus Gittinger <cg@exept.de>
parents:
373
diff
changeset
|
263 |
id := cursor id. |
15fd1c806d2a
pass info if focus change was explicit (i.e. Tab-key) or by window manager.
Claus Gittinger <cg@exept.de>
parents:
373
diff
changeset
|
264 |
id isNil ifTrue:[ |
15fd1c806d2a
pass info if focus change was explicit (i.e. Tab-key) or by window manager.
Claus Gittinger <cg@exept.de>
parents:
373
diff
changeset
|
265 |
'PSEUDOVIEW: nil cursorId ignored; shape=' errorPrint. cursor shape errorPrintNL. |
15fd1c806d2a
pass info if focus change was explicit (i.e. Tab-key) or by window manager.
Claus Gittinger <cg@exept.de>
parents:
373
diff
changeset
|
266 |
^ self |
15fd1c806d2a
pass info if focus change was explicit (i.e. Tab-key) or by window manager.
Claus Gittinger <cg@exept.de>
parents:
373
diff
changeset
|
267 |
]. |
15fd1c806d2a
pass info if focus change was explicit (i.e. Tab-key) or by window manager.
Claus Gittinger <cg@exept.de>
parents:
373
diff
changeset
|
268 |
device setCursor:id in:drawableId. |
15fd1c806d2a
pass info if focus change was explicit (i.e. Tab-key) or by window manager.
Claus Gittinger <cg@exept.de>
parents:
373
diff
changeset
|
269 |
(showImmediately and:[realized]) ifTrue:[ |
15fd1c806d2a
pass info if focus change was explicit (i.e. Tab-key) or by window manager.
Claus Gittinger <cg@exept.de>
parents:
373
diff
changeset
|
270 |
"flush, to make cursor immediately visible" |
15fd1c806d2a
pass info if focus change was explicit (i.e. Tab-key) or by window manager.
Claus Gittinger <cg@exept.de>
parents:
373
diff
changeset
|
271 |
device flush |
15fd1c806d2a
pass info if focus change was explicit (i.e. Tab-key) or by window manager.
Claus Gittinger <cg@exept.de>
parents:
373
diff
changeset
|
272 |
] |
15fd1c806d2a
pass info if focus change was explicit (i.e. Tab-key) or by window manager.
Claus Gittinger <cg@exept.de>
parents:
373
diff
changeset
|
273 |
] |
15fd1c806d2a
pass info if focus change was explicit (i.e. Tab-key) or by window manager.
Claus Gittinger <cg@exept.de>
parents:
373
diff
changeset
|
274 |
] |
0 | 275 |
] |
141 | 276 |
|
277 |
" |
|
278 |
|v| |
|
279 |
||
280 |
v := View new. |
|
281 |
v cursor:(Cursor wait). |
|
282 |
v open. |
|
283 |
[v shown] whileFalse:[Processor yield]. |
|
284 |
[v shown] whileTrue:[ |
|
385
15fd1c806d2a
pass info if focus change was explicit (i.e. Tab-key) or by window manager.
Claus Gittinger <cg@exept.de>
parents:
373
diff
changeset
|
285 |
(Delay forSeconds:1) wait. |
15fd1c806d2a
pass info if focus change was explicit (i.e. Tab-key) or by window manager.
Claus Gittinger <cg@exept.de>
parents:
373
diff
changeset
|
286 |
v cursor:(Cursor normal). |
15fd1c806d2a
pass info if focus change was explicit (i.e. Tab-key) or by window manager.
Claus Gittinger <cg@exept.de>
parents:
373
diff
changeset
|
287 |
(Delay forSeconds:1) wait. |
15fd1c806d2a
pass info if focus change was explicit (i.e. Tab-key) or by window manager.
Claus Gittinger <cg@exept.de>
parents:
373
diff
changeset
|
288 |
v cursor:(Cursor wait). |
141 | 289 |
] |
290 |
" |
|
316 | 291 |
|
292 |
"Created: 14.12.1995 / 21:28:00 / cg" |
|
0 | 293 |
! |
294 |
||
295 |
withCursor:aCursor do:aBlock |
|
160 | 296 |
"evaluate aBlock showing aCursor until ready; then restore the old cursor |
297 |
and return the value as returned by aBlock. |
|
298 |
||
299 |
Notice, that this method only changes the cursor for a SINGLE (sub-)view. |
|
300 |
Most applications want to have the cursor changed in all views of its |
|
301 |
application. Use 'aView windowGroup withCursor:do:' to acomplish this." |
|
0 | 302 |
|
303 |
|savedCursor| |
|
304 |
||
305 |
savedCursor := cursor. |
|
306 |
self cursor:aCursor. |
|
160 | 307 |
^ aBlock valueNowOrOnUnwindDo:[self cursor:savedCursor] |
359
fc8d3db46d29
moved withWaitCursorDo: from TopView to here
Claus Gittinger <cg@exept.de>
parents:
343
diff
changeset
|
308 |
! |
fc8d3db46d29
moved withWaitCursorDo: from TopView to here
Claus Gittinger <cg@exept.de>
parents:
343
diff
changeset
|
309 |
|
360
9785d77aa3a8
moved withReadCursorDo: / withExecuteCursor to here
Claus Gittinger <cg@exept.de>
parents:
359
diff
changeset
|
310 |
withExecuteCursorDo:aBlock |
9785d77aa3a8
moved withReadCursorDo: / withExecuteCursor to here
Claus Gittinger <cg@exept.de>
parents:
359
diff
changeset
|
311 |
"evaluate aBlock while showing an execute cursor in all my views. |
9785d77aa3a8
moved withReadCursorDo: / withExecuteCursor to here
Claus Gittinger <cg@exept.de>
parents:
359
diff
changeset
|
312 |
Return the value as returned by aBlock." |
9785d77aa3a8
moved withReadCursorDo: / withExecuteCursor to here
Claus Gittinger <cg@exept.de>
parents:
359
diff
changeset
|
313 |
|
9785d77aa3a8
moved withReadCursorDo: / withExecuteCursor to here
Claus Gittinger <cg@exept.de>
parents:
359
diff
changeset
|
314 |
^ self withCursor:(Cursor execute) do:aBlock |
9785d77aa3a8
moved withReadCursorDo: / withExecuteCursor to here
Claus Gittinger <cg@exept.de>
parents:
359
diff
changeset
|
315 |
|
9785d77aa3a8
moved withReadCursorDo: / withExecuteCursor to here
Claus Gittinger <cg@exept.de>
parents:
359
diff
changeset
|
316 |
"Created: 10.1.1996 / 13:53:03 / cg" |
9785d77aa3a8
moved withReadCursorDo: / withExecuteCursor to here
Claus Gittinger <cg@exept.de>
parents:
359
diff
changeset
|
317 |
! |
9785d77aa3a8
moved withReadCursorDo: / withExecuteCursor to here
Claus Gittinger <cg@exept.de>
parents:
359
diff
changeset
|
318 |
|
9785d77aa3a8
moved withReadCursorDo: / withExecuteCursor to here
Claus Gittinger <cg@exept.de>
parents:
359
diff
changeset
|
319 |
withReadCursorDo:aBlock |
9785d77aa3a8
moved withReadCursorDo: / withExecuteCursor to here
Claus Gittinger <cg@exept.de>
parents:
359
diff
changeset
|
320 |
"evaluate aBlock while showing a readCursor in all my views. |
9785d77aa3a8
moved withReadCursorDo: / withExecuteCursor to here
Claus Gittinger <cg@exept.de>
parents:
359
diff
changeset
|
321 |
Return the value as returned by aBlock." |
9785d77aa3a8
moved withReadCursorDo: / withExecuteCursor to here
Claus Gittinger <cg@exept.de>
parents:
359
diff
changeset
|
322 |
|
9785d77aa3a8
moved withReadCursorDo: / withExecuteCursor to here
Claus Gittinger <cg@exept.de>
parents:
359
diff
changeset
|
323 |
^ self withCursor:(Cursor read) do:aBlock |
9785d77aa3a8
moved withReadCursorDo: / withExecuteCursor to here
Claus Gittinger <cg@exept.de>
parents:
359
diff
changeset
|
324 |
|
9785d77aa3a8
moved withReadCursorDo: / withExecuteCursor to here
Claus Gittinger <cg@exept.de>
parents:
359
diff
changeset
|
325 |
"Modified: 14.12.1995 / 20:57:40 / cg" |
9785d77aa3a8
moved withReadCursorDo: / withExecuteCursor to here
Claus Gittinger <cg@exept.de>
parents:
359
diff
changeset
|
326 |
"Created: 10.1.1996 / 13:52:52 / cg" |
9785d77aa3a8
moved withReadCursorDo: / withExecuteCursor to here
Claus Gittinger <cg@exept.de>
parents:
359
diff
changeset
|
327 |
! |
9785d77aa3a8
moved withReadCursorDo: / withExecuteCursor to here
Claus Gittinger <cg@exept.de>
parents:
359
diff
changeset
|
328 |
|
359
fc8d3db46d29
moved withWaitCursorDo: from TopView to here
Claus Gittinger <cg@exept.de>
parents:
343
diff
changeset
|
329 |
withWaitCursorDo:aBlock |
fc8d3db46d29
moved withWaitCursorDo: from TopView to here
Claus Gittinger <cg@exept.de>
parents:
343
diff
changeset
|
330 |
"evaluate aBlock while showing a waitCursor in all my views. |
fc8d3db46d29
moved withWaitCursorDo: from TopView to here
Claus Gittinger <cg@exept.de>
parents:
343
diff
changeset
|
331 |
Return the value as returned by aBlock." |
fc8d3db46d29
moved withWaitCursorDo: from TopView to here
Claus Gittinger <cg@exept.de>
parents:
343
diff
changeset
|
332 |
|
fc8d3db46d29
moved withWaitCursorDo: from TopView to here
Claus Gittinger <cg@exept.de>
parents:
343
diff
changeset
|
333 |
^ self withCursor:(Cursor wait) do:aBlock |
fc8d3db46d29
moved withWaitCursorDo: from TopView to here
Claus Gittinger <cg@exept.de>
parents:
343
diff
changeset
|
334 |
|
fc8d3db46d29
moved withWaitCursorDo: from TopView to here
Claus Gittinger <cg@exept.de>
parents:
343
diff
changeset
|
335 |
"Created: 10.1.1996 / 13:51:08 / cg" |
40 | 336 |
! ! |
337 |
||
338 |
!PseudoView methodsFor:'accessing-hierarchy'! |
|
0 | 339 |
|
12 | 340 |
delegate |
341 |
"return the delegate - thats the one getting keyboard and button events" |
|
0 | 342 |
|
12 | 343 |
^ delegate |
344 |
! |
|
345 |
||
346 |
delegate:someOne |
|
141 | 347 |
"set the delegate - keyboard- and button events will be forwarded to |
320
b7b8dc88fe9f
interest is written with one 'r' (shame on me)
Claus Gittinger <cg@exept.de>
parents:
316
diff
changeset
|
348 |
that object if it is interested in them. |
141 | 349 |
See the sendEvent... method in WindowEvent." |
12 | 350 |
|
351 |
delegate := someOne |
|
269 | 352 |
! |
353 |
||
354 |
superView |
|
355 |
"return the superView - nil here" |
|
356 |
||
357 |
^ nil |
|
358 |
! |
|
359 |
||
360 |
topView |
|
361 |
"return the topView - that the one with no superview" |
|
362 |
||
363 |
^ self |
|
364 |
! ! |
|
365 |
||
366 |
!PseudoView methodsFor:'accessing-limits'! |
|
367 |
||
368 |
maxExtent |
|
369 |
"return the views maximum extent - this is nil here. |
|
370 |
Only standardSystemViews support this." |
|
371 |
||
372 |
^ nil |
|
373 |
! |
|
374 |
||
375 |
maxExtent:extent |
|
376 |
"set the views maximum extent - ignored here. |
|
377 |
Only standardSystemViews support this." |
|
378 |
||
379 |
^ self |
|
380 |
! |
|
381 |
||
382 |
minExtent |
|
383 |
"return the views minimum extent - this is nil here. |
|
384 |
Only standardSystemViews support this." |
|
385 |
||
386 |
^ nil |
|
387 |
! |
|
388 |
||
389 |
minExtent:extent |
|
390 |
"set the views minimum extent - ignored here. |
|
391 |
Only standardSystemViews support this." |
|
392 |
||
393 |
^ self |
|
394 |
! ! |
|
395 |
||
396 |
!PseudoView methodsFor:'accessing-misc'! |
|
397 |
||
398 |
backingStore:how |
|
399 |
"turn on/off backingStore (saving my pixels) |
|
400 |
how may true/false, but also #always, #whenMapped or #never." |
|
401 |
||
402 |
how ~~ backed ifTrue:[ |
|
403 |
backed := how. |
|
404 |
drawableId notNil ifTrue:[ |
|
405 |
device setBackingStore:how in:drawableId |
|
406 |
] |
|
407 |
] |
|
408 |
! |
|
409 |
||
410 |
clipByChildren |
|
411 |
"drawing shall be done into my view only (default)" |
|
412 |
||
413 |
^ self clippedByChildren:true |
|
414 |
! |
|
415 |
||
416 |
clippedByChildren:aBoolean |
|
417 |
"turn on/off drawing over children. |
|
418 |
If on, a superview may draw 'over' its children. |
|
419 |
If off (the default), drawing is 'under' its children. |
|
420 |
Only useful for the rootView, to draw over any visible views. |
|
421 |
(for example, when dragging a rubber-line)" |
|
422 |
||
423 |
gcId isNil ifTrue:[ |
|
424 |
self initGC |
|
425 |
]. |
|
426 |
device setClipByChildren:aBoolean in:gcId |
|
427 |
! |
|
428 |
||
429 |
eventMask |
|
430 |
"return a (numeric) mask of allowed events - |
|
431 |
this is X-specific and will be removed / replaced by symbolic values)" |
|
432 |
||
433 |
^ eventMask |
|
434 |
! |
|
435 |
||
436 |
eventMask:aMask |
|
437 |
"set a (numeric) mask of allowed events - |
|
438 |
this is X-specific and will be removed / replaced by symbolic values)" |
|
439 |
||
440 |
eventMask := aMask |
|
441 |
! |
|
442 |
||
443 |
getKeyboardFocus |
|
444 |
"tell the Display to assign keyboard focus to the receiver" |
|
445 |
||
446 |
drawableId notNil ifTrue:[ |
|
447 |
self shown ifTrue:[ |
|
448 |
device setInputFocusTo:drawableId |
|
449 |
] |
|
450 |
]. |
|
451 |
! |
|
452 |
||
453 |
inputOnly |
|
454 |
"return true, if the receiver is an input only view - that is: |
|
455 |
the view will realize as a transparent view, into which you cannot |
|
456 |
draw, but get events as usual. Thich can be used to catch events away from |
|
457 |
others, which where never meant to work in such a setup. |
|
458 |
(for example, if you want to manipulate views in some DrawTool-like manner). |
|
459 |
This uses a special X feature, which might not be supported in the near future |
|
460 |
or on other plattforms." |
|
461 |
||
462 |
^ false |
|
463 |
! |
|
464 |
||
465 |
noClipByChildren |
|
466 |
"drawing shall also be done into subviews" |
|
467 |
||
468 |
^ self clippedByChildren:false |
|
469 |
||
470 |
! |
|
471 |
||
472 |
preferredDepth |
|
473 |
"return a non nil integer, if a specific depth is wanted in this view. |
|
474 |
Return nil if we do not care (i.e. the displays default is wanted). |
|
475 |
This is experimental and may change/vanish - do not use it." |
|
476 |
||
477 |
^ nil |
|
478 |
! |
|
479 |
||
480 |
preferredVisual |
|
481 |
"return a non nil id, if a specific visual is wanted in this view. |
|
482 |
Return nil if we do not care (i.e. the displays default is wanted). |
|
483 |
This is experimental and may change/vanish - do not use it." |
|
484 |
||
485 |
^ nil |
|
486 |
! |
|
487 |
||
488 |
realized |
|
489 |
"return true, if the receiver is realized" |
|
490 |
||
491 |
^ realized |
|
492 |
! |
|
493 |
||
494 |
saveUnder:aBoolean |
|
495 |
"turn on/off saveUnder (saving pixels under myself) |
|
496 |
- used for temporary views (i.e. PopUps and ModalBoxes)" |
|
497 |
||
498 |
saveUnder := aBoolean. |
|
499 |
drawableId notNil ifTrue:[ |
|
500 |
device setSaveUnder:aBoolean in:drawableId |
|
501 |
] |
|
40 | 502 |
! ! |
503 |
||
504 |
!PseudoView methodsFor:'accessing-names'! |
|
0 | 505 |
|
269 | 506 |
icon |
507 |
"return the views icon - this is nil here. |
|
40 | 508 |
Only standardSystemViews support labels and icons." |
0 | 509 |
|
510 |
^ nil |
|
511 |
! |
|
512 |
||
269 | 513 |
icon:aBitmap |
514 |
"set the views icon - ignored here. |
|
40 | 515 |
Only standardSystemViews support labels and icons." |
0 | 516 |
|
517 |
^ self |
|
518 |
! |
|
519 |
||
24 | 520 |
iconLabel |
40 | 521 |
"return the views icon label - this is nil here. |
522 |
Only standardSystemViews support labels and icons." |
|
24 | 523 |
|
524 |
^ nil |
|
525 |
! |
|
526 |
||
527 |
iconLabel:aLabel |
|
40 | 528 |
"set the views icon label - ignored here. |
529 |
Only standardSystemViews support labels and icons." |
|
0 | 530 |
|
531 |
^ self |
|
532 |
! |
|
533 |
||
534 |
iconView |
|
40 | 535 |
"return the views iconView - this is nil here. |
536 |
Only standardSystemViews support labels and icons." |
|
0 | 537 |
|
538 |
^ nil |
|
539 |
! |
|
540 |
||
24 | 541 |
iconView:aView |
40 | 542 |
"set the views icon view - ignored here. |
543 |
Only standardSystemViews support labels and icons." |
|
24 | 544 |
|
545 |
^ self |
|
546 |
! |
|
547 |
||
269 | 548 |
label |
549 |
"return the views label - this is nil here. |
|
40 | 550 |
Only standardSystemViews support labels and icons." |
0 | 551 |
|
552 |
^ nil |
|
553 |
! |
|
554 |
||
269 | 555 |
label:aLabel |
556 |
"set the views label - ignored here. |
|
40 | 557 |
Only standardSystemViews support labels and icons." |
558 |
||
559 |
^ self |
|
560 |
! ! |
|
561 |
||
269 | 562 |
!PseudoView methodsFor:'binary storage'! |
40 | 563 |
|
269 | 564 |
readBinaryContentsFrom: stream manager: manager |
565 |
"tell the newly restored View to recreate itself. |
|
566 |
Bug: does not work correctly yet. |
|
567 |
(restored view looses its position & wg process)" |
|
40 | 568 |
|
269 | 569 |
super readBinaryContentsFrom: stream manager: manager. |
40 | 570 |
|
269 | 571 |
gcId := nil. |
572 |
drawableId := nil. |
|
573 |
self recreate. |
|
574 |
realized ifTrue:[ |
|
575 |
self rerealize |
|
576 |
] |
|
40 | 577 |
|
269 | 578 |
" |
579 |
|s| |
|
580 |
s := 'storedLabel.boss' asFilename writeStream binary. |
|
581 |
(Label label:'hello there') realize storeBinaryOn:s. |
|
582 |
s close. |
|
583 |
" |
|
40 | 584 |
|
269 | 585 |
" |
586 |
|s l| |
|
587 |
s := 'storedLabel.boss' asFilename writeStream binary. |
|
588 |
(l := Label label:'hello there') open. |
|
589 |
(Delay forSeconds:10) wait. |
|
590 |
l storeBinaryOn:s. |
|
591 |
s close. |
|
592 |
l destroy. |
|
593 |
" |
|
40 | 594 |
|
269 | 595 |
" |
596 |
|s| |
|
597 |
s := 'storedLabel.boss' asFilename readStream binary. |
|
598 |
(Object readBinaryFrom:s) |
|
599 |
" |
|
40 | 600 |
! ! |
601 |
||
269 | 602 |
!PseudoView methodsFor:'button menus'! |
40 | 603 |
|
269 | 604 |
middleButtonMenu |
605 |
"return the menu associated with the middle mouse button" |
|
12 | 606 |
|
269 | 607 |
^ middleButtonMenu |
0 | 608 |
! |
609 |
||
269 | 610 |
middleButtonMenu:aMenu |
611 |
"associate aMenu with the middle mouse button" |
|
0 | 612 |
|
269 | 613 |
middleButtonMenu notNil ifTrue:[ |
614 |
middleButtonMenu destroy |
|
0 | 615 |
]. |
269 | 616 |
middleButtonMenu := aMenu |
0 | 617 |
! |
618 |
||
269 | 619 |
setMiddleButtonMenu:aMenu |
620 |
"associate aMenu with the middle mouse button. |
|
621 |
Do not destroy old menu if any" |
|
0 | 622 |
|
269 | 623 |
middleButtonMenu := aMenu |
0 | 624 |
! ! |
625 |
||
626 |
!PseudoView methodsFor:'drawing'! |
|
627 |
||
81 | 628 |
clearDeviceRectangleX:x y:y width:w height:h |
0 | 629 |
"clear a rectangular area to viewBackground - |
630 |
redefined since DisplayMedium fills with background |
|
72 | 631 |
- not viewBackground as we want here." |
632 |
||
116 | 633 |
|oldPaint org| |
72 | 634 |
|
635 |
oldPaint := paint. |
|
636 |
self paint:viewBackground. |
|
0 | 637 |
|
40 | 638 |
viewBackground isColor ifFalse:[ |
89 | 639 |
gcId notNil ifTrue:[ |
116 | 640 |
org := self viewOrigin. |
641 |
device setMaskOriginX:org x rounded negated |
|
642 |
y:org y rounded negated |
|
89 | 643 |
in:gcId |
644 |
]. |
|
0 | 645 |
]. |
72 | 646 |
" |
647 |
fill in device coordinates - not logical coordinates |
|
648 |
" |
|
649 |
self fillDeviceRectangleX:x y:y width:w height:h "with:viewBackground". |
|
650 |
self paint:oldPaint |
|
81 | 651 |
! |
652 |
||
653 |
clearRectangleX:x y:y width:w height:h |
|
654 |
"clear a rectangular area to viewBackground - |
|
655 |
redefined since DisplayMedium fills with background |
|
656 |
- not viewBackground as we want here." |
|
657 |
||
116 | 658 |
|oldPaint org| |
81 | 659 |
|
660 |
oldPaint := paint. |
|
661 |
self paint:viewBackground. |
|
662 |
||
663 |
viewBackground isColor ifFalse:[ |
|
89 | 664 |
gcId notNil ifTrue:[ |
116 | 665 |
org := self viewOrigin. |
666 |
device setMaskOriginX:org x rounded negated |
|
667 |
y:org y rounded negated |
|
89 | 668 |
in:gcId |
669 |
]. |
|
81 | 670 |
]. |
671 |
self fillRectangleX:x y:y width:w height:h. |
|
672 |
self paint:oldPaint |
|
0 | 673 |
! |
674 |
||
269 | 675 |
redraw |
676 |
"nothing done here" |
|
0 | 677 |
|
269 | 678 |
^ self |
0 | 679 |
! ! |
680 |
||
681 |
!PseudoView methodsFor:'enable/disable events'! |
|
682 |
||
269 | 683 |
compressMotionEvents:aBoolean |
684 |
"enable/disable motion event compression |
|
685 |
(i.e. replacing all motion events by the last one). |
|
686 |
Compression makes almost always sense, except when |
|
687 |
doing things like freehand drawing" |
|
688 |
||
689 |
|s| |
|
690 |
||
691 |
(s := self sensor) notNil ifTrue:[ |
|
692 |
s compressMotionEvents:aBoolean |
|
693 |
] |
|
694 |
! |
|
695 |
||
696 |
disableButtonEvents |
|
697 |
"disable all button events" |
|
698 |
||
699 |
self disableEvent:#buttonpress. |
|
700 |
self disableEvent:#buttonRelease |
|
701 |
! |
|
702 |
||
703 |
disableButtonMotionEvents |
|
704 |
"disable button motion-while-button-is-pressed events" |
|
705 |
||
706 |
self disableEvent:#buttonMotion |
|
707 |
! |
|
708 |
||
709 |
disableButtonPressEvents |
|
710 |
"disable button press events" |
|
711 |
||
712 |
self disableEvent:#buttonPress |
|
713 |
! |
|
714 |
||
715 |
disableButtonReleaseEvents |
|
716 |
"disable button release events" |
|
717 |
||
718 |
self disableEvent:#buttonRelease |
|
719 |
! |
|
720 |
||
721 |
disableEnterLeaveEvents |
|
722 |
"disable both mouse-pointer enter and leave events" |
|
723 |
||
724 |
self disableEvent:#enter. |
|
725 |
self disableEvent:#leave |
|
726 |
! |
|
727 |
||
728 |
disableEvent:anEventSymbol |
|
729 |
"disable an event - |
|
730 |
this is a private (internal) method not to be used externally. |
|
731 |
for a list of allowed event symbols see Workstation class" |
|
732 |
||
733 |
eventMask := eventMask bitAnd:(device eventMaskFor:anEventSymbol) bitInvert. |
|
734 |
drawableId notNil ifTrue:[ |
|
735 |
device setEventMask:eventMask in:drawableId |
|
736 |
] |
|
737 |
! |
|
738 |
||
739 |
disableMotionEvents |
|
740 |
"disable motion events" |
|
741 |
||
742 |
self disableEvent:#pointerMotion |
|
743 |
! |
|
744 |
||
745 |
enableButtonEvents |
|
746 |
"enable both mouse button press and release events. |
|
747 |
These are enabled by default anyway." |
|
748 |
||
749 |
self enableEvent:#buttonPress. |
|
750 |
self enableEvent:#buttonRelease |
|
751 |
! |
|
752 |
||
753 |
enableButtonMotionEvents |
|
754 |
"enable mouse-pointer motion-while-button-is-pressed events. |
|
755 |
These are enabled by default anyway." |
|
756 |
||
757 |
self enableEvent:#buttonMotion |
|
758 |
! |
|
759 |
||
760 |
enableButtonPressEvents |
|
761 |
"enable mouse button press events. |
|
762 |
These are enabled by default anyway." |
|
763 |
||
764 |
self enableEvent:#buttonPress |
|
765 |
! |
|
766 |
||
767 |
enableButtonReleaseEvents |
|
768 |
"enable mouse button release events. |
|
769 |
These are enabled by default anyway." |
|
770 |
||
771 |
self enableEvent:#buttonRelease |
|
772 |
! |
|
773 |
||
774 |
enableEnterEvents |
|
775 |
"enable mouse-pointer enter events" |
|
776 |
||
777 |
self enableEvent:#enter |
|
778 |
! |
|
779 |
||
780 |
enableEnterLeaveEvents |
|
781 |
"enable both mouse-pointer enter and leave events" |
|
782 |
||
783 |
self enableEvent:#enter. |
|
784 |
self enableEvent:#leave |
|
785 |
! |
|
786 |
||
0 | 787 |
enableEvent:anEventSymbol |
788 |
"enable an event - |
|
789 |
this is a private (internal) method not to be used externally. |
|
2 | 790 |
for a list of allowed event symbols see Workstation class" |
0 | 791 |
|
792 |
eventMask := eventMask bitOr:(device eventMaskFor:anEventSymbol). |
|
2 | 793 |
drawableId notNil ifTrue:[ |
72 | 794 |
device setEventMask:eventMask in:drawableId |
0 | 795 |
] |
796 |
! |
|
797 |
||
269 | 798 |
enableFocusEvents |
799 |
"enable keyboard focus change events" |
|
800 |
||
801 |
self enableEvent:#focusChange |
|
0 | 802 |
! |
803 |
||
54 | 804 |
enableKeyEvents |
805 |
"this is a compatibility leftover - |
|
806 |
starting with 2.10.3, keyPress is always enabled to allow |
|
807 |
^C processing." |
|
808 |
||
809 |
! |
|
810 |
||
0 | 811 |
enableKeyPressEvents |
54 | 812 |
"this is a compatibility leftover - |
813 |
starting with 2.10.3, keyPress is always enabled to allow |
|
814 |
^C processing." |
|
0 | 815 |
|
816 |
! |
|
817 |
||
818 |
enableKeyReleaseEvents |
|
819 |
"enable key release events" |
|
820 |
||
821 |
self enableEvent:#keyRelease |
|
822 |
! |
|
823 |
||
824 |
enableLeaveEvents |
|
825 |
"enable mouse-pointer leave events" |
|
826 |
||
827 |
self enableEvent:#leave |
|
828 |
! |
|
829 |
||
830 |
enableMotionEvents |
|
831 |
"enable mouse-pointer motion events" |
|
832 |
||
833 |
self enableEvent:#pointerMotion |
|
269 | 834 |
! ! |
835 |
||
836 |
!PseudoView methodsFor:'event handling'! |
|
837 |
||
838 |
buttonMotion:state x:x y:y |
|
839 |
"mouse was moved while button is pressed - do nothing here" |
|
840 |
||
841 |
^ self |
|
0 | 842 |
! |
843 |
||
269 | 844 |
buttonMultiPress:button x:x y:y |
845 |
"button was pressed fast after previous press - default to press-again" |
|
846 |
||
847 |
^ self buttonPress:button x:x y:y |
|
848 |
! |
|
21 | 849 |
|
269 | 850 |
buttonPress:button x:x y:y |
851 |
"button was pressed - if its middle button and there is a menu, |
|
852 |
show it." |
|
85 | 853 |
|
269 | 854 |
((button == 2) or:[button == #menu]) ifTrue:[ |
855 |
middleButtonMenu notNil ifTrue:[ |
|
856 |
middleButtonMenu showAtPointer |
|
857 |
] |
|
85 | 858 |
] |
21 | 859 |
! |
860 |
||
269 | 861 |
buttonRelease:button x:x y:y |
862 |
"button was released - do nothing here" |
|
0 | 863 |
|
269 | 864 |
^ self |
89 | 865 |
! |
866 |
||
269 | 867 |
buttonShiftPress:button x:x y:y |
868 |
"button was pressed with shift - default to unshift-press action" |
|
89 | 869 |
|
269 | 870 |
^ self buttonPress:button x:x y:y |
89 | 871 |
! |
872 |
||
28 | 873 |
catchExpose |
54 | 874 |
"this MUST be sent BEFORE doing a bit-blt copy (i.e. copyFrom...), |
875 |
to tell the sensor that incoming expose events are to be remembered. |
|
876 |
Sometime after the bit-blt, waitForExpose should be sent, to finally |
|
877 |
suspend until the expose/noExpose event arrives. |
|
878 |
This may be an X speciality and be reimplemented to handle devices |
|
879 |
which do not need this kind of asynchronous bit-blt confirmation. |
|
880 |
" |
|
28 | 881 |
|
882 |
|wg| |
|
883 |
||
54 | 884 |
gotExpose := false. |
28 | 885 |
wg := self windowGroup. |
886 |
wg notNil ifTrue:[ |
|
72 | 887 |
" |
888 |
must process eny pending expose events, since |
|
889 |
usually the origin is changed soon so that previous |
|
890 |
expose events coordinates are invalid |
|
891 |
" |
|
892 |
wg processExposeEvents. |
|
893 |
wg sensor catchExpose |
|
28 | 894 |
] |
895 |
! |
|
896 |
||
269 | 897 |
deviceButtonMotion:state x:x y:y |
77 | 898 |
"this is the low-level (untransformed) event as received |
83 | 899 |
from the device (i.e. coordinates are in device coordinates). |
900 |
If there is a transformation, apply the inverse |
|
269 | 901 |
and send a buttonMotion with the logical coordinates." |
77 | 902 |
|
903 |
|lx ly| |
|
904 |
||
905 |
lx := x. |
|
906 |
ly := y. |
|
907 |
transformation notNil ifTrue:[ |
|
908 |
lx := transformation applyInverseToX:lx. |
|
909 |
ly := transformation applyInverseToY:ly. |
|
910 |
]. |
|
269 | 911 |
self buttonMotion:state x:lx y:ly |
77 | 912 |
! |
913 |
||
269 | 914 |
deviceButtonMultiPress:butt x:x y:y |
77 | 915 |
"this is the low-level (untransformed) event as received |
83 | 916 |
from the device (i.e. coordinates are in device coordinates). |
917 |
If there is a transformation, apply the inverse |
|
269 | 918 |
and send a buttonMultiPress with the logical coordinates." |
77 | 919 |
|
920 |
|lx ly| |
|
921 |
||
922 |
lx := x. |
|
923 |
ly := y. |
|
924 |
transformation notNil ifTrue:[ |
|
925 |
lx := transformation applyInverseToX:lx. |
|
926 |
ly := transformation applyInverseToY:ly. |
|
927 |
]. |
|
269 | 928 |
self buttonMultiPress:butt x:lx y:ly |
77 | 929 |
! |
930 |
||
83 | 931 |
deviceButtonPress:butt x:x y:y |
77 | 932 |
"this is the low-level (untransformed) event as received |
83 | 933 |
from the device (i.e. coordinates are in device coordinates). |
934 |
If there is a transformation, apply the inverse |
|
77 | 935 |
and send a buttonPress with the logical coordinates." |
936 |
||
937 |
|lx ly| |
|
938 |
||
939 |
lx := x. |
|
940 |
ly := y. |
|
941 |
transformation notNil ifTrue:[ |
|
942 |
lx := transformation applyInverseToX:lx. |
|
943 |
ly := transformation applyInverseToY:ly. |
|
944 |
]. |
|
945 |
self buttonPress:butt x:lx y:ly |
|
946 |
! |
|
947 |
||
83 | 948 |
deviceButtonRelease:butt x:x y:y |
77 | 949 |
"this is the low-level (untransformed) event as received |
83 | 950 |
from the device (i.e. coordinates are in device coordinates). |
951 |
If there is a transformation, apply the inverse |
|
77 | 952 |
and send a buttonRelease with the logical coordinates." |
953 |
||
954 |
|lx ly| |
|
955 |
||
956 |
lx := x. |
|
957 |
ly := y. |
|
958 |
transformation notNil ifTrue:[ |
|
959 |
lx := transformation applyInverseToX:lx. |
|
960 |
ly := transformation applyInverseToY:ly. |
|
961 |
]. |
|
962 |
self buttonRelease:butt x:lx y:ly |
|
963 |
! |
|
964 |
||
83 | 965 |
deviceButtonShiftPress:butt x:x y:y |
77 | 966 |
"this is the low-level (untransformed) event as received |
83 | 967 |
from the device (i.e. coordinates are in device coordinates). |
968 |
If there is a transformation, apply the inverse |
|
77 | 969 |
and send a buttonShiftPress with the logical coordinates." |
970 |
||
971 |
|lx ly| |
|
972 |
||
973 |
lx := x. |
|
974 |
ly := y. |
|
975 |
transformation notNil ifTrue:[ |
|
976 |
lx := transformation applyInverseToX:lx. |
|
977 |
ly := transformation applyInverseToY:ly. |
|
978 |
]. |
|
979 |
self buttonShiftPress:butt x:lx y:ly |
|
980 |
! |
|
981 |
||
269 | 982 |
deviceExposeX:x y:y width:w height:h |
77 | 983 |
"this is the low-level (untransformed) event as received |
83 | 984 |
from the device (i.e. coordinates are in device coordinates). |
985 |
If there is a transformation, apply the inverse |
|
269 | 986 |
and send an expose with the logical coordinates." |
987 |
||
988 |
|lx ly lw lh| |
|
989 |
||
990 |
lx := x. |
|
991 |
ly := y. |
|
992 |
lw := w. |
|
993 |
lh := h. |
|
994 |
transformation notNil ifTrue:[ |
|
995 |
lx := transformation applyInverseToX:lx. |
|
996 |
ly := transformation applyInverseToY:ly. |
|
997 |
lw := transformation applyInverseScaleX:lw. |
|
998 |
lh := transformation applyInverseScaleY:lh. |
|
999 |
]. |
|
1000 |
self exposeX:lx y:ly width:lw height:lh |
|
1001 |
! |
|
1002 |
||
1003 |
deviceGraphicExposeX:x y:y width:w height:h |
|
1004 |
"this is the low-level (untransformed) event as received |
|
1005 |
from the device (i.e. coordinates are in device coordinates). |
|
1006 |
If there is a transformation, apply the inverse |
|
1007 |
and send a graphicExpose with the logical coordinates." |
|
1008 |
||
1009 |
|lx ly lw lh| |
|
1010 |
||
1011 |
lx := x. |
|
1012 |
ly := y. |
|
1013 |
lw := w. |
|
1014 |
lh := h. |
|
1015 |
transformation notNil ifTrue:[ |
|
1016 |
lx := transformation applyInverseToX:lx. |
|
1017 |
ly := transformation applyInverseToY:ly. |
|
1018 |
lw := transformation applyInverseScaleX:lw. |
|
1019 |
lh := transformation applyInverseScaleY:lh. |
|
1020 |
]. |
|
1021 |
self graphicExposeX:lx y:ly width:lw height:lh |
|
1022 |
! |
|
1023 |
||
1024 |
deviceKeyPress:key x:x y:y |
|
1025 |
"this is the low-level (untransformed) event as received |
|
1026 |
from the device (i.e. coordinates are in device coordinates). |
|
1027 |
If there is a transformation, apply the inverse |
|
1028 |
and send a keyPress with the logical coordinates." |
|
77 | 1029 |
|
1030 |
|lx ly| |
|
1031 |
||
1032 |
lx := x. |
|
1033 |
ly := y. |
|
1034 |
transformation notNil ifTrue:[ |
|
1035 |
lx := transformation applyInverseToX:lx. |
|
1036 |
ly := transformation applyInverseToY:ly. |
|
1037 |
]. |
|
269 | 1038 |
self keyPress:key x:lx y:ly |
77 | 1039 |
! |
1040 |
||
269 | 1041 |
deviceKeyRelease:key x:x y:y |
77 | 1042 |
"this is the low-level (untransformed) event as received |
83 | 1043 |
from the device (i.e. coordinates are in device coordinates). |
1044 |
If there is a transformation, apply the inverse |
|
269 | 1045 |
and send a keyRelease with the logical coordinates." |
77 | 1046 |
|
1047 |
|lx ly| |
|
1048 |
||
1049 |
lx := x. |
|
1050 |
ly := y. |
|
1051 |
transformation notNil ifTrue:[ |
|
1052 |
lx := transformation applyInverseToX:lx. |
|
1053 |
ly := transformation applyInverseToY:ly. |
|
1054 |
]. |
|
269 | 1055 |
self keyRelease:key x:lx y:ly |
77 | 1056 |
! |
1057 |
||
83 | 1058 |
devicePointerEnter:state x:x y:y |
77 | 1059 |
"this is the low-level (untransformed) event as received |
83 | 1060 |
from the device (i.e. coordinates are in device coordinates). |
1061 |
If there is a transformation, apply the inverse |
|
77 | 1062 |
and send a pointerEnter with the logical coordinates." |
1063 |
||
1064 |
|lx ly| |
|
1065 |
||
1066 |
lx := x. |
|
1067 |
ly := y. |
|
1068 |
transformation notNil ifTrue:[ |
|
1069 |
lx := transformation applyInverseToX:lx. |
|
1070 |
ly := transformation applyInverseToY:ly. |
|
1071 |
]. |
|
1072 |
self pointerEnter:state x:lx y:ly |
|
1073 |
! |
|
1074 |
||
269 | 1075 |
exposeX:x y:y width:w height:h |
1076 |
"an expose event - nothing done here" |
|
1077 |
||
1078 |
^ self |
|
1079 |
! |
|
1080 |
||
1081 |
focusIn |
|
385
15fd1c806d2a
pass info if focus change was explicit (i.e. Tab-key) or by window manager.
Claus Gittinger <cg@exept.de>
parents:
373
diff
changeset
|
1082 |
"got keyboard focus - do nothing here" |
269 | 1083 |
|
1084 |
^ self |
|
1085 |
! |
|
1086 |
||
1087 |
focusOut |
|
385
15fd1c806d2a
pass info if focus change was explicit (i.e. Tab-key) or by window manager.
Claus Gittinger <cg@exept.de>
parents:
373
diff
changeset
|
1088 |
"lost keyboard focus - do nothing here" |
269 | 1089 |
|
1090 |
^ self |
|
1091 |
! |
|
1092 |
||
0 | 1093 |
graphicExposeX:x y:y width:w height:h |
54 | 1094 |
"an expose event after a scroll - do normal redraw processing" |
0 | 1095 |
|
1096 |
self exposeX:x y:y width:w height:h |
|
1097 |
! |
|
1098 |
||
1099 |
keyPress:key x:x y:y |
|
54 | 1100 |
"a key was pressed in this view. |
1101 |
Here only keyCommands are handled - more action has to |
|
0 | 1102 |
be implemented by redefining this method" |
1103 |
||
1104 |
|action| |
|
1105 |
||
1106 |
keyCommands notNil ifTrue:[ |
|
72 | 1107 |
action := keyCommands at:key ifAbsent:[nil]. |
1108 |
action notNil ifTrue:[ |
|
1109 |
action value |
|
1110 |
] |
|
0 | 1111 |
] |
1112 |
! |
|
1113 |
||
1114 |
keyRelease:key x:x y:y |
|
1115 |
"default action is to do nothing" |
|
1116 |
||
1117 |
^ self |
|
1118 |
! |
|
1119 |
||
269 | 1120 |
noExpose |
1121 |
"a no expose event after a scroll (event-mode only)" |
|
0 | 1122 |
|
269 | 1123 |
exposePending := false. |
1124 |
gotExpose := true |
|
0 | 1125 |
! |
1126 |
||
1127 |
pointerEnter:state x:x y:y |
|
1128 |
"mouse cursor entered view - do nothing here" |
|
1129 |
||
1130 |
^ self |
|
1131 |
! |
|
1132 |
||
1133 |
pointerLeave:state |
|
1134 |
"mouse cursor left view - do nothing here" |
|
1135 |
||
1136 |
^ self |
|
31 | 1137 |
! |
1138 |
||
1139 |
resizeRequest |
|
1140 |
^ self |
|
269 | 1141 |
! |
1142 |
||
1143 |
waitForExpose |
|
1144 |
"wait until an expose event arrives (to wait for scroll-finish)" |
|
1145 |
||
1146 |
|wg| |
|
1147 |
||
1148 |
wg := self windowGroup. |
|
1149 |
wg notNil ifTrue:[ |
|
1150 |
" |
|
1151 |
a normal (suspendable) view. |
|
1152 |
wait by doing a real wait |
|
1153 |
" |
|
1154 |
wg waitForExposeFor:self |
|
1155 |
] ifFalse:[ |
|
1156 |
" |
|
1157 |
a pure event driven view. |
|
1158 |
wait by doing a direct dispatch loop until the event arrives. |
|
1159 |
" |
|
1160 |
[gotExpose] whileFalse:[ |
|
1161 |
device dispatchExposeEventFor:drawableId |
|
1162 |
]. |
|
1163 |
] |
|
1164 |
! ! |
|
1165 |
||
1166 |
!PseudoView methodsFor:'initialize / release'! |
|
1167 |
||
1168 |
destroy |
|
1169 |
"view is about to be destroyed - |
|
1170 |
first destroy menu if there is one and also destroy the GC. |
|
1171 |
then the view is physically destroyed." |
|
1172 |
||
1173 |
middleButtonMenu notNil ifTrue:[ |
|
1174 |
middleButtonMenu destroy. |
|
1175 |
middleButtonMenu := nil |
|
1176 |
]. |
|
1177 |
keyCommands := nil. |
|
1178 |
gcId notNil ifTrue:[ |
|
1179 |
device destroyGC:gcId. |
|
1180 |
gcId := nil |
|
1181 |
]. |
|
1182 |
drawableId notNil ifTrue:[ |
|
1183 |
device destroyView:self withId:drawableId. |
|
1184 |
drawableId := nil |
|
1185 |
]. |
|
1186 |
Lobby unregister:self. |
|
1187 |
! |
|
1188 |
||
1189 |
destroyed |
|
1190 |
"view has been destroyed by someone else" |
|
1191 |
||
1192 |
drawableId notNil ifTrue:[ |
|
1193 |
device removeKnownView:self. |
|
1194 |
drawableId := nil. |
|
1195 |
realized := false. |
|
1196 |
]. |
|
1197 |
self destroy |
|
1198 |
! |
|
1199 |
||
1200 |
disposed |
|
1201 |
"view was collected - release system resources" |
|
1202 |
||
1203 |
drawableId notNil ifTrue:[ |
|
1204 |
gcId notNil ifTrue:[ |
|
1205 |
device destroyGC:gcId. |
|
1206 |
gcId := nil. |
|
1207 |
]. |
|
1208 |
device destroyView:self withId:drawableId. |
|
1209 |
drawableId := nil. |
|
1210 |
]. |
|
1211 |
! |
|
1212 |
||
1213 |
initCursor |
|
1214 |
"default cursor for all views" |
|
1215 |
||
1216 |
cursor := Cursor arrow |
|
1217 |
! |
|
1218 |
||
1219 |
initStyle |
|
1220 |
"nothing done here" |
|
1221 |
||
1222 |
^ self |
|
1223 |
! |
|
1224 |
||
1225 |
initialize |
|
1226 |
"initialize defaults" |
|
1227 |
||
1228 |
super initialize. |
|
1229 |
||
1230 |
eventMask := Display defaultEventMask. |
|
1231 |
viewBackground := background. |
|
1232 |
backed := false. |
|
1233 |
saveUnder := false. |
|
1234 |
exposePending := false. |
|
1235 |
self initCursor |
|
1236 |
! |
|
1237 |
||
1238 |
reAdjustGeometry |
|
1239 |
"sent late during snapin processing, nothing done here" |
|
1240 |
||
1241 |
^ self |
|
1242 |
! |
|
1243 |
||
1244 |
recreate |
|
1245 |
"recreate (i.e. tell X about me) after a snapin" |
|
1246 |
||
1247 |
viewBackground isColor ifTrue:[ |
|
1248 |
viewBackground := viewBackground on:device |
|
1249 |
]. |
|
1250 |
super recreate. |
|
1251 |
cursor := cursor on:device. |
|
1252 |
exposePending := false |
|
1253 |
! |
|
1254 |
||
1255 |
reinitStyle |
|
1256 |
"nothing done here" |
|
1257 |
||
1258 |
^ self |
|
0 | 1259 |
! ! |
2 | 1260 |
|
269 | 1261 |
!PseudoView methodsFor:'keyboard commands'! |
1262 |
||
1263 |
addActionForKey:aKey action:aBlock |
|
1264 |
"define a keyboard command function" |
|
1265 |
||
1266 |
keyCommands isNil ifTrue:[ |
|
1267 |
keyCommands := IdentityDictionary new |
|
1268 |
]. |
|
1269 |
keyCommands at:aKey put:aBlock |
|
1270 |
! |
|
1271 |
||
1272 |
removeActionForKey:aKey |
|
1273 |
keyCommands notNil ifTrue:[ |
|
1274 |
keyCommands removeKey:aKey ifAbsent:[] |
|
1275 |
] |
|
1276 |
! ! |
|
1277 |
||
1278 |
!PseudoView methodsFor:'queries'! |
|
1279 |
||
1280 |
buttonMotionEventPending |
|
1281 |
"return true, if a button motion event is pending. |
|
1282 |
Normally, you dont want to use this, since no polling is needed |
|
1283 |
(not even for mouse-tracking). |
|
1284 |
Dont use it, since it does not honor the windowGroup, but |
|
1285 |
goes directly to the device instead. |
|
1286 |
Actually, its a historical leftover" |
|
1287 |
||
1288 |
device flush. |
|
1289 |
^ device eventPending:#buttonMotion for:drawableId |
|
1290 |
! |
|
2 | 1291 |
|
269 | 1292 |
buttonReleaseEventPending |
1293 |
"return true, if a button release event is pending. |
|
1294 |
Dont use it, since it does not honor the windowGroup, but |
|
1295 |
goes directly to the device instead. |
|
1296 |
Actually, its a historical leftover" |
|
1297 |
||
1298 |
device flush. |
|
1299 |
^ device eventPending:#buttonRelease for:drawableId |
|
1300 |
! |
|
1301 |
||
1302 |
exposeEventPending |
|
1303 |
"return true, if an expose event is pending." |
|
1304 |
||
1305 |
|sensor| |
|
1306 |
||
1307 |
((sensor := self sensor) notNil and:[sensor hasDamageFor:self]) ifTrue:[^ true]. |
|
1308 |
^ device eventPending:#expose for:drawableId |
|
1309 |
! |
|
1310 |
||
1311 |
isView |
|
1312 |
"return true, if the receiver is a view" |
|
1313 |
||
1314 |
^ true |
|
1315 |
! |
|
1316 |
||
1317 |
isXtWidget |
|
1318 |
^ false |
|
1319 |
! ! |
|
1320 |
||
1321 |
!PseudoView methodsFor:'queries-contents'! |
|
1322 |
||
1323 |
heightOfContents |
|
1324 |
"return the height of the contents in pixels. |
|
1325 |
Since we dont know here, just return the views size. |
|
1326 |
This will make your scrollbars show 100%-visible. |
|
1327 |
Must be redefined in subviews to make scrollbars really work." |
|
1328 |
||
1329 |
^ self height |
|
1330 |
! |
|
2 | 1331 |
|
269 | 1332 |
widthOfContents |
1333 |
"return the width of the contents in pixels. |
|
1334 |
Since we dont know here, just return the views size. |
|
1335 |
This will make your scrollbars show 100%-visible. |
|
1336 |
Must be redefined in subviews to make scrollbars really work." |
|
1337 |
||
1338 |
^ self width |
|
1339 |
! |
|
1340 |
||
1341 |
xOriginOfContents |
|
1342 |
"return the x-origin of the contents in pixels. |
|
1343 |
Since we dont know here, just return 0 for left. |
|
1344 |
Must be redefined in subviews to make scrollbars really work." |
|
1345 |
||
1346 |
^ 0 |
|
1347 |
! |
|
1348 |
||
1349 |
yOriginOfContents |
|
1350 |
"return the y-origin of the contents in pixels. |
|
1351 |
Since we dont know here, just return 0 for top. |
|
1352 |
Must be redefined in subviews to make scrollbars really work." |
|
1353 |
||
1354 |
^ 0 |
|
1355 |
! ! |
|
1356 |
||
1357 |
!PseudoView methodsFor:'selection handling '! |
|
1358 |
||
1359 |
getSelection |
|
1360 |
"return the object selection - either the local one, or the displays |
|
1361 |
selection buffer." |
|
1362 |
||
1363 |
|sel| |
|
2 | 1364 |
|
269 | 1365 |
sel := Smalltalk at:#CopyBuffer. |
1366 |
sel isNil ifTrue:[ |
|
1367 |
sel := device getSelectionFor:drawableId. |
|
1368 |
sel isNil ifTrue:[^ nil]. |
|
1369 |
]. |
|
1370 |
^ sel |
|
1371 |
! |
|
1372 |
||
1373 |
getTextSelection |
|
1374 |
"return the text selection - either the local one, or the displays |
|
1375 |
selection buffer." |
|
1376 |
||
1377 |
|sel| |
|
1378 |
||
1379 |
sel := Smalltalk at:#CopyBuffer. |
|
1380 |
sel isNil ifTrue:[ |
|
1381 |
sel := device getTextSelectionFor:drawableId. |
|
1382 |
sel isNil ifTrue:[^ nil]. |
|
1383 |
]. |
|
1384 |
^ sel |
|
1385 |
! |
|
1386 |
||
1387 |
selectionAsString |
|
1388 |
"our current selection as a string" |
|
1389 |
||
1390 |
|o s| |
|
1391 |
||
1392 |
o := Smalltalk at:#CopyBuffer. |
|
1393 |
s := o. |
|
1394 |
o isString ifFalse:[ |
|
1395 |
o isNil ifTrue:[ |
|
1396 |
s := '' |
|
1397 |
] ifFalse:[ |
|
1398 |
(o isKindOf:StringCollection) ifTrue:[ |
|
1399 |
s := o asStringWithCRsFrom:1 to:(o size) compressTabs:false withCR:false |
|
1400 |
] ifFalse:[ |
|
1401 |
s := o storeString |
|
1402 |
] |
|
1403 |
] |
|
1404 |
]. |
|
1405 |
^ s |
|
1406 |
! |
|
1407 |
||
1408 |
selectionClear:selectionID |
|
1409 |
"someone else has the selection" |
|
40 | 1410 |
|
1411 |
" |
|
269 | 1412 |
workaround a bug in olvwm: it clears selections |
1413 |
on window raise. In this case, keep my last own selection |
|
1414 |
" |
|
1415 |
Smalltalk at:#LastCopyBuffer put:(Smalltalk at:#CopyBuffer). |
|
1416 |
Smalltalk at:#CopyBuffer put:nil. |
|
1417 |
! |
|
1418 |
||
1419 |
selectionNotify:propertyID target:targetID selection:selectionID from:windowID |
|
1420 |
"this is sent from the display as a reply to a request for a |
|
1421 |
selection. The view should be prepared to paste the received |
|
1422 |
string (it asked for it so that should not be a problem)" |
|
1423 |
||
1424 |
|s| |
|
1425 |
||
1426 |
"workaround a bug in olvwm: |
|
1427 |
it looses selection when bringing a view |
|
1428 |
up front |
|
40 | 1429 |
" |
269 | 1430 |
propertyID == 0 ifTrue:[ |
1431 |
"invalid olvwm behavior" |
|
1432 |
s := Smalltalk at:#LastCopyBuffer |
|
1433 |
] ifFalse:[ |
|
1434 |
targetID == (device atomIDOfSTRING) ifTrue:[ |
|
1435 |
" |
|
1436 |
a returned string |
|
1437 |
" |
|
1438 |
s := device getTextProperty:propertyID from:windowID. |
|
1439 |
s notNil ifTrue:[ |
|
1440 |
(s endsWith:Character cr) ifTrue:[ |
|
1441 |
s := s asStringCollection copyWith:'' |
|
1442 |
] |
|
1443 |
] |
|
1444 |
] ifFalse:[ |
|
1445 |
" |
|
1446 |
a returned object |
|
1447 |
" |
|
1448 |
s := device getObjectProperty:propertyID from:windowID. |
|
1449 |
]. |
|
1450 |
]. |
|
1451 |
s notNil ifTrue:[ |
|
1452 |
self paste:s |
|
1453 |
] |
|
1454 |
! |
|
1455 |
||
1456 |
selectionRequest:propertyID target:targetID selection:selectionID from:windowID |
|
1457 |
"someone asks for our selection" |
|
1458 |
||
1459 |
|o s stream| |
|
40 | 1460 |
|
1461 |
" |
|
269 | 1462 |
the code below has been hacked in a hurry - |
1463 |
it MUST go into the XWorkstation class, |
|
1464 |
since PseudoV should stay independend of any particular |
|
1465 |
implementation (i.e. indep. of the display device) |
|
1466 |
Expect this stuff to vanish in the next version ... |
|
117 | 1467 |
" |
269 | 1468 |
targetID == (device atomIDOfLENGTH) ifTrue:[ |
1469 |
"the other one wants to know the size of our selection ..." |
|
1470 |
s := self selectionAsString. |
|
1471 |
device |
|
1472 |
setLengthProperty:propertyID |
|
1473 |
value:s size |
|
1474 |
for:windowID. |
|
1475 |
device |
|
1476 |
sendSelectionNotifySelection:selectionID |
|
1477 |
property:propertyID |
|
1478 |
target:targetID |
|
1479 |
from:drawableId |
|
1480 |
to:windowID. |
|
1481 |
^ self |
|
1482 |
]. |
|
1483 |
(targetID == device atomIDOfSTRING or:[ |
|
1484 |
targetID == (device atomIDOf:'COMPOUND_TEXT')]) ifTrue:[ |
|
1485 |
s := self selectionAsString. |
|
1486 |
device |
|
1487 |
sendSelection:s |
|
1488 |
property:propertyID |
|
1489 |
target:targetID |
|
1490 |
from:drawableId |
|
1491 |
to:windowID. |
|
1492 |
^ self |
|
1493 |
]. |
|
117 | 1494 |
|
269 | 1495 |
o := Smalltalk at:#CopyBuffer. |
1496 |
stream := WriteStream on:(ByteArray new:200). |
|
1497 |
o storeBinaryOn:stream. |
|
1498 |
device |
|
1499 |
sendSelection:(stream contents) |
|
1500 |
property:propertyID |
|
1501 |
target:(device atomIDOf:'ST_OBJECT' create:true) |
|
1502 |
from:drawableId |
|
1503 |
to:windowID |
|
1504 |
! |
|
1505 |
||
1506 |
setSelection:something |
|
1507 |
"set the object selection - both the local one, and tell the display |
|
1508 |
that we have changed it." |
|
1509 |
||
1510 |
Smalltalk at:#LastCopyBuffer put:nil. |
|
1511 |
Smalltalk at:#CopyBuffer put:something. |
|
1512 |
(device setSelection:something owner:drawableId) ifFalse:[ |
|
1513 |
'PSEUDOVIEW: selection failed' errorPrintNL |
|
1514 |
] |
|
1515 |
! |
|
1516 |
||
1517 |
setTextSelection:something |
|
1518 |
"set the text selection - both the local one, and tell the display |
|
1519 |
that we have changed it." |
|
1520 |
||
1521 |
|s| |
|
1522 |
||
1523 |
Smalltalk at:#LastCopyBuffer put:nil. |
|
1524 |
Smalltalk at:#CopyBuffer put:something. |
|
1525 |
s := something. |
|
1526 |
s isString ifFalse:[ |
|
1527 |
s := s asStringWithCRsFrom:1 to:(s size) compressTabs:false withCR:false |
|
1528 |
]. |
|
1529 |
(device setTextSelection:s owner:drawableId) ifFalse:[ |
|
1530 |
'PSEUDOVIEW: selection failed' errorPrintNL |
|
1531 |
] |
|
2 | 1532 |
! ! |
269 | 1533 |
|
373 | 1534 |
!PseudoView methodsFor:'user notifications'! |
1535 |
||
1536 |
showActivity:aMessage |
|
1537 |
"this is sent indirectly by the activityNotification mechanism. |
|
1538 |
Defined here as a fallback, if ever sent to non topviews." |
|
1539 |
||
1540 |
Transcript showCr:aMessage |
|
1541 |
! ! |
|
1542 |
||
269 | 1543 |
!PseudoView class methodsFor:'documentation'! |
1544 |
||
1545 |
version |
|
385
15fd1c806d2a
pass info if focus change was explicit (i.e. Tab-key) or by window manager.
Claus Gittinger <cg@exept.de>
parents:
373
diff
changeset
|
1546 |
^ '$Header: /cvs/stx/stx/libview/Attic/PseudoV.st,v 1.51 1996-01-27 15:34:58 cg Exp $' |
269 | 1547 |
! ! |