author | Claus Gittinger <cg@exept.de> |
Fri, 15 Dec 1995 14:04:06 +0100 | |
changeset 258 | ae4b8f1a6738 |
parent 231 | 014756a636e3 |
child 261 | afcea54bd74e |
permissions | -rw-r--r-- |
0 | 1 |
" |
5 | 2 |
COPYRIGHT (c) 1990 by Claus Gittinger |
59 | 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 |
EditTextView subclass:#EditField |
|
125 | 14 |
instanceVariableNames:'leaveAction enabled enableAction crAction tabAction converter |
209
7a6db7fac566
dont allow multiline selections in EditField
Claus Gittinger <cg@exept.de>
parents:
192
diff
changeset
|
15 |
leaveKeys immediateAccept acceptOnLeave acceptOnReturn |
7a6db7fac566
dont allow multiline selections in EditField
Claus Gittinger <cg@exept.de>
parents:
192
diff
changeset
|
16 |
lengthLimit entryCompletionBlock passwordCharacter |
7a6db7fac566
dont allow multiline selections in EditField
Claus Gittinger <cg@exept.de>
parents:
192
diff
changeset
|
17 |
cursorMovementWhenUpdating' |
105 | 18 |
classVariableNames:'DefaultForegroundColor DefaultBackgroundColor |
209
7a6db7fac566
dont allow multiline selections in EditField
Claus Gittinger <cg@exept.de>
parents:
192
diff
changeset
|
19 |
DefaultSelectionForegroundColor DefaultSelectionBackgroundColor |
7a6db7fac566
dont allow multiline selections in EditField
Claus Gittinger <cg@exept.de>
parents:
192
diff
changeset
|
20 |
DefaultFont' |
105 | 21 |
poolDictionaries:'' |
22 |
category:'Views-Text' |
|
0 | 23 |
! |
24 |
||
19 | 25 |
!EditField class methodsFor:'documentation'! |
26 |
||
38 | 27 |
copyright |
28 |
" |
|
29 |
COPYRIGHT (c) 1990 by Claus Gittinger |
|
59 | 30 |
All Rights Reserved |
38 | 31 |
|
32 |
This software is furnished under a license and may be used |
|
33 |
only in accordance with the terms of that license and with the |
|
34 |
inclusion of the above copyright notice. This software may not |
|
35 |
be provided or otherwise made available to, or used by, any |
|
36 |
other person. No title to or ownership of the software is |
|
37 |
hereby transferred. |
|
38 |
" |
|
39 |
! |
|
40 |
||
19 | 41 |
documentation |
42 |
" |
|
38 | 43 |
an editable text-field. Realized by using an EditTextView, |
44 |
and forcing its size to 1 line - disabling cursor movement |
|
45 |
in the vertical direction. |
|
121 | 46 |
|
47 |
Instance variables: |
|
48 |
||
49 |
leaveAction <Block | nil> if non-nil, this is evaluated with |
|
50 |
the key (#Return, #CursorUp etc.) when |
|
51 |
the field is left via keyboard keys. |
|
52 |
(fieldGroups use this to decide which |
|
53 |
field has to be enabled next) |
|
54 |
||
55 |
enabled <Boolean> if false, input is ignored. |
|
56 |
||
125 | 57 |
enableAction <Block | nil> action performed if the field is |
58 |
enabled via an explicit click. |
|
59 |
(this is used by the group to |
|
60 |
set the active field to the clicked upon field) |
|
121 | 61 |
|
62 |
crAction <Block | nil> if non-nil, keyboard input of a cr are not |
|
63 |
handled specially, instead this block is evaluated |
|
64 |
(however, this block can perform additional checks and send |
|
65 |
a #accept then) |
|
66 |
||
67 |
tabAction <Block | nil> if non-nil, keyboard input of a tab character |
|
68 |
is not entered into the text, instead this block |
|
69 |
is evaluated. |
|
70 |
||
71 |
converter <PrintConverter | nil> if non-nil, this is supposed to convert between |
|
72 |
the object and its printed representation. |
|
73 |
Defaults to nil i.e. assume that strings are edited. |
|
74 |
||
75 |
leaveKeys <Collection> keys which are interpreted as 'leving the field' |
|
122 | 76 |
|
125 | 77 |
immediateAccept <Boolean> if true, every change of the text is immediately |
78 |
forwarded to the model/acceptBlock. If false, |
|
79 |
the changed value is only stored in the model |
|
80 |
if the field is left or accepted. |
|
81 |
Default is false. |
|
122 | 82 |
|
83 |
acceptOnLeave <Boolean> if true, leaving the field (via cursor keys) |
|
84 |
automatically accepts the value into the model. |
|
130 | 85 |
Default is true. |
122 | 86 |
|
87 |
acceptOnReturn <Boolean> if true, leaving the field via return |
|
88 |
automatically accepts the value into the model. |
|
130 | 89 |
Default is true. |
19 | 90 |
" |
120 | 91 |
! |
92 |
||
93 |
examples |
|
94 |
" |
|
122 | 95 |
see more examples in EnterFieldGroup>>examples. |
96 |
||
97 |
||
98 |
basic field in a view: |
|
120 | 99 |
|
100 |
|top field| |
|
101 |
||
102 |
top := StandardSystemView new. |
|
103 |
top extent:200@100. |
|
104 |
||
105 |
field := EditField origin:0.0@0.0 in:top. |
|
106 |
field width:1.0. 'let its height as-is'. |
|
107 |
||
108 |
top open |
|
109 |
||
122 | 110 |
|
125 | 111 |
forward input in topView to the field: |
112 |
(currently, the field does not know this - therefore, |
|
113 |
its been told here ... this may change) |
|
122 | 114 |
|
115 |
|top field| |
|
116 |
||
117 |
top := StandardSystemView new. |
|
118 |
top extent:200@100. |
|
119 |
||
120 |
field := EditField origin:0.0@0.0 in:top. |
|
121 |
field width:1.0. 'let its height as-is'. |
|
122 |
||
123 |
top delegate:(KeyboardForwarder toView:field). |
|
125 | 124 |
field hasKeyboardFocus:true. |
122 | 125 |
top open |
126 |
||
127 |
||
125 | 128 |
to make it look better: set some inset: |
120 | 129 |
|
130 |
|top field| |
|
131 |
||
132 |
top := StandardSystemView new. |
|
133 |
top extent:200@100. |
|
134 |
||
135 |
field := EditField origin:0.0@ViewSpacing in:top. |
|
136 |
field width:1.0. 'let its height as-is'. |
|
137 |
field leftInset:ViewSpacing; |
|
138 |
rightInset:ViewSpacing. |
|
139 |
||
140 |
top open |
|
141 |
||
122 | 142 |
|
120 | 143 |
give it an initial contents: |
144 |
||
145 |
|top field| |
|
146 |
||
147 |
top := StandardSystemView new. |
|
148 |
top extent:200@100. |
|
149 |
||
150 |
field := EditField origin:0.0@ViewSpacing in:top. |
|
151 |
field width:1.0. |
|
152 |
field leftInset:ViewSpacing; |
|
153 |
rightInset:ViewSpacing. |
|
121 | 154 |
field editValue:'hello world'. |
120 | 155 |
|
156 |
top open |
|
157 |
||
122 | 158 |
|
125 | 159 |
have it preselected: |
120 | 160 |
|
161 |
|top field| |
|
162 |
||
163 |
top := StandardSystemView new. |
|
164 |
top extent:200@100. |
|
165 |
||
166 |
field := EditField origin:0.0@ViewSpacing in:top. |
|
167 |
field width:1.0. |
|
168 |
field leftInset:ViewSpacing; |
|
169 |
rightInset:ViewSpacing. |
|
121 | 170 |
field editValue:'hello world' selected:true. |
120 | 171 |
|
172 |
top open |
|
173 |
||
122 | 174 |
|
120 | 175 |
have part of it preselected: |
176 |
||
177 |
|top field| |
|
178 |
||
179 |
top := StandardSystemView new. |
|
180 |
top extent:200@100. |
|
181 |
||
182 |
field := EditField origin:0.0@ViewSpacing in:top. |
|
183 |
field width:1.0. |
|
184 |
field leftInset:ViewSpacing; |
|
185 |
rightInset:ViewSpacing. |
|
121 | 186 |
field editValue:'hello world'; |
120 | 187 |
selectFromCharacterPosition:1 to:5. |
188 |
||
189 |
top open |
|
190 |
||
122 | 191 |
|
125 | 192 |
set a size limit: |
193 |
||
194 |
|top field| |
|
195 |
||
196 |
top := StandardSystemView new. |
|
197 |
top extent:200@100. |
|
198 |
||
199 |
field := EditField origin:0.0@ViewSpacing in:top. |
|
200 |
field width:1.0. |
|
201 |
field leftInset:ViewSpacing; |
|
202 |
rightInset:ViewSpacing. |
|
203 |
field editValue:'hello'; |
|
204 |
maxChars:8. |
|
205 |
||
206 |
top open |
|
207 |
||
208 |
||
121 | 209 |
use a converter: |
125 | 210 |
- numbers (default to 0): |
121 | 211 |
|
212 |
|top field| |
|
213 |
||
214 |
top := StandardSystemView new. |
|
215 |
top extent:200@100. |
|
216 |
||
217 |
field := EditField origin:0.0@ViewSpacing in:top. |
|
218 |
field width:1.0. |
|
219 |
field leftInset:ViewSpacing; |
|
220 |
rightInset:ViewSpacing. |
|
221 |
||
222 |
field converter:(PrintConverter new initForNumber). |
|
223 |
field editValue:1234. |
|
224 |
field acceptAction:[:value | Transcript showCr:value]. |
|
225 |
field crAction:[field accept. top destroy]. |
|
226 |
top open. |
|
227 |
||
228 |
- dates: |
|
229 |
||
230 |
|top field| |
|
231 |
||
232 |
top := StandardSystemView new. |
|
233 |
top extent:200@100. |
|
234 |
||
235 |
field := EditField origin:0.0@ViewSpacing in:top. |
|
236 |
field width:1.0. |
|
237 |
field leftInset:ViewSpacing; |
|
238 |
rightInset:ViewSpacing. |
|
239 |
||
240 |
field converter:(PrintConverter new initForDate). |
|
241 |
field editValue:Date today. |
|
125 | 242 |
field acceptAction:[:value | Transcript showCr:value class name , ' ' , value printString]. |
121 | 243 |
field crAction:[field accept. top destroy]. |
244 |
top open. |
|
245 |
||
122 | 246 |
|
125 | 247 |
setting immediateAccept, makes the field update with every key: |
248 |
||
249 |
- immediate accept numbers, defaulting to nil: |
|
121 | 250 |
|
251 |
|top field| |
|
252 |
||
253 |
top := StandardSystemView new. |
|
254 |
top extent:200@100. |
|
255 |
||
256 |
field := EditField origin:0.0@ViewSpacing in:top. |
|
257 |
field width:1.0. |
|
258 |
field leftInset:ViewSpacing; |
|
259 |
rightInset:ViewSpacing. |
|
260 |
||
125 | 261 |
field converter:(PrintConverter new initForNumberOrNil). |
262 |
field immediateAccept:true. |
|
121 | 263 |
field editValue:1234. |
264 |
field acceptAction:[:value | Transcript showCr:value]. |
|
265 |
field crAction:[field accept. top destroy]. |
|
266 |
top open. |
|
267 |
||
122 | 268 |
|
127 | 269 |
|
270 |
||
120 | 271 |
use a model: |
272 |
(see changing model value in inspector when return is pressed in the field) |
|
273 |
||
274 |
|top field model| |
|
275 |
||
276 |
model := 'hello world' asValue. |
|
277 |
||
278 |
top := StandardSystemView new. |
|
279 |
top extent:200@100. |
|
280 |
||
281 |
field := EditField origin:0.0@ViewSpacing in:top. |
|
121 | 282 |
field width:1.0. |
120 | 283 |
field leftInset:ViewSpacing; |
284 |
rightInset:ViewSpacing. |
|
285 |
field model:model. |
|
128 | 286 |
field acceptOnReturn:true. |
120 | 287 |
|
288 |
top open. |
|
121 | 289 |
model inspect. |
290 |
||
122 | 291 |
|
127 | 292 |
two views on the same model (each accepts on return): |
121 | 293 |
|
294 |
|top1 top2 field1 field2 model| |
|
295 |
||
296 |
model := 'hello world' asValue. |
|
297 |
||
298 |
top1 := StandardSystemView new. |
|
299 |
top1 extent:200@100. |
|
300 |
field1 := EditField origin:0.0@ViewSpacing in:top1. |
|
301 |
field1 width:1.0. |
|
302 |
field1 leftInset:ViewSpacing; |
|
303 |
rightInset:ViewSpacing. |
|
304 |
field1 model:model. |
|
128 | 305 |
field1 acceptOnReturn:true. |
121 | 306 |
top1 open. |
307 |
||
308 |
top2 := StandardSystemView new. |
|
309 |
top2 extent:200@100. |
|
310 |
field2 := EditField origin:0.0@ViewSpacing in:top2. |
|
311 |
field2 width:1.0. |
|
312 |
field2 leftInset:ViewSpacing; |
|
313 |
rightInset:ViewSpacing. |
|
314 |
field2 model:model. |
|
128 | 315 |
field2 acceptOnReturn:true. |
121 | 316 |
top2 open. |
317 |
||
127 | 318 |
two views on the same model (no accept on return): |
319 |
||
320 |
|top1 top2 field1 field2 model| |
|
321 |
||
322 |
model := 'hello world' asValue. |
|
323 |
||
324 |
top1 := StandardSystemView new. |
|
325 |
top1 extent:200@100. |
|
326 |
field1 := EditField origin:0.0@ViewSpacing in:top1. |
|
327 |
field1 width:1.0. |
|
328 |
field1 leftInset:ViewSpacing; |
|
329 |
rightInset:ViewSpacing. |
|
330 |
field1 model:model; acceptOnReturn:false. |
|
331 |
top1 open. |
|
332 |
||
333 |
top2 := StandardSystemView new. |
|
334 |
top2 extent:200@100. |
|
335 |
field2 := EditField origin:0.0@ViewSpacing in:top2. |
|
336 |
field2 width:1.0. |
|
337 |
field2 leftInset:ViewSpacing; |
|
338 |
rightInset:ViewSpacing. |
|
339 |
field2 model:model; acceptOnReturn:false. |
|
340 |
top2 open. |
|
341 |
||
125 | 342 |
with immediate accept: |
343 |
||
344 |
|top1 top2 field1 field2 model| |
|
345 |
||
346 |
model := 'hello world' asValue. |
|
347 |
||
348 |
top1 := StandardSystemView new. |
|
349 |
top1 extent:200@100. |
|
350 |
field1 := EditField origin:0.0@ViewSpacing in:top1. |
|
351 |
field1 width:1.0. |
|
352 |
field1 leftInset:ViewSpacing; rightInset:ViewSpacing. |
|
353 |
field1 model:model; immediateAccept:true. |
|
354 |
top1 open. |
|
355 |
||
356 |
top2 := StandardSystemView new. |
|
357 |
top2 extent:200@100. |
|
358 |
field2 := EditField origin:0.0@ViewSpacing in:top2. |
|
359 |
field2 width:1.0. |
|
360 |
field2 leftInset:ViewSpacing; rightInset:ViewSpacing. |
|
361 |
field2 model:model; immediateAccept:true. |
|
362 |
top2 open. |
|
122 | 363 |
|
121 | 364 |
just an example; a checkBox and an editField on the same model: |
365 |
||
366 |
|top1 top2 field1 box model| |
|
367 |
||
368 |
model := false asValue. |
|
369 |
||
370 |
top1 := StandardSystemView new. |
|
371 |
top1 extent:200@100. |
|
372 |
field1 := EditField origin:0.0@ViewSpacing in:top1. |
|
373 |
field1 width:1.0. |
|
374 |
field1 leftInset:ViewSpacing; |
|
375 |
rightInset:ViewSpacing. |
|
376 |
field1 converter:(PrintConverter new initForYesNo). |
|
377 |
field1 model:model. |
|
378 |
top1 open. |
|
379 |
||
380 |
top2 := StandardSystemView new. |
|
381 |
top2 extent:200@100. |
|
382 |
box := CheckBox on:model. |
|
383 |
box label:'on/off'. |
|
384 |
top2 add:box. |
|
385 |
top2 open. |
|
386 |
||
120 | 387 |
model inspect. |
125 | 388 |
|
389 |
||
390 |
connecting fields: |
|
391 |
update field2 wehenever field1 is changed. |
|
392 |
(normally, the processing below (xChanged) is done in your application |
|
393 |
class, or in a complex model. For the demonstration below, we use |
|
394 |
a Plug to simulate the protocol.) |
|
395 |
||
396 |
|application top field1 field2 value1 value2| |
|
397 |
||
398 |
application := Plug new. |
|
399 |
application respondTo:#value1Changed |
|
400 |
with:[value2 value:(value1 value isNil ifTrue:[nil] |
|
401 |
ifFalse:[value1 value squared])]. |
|
402 |
||
403 |
value1 := 1 asValue. |
|
404 |
value2 := 1 asValue. |
|
405 |
||
406 |
top := Dialog new. |
|
407 |
top extent:200@200. |
|
408 |
||
409 |
(top addTextLabel:'some number:') layout:#left. |
|
410 |
top addVerticalSpace. |
|
411 |
||
412 |
(top addInputFieldOn:value1 tabable:false) |
|
413 |
converter:(PrintConverter new initForNumberOrNil); |
|
414 |
immediateAccept:true. |
|
415 |
top addVerticalSpace. |
|
416 |
||
417 |
(top addTextLabel:'squared:') layout:#left. |
|
418 |
top addVerticalSpace. |
|
419 |
(top addInputFieldOn:value2 tabable:false) |
|
420 |
converter:(PrintConverter new initForNumberOrNil). |
|
421 |
||
422 |
value1 onChangeSend:#value1Changed to:application. |
|
423 |
||
424 |
top openModeless. |
|
425 |
||
426 |
||
427 |
two-way connect: |
|
428 |
each field updates the other (notice, that we have to turn off |
|
429 |
onChange: notification, to avoid an endless notification cycle) |
|
430 |
||
431 |
|application top field1 field2 value1 value2| |
|
432 |
||
433 |
application := Plug new. |
|
434 |
application respondTo:#value1Changed |
|
258
ae4b8f1a6738
interest is written with one 'r' (shame on me)
Claus Gittinger <cg@exept.de>
parents:
231
diff
changeset
|
435 |
with:[value2 retractInterestsFor:application. |
125 | 436 |
value2 value:(value1 value isNil ifTrue:[nil] |
437 |
ifFalse:[value1 value squared]). |
|
438 |
value2 onChangeSend:#value2Changed to:application. |
|
439 |
]. |
|
440 |
application respondTo:#value2Changed |
|
258
ae4b8f1a6738
interest is written with one 'r' (shame on me)
Claus Gittinger <cg@exept.de>
parents:
231
diff
changeset
|
441 |
with:[value1 retractInterestsFor:application. |
125 | 442 |
value1 value:(value2 value isNil ifTrue:[nil] |
443 |
ifFalse:[value2 value sqrt]). |
|
444 |
value1 onChangeSend:#value1Changed to:application. |
|
445 |
]. |
|
446 |
||
447 |
value1 := 1 asValue. |
|
448 |
value2 := 1 asValue. |
|
449 |
||
450 |
top := Dialog new. |
|
451 |
top extent:200@200. |
|
452 |
||
453 |
(top addTextLabel:'some number:') layout:#left. |
|
454 |
top addVerticalSpace. |
|
455 |
||
456 |
(top addInputFieldOn:value1 tabable:false) |
|
457 |
converter:(PrintConverter new initForNumberOrNil); |
|
458 |
immediateAccept:true. |
|
459 |
top addVerticalSpace. |
|
460 |
||
461 |
(top addTextLabel:'squared:') layout:#left. |
|
462 |
top addVerticalSpace. |
|
463 |
(top addInputFieldOn:value2 tabable:false) |
|
127 | 464 |
converter:(PrintConverter new initForNumberOrNil); |
465 |
immediateAccept:true. |
|
125 | 466 |
|
467 |
value1 onChangeSend:#value1Changed to:application. |
|
468 |
value2 onChangeSend:#value2Changed to:application. |
|
469 |
||
470 |
top openModeless. |
|
120 | 471 |
" |
192 | 472 |
! |
473 |
||
474 |
version |
|
258
ae4b8f1a6738
interest is written with one 'r' (shame on me)
Claus Gittinger <cg@exept.de>
parents:
231
diff
changeset
|
475 |
^ '$Header: /cvs/stx/stx/libwidg/EditField.st,v 1.35 1995-12-15 13:04:02 cg Exp $' |
19 | 476 |
! ! |
0 | 477 |
|
478 |
!EditField class methodsFor:'defaults'! |
|
479 |
||
125 | 480 |
defaultLeaveKeys |
128 | 481 |
"return the set of keys which are taken as leave-keys. |
482 |
If the field is in an enterFieldGroup, all leave keys will be |
|
483 |
forwarded to the group and possible step to the next/previous field. |
|
484 |
Also, if acceptOnLeave is true, leave keys will store the current |
|
485 |
value into their model (if any)" |
|
486 |
||
125 | 487 |
^ #(Return CursorUp CursorDown Next Previous Accept) |
488 |
! |
|
489 |
||
192 | 490 |
defaultNumberOfLines |
491 |
"the number of lines in the field" |
|
492 |
||
493 |
^ 1 |
|
494 |
! |
|
495 |
||
59 | 496 |
updateStyleCache |
60 | 497 |
DefaultForegroundColor := StyleSheet colorAt:'editFieldForegroundColor' default:Black. |
498 |
DefaultBackgroundColor := StyleSheet colorAt:'editFieldBackgroundColor' default:White. |
|
499 |
DefaultSelectionForegroundColor := StyleSheet colorAt:'editFieldSelectionForegroundColor' default:DefaultBackgroundColor. |
|
500 |
DefaultSelectionBackgroundColor := StyleSheet colorAt:'editFieldSelectionBackgroundColor' default:DefaultForegroundColor. |
|
501 |
DefaultFont := StyleSheet fontAt:'editFieldFont' default:nil. |
|
59 | 502 |
|
503 |
" |
|
60 | 504 |
self updateStyleCache |
59 | 505 |
" |
0 | 506 |
! ! |
507 |
||
192 | 508 |
!EditField methodsFor:'accessing-behavior'! |
125 | 509 |
|
192 | 510 |
acceptOnLeave:aBoolean |
511 |
"set/clear the acceptOnLeave flag. The default is false." |
|
125 | 512 |
|
192 | 513 |
acceptOnLeave := aBoolean |
514 |
! |
|
515 |
||
516 |
acceptOnReturn:aBoolean |
|
517 |
"set/clear the acceptOnReturn flag. The default is false." |
|
518 |
||
519 |
acceptOnReturn := aBoolean |
|
125 | 520 |
! |
521 |
||
192 | 522 |
crAction:aBlock |
523 |
"define an action to be evaluated when the return key is pressed." |
|
524 |
||
525 |
crAction := aBlock |
|
526 |
! |
|
125 | 527 |
|
192 | 528 |
cursorMovementWhenUpdating:aSymbol |
529 |
"define what should be done with the cursor, when I update |
|
530 |
my contents from the model. Allowed argumetns are: |
|
531 |
#keep / nil -> stay where it was |
|
532 |
#endOfLine -> position cursor after the string |
|
533 |
#beginOfLine -> position cursor to the beginning |
|
534 |
The default is #endOfLine" |
|
125 | 535 |
|
192 | 536 |
cursorMovementWhenUpdating := aSymbol |
537 |
! |
|
538 |
||
539 |
disable |
|
540 |
"disable the field; hide cursor and ignore input" |
|
541 |
||
542 |
enabled ifTrue:[ |
|
543 |
enabled := false. |
|
544 |
self hideCursor |
|
125 | 545 |
] |
546 |
! |
|
547 |
||
192 | 548 |
enable |
549 |
"enable the field; show cursor and allow input" |
|
127 | 550 |
|
192 | 551 |
enabled ifFalse:[ |
552 |
"/ enableAction notNil ifTrue:[ |
|
553 |
"/ enableAction value |
|
554 |
"/ ]. |
|
555 |
enabled := true. |
|
556 |
super showCursor |
|
557 |
] |
|
127 | 558 |
! |
559 |
||
192 | 560 |
enableAction:aBlock |
561 |
"define an action to be evaluated when enabled by clicking upon" |
|
562 |
||
563 |
enableAction := aBlock |
|
564 |
! |
|
125 | 565 |
|
192 | 566 |
entryCompletionBlock:aOneArgBlock |
567 |
"define an action to be evaluated when Tab (NameCompletion) is pressed. |
|
568 |
The block gets the current contents as argument." |
|
569 |
||
570 |
entryCompletionBlock := aOneArgBlock |
|
125 | 571 |
! |
572 |
||
192 | 573 |
immediateAccept:aBoolean |
574 |
"set/clear the immediateAccept flag. The default is false." |
|
155 | 575 |
|
192 | 576 |
immediateAccept := aBoolean |
577 |
! |
|
155 | 578 |
|
192 | 579 |
leaveAction:aBlock |
580 |
"define an action to be evaluated when field is left by return key" |
|
581 |
||
582 |
leaveAction := aBlock |
|
155 | 583 |
! |
584 |
||
192 | 585 |
leaveKeys:aCollectionOfKeySymbols |
586 |
"define the set of keys which are interpreted as leaveKeys. |
|
587 |
I.e. those that make the field inactive and accept (if acceptOnLeave is true). |
|
588 |
The default is a set of #CursorUp, #CursorDown, #Next, #Prior and #Return." |
|
155 | 589 |
|
192 | 590 |
leaveKeys := aCollectionOfKeySymbols |
591 |
! |
|
155 | 592 |
|
192 | 593 |
tabAction:aBlock |
594 |
"define an action to be evaluated when the tabulator key is pressed." |
|
155 | 595 |
|
192 | 596 |
tabAction := aBlock |
187 | 597 |
! ! |
125 | 598 |
|
187 | 599 |
!EditField methodsFor:'accessing-contents'! |
125 | 600 |
|
187 | 601 |
contents |
602 |
"return contents as a string |
|
603 |
- redefined since EditFields hold only one line of text. |
|
604 |
In your application, please use #editValue; |
|
605 |
it uses a converter (if any) and is compatible to ST-80." |
|
606 |
||
607 |
list isNil ifTrue:[^ '']. |
|
608 |
(list size == 0) ifTrue:[^ '']. |
|
609 |
^ list at:1 |
|
610 |
! |
|
611 |
||
125 | 612 |
contents:someText |
613 |
"set the contents from a string |
|
614 |
- redefined to place the cursor to the end. |
|
615 |
In your application, please use #editValue:; |
|
616 |
it uses a converter (if any) and is compatible to ST-80." |
|
617 |
||
187 | 618 |
|newCol| |
619 |
||
620 |
newCol := cursorCol. |
|
621 |
||
125 | 622 |
super contents:someText. |
623 |
||
187 | 624 |
cursorMovementWhenUpdating == #endOfLine ifTrue:[ |
625 |
newCol := (someText size + 1). |
|
626 |
] ifFalse:[ |
|
627 |
cursorMovementWhenUpdating == #beginOfLine ifTrue:[ |
|
628 |
newCol := 1 |
|
629 |
] ifFalse:[ |
|
630 |
"/ default: stay where it was |
|
631 |
] |
|
632 |
]. |
|
125 | 633 |
|
187 | 634 |
self cursorCol:newCol. |
125 | 635 |
! |
636 |
||
192 | 637 |
converter |
638 |
"return the converter (if any)." |
|
639 |
||
640 |
^ converter |
|
641 |
! |
|
642 |
||
643 |
converter:aConverter |
|
644 |
"set the converter. If non-nil, |
|
645 |
the converter is applied to the text to convert from the string |
|
646 |
representation to the actual object value and vice versa. |
|
647 |
The default converter is nil, meaning no-conversion |
|
648 |
(i.e. the edited object is the string itself." |
|
649 |
||
650 |
converter := aConverter |
|
651 |
! |
|
652 |
||
125 | 653 |
editValue |
654 |
"if the field edits a string, this is a name alias for #contents. |
|
655 |
Otherwise, if there is a converter, return the edited string |
|
656 |
converted to an appropriate object." |
|
657 |
||
658 |
|string| |
|
659 |
||
660 |
string := self contents. |
|
661 |
converter isNil ifTrue:[^ string]. |
|
662 |
string isNil ifTrue:[string := '']. |
|
663 |
^ converter readValueFrom:string |
|
664 |
! |
|
0 | 665 |
|
125 | 666 |
editValue:aStringOrObject |
667 |
"set the contents. If there is a converter, use it to convert |
|
668 |
the object into a printed representation. |
|
669 |
Otherwise, the argument is supposed to be a string like object, |
|
670 |
and used directly (i.e. this is equivalent to sending #contents:)." |
|
671 |
||
672 |
self editValue:aStringOrObject selected:false |
|
0 | 673 |
! |
674 |
||
125 | 675 |
editValue:aStringOrObject selected:aBoolean |
676 |
"set the contents. If there is a converter, use it to convert |
|
677 |
the object into a printed representation. |
|
678 |
Otherwise, the argument is supposed to be a string like object, |
|
187 | 679 |
and used directly (i.e. this is equivalent to sending #initialText:selected:)." |
125 | 680 |
|
681 |
|string| |
|
682 |
||
683 |
converter notNil ifTrue:[ |
|
684 |
string := converter printStringFor:aStringOrObject |
|
685 |
] ifFalse:[ |
|
686 |
string := aStringOrObject. |
|
687 |
]. |
|
688 |
self contents:string. |
|
689 |
aBoolean ifTrue:[ |
|
690 |
self selectFromLine:1 col:1 toLine:1 col:string size |
|
691 |
] |
|
692 |
! |
|
693 |
||
192 | 694 |
initialText:aString |
695 |
"set the initialText and select it" |
|
696 |
||
697 |
self initialText:aString selected:true |
|
698 |
! |
|
699 |
||
187 | 700 |
initialText:aString selected:aBoolean |
701 |
"set the initialText and select it if aBoolean is true" |
|
702 |
||
703 |
|len s| |
|
125 | 704 |
|
187 | 705 |
leftOffset := 0. |
706 |
(s := aString) notNil ifTrue:[ |
|
707 |
s := s asString |
|
708 |
]. |
|
709 |
self contents:s. |
|
710 |
aBoolean ifTrue:[ |
|
711 |
(len := s size) ~~ 0 ifTrue:[ |
|
712 |
self selectFromLine:1 col:1 toLine:1 col:len |
|
713 |
] |
|
714 |
] |
|
715 |
! |
|
716 |
||
192 | 717 |
list:someText |
718 |
"low level access to the underlying contents' list. |
|
719 |
Redefined to force text to 1 line, and notify dependents |
|
720 |
of any changed extent-wishes (for automatic box resizing)." |
|
721 |
||
722 |
|l oldWidth| |
|
187 | 723 |
|
192 | 724 |
l := someText. |
725 |
l size > 1 ifTrue:[ |
|
726 |
l := OrderedCollection with:(l at:1) |
|
727 |
]. |
|
728 |
oldWidth := self widthOfContents. |
|
729 |
super list:l. |
|
730 |
self widthOfContents ~~ oldWidth ifTrue:[ |
|
731 |
self changed:#preferredExtent |
|
732 |
] |
|
187 | 733 |
! |
734 |
||
735 |
stringValue |
|
736 |
"alias for #contents - for compatibility with ST-80's InputField" |
|
737 |
||
738 |
^ self contents |
|
739 |
! ! |
|
740 |
||
741 |
!EditField methodsFor:'accessing-look'! |
|
125 | 742 |
|
155 | 743 |
maxChars |
744 |
"return the maximum number of characters that are allowed in |
|
745 |
the field. |
|
746 |
A limit of nil means: unlimited. This is the default." |
|
747 |
||
748 |
^ lengthLimit |
|
749 |
||
750 |
"Modified: 6.9.1995 / 13:43:33 / claus" |
|
751 |
! |
|
752 |
||
125 | 753 |
maxChars:aNumberOrNil |
754 |
"set the maximum number of characters that are allowed in |
|
755 |
the field. Additional input will be ignored by the field. |
|
756 |
A limit of nil means: unlimited. This is the default. |
|
757 |
This method has been renamed from #lengthLimit: for ST-80 |
|
758 |
compatibility." |
|
759 |
||
760 |
lengthLimit := aNumberOrNil |
|
187 | 761 |
! |
762 |
||
192 | 763 |
passwordCharacter |
764 |
^ passwordCharacter |
|
0 | 765 |
|
192 | 766 |
"Modified: 6.9.1995 / 12:25:39 / claus" |
125 | 767 |
! |
768 |
||
192 | 769 |
passwordCharacter:aCharacter |
770 |
passwordCharacter := aCharacter |
|
97 | 771 |
|
192 | 772 |
"Modified: 6.9.1995 / 12:25:33 / claus" |
38 | 773 |
! ! |
774 |
||
0 | 775 |
!EditField methodsFor:'cursor drawing'! |
776 |
||
155 | 777 |
drawFromVisibleLine:startVisLineNr to:endVisLineNr with:fg and:bg |
778 |
startVisLineNr to:endVisLineNr do:[:visLine | |
|
779 |
self drawVisibleLine:visLine with:fg and:bg |
|
780 |
] |
|
781 |
||
782 |
"Modified: 6.9.1995 / 12:24:29 / claus" |
|
783 |
! |
|
784 |
||
0 | 785 |
showCursor |
786 |
"make cursor visible if currently invisible - but only if this |
|
787 |
EditField is enabled" |
|
788 |
||
789 |
enabled ifTrue:[super showCursor] |
|
790 |
! ! |
|
791 |
||
792 |
!EditField methodsFor:'cursor movement'! |
|
793 |
||
125 | 794 |
cursorCol:col |
795 |
"redefined to lock the cursor at the end, if I have a lngthLimit" |
|
796 |
||
797 |
|c sz| |
|
798 |
||
799 |
c := col. |
|
800 |
lengthLimit notNil ifTrue:[ |
|
801 |
sz := lengthLimit. |
|
802 |
c > sz ifTrue:[ |
|
803 |
c := sz+1. |
|
804 |
] |
|
805 |
]. |
|
806 |
super cursorCol:c |
|
807 |
! |
|
808 |
||
0 | 809 |
cursorDown |
810 |
"catch cursor movement" |
|
811 |
||
812 |
(cursorVisibleLine == nLinesShown) ifFalse:[ |
|
59 | 813 |
super cursorDown |
0 | 814 |
] |
192 | 815 |
! |
816 |
||
817 |
cursorLine:line col:col |
|
818 |
"catch cursor movement" |
|
819 |
||
820 |
super cursorLine:1 col:col |
|
821 |
! ! |
|
822 |
||
823 |
!EditField methodsFor:'editing'! |
|
824 |
||
825 |
paste:someText |
|
826 |
"redefined to force text to 1 line" |
|
827 |
||
828 |
super paste:someText. |
|
829 |
list size > 1 ifTrue:[ |
|
830 |
self deleteFromLine:2 toLine:(list size) |
|
831 |
] |
|
0 | 832 |
! ! |
833 |
||
70 | 834 |
!EditField methodsFor:'event handling'! |
19 | 835 |
|
192 | 836 |
buttonPress:button x:x y:y |
837 |
"enable myself on mouse click" |
|
838 |
||
839 |
enabled ifFalse:[ |
|
840 |
enabled := true. |
|
841 |
super buttonPress:button x:x y:y. |
|
842 |
enableAction notNil ifTrue:[ |
|
843 |
enableAction value |
|
844 |
] |
|
845 |
] ifTrue:[ |
|
846 |
super buttonPress:button x:x y:y |
|
847 |
] |
|
848 |
! |
|
849 |
||
850 |
canHandle:aKey |
|
851 |
"return true, if the receiver would like to handle aKey |
|
852 |
(usually from another view, when the receiver is part of |
|
853 |
a more complex dialog box). |
|
854 |
We do return true here, since the editfield will handle |
|
855 |
all keys. |
|
856 |
OBSOLETE: dont use this anymore - its a leftover for the tableWidget" |
|
857 |
||
858 |
^ true |
|
859 |
! |
|
860 |
||
861 |
focusIn |
|
862 |
"got the explicit focus" |
|
863 |
||
864 |
enabled ifFalse:[ |
|
865 |
enabled := true. |
|
866 |
super focusIn. |
|
867 |
enableAction notNil ifTrue:[ |
|
868 |
enableAction value |
|
869 |
] |
|
870 |
] ifTrue:[ |
|
871 |
super focusIn |
|
872 |
]. |
|
873 |
! |
|
874 |
||
125 | 875 |
keyPress:key x:x y:y |
876 |
"if keyHandler is defined, pass input; otherwise check for leave |
|
877 |
keys" |
|
878 |
||
132 | 879 |
<resource: #keyboard (#DeleteLine #EndOfText)> |
880 |
||
163 | 881 |
|leave xCol newOffset oldWidth newWidth s| |
125 | 882 |
|
883 |
enabled ifFalse:[ |
|
127 | 884 |
^ self |
125 | 885 |
]. |
886 |
||
887 |
(key == #DeleteLine) ifTrue:[ |
|
127 | 888 |
Smalltalk at:#CopyBuffer put:(self contents). |
889 |
self contents:''. ^ self |
|
125 | 890 |
]. |
19 | 891 |
|
125 | 892 |
(key == #Tab) ifTrue:[ |
127 | 893 |
tabAction notNil ifTrue:[tabAction value. ^ self]. |
144 | 894 |
entryCompletionBlock notNil ifTrue:[ |
163 | 895 |
s := self contents. |
896 |
s isNil ifTrue:[ |
|
897 |
s := '' |
|
898 |
] ifFalse:[ |
|
899 |
s := s asString |
|
900 |
]. |
|
901 |
entryCompletionBlock value:s. ^ self |
|
144 | 902 |
] |
125 | 903 |
]. |
904 |
(key == #Return) ifTrue:[ |
|
127 | 905 |
crAction notNil ifTrue:[crAction value. ^ self]. |
125 | 906 |
]. |
907 |
leave := leaveKeys includes:key. |
|
908 |
leave ifTrue:[ |
|
127 | 909 |
leaveAction notNil ifTrue:[ |
910 |
leaveAction value:key |
|
911 |
]. |
|
121 | 912 |
|
127 | 913 |
((key == #Return and:[acceptOnReturn]) |
914 |
or:[key ~~ #Return and:[acceptOnLeave]]) ifTrue:[ |
|
915 |
self accept. |
|
916 |
]. |
|
125 | 917 |
|
127 | 918 |
x >= 0 ifTrue:[ |
919 |
" |
|
920 |
let superview know about the leave ... |
|
921 |
This is a temporary kludge for the tableWidget - |
|
922 |
it is no clean coding style. Should make the tableWidget |
|
923 |
a proper model and handle it via the changed mechanism .... |
|
924 |
" |
|
925 |
(superView notNil and:[superView canHandle:key from:self]) ifTrue:[ |
|
926 |
superView keyPress:key x:x y:y. |
|
927 |
]. |
|
928 |
]. |
|
929 |
^ self |
|
19 | 930 |
]. |
121 | 931 |
|
125 | 932 |
" |
933 |
ignore some keys (if not a leaveKey) ... |
|
934 |
" |
|
935 |
(key == #Find) ifTrue:[^self]. |
|
936 |
(key == #FindNext) ifTrue:[^self]. |
|
937 |
(key == #FindPrev) ifTrue:[^self]. |
|
938 |
(key == #GotoLine) ifTrue:[^self]. |
|
939 |
||
940 |
" |
|
941 |
a normal key - let superclass's method insert it |
|
942 |
" |
|
943 |
oldWidth := self widthOfContents. |
|
944 |
super keyPress:key x:x y:y. |
|
945 |
||
946 |
" |
|
947 |
for end-of-text, also move to end-of-line |
|
948 |
" |
|
949 |
key == #EndOfText ifTrue:[ |
|
127 | 950 |
super keyPress:#EndOfLine x:x y:y. |
125 | 951 |
]. |
952 |
newWidth := self widthOfContents. |
|
953 |
||
954 |
" |
|
955 |
should (& can) we resize ? |
|
956 |
" |
|
957 |
xCol := (self xOfCol:cursorCol inVisibleLine:cursorLine) - leftOffset. |
|
958 |
(xCol > (width * (5/6))) ifTrue:[ |
|
130 | 959 |
self changed:#preferredExtent |
125 | 960 |
] ifFalse:[ |
127 | 961 |
newWidth < (width * (1/6)) ifTrue:[ |
130 | 962 |
self changed:#preferredExtent |
127 | 963 |
] |
125 | 964 |
]. |
965 |
||
966 |
" |
|
155 | 967 |
did someone react (i.e. has my extent changed) ? |
125 | 968 |
(if not, we scroll horizontally) |
969 |
" |
|
970 |
xCol := (self xOfCol:cursorCol inVisibleLine:cursorLine) - leftOffset. |
|
971 |
(xCol > (width * (5/6))) ifTrue:[ |
|
127 | 972 |
newOffset := leftOffset + (width // 2). |
125 | 973 |
] ifFalse:[ |
127 | 974 |
(xCol < (width * (1/6))) ifTrue:[ |
975 |
newOffset := 0 max: leftOffset - (width // 2). |
|
976 |
] ifFalse:[ |
|
977 |
newOffset := leftOffset |
|
978 |
] |
|
125 | 979 |
]. |
980 |
newOffset ~~ leftOffset ifTrue:[ |
|
155 | 981 |
self scrollHorizontalTo:newOffset. |
982 |
"/ leftOffset := newOffset. |
|
983 |
"/ self clear. |
|
984 |
"/ self redraw |
|
125 | 985 |
] |
192 | 986 |
! ! |
987 |
||
988 |
!EditField methodsFor:'initialization'! |
|
989 |
||
990 |
editMenu |
|
991 |
|labels selectors m| |
|
992 |
||
993 |
labels := #( |
|
994 |
'copy' |
|
995 |
'cut' |
|
996 |
'paste' |
|
997 |
" |
|
998 |
'replace' |
|
999 |
" |
|
1000 |
'-' |
|
1001 |
'accept' |
|
1002 |
). |
|
1003 |
||
1004 |
selectors := #( |
|
1005 |
copySelection |
|
1006 |
cut |
|
1007 |
paste |
|
1008 |
" |
|
1009 |
replace |
|
1010 |
" |
|
1011 |
nil |
|
1012 |
accept |
|
1013 |
). |
|
1014 |
||
1015 |
m := PopUpMenu |
|
1016 |
labels:(resources array:labels) |
|
1017 |
selectors:selectors. |
|
1018 |
||
1019 |
self hasSelection ifFalse:[ |
|
1020 |
m disableAll:#(copySelection cut) |
|
1021 |
]. |
|
1022 |
||
1023 |
^ m |
|
19 | 1024 |
! |
0 | 1025 |
|
192 | 1026 |
initStyle |
1027 |
super initStyle. |
|
1028 |
||
1029 |
DefaultBackgroundColor notNil ifTrue:[ |
|
1030 |
bgColor := DefaultBackgroundColor on:device. |
|
1031 |
self viewBackground:bgColor. |
|
1032 |
]. |
|
1033 |
fgColor := DefaultForegroundColor. |
|
1034 |
selectionFgColor := DefaultSelectionForegroundColor. |
|
1035 |
selectionBgColor := DefaultSelectionBackgroundColor. |
|
1036 |
||
1037 |
DefaultFont notNil ifTrue:[ |
|
1038 |
font := DefaultFont on:device |
|
1039 |
] |
|
1040 |
! |
|
0 | 1041 |
|
192 | 1042 |
initialize |
1043 |
super initialize. |
|
1044 |
self height:(font height + font descent + (topMargin * 2)). |
|
1045 |
enabled := true. |
|
1046 |
fixedSize := true. |
|
1047 |
nFullLinesShown := 1. |
|
1048 |
nLinesShown := 1. |
|
1049 |
immediateAccept := false. |
|
1050 |
"/ acceptOnLeave := false. |
|
1051 |
"/ acceptOnReturn := false. |
|
1052 |
acceptOnLeave := acceptOnReturn := true. |
|
1053 |
cursorShown := true. |
|
1054 |
leaveKeys := self class defaultLeaveKeys. |
|
1055 |
cursorMovementWhenUpdating := #endOfLine |
|
1056 |
! ! |
|
1057 |
||
1058 |
!EditField methodsFor:'private'! |
|
1059 |
||
1060 |
argForChangeMessage |
|
1061 |
"redefined to send use converted value (if I have one)" |
|
1062 |
||
1063 |
^ self editValue |
|
1064 |
! |
|
1065 |
||
1066 |
getListFromModel |
|
1067 |
"redefined to aquire the text via the aspectMsg - not the listMsg, |
|
1068 |
and to ignore updates resulting from my own change." |
|
1069 |
||
1070 |
" |
|
1071 |
ignore updates from my own change |
|
1072 |
" |
|
1073 |
lockUpdates ifTrue:[ |
|
1074 |
lockUpdates := false. |
|
1075 |
^ self |
|
1076 |
]. |
|
1077 |
||
1078 |
(model notNil and:[aspectMsg notNil]) ifTrue:[ |
|
1079 |
self editValue:(model perform:aspectMsg). |
|
0 | 1080 |
] |
1081 |
! |
|
1082 |
||
192 | 1083 |
startAutoScrollDown:y |
1084 |
"no vertical scrolling in editfields" |
|
1085 |
||
1086 |
^ self |
|
1087 |
! |
|
1088 |
||
1089 |
startAutoScrollUp:y |
|
1090 |
"no vertical scrolling in editfields" |
|
1091 |
||
1092 |
^ self |
|
1093 |
! |
|
0 | 1094 |
|
192 | 1095 |
textChanged |
1096 |
"this is sent by mySelf (somewhere in a superclass) whenever |
|
1097 |
my contents has changed. |
|
1098 |
A good place to add immediateAccept functionality and check for the |
|
1099 |
lengthLimit." |
|
1100 |
||
1101 |
|string c| |
|
1102 |
||
1103 |
super textChanged. |
|
1104 |
string := self contents. |
|
1105 |
lengthLimit notNil ifTrue:[ |
|
1106 |
string size > lengthLimit ifTrue:[ |
|
1107 |
c := cursorCol. |
|
1108 |
self contents:(string copyTo:lengthLimit). |
|
1109 |
self flash. |
|
1110 |
self cursorCol:c. |
|
125 | 1111 |
] |
0 | 1112 |
]. |
192 | 1113 |
immediateAccept ifTrue:[ |
1114 |
self accept |
|
1115 |
] |
|
105 | 1116 |
! |
1117 |
||
192 | 1118 |
visibleAt:visLineNr |
1119 |
"return the string at lineNr for display. |
|
1120 |
If there is a password character, return a string consisting of those only." |
|
1121 |
||
1122 |
|s| |
|
105 | 1123 |
|
192 | 1124 |
s := super visibleAt:visLineNr. |
1125 |
passwordCharacter notNil ifTrue:[ |
|
1126 |
^ String new:(s size) withAll:passwordCharacter |
|
1127 |
]. |
|
1128 |
^ s |
|
1129 |
||
1130 |
"Modified: 6.9.1995 / 12:25:06 / claus" |
|
0 | 1131 |
! ! |
125 | 1132 |
|
192 | 1133 |
!EditField methodsFor:'queries'! |
1134 |
||
1135 |
preferredExtent |
|
1136 |
"return the preferred extent of this view. |
|
1137 |
That is the width of the string plus some extra, |
|
1138 |
but not wider than half of the screen" |
|
1139 |
||
1140 |
|string w f| |
|
125 | 1141 |
|
192 | 1142 |
string := self contents. |
1143 |
(string isNil or:[string isBlank]) ifTrue:[ |
|
1144 |
string := ' ' "/ just any string is ok ^ super preferredExtent |
|
1145 |
]. |
|
1146 |
f := font on:device. |
|
1147 |
w := ((f widthOf:string) * 1.5) rounded. |
|
1148 |
w := w min:(device width // 2). |
|
231 | 1149 |
"/ ^ w @ (f height * 1.5) rounded |
1150 |
^ w @ (f height + f descent + (margin * 2)"* 1.5") rounded |
|
192 | 1151 |
|
1152 |
"Modified: 6.9.1995 / 19:24:06 / claus" |
|
1153 |
! |
|
1154 |
||
1155 |
specClass |
|
1156 |
self class == EditField ifTrue:[^ InputFieldSpec]. |
|
1157 |
^ nil |
|
125 | 1158 |
|
192 | 1159 |
"Modified: 5.9.1995 / 17:28:27 / claus" |
1160 |
! ! |
|
1161 |
||
1162 |
!EditField methodsFor:'realization'! |
|
1163 |
||
1164 |
realize |
|
1165 |
"scroll back to beginning when realized" |
|
1166 |
leftOffset := 0. |
|
1167 |
super realize |
|
125 | 1168 |
! ! |
192 | 1169 |
|
209
7a6db7fac566
dont allow multiline selections in EditField
Claus Gittinger <cg@exept.de>
parents:
192
diff
changeset
|
1170 |
!EditField methodsFor:'selections'! |
7a6db7fac566
dont allow multiline selections in EditField
Claus Gittinger <cg@exept.de>
parents:
192
diff
changeset
|
1171 |
|
7a6db7fac566
dont allow multiline selections in EditField
Claus Gittinger <cg@exept.de>
parents:
192
diff
changeset
|
1172 |
validateNewSelection |
7a6db7fac566
dont allow multiline selections in EditField
Claus Gittinger <cg@exept.de>
parents:
192
diff
changeset
|
1173 |
"make certain that only one line is ever selected" |
7a6db7fac566
dont allow multiline selections in EditField
Claus Gittinger <cg@exept.de>
parents:
192
diff
changeset
|
1174 |
|
7a6db7fac566
dont allow multiline selections in EditField
Claus Gittinger <cg@exept.de>
parents:
192
diff
changeset
|
1175 |
selectionEndLine > 1 ifTrue:[ |
7a6db7fac566
dont allow multiline selections in EditField
Claus Gittinger <cg@exept.de>
parents:
192
diff
changeset
|
1176 |
selectionEndLine := 2. selectionEndCol := 0 |
7a6db7fac566
dont allow multiline selections in EditField
Claus Gittinger <cg@exept.de>
parents:
192
diff
changeset
|
1177 |
]. |
7a6db7fac566
dont allow multiline selections in EditField
Claus Gittinger <cg@exept.de>
parents:
192
diff
changeset
|
1178 |
! ! |
7a6db7fac566
dont allow multiline selections in EditField
Claus Gittinger <cg@exept.de>
parents:
192
diff
changeset
|
1179 |
|
192 | 1180 |
!EditField methodsFor:'scrolling'! |
1181 |
||
1182 |
makeColVisible:col inLine:line |
|
1183 |
"dont scroll for the cursor, if its behond the text and a lengthLimit |
|
1184 |
is present." |
|
1185 |
||
1186 |
lengthLimit notNil ifTrue:[ |
|
1187 |
(col == cursorCol and:[col > lengthLimit]) ifTrue:[ |
|
1188 |
^ super makeColVisible:lengthLimit inLine:line |
|
1189 |
] |
|
1190 |
]. |
|
1191 |
^ super makeColVisible:col inLine:line |
|
1192 |
||
1193 |
"Modified: 6.9.1995 / 13:57:53 / claus" |
|
1194 |
! ! |
|
1195 |