327 box label:'on/off'. |
368 box label:'on/off'. |
328 top2 add:box. |
369 top2 add:box. |
329 top2 open. |
370 top2 open. |
330 |
371 |
331 model inspect. |
372 model inspect. |
|
373 |
|
374 |
|
375 connecting fields: |
|
376 update field2 wehenever field1 is changed. |
|
377 (normally, the processing below (xChanged) is done in your application |
|
378 class, or in a complex model. For the demonstration below, we use |
|
379 a Plug to simulate the protocol.) |
|
380 |
|
381 |application top field1 field2 value1 value2| |
|
382 |
|
383 application := Plug new. |
|
384 application respondTo:#value1Changed |
|
385 with:[value2 value:(value1 value isNil ifTrue:[nil] |
|
386 ifFalse:[value1 value squared])]. |
|
387 |
|
388 value1 := 1 asValue. |
|
389 value2 := 1 asValue. |
|
390 |
|
391 top := Dialog new. |
|
392 top extent:200@200. |
|
393 |
|
394 (top addTextLabel:'some number:') layout:#left. |
|
395 top addVerticalSpace. |
|
396 |
|
397 (top addInputFieldOn:value1 tabable:false) |
|
398 converter:(PrintConverter new initForNumberOrNil); |
|
399 immediateAccept:true. |
|
400 top addVerticalSpace. |
|
401 |
|
402 (top addTextLabel:'squared:') layout:#left. |
|
403 top addVerticalSpace. |
|
404 (top addInputFieldOn:value2 tabable:false) |
|
405 converter:(PrintConverter new initForNumberOrNil). |
|
406 |
|
407 value1 onChangeSend:#value1Changed to:application. |
|
408 |
|
409 top openModeless. |
|
410 |
|
411 |
|
412 two-way connect: |
|
413 each field updates the other (notice, that we have to turn off |
|
414 onChange: notification, to avoid an endless notification cycle) |
|
415 |
|
416 |application top field1 field2 value1 value2| |
|
417 |
|
418 application := Plug new. |
|
419 application respondTo:#value1Changed |
|
420 with:[value2 retractInterrestFor:application. |
|
421 value2 value:(value1 value isNil ifTrue:[nil] |
|
422 ifFalse:[value1 value squared]). |
|
423 value2 onChangeSend:#value2Changed to:application. |
|
424 ]. |
|
425 application respondTo:#value2Changed |
|
426 with:[value1 retractInterrestFor:application. |
|
427 value1 value:(value2 value isNil ifTrue:[nil] |
|
428 ifFalse:[value2 value sqrt]). |
|
429 value1 onChangeSend:#value1Changed to:application. |
|
430 ]. |
|
431 |
|
432 value1 := 1 asValue. |
|
433 value2 := 1 asValue. |
|
434 |
|
435 top := Dialog new. |
|
436 top extent:200@200. |
|
437 |
|
438 (top addTextLabel:'some number:') layout:#left. |
|
439 top addVerticalSpace. |
|
440 |
|
441 (top addInputFieldOn:value1 tabable:false) |
|
442 converter:(PrintConverter new initForNumberOrNil); |
|
443 immediateAccept:true. |
|
444 top addVerticalSpace. |
|
445 |
|
446 (top addTextLabel:'squared:') layout:#left. |
|
447 top addVerticalSpace. |
|
448 (top addInputFieldOn:value2 tabable:false) |
|
449 converter:(PrintConverter new initForNumberOrNil). |
|
450 |
|
451 value1 onChangeSend:#value1Changed to:application. |
|
452 value2 onChangeSend:#value2Changed to:application. |
|
453 |
|
454 top openModeless. |
332 " |
455 " |
333 ! ! |
456 ! ! |
334 |
457 |
335 !EditField class methodsFor:'defaults'! |
458 !EditField class methodsFor:'defaults'! |
|
459 |
|
460 defaultLeaveKeys |
|
461 ^ #(Return CursorUp CursorDown Next Previous Accept) |
|
462 ! |
336 |
463 |
337 updateStyleCache |
464 updateStyleCache |
338 DefaultForegroundColor := StyleSheet colorAt:'editFieldForegroundColor' default:Black. |
465 DefaultForegroundColor := StyleSheet colorAt:'editFieldForegroundColor' default:Black. |
339 DefaultBackgroundColor := StyleSheet colorAt:'editFieldBackgroundColor' default:White. |
466 DefaultBackgroundColor := StyleSheet colorAt:'editFieldBackgroundColor' default:White. |
340 DefaultSelectionForegroundColor := StyleSheet colorAt:'editFieldSelectionForegroundColor' default:DefaultBackgroundColor. |
467 DefaultSelectionForegroundColor := StyleSheet colorAt:'editFieldSelectionForegroundColor' default:DefaultBackgroundColor. |
344 " |
471 " |
345 self updateStyleCache |
472 self updateStyleCache |
346 " |
473 " |
347 ! |
474 ! |
348 |
475 |
349 defaultLeaveKeys |
|
350 ^ #(Return CursorUp CursorDown Next Previous Accept) |
|
351 ! |
|
352 |
|
353 defaultNumberOfLines |
476 defaultNumberOfLines |
354 "the number of lines in the field" |
477 "the number of lines in the field" |
355 |
478 |
356 ^ 1 |
479 ^ 1 |
357 ! ! |
480 ! ! |
358 |
481 |
|
482 !EditField methodsFor:'private'! |
|
483 |
|
484 textChanged |
|
485 "this is sent by mySelf (somewhere in a superclass) whenever |
|
486 my contents has changed. |
|
487 A good place to add immediateAccept functionality and check for the |
|
488 lengthLimit." |
|
489 |
|
490 |string| |
|
491 |
|
492 super textChanged. |
|
493 string := self contents. |
|
494 lengthLimit notNil ifTrue:[ |
|
495 string size > lengthLimit ifTrue:[ |
|
496 self contents:(string := string copyTo:lengthLimit). |
|
497 self flash. |
|
498 ] |
|
499 ]. |
|
500 immediateAccept ifTrue:[ |
|
501 self accept |
|
502 ] |
|
503 ! |
|
504 |
|
505 getListFromModel |
|
506 "redefined to aquire the text via the aspectMsg - not the listMsg, |
|
507 and to ignore updates resulting from my own change." |
|
508 |
|
509 " |
|
510 ignore updates from my own change |
|
511 " |
|
512 lockUpdates ifTrue:[ |
|
513 lockUpdates := false. |
|
514 ^ self |
|
515 ]. |
|
516 |
|
517 (model notNil and:[aspectMsg notNil]) ifTrue:[ |
|
518 self editValue:(model perform:aspectMsg). |
|
519 ] |
|
520 ! |
|
521 |
|
522 startAutoScrollUp:y |
|
523 "no vertical scrolling in editfields" |
|
524 |
|
525 ^ self |
|
526 ! |
|
527 |
|
528 startAutoScrollDown:y |
|
529 "no vertical scrolling in editfields" |
|
530 |
|
531 ^ self |
|
532 ! ! |
|
533 |
|
534 !EditField methodsFor:'accessing'! |
|
535 |
|
536 contents |
|
537 "return contents as a string |
|
538 - redefined since EditFields hold only one line of text. |
|
539 In your application, please use #editValue; |
|
540 it uses a converter (if any) and is compatible to ST-80." |
|
541 |
|
542 list isNil ifTrue:[^ '']. |
|
543 (list size == 0) ifTrue:[^ '']. |
|
544 ^ list at:1 |
|
545 ! |
|
546 |
|
547 leaveAction:aBlock |
|
548 "define an action to be evaluated when field is left by return key" |
|
549 |
|
550 leaveAction := aBlock |
|
551 ! |
|
552 |
|
553 list:someText |
|
554 "redefined to force text to 1 line, and notify dependents |
|
555 of any changed extent-wishes." |
|
556 |
|
557 |l oldWidth| |
|
558 |
|
559 l := someText. |
|
560 l size > 1 ifTrue:[ |
|
561 l := OrderedCollection with:(l at:1) |
|
562 ]. |
|
563 oldWidth := self widthOfContents. |
|
564 super list:l. |
|
565 self widthOfContents ~~ oldWidth ifTrue:[ |
|
566 self changed:#preferedExtent |
|
567 ] |
|
568 ! |
|
569 |
|
570 contents:someText |
|
571 "set the contents from a string |
|
572 - redefined to place the cursor to the end. |
|
573 In your application, please use #editValue:; |
|
574 it uses a converter (if any) and is compatible to ST-80." |
|
575 |
|
576 super contents:someText. |
|
577 self cursorCol:(someText size + 1). |
|
578 ! |
|
579 |
|
580 enable |
|
581 "enable the field; show cursor and allow input" |
|
582 |
|
583 enabled ifFalse:[ |
|
584 "/ enableAction notNil ifTrue:[ |
|
585 "/ enableAction value |
|
586 "/ ]. |
|
587 enabled := true. |
|
588 super showCursor |
|
589 ] |
|
590 ! |
|
591 |
|
592 immediateAccept:aBoolean |
|
593 "set/clear the immediateAccept flag. The default is false." |
|
594 |
|
595 immediateAccept := aBoolean |
|
596 ! |
|
597 |
|
598 editValue |
|
599 "if the field edits a string, this is a name alias for #contents. |
|
600 Otherwise, if there is a converter, return the edited string |
|
601 converted to an appropriate object." |
|
602 |
|
603 |string| |
|
604 |
|
605 string := self contents. |
|
606 converter isNil ifTrue:[^ string]. |
|
607 string isNil ifTrue:[string := '']. |
|
608 ^ converter readValueFrom:string |
|
609 ! |
|
610 |
|
611 leaveKeys:aCollectionOfKeySymbols |
|
612 "define the set of keys which are interpreted as leaveKeys. |
|
613 I.e. those that make the field inactive and accept (if acceptOnLeave is true). |
|
614 The default is a set of #CursorUp, #CursorDown, #Next, #Prior and #Return." |
|
615 |
|
616 leaveKeys := aCollectionOfKeySymbols |
|
617 ! |
|
618 |
|
619 initialText:aString selected:aBoolean |
|
620 "set the initialText and select it if aBoolean is true" |
|
621 |
|
622 |len s| |
|
623 |
|
624 leftOffset := 0. |
|
625 aString isNil ifTrue:[ |
|
626 s := nil |
|
627 ] ifFalse:[ |
|
628 s := aString asString |
|
629 ]. |
|
630 self contents:s. |
|
631 aBoolean ifTrue:[ |
|
632 (len := s size) ~~ 0 ifTrue:[ |
|
633 self selectFromLine:1 col:1 toLine:1 col:len |
|
634 ] |
|
635 ] |
|
636 ! |
|
637 |
|
638 crAction:aBlock |
|
639 "define an action to be evaluated when the return key is pressed." |
|
640 |
|
641 crAction := aBlock |
|
642 ! |
|
643 |
|
644 tabAction:aBlock |
|
645 "define an action to be evaluated when the tabulator key is pressed." |
|
646 |
|
647 tabAction := aBlock |
|
648 ! |
|
649 |
|
650 acceptOnReturn:aBoolean |
|
651 "set/clear the acceptOnReturn flag. The default is true." |
|
652 |
|
653 acceptOnReturn := aBoolean |
|
654 ! |
|
655 |
|
656 initialText:aString |
|
657 "set the initialText and select it" |
|
658 |
|
659 self initialText:aString selected:true |
|
660 ! |
|
661 |
|
662 editValue:aStringOrObject |
|
663 "set the contents. If there is a converter, use it to convert |
|
664 the object into a printed representation. |
|
665 Otherwise, the argument is supposed to be a string like object, |
|
666 and used directly (i.e. this is equivalent to sending #contents:)." |
|
667 |
|
668 self editValue:aStringOrObject selected:false |
|
669 ! |
|
670 |
|
671 disable |
|
672 "disable the field; hide cursor and ignore input" |
|
673 |
|
674 enabled ifTrue:[ |
|
675 enabled := false. |
|
676 self hideCursor |
|
677 ] |
|
678 ! |
|
679 |
|
680 editValue:aStringOrObject selected:aBoolean |
|
681 "set the contents. If there is a converter, use it to convert |
|
682 the object into a printed representation. |
|
683 Otherwise, the argument is supposed to be a string like object, |
|
684 and used directly (i.e. this is equivalent to sending #contents:)." |
|
685 |
|
686 |string| |
|
687 |
|
688 converter notNil ifTrue:[ |
|
689 string := converter printStringFor:aStringOrObject |
|
690 ] ifFalse:[ |
|
691 string := aStringOrObject. |
|
692 ]. |
|
693 self contents:string. |
|
694 aBoolean ifTrue:[ |
|
695 self selectFromLine:1 col:1 toLine:1 col:string size |
|
696 ] |
|
697 ! |
|
698 |
|
699 acceptOnLeave:aBoolean |
|
700 "set/clear the acceptOnLeave flag. The default is false." |
|
701 |
|
702 acceptOnLeave := aBoolean |
|
703 ! |
|
704 |
|
705 converter:aConverter |
|
706 "set the converter. If non-nil, |
|
707 the converter is applied to the text to convert from the string |
|
708 representation to the actual object value and vice versa. |
|
709 The default converter is nil, meaning no-conversion |
|
710 (i.e. the edited object is the string itself." |
|
711 |
|
712 converter := aConverter |
|
713 ! |
|
714 |
|
715 enableAction:aBlock |
|
716 "define an action to be evaluated when enabled by clicking upon" |
|
717 |
|
718 enableAction := aBlock |
|
719 ! |
|
720 |
|
721 converter |
|
722 "return the converter (if any)." |
|
723 |
|
724 ^ converter |
|
725 ! |
|
726 |
|
727 maxChars:aNumberOrNil |
|
728 "set the maximum number of characters that are allowed in |
|
729 the field. Additional input will be ignored by the field. |
|
730 A limit of nil means: unlimited. This is the default. |
|
731 This method has been renamed from #lengthLimit: for ST-80 |
|
732 compatibility." |
|
733 |
|
734 lengthLimit := aNumberOrNil |
|
735 ! |
|
736 |
|
737 stringValue |
|
738 "alias for #contents - for ST-80 compatibility" |
|
739 |
|
740 ^ self contents |
|
741 ! ! |
|
742 |
359 !EditField methodsFor:'initialization'! |
743 !EditField methodsFor:'initialization'! |
|
744 |
|
745 initStyle |
|
746 super initStyle. |
|
747 |
|
748 DefaultBackgroundColor notNil ifTrue:[ |
|
749 bgColor := DefaultBackgroundColor on:device. |
|
750 self viewBackground:bgColor. |
|
751 ]. |
|
752 fgColor := DefaultForegroundColor. |
|
753 selectionFgColor := DefaultSelectionForegroundColor. |
|
754 selectionBgColor := DefaultSelectionBackgroundColor. |
|
755 |
|
756 DefaultFont notNil ifTrue:[ |
|
757 font := DefaultFont on:device |
|
758 ] |
|
759 ! |
360 |
760 |
361 initialize |
761 initialize |
362 super initialize. |
762 super initialize. |
363 self height:(font height + font descent + (topMargin * 2)). |
763 self height:(font height + font descent + (topMargin * 2)). |
364 enabled := true. |
764 enabled := true. |
365 fixedSize := true. |
765 fixedSize := true. |
366 nFullLinesShown := 1. |
766 nFullLinesShown := 1. |
367 nLinesShown := 1. |
767 nLinesShown := 1. |
368 alwaysAccept := false. |
768 immediateAccept := acceptOnLeave := false. |
369 acceptOnLeave := false. |
|
370 acceptOnReturn := true. |
769 acceptOnReturn := true. |
|
770 cursorShown := true. |
371 leaveKeys := self class defaultLeaveKeys. |
771 leaveKeys := self class defaultLeaveKeys. |
372 cursorShown := true |
|
373 ! |
|
374 |
|
375 initStyle |
|
376 super initStyle. |
|
377 |
|
378 DefaultBackgroundColor notNil ifTrue:[ |
|
379 bgColor := DefaultBackgroundColor on:device. |
|
380 self viewBackground:bgColor. |
|
381 ]. |
|
382 fgColor := DefaultForegroundColor. |
|
383 selectionFgColor := DefaultSelectionForegroundColor. |
|
384 selectionBgColor := DefaultSelectionBackgroundColor. |
|
385 |
|
386 DefaultFont notNil ifTrue:[ |
|
387 font := DefaultFont on:device |
|
388 ] |
|
389 ! |
772 ! |
390 |
773 |
391 editMenu |
774 editMenu |
392 |labels selectors m| |
775 |labels selectors m| |
393 |
776 |
486 w := (((font on:device) widthOf:string) * 1.5) rounded. |
832 w := (((font on:device) widthOf:string) * 1.5) rounded. |
487 w := w min:(device width // 2). |
833 w := w min:(device width // 2). |
488 ^ w @ self height |
834 ^ w @ self height |
489 ! ! |
835 ! ! |
490 |
836 |
491 !EditField methodsFor:'accessing'! |
|
492 |
|
493 list:someText |
|
494 "redefined to force text to 1 line, and notify dependents |
|
495 of any changed extent-wishes." |
|
496 |
|
497 |l oldWidth| |
|
498 |
|
499 l := someText. |
|
500 l size > 1 ifTrue:[ |
|
501 l := OrderedCollection with:(l at:1) |
|
502 ]. |
|
503 oldWidth := self widthOfContents. |
|
504 super list:l. |
|
505 self widthOfContents ~~ oldWidth ifTrue:[ |
|
506 self changed:#preferedExtent |
|
507 ] |
|
508 ! |
|
509 |
|
510 contents:someText |
|
511 "set the contents from a string |
|
512 - redefined to place the cursor to the end. |
|
513 In your application, please use #editValue:; |
|
514 it uses a converter (if any) and is compatible to ST-80." |
|
515 |
|
516 super contents:someText. |
|
517 self cursorCol:(someText size + 1). |
|
518 ! |
|
519 |
|
520 contents |
|
521 "return contents as a string |
|
522 - redefined since EditFields hold only one line of text. |
|
523 In your application, please use #editValue; |
|
524 it uses a converter (if any) and is compatible to ST-80." |
|
525 |
|
526 list isNil ifTrue:[^ '']. |
|
527 (list size == 0) ifTrue:[^ '']. |
|
528 ^ list at:1 |
|
529 ! |
|
530 |
|
531 enable |
|
532 "enable the field; show cursor and allow input" |
|
533 |
|
534 enabled ifFalse:[ |
|
535 enableAction notNil ifTrue:[ |
|
536 enableAction value |
|
537 ]. |
|
538 enabled := true. |
|
539 super showCursor |
|
540 ] |
|
541 ! |
|
542 |
|
543 leaveAction:aBlock |
|
544 "define an action to be evaluated when field is left by return key" |
|
545 |
|
546 leaveAction := aBlock |
|
547 ! |
|
548 |
|
549 leaveKeys:aCollectionOfKeySymbols |
|
550 "define the set of keys which are interpreted as leaveKeys. |
|
551 I.e. those that make the field inactive and accept (if acceptOnLeave is true). |
|
552 The default is a set of #CursorUp, #CursorDown, #Next, #Prior and #Return." |
|
553 |
|
554 leaveKeys := aCollectionOfKeySymbols |
|
555 ! |
|
556 |
|
557 crAction:aBlock |
|
558 "define an action to be evaluated when the return key is pressed." |
|
559 |
|
560 crAction := aBlock |
|
561 ! |
|
562 |
|
563 acceptAction:aBlock |
|
564 "define an action to be evaluated when accepted." |
|
565 |
|
566 acceptAction := aBlock |
|
567 ! |
|
568 |
|
569 tabAction:aBlock |
|
570 "define an action to be evaluated when the tabulator key is pressed." |
|
571 |
|
572 tabAction := aBlock |
|
573 ! |
|
574 |
|
575 alwaysAccept:aBoolean |
|
576 "set/clear the alwaysAccept flag. The default is false." |
|
577 |
|
578 alwaysAccept := aBoolean |
|
579 ! |
|
580 |
|
581 acceptOnReturn:aBoolean |
|
582 "set/clear the acceptOnReturn flag. The default is true." |
|
583 |
|
584 acceptOnReturn := aBoolean |
|
585 ! |
|
586 |
|
587 acceptOnLeave:aBoolean |
|
588 "set/clear the acceptOnLeave flag. The default is false." |
|
589 |
|
590 acceptOnLeave := aBoolean |
|
591 ! |
|
592 |
|
593 converter |
|
594 "return the converter (if any)." |
|
595 |
|
596 ^ converter |
|
597 ! |
|
598 |
|
599 editValue |
|
600 "if the field edits a string, this is a name alias for #contents. |
|
601 Otherwise, if there is a converter, return the edited string |
|
602 converted to an appropriate object." |
|
603 |
|
604 |text| |
|
605 |
|
606 text := self contents. |
|
607 converter isNil ifTrue:[^ text]. |
|
608 ^ converter readValueFrom:text withoutSpaces |
|
609 ! |
|
610 |
|
611 editValue:aStringOrObject |
|
612 "set the contents. If there is a converter, use it to convert |
|
613 the object into a printed representation. |
|
614 Otherwise, the argument is supposed to be a string like object, |
|
615 and used directly (i.e. this is equivalent to sending #contents:)." |
|
616 |
|
617 self editValue:aStringOrObject selected:false |
|
618 ! |
|
619 |
|
620 editValue:aStringOrObject selected:aBoolean |
|
621 "set the contents. If there is a converter, use it to convert |
|
622 the object into a printed representation. |
|
623 Otherwise, the argument is supposed to be a string like object, |
|
624 and used directly (i.e. this is equivalent to sending #contents:)." |
|
625 |
|
626 |text| |
|
627 |
|
628 converter notNil ifTrue:[ |
|
629 text := converter printStringFor:aStringOrObject |
|
630 ] ifFalse:[ |
|
631 text := aStringOrObject. |
|
632 ]. |
|
633 self contents:text. |
|
634 aBoolean ifTrue:[ |
|
635 self selectFromLine:1 col:1 toLine:1 col:text size |
|
636 ] |
|
637 ! |
|
638 |
|
639 converter:aConverter |
|
640 "set the converter. If non-nil, |
|
641 the converter is applied to the text to convert from the string |
|
642 representation to the actual object value and vice versa. |
|
643 The default converter is nil, meaning no-conversion |
|
644 (i.e. the edited object is the string itself." |
|
645 |
|
646 converter := aConverter |
|
647 ! |
|
648 |
|
649 |
|
650 disable |
|
651 "disable the field; hide cursor and ignore input" |
|
652 |
|
653 enabled ifTrue:[ |
|
654 enabled := false. |
|
655 self hideCursor |
|
656 ] |
|
657 ! |
|
658 |
|
659 enableAction:aBlock |
|
660 "define an action to be evaluated when enabled by clicking upon" |
|
661 |
|
662 enableAction := aBlock |
|
663 ! |
|
664 |
|
665 initialText:aString selected:aBoolean |
|
666 "set the initialText and select it if aBoolean is true" |
|
667 |
|
668 |len s| |
|
669 |
|
670 leftOffset := 0. |
|
671 self contents:(s := aString asString). |
|
672 aBoolean ifTrue:[ |
|
673 (len := s size) ~~ 0 ifTrue:[ |
|
674 self selectFromLine:1 col:1 toLine:1 col:len |
|
675 ] |
|
676 ] |
|
677 ! |
|
678 |
|
679 initialText:aString |
|
680 "set the initialText and select it" |
|
681 |
|
682 self initialText:aString selected:true |
|
683 ! ! |
|
684 |
|
685 !EditField methodsFor:'editing'! |
|
686 |
|
687 paste:someText |
|
688 "redefined to force text to 1 line" |
|
689 |
|
690 super paste:someText. |
|
691 list size > 1 ifTrue:[ |
|
692 self deleteFromLine:2 toLine:(list size) |
|
693 ] |
|
694 ! ! |
|
695 |
|
696 !EditField methodsFor:'cursor drawing'! |
837 !EditField methodsFor:'cursor drawing'! |
697 |
838 |
698 showCursor |
839 showCursor |
699 "make cursor visible if currently invisible - but only if this |
840 "make cursor visible if currently invisible - but only if this |
700 EditField is enabled" |
841 EditField is enabled" |
718 ] |
874 ] |
719 ! ! |
875 ! ! |
720 |
876 |
721 !EditField methodsFor:'event handling'! |
877 !EditField methodsFor:'event handling'! |
722 |
878 |
723 accept |
879 keyPress:key x:x y:y |
724 "accept the fields contents - perform the leave action as if |
880 "if keyHandler is defined, pass input; otherwise check for leave |
725 return was pressed." |
881 keys" |
726 |
882 |
727 |value| |
883 |leave xCol newOffset oldWidth newWidth| |
728 |
884 |
729 value := self editValue. |
885 enabled ifFalse:[ |
730 acceptAction notNil ifTrue:[ |
886 ^ self |
731 acceptAction value:value |
887 ]. |
732 ]. |
888 |
733 |
889 (key == #DeleteLine) ifTrue:[ |
734 "model-view behavior" |
890 Smalltalk at:#CopyBuffer put:(self contents). |
735 self sendChangeMessageWith:value. |
891 self contents:''. ^ self |
|
892 ]. |
|
893 |
|
894 (key == #Tab) ifTrue:[ |
|
895 tabAction notNil ifTrue:[tabAction value. ^ self]. |
|
896 ]. |
|
897 (key == #Return) ifTrue:[ |
|
898 crAction notNil ifTrue:[crAction value. ^ self]. |
|
899 ]. |
|
900 leave := leaveKeys includes:key. |
|
901 leave ifTrue:[ |
|
902 leaveAction notNil ifTrue:[ |
|
903 leaveAction value:key |
|
904 ]. |
|
905 |
|
906 ((key == #Return and:[acceptOnReturn]) |
|
907 or:[key ~~ #Return and:[acceptOnLeave]]) ifTrue:[ |
|
908 self accept. |
|
909 ]. |
|
910 |
|
911 x >= 0 ifTrue:[ |
|
912 " |
|
913 let superview know about the leave ... |
|
914 This is a temporary kludge for the tableWidget - |
|
915 it is no clean coding style. Should make the tableWidget |
|
916 a proper model and handle it via the changed mechanism .... |
|
917 " |
|
918 (superView notNil and:[superView canHandle:key from:self]) ifTrue:[ |
|
919 superView keyPress:key x:x y:y. |
|
920 ]. |
|
921 ]. |
|
922 ^ self |
|
923 ]. |
|
924 |
|
925 " |
|
926 ignore some keys (if not a leaveKey) ... |
|
927 " |
|
928 (key == #Find) ifTrue:[^self]. |
|
929 (key == #FindNext) ifTrue:[^self]. |
|
930 (key == #FindPrev) ifTrue:[^self]. |
|
931 (key == #GotoLine) ifTrue:[^self]. |
|
932 |
|
933 " |
|
934 a normal key - let superclass's method insert it |
|
935 " |
|
936 oldWidth := self widthOfContents. |
|
937 super keyPress:key x:x y:y. |
|
938 |
|
939 " |
|
940 for end-of-text, also move to end-of-line |
|
941 " |
|
942 key == #EndOfText ifTrue:[ |
|
943 super keyPress:#EndOfLine x:x y:y. |
|
944 ]. |
|
945 newWidth := self widthOfContents. |
|
946 |
|
947 " |
|
948 should (& can) we resize ? |
|
949 " |
|
950 xCol := (self xOfCol:cursorCol inVisibleLine:cursorLine) - leftOffset. |
|
951 (xCol > (width * (5/6))) ifTrue:[ |
|
952 self changed:#preferedExtent |
|
953 ] ifFalse:[ |
|
954 newWidth < (width * (1/6)) ifTrue:[ |
|
955 self changed:#preferedExtent |
|
956 ] |
|
957 ]. |
|
958 |
|
959 " |
|
960 did someone react ? |
|
961 (if not, we scroll horizontally) |
|
962 " |
|
963 xCol := (self xOfCol:cursorCol inVisibleLine:cursorLine) - leftOffset. |
|
964 (xCol > (width * (5/6))) ifTrue:[ |
|
965 newOffset := leftOffset + (width // 2). |
|
966 ] ifFalse:[ |
|
967 (xCol < (width * (1/6))) ifTrue:[ |
|
968 newOffset := 0 max: leftOffset - (width // 2). |
|
969 ] ifFalse:[ |
|
970 newOffset := leftOffset |
|
971 ] |
|
972 ]. |
|
973 newOffset ~~ leftOffset ifTrue:[ |
|
974 leftOffset := newOffset. |
|
975 self clear. |
|
976 self redraw |
|
977 ] |
736 ! |
978 ! |
737 |
979 |
738 buttonPress:button x:x y:y |
980 buttonPress:button x:x y:y |
739 "enable myself on mouse click" |
981 "enable myself on mouse click" |
740 |
982 |
747 ] ifTrue:[ |
989 ] ifTrue:[ |
748 super buttonPress:button x:x y:y |
990 super buttonPress:button x:x y:y |
749 ] |
991 ] |
750 ! |
992 ! |
751 |
993 |
752 keyPress:key x:x y:y |
994 focusIn |
753 "if keyHandler is defined, pass input; otherwise check for leave |
995 "got the explicit focus" |
754 keys" |
|
755 |
|
756 |leave xCol newOffset oldWidth newWidth| |
|
757 |
996 |
758 enabled ifFalse:[ |
997 enabled ifFalse:[ |
759 ^ self |
998 enabled := true. |
760 ]. |
999 super focusIn. |
761 |
1000 enableAction notNil ifTrue:[ |
762 (key == #DeleteLine) ifTrue:[ |
1001 enableAction value |
763 Smalltalk at:#CopyBuffer put:(self contents). |
|
764 self contents:''. ^ self |
|
765 ]. |
|
766 |
|
767 (key == #Tab) ifTrue:[ |
|
768 tabAction notNil ifTrue:[tabAction value. ^ self]. |
|
769 ]. |
|
770 (key == #Return) ifTrue:[ |
|
771 crAction notNil ifTrue:[crAction value. ^ self]. |
|
772 ]. |
|
773 leave := leaveKeys includes:key. |
|
774 leave ifTrue:[ |
|
775 leaveAction notNil ifTrue:[ |
|
776 leaveAction value:key |
|
777 ]. |
|
778 |
|
779 ((key == #Return and:[acceptOnReturn]) |
|
780 or:[key ~~ #Return and:[acceptOnLeave]]) ifTrue:[ |
|
781 self accept. |
|
782 ]. |
|
783 |
|
784 x >= 0 ifTrue:[ |
|
785 " |
|
786 let superview know about the leave ... |
|
787 This is a temporary kludge for the tableWidget - |
|
788 it is no clean coding style. Should make the tableWidget |
|
789 a proper model and handle it via the changed mechanism .... |
|
790 " |
|
791 (superView notNil and:[superView canHandle:key from:self]) ifTrue:[ |
|
792 superView keyPress:key x:x y:y. |
|
793 ]. |
|
794 ]. |
|
795 ^ self |
|
796 ]. |
|
797 |
|
798 " |
|
799 ignore some keys (if not a leaveKey) ... |
|
800 " |
|
801 (key == #Find) ifTrue:[^self]. |
|
802 (key == #FindNext) ifTrue:[^self]. |
|
803 (key == #FindPrev) ifTrue:[^self]. |
|
804 (key == #GotoLine) ifTrue:[^self]. |
|
805 |
|
806 " |
|
807 a normal key - let superclass's method insert it |
|
808 " |
|
809 oldWidth := self widthOfContents. |
|
810 super keyPress:key x:x y:y. |
|
811 newWidth := self widthOfContents. |
|
812 |
|
813 " |
|
814 should (& can) we resize ? |
|
815 " |
|
816 xCol := (self xOfCol:cursorCol inVisibleLine:cursorLine) - leftOffset. |
|
817 (xCol > (width * (5/6))) ifTrue:[ |
|
818 self changed:#preferedExtent |
|
819 ] ifFalse:[ |
|
820 newWidth < (width * (1/6)) ifTrue:[ |
|
821 self changed:#preferedExtent |
|
822 ] |
1002 ] |
823 ]. |
1003 ] ifTrue:[ |
824 |
1004 super focusIn |
825 " |
1005 ]. |
826 did someone react ? |
|
827 (if not, we scroll horizontally) |
|
828 " |
|
829 xCol := (self xOfCol:cursorCol inVisibleLine:cursorLine) - leftOffset. |
|
830 (xCol > (width * (5/6))) ifTrue:[ |
|
831 newOffset := leftOffset + (width // 2). |
|
832 ] ifFalse:[ |
|
833 (xCol < (width * (1/6))) ifTrue:[ |
|
834 newOffset := 0 max: leftOffset - (width // 2). |
|
835 ] ifFalse:[ |
|
836 newOffset := leftOffset |
|
837 ] |
|
838 ]. |
|
839 newOffset ~~ leftOffset ifTrue:[ |
|
840 leftOffset := newOffset. |
|
841 self clear. |
|
842 self redraw |
|
843 ] |
|
844 ! |
1006 ! |
845 |
1007 |
846 canHandle:aKey |
1008 canHandle:aKey |
847 "return true, if the receiver would like to handle aKey |
1009 "return true, if the receiver would like to handle aKey |
848 (usually from another view, when the receiver is part of |
1010 (usually from another view, when the receiver is part of |
849 a more complex dialog box). |
1011 a more complex dialog box). |
850 We do return true here, since the editfield will handle |
1012 We do return true here, since the editfield will handle |
851 all keys." |
1013 all keys. |
|
1014 OBSOLETE: dont use this anymore - its a leftover for the tableWidget" |
852 |
1015 |
853 ^ true |
1016 ^ true |
854 ! ! |
1017 ! ! |
|
1018 |
|
1019 !EditField methodsFor:'editing'! |
|
1020 |
|
1021 paste:someText |
|
1022 "redefined to force text to 1 line" |
|
1023 |
|
1024 super paste:someText. |
|
1025 list size > 1 ifTrue:[ |
|
1026 self deleteFromLine:2 toLine:(list size) |
|
1027 ] |
|
1028 ! ! |
|
1029 |