EditTextView.st
changeset 297 08eec8838a4c
parent 274 6df4bb990f04
child 309 b5c9d68e95e1
--- a/EditTextView.st	Thu Jan 18 22:28:46 1996 +0100
+++ b/EditTextView.st	Thu Jan 18 22:29:07 1996 +0100
@@ -42,11 +42,11 @@
 "
     a view for editable text - adds editing functionality to TextView
     Also, it adds accept functionality, and defines a new actionBlock: 
-      acceptAction to be performed for accept
+    acceptAction to be performed for accept
 
     If used with a model, this is informed by sending it a changeMsg with
     the current contents as argument.
-    (however, it is possible to define moth changeMsg and acceptAction)
+    (however, it is possible to define both changeMsg and acceptAction)
 
 
     Instance variables:
@@ -86,6 +86,151 @@
       textCursorBackgroundColor <Color>       cursor bg color; default: text foreground
       textCursorType            <Symbol>      cursor type; default:  #block
 "
+!
+
+examples
+"
+  non MVC operation:
+
+    basic setup:
+
+	|top textView|
+
+	top := StandardSystemView new.
+	top extent:300@200.
+
+	textView := EditTextView new.
+	textView origin:0.0 @ 0.0 corner:1.0 @ 1.0.
+	top addSubView:textView.
+
+	textView contents:('/etc/hosts' asFilename contentsOfEntireFile).
+
+	top open.
+
+    with vertical scrollbar:
+
+	|top scrollView textView|
+
+	top := StandardSystemView new.
+	top extent:300@200.
+
+	scrollView := ScrollableView for:EditTextView.
+	textView := scrollView scrolledView.
+	scrollView origin:0.0 @ 0.0 corner:1.0 @ 1.0.
+	top addSubView:scrollView.
+
+	textView contents:('/etc/hosts' asFilename contentsOfEntireFile).
+
+	top open.
+
+    with horizontal & vertical scrollbars:
+
+	|top scrollView textView|
+
+	top := StandardSystemView new.
+	top extent:300@200.
+
+	scrollView := HVScrollableView for:EditTextView.
+	textView := scrollView scrolledView.
+	scrollView origin:0.0 @ 0.0 corner:1.0 @ 1.0.
+	top addSubView:scrollView.
+
+	textView contents:('/etc/hosts' asFilename contentsOfEntireFile).
+
+	top open.
+
+
+    set the action for accept:
+
+	|top textView|
+
+	top := StandardSystemView new.
+	top extent:300@200.
+
+	textView := EditTextView new.
+	textView origin:0.0 @ 0.0 corner:1.0 @ 1.0.
+	top addSubView:textView.
+
+	textView contents:('/etc/hosts' asFilename contentsOfEntireFile).
+	textView acceptAction:[:contents |
+				Transcript showCr:'will not overwrite the file with:'.
+				Transcript showCr:contents asString
+			      ].
+	top open.
+
+
+  MVC operation:
+
+	(the examples model here is a plug simulating a real model;
+	 real world applications would not use a plug ..)
+
+	|top textView model|
+
+	model := Plug new.
+	model respondTo:#accepted:
+		   with:[:newContents | 
+				Transcript showCr:'will not overwrite the file with:'.
+				Transcript showCr:newContents asString
+			].
+	model respondTo:#getList
+		   with:['/etc/hosts' asFilename contentsOfEntireFile].
+
+        
+	top := StandardSystemView new.
+	top extent:300@200.
+
+	textView := EditTextView new.
+	textView origin:0.0 @ 0.0 corner:1.0 @ 1.0.
+	top addSubView:textView.
+
+	textView model:model;
+		 changeMessage:#accepted:;
+		 listMessage:#getList;
+		 aspect:#list.
+	top open.
+
+    two textViews on the same model:
+
+	|top1 textView1 top2 textView2 model currentContents|
+
+	model := Plug new.
+	model respondTo:#accepted:
+		   with:[:newContents |
+				Transcript showCr:'accepted'.
+				currentContents := newContents.
+				self changed:#contents
+			].
+	model respondTo:#getList
+		   with:[self halt. currentContents].
+
+
+	top1 := StandardSystemView new.
+	top1 extent:300@200.
+
+	textView1 := EditTextView new.
+	textView1 origin:0.0 @ 0.0 corner:1.0 @ 1.0.
+	top1 addSubView:textView1.
+
+	textView1 model:model;
+		  aspect:#contents;
+		  changeMessage:#accepted:;
+		  listMessage:#getList.
+	top1 open.
+
+	top2 := StandardSystemView new.
+	top2 extent:300@200.
+
+	textView2 := EditTextView new.
+	textView2 origin:0.0 @ 0.0 corner:1.0 @ 1.0.
+	top2 addSubView:textView2.
+
+	textView2 model:model;
+		  aspect:#contents;
+		  changeMessage:#accepted:;
+		  listMessage:#getList.
+	top2 open.
+
+"
 ! !
 
 !EditTextView class methodsFor:'defaults'!
@@ -312,6 +457,12 @@
 	cursorVisibleLine := self listLineToVisibleLine:cursorLine.
 	self makeCursorVisible.
     ].
+    "/ cursor no longer visible ?
+    cursorVisibleLine isNil ifTrue:[
+	cursorLine > list size ifTrue:[
+	    device beep. device sync.
+	]
+    ]
 !
 
 cursorHome
@@ -1816,88 +1967,88 @@
     "handle keyboard input"
 
     <resource: #keyboard (#Paste #Insert #Cut #Again #Replace 
-                          #SelectWord #SearchMatchingParent
-                          #SelectMatchingParents #SelectToEnd
-                          #SelectFromBeginning
-                          #BeginOfLine #EndOfLine #NextWord
-                          #GotoLine #Delete #BeginOfText #EndOfText
-                          #SelectLine #ExpandSelectionByLine #DeleteLine
-                          #InsertLine)>
+			  #SelectWord #SearchMatchingParent
+			  #SelectMatchingParents #SelectToEnd
+			  #SelectFromBeginning
+			  #BeginOfLine #EndOfLine #NextWord
+			  #GotoLine #Delete #BeginOfText #EndOfText
+			  #SelectLine #ExpandSelectionByLine #DeleteLine
+			  #InsertLine)>
 
     |sensor n fKeyMacros|
 
     sensor := self sensor.
 
     (key isMemberOf:Character) ifTrue:[
-        readOnly ifFalse:[
-            typeOfSelection == #paste ifTrue:[
-                "pasted selection will NOT be replaced by keystroke"
-                self unselect
-            ].
-
-            "replace selection by what is typed in -
-             if word was selected with a space, keep it"
-
-            (selectStyle == #wordLeft) ifTrue:[
-                self replaceSelectionBy:(' ' copyWith:key)
-            ] ifFalse:[
-                (selectStyle == #wordRight) ifTrue:[
-                    self replaceSelectionBy:(key asString , ' ').
-                    self cursorLeft
-                ] ifFalse:[
-                    self replaceSelectionBy:key
-                ]
-            ].
-            selectStyle := nil.
-
-            showMatchingParenthesis ifTrue:[
-                "emacs style parenthesis shower"
-
-                "claus: only do it for closing parenthesis -
-                        otherwise its too anoying.
-                "
+	readOnly ifFalse:[
+	    typeOfSelection == #paste ifTrue:[
+		"pasted selection will NOT be replaced by keystroke"
+		self unselect
+	    ].
+
+	    "replace selection by what is typed in -
+	     if word was selected with a space, keep it"
+
+	    (selectStyle == #wordLeft) ifTrue:[
+		self replaceSelectionBy:(' ' copyWith:key)
+	    ] ifFalse:[
+		(selectStyle == #wordRight) ifTrue:[
+		    self replaceSelectionBy:(key asString , ' ').
+		    self cursorLeft
+		] ifFalse:[
+		    self replaceSelectionBy:key
+		]
+	    ].
+	    selectStyle := nil.
+
+	    showMatchingParenthesis ifTrue:[
+		"emacs style parenthesis shower"
+
+		"claus: only do it for closing parenthesis -
+			otherwise its too anoying.
+		"
 "
-                (#( $( $) $[ $] ${ $} ) includes:key) ifTrue:[
+		(#( $( $) $[ $] ${ $} ) includes:key) ifTrue:[
 "
-                (#( $) $] $} ) includes:key) ifTrue:[
-                self searchForMatchingParenthesisFromLine:cursorLine col:(cursorCol - 1)
-                                   ifFound:[:line :col |
-                                                |savLine savCol|
-
-                                                savLine := cursorLine.
-                                                savCol := cursorCol.
-                                                self cursorLine:line col:col.
-                                                device flush.
-                                                Processor activeProcess millisecondDelay:200.
-                                                self cursorLine:savLine col:savCol
-                                           ]
-                                ifNotFound:[self showNotFound]
-                                   onError:[device beep]
-                ].
-            ].
-        ].
-        ^ self
+		(#( $) $] $} ) includes:key) ifTrue:[
+		self searchForMatchingParenthesisFromLine:cursorLine col:(cursorCol - 1)
+				   ifFound:[:line :col |
+						|savLine savCol|
+
+						savLine := cursorLine.
+						savCol := cursorCol.
+						self cursorLine:line col:col.
+						device flush.
+						Processor activeProcess millisecondDelay:200.
+						self cursorLine:savLine col:savCol
+					   ]
+				ifNotFound:[self showNotFound]
+				   onError:[device beep]
+		].
+	    ].
+	].
+	^ self
     ].                         
 
     replacing := false.
 
     "
      Fn      pastes a key-sequence (but only if not overlayed with
-             another function in the keyboard map)
+	     another function in the keyboard map)
 
      see TextView>>:x:y
     "
     (('[fF][0-9]' match:key)
     or:['[fF][0-9][0-9]' match:key]) ifTrue:[
-        device shiftDown ifFalse:[
-            fKeyMacros := Smalltalk at:#FunctionKeySequences.
-            fKeyMacros notNil ifTrue:[
-                (fKeyMacros includesKey:key) ifTrue:[
-                    self pasteOrReplace:(fKeyMacros at:key) asStringCollection.
-                    ^ self
-                ]
-            ]
-        ]
+	device shiftDown ifFalse:[
+	    fKeyMacros := Smalltalk at:#FunctionKeySequences.
+	    fKeyMacros notNil ifTrue:[
+		(fKeyMacros includesKey:key) ifTrue:[
+		    self pasteOrReplace:(fKeyMacros at:key) asStringCollection.
+		    ^ self
+		]
+	    ]
+	]
     ].
 
     (key == #Accept)  ifTrue:[^ self accept].
@@ -1908,8 +2059,8 @@
 
     (key == #Replace) ifTrue:[self replace. ^self].
     (key == #SelectWord) ifTrue:[
-        self makeCursorVisible.
-        ^ self selectWordUnderCursor. 
+	self makeCursorVisible.
+	^ self selectWordUnderCursor. 
     ].
 
     (key == #SearchMatchingParent) ifTrue:[^ self searchForMatchingParenthesis.].
@@ -1932,149 +2083,149 @@
     (key == #GotoLine) ifTrue:[self gotoLine. ^self].
 
     (key == #CursorRight) ifTrue:[
-        selectionStartLine notNil ifTrue:[
-            cursorLine := selectionEndLine.
-            cursorVisibleLine := self listLineToVisibleLine:cursorLine.
-            cursorCol := selectionEndCol.
-            cursorCol == 0 ifTrue:[
-                cursorCol := 1.
-            ].
-            self unselect; makeCursorVisible.
-            cursorCol == 1 ifTrue:[^ self].
-        ].
-        self cursorRight. ^self
+	selectionStartLine notNil ifTrue:[
+	    cursorLine := selectionEndLine.
+	    cursorVisibleLine := self listLineToVisibleLine:cursorLine.
+	    cursorCol := selectionEndCol.
+	    cursorCol == 0 ifTrue:[
+		cursorCol := 1.
+	    ].
+	    self unselect; makeCursorVisible.
+	    cursorCol == 1 ifTrue:[^ self].
+	].
+	self cursorRight. ^self
     ].
     (key == #CursorDown) ifTrue:[
-        selectionStartLine notNil ifTrue:[
-            cursorLine := selectionEndLine.
-            cursorVisibleLine := self listLineToVisibleLine:cursorLine.
-            cursorCol := selectionEndCol.
-            cursorCol == 0 ifTrue:[
-                cursorCol := 1.
-                cursorLine := cursorLine - 1.
-                cursorVisibleLine := self listLineToVisibleLine:cursorLine.
-            ].
-            self makeCursorVisible
-        ].
-        self unselect. 
-
-        sensor isNil ifTrue:[
-            n := 1
-        ] ifFalse:[
-            n := 1 + (sensor compressKeyPressEventsWithKey:#CursorDown).
-        ].
-        self cursorDown:n. 
-        ^ self
+	selectionStartLine notNil ifTrue:[
+	    cursorLine := selectionEndLine.
+	    cursorVisibleLine := self listLineToVisibleLine:cursorLine.
+	    cursorCol := selectionEndCol.
+	    cursorCol == 0 ifTrue:[
+		cursorCol := 1.
+		cursorLine := cursorLine - 1.
+		cursorVisibleLine := self listLineToVisibleLine:cursorLine.
+	    ].
+	    self makeCursorVisible
+	].
+	self unselect. 
+
+	sensor isNil ifTrue:[
+	    n := 1
+	] ifFalse:[
+	    n := 1 + (sensor compressKeyPressEventsWithKey:#CursorDown).
+	].
+	self cursorDown:n. 
+	^ self
     ].
     (key == #CursorLeft or:[key == #CursorUp]) ifTrue:[
-        selectionStartLine notNil ifTrue:[
-            cursorLine := selectionStartLine.
-            cursorVisibleLine := self listLineToVisibleLine:cursorLine.
-            cursorCol := selectionStartCol.
-            self makeCursorVisible
-        ].
-        self unselect. 
-        (key == #CursorLeft) ifTrue:[
-            self cursorLeft. ^self
-        ].
-        (key == #CursorUp)        ifTrue:[
-            sensor isNil ifTrue:[
-                n := 1
-            ] ifFalse:[
-                n := 1 + (sensor compressKeyPressEventsWithKey:#CursorUp).
-            ].
-            self cursorUp:n. 
-            ^ self
-        ].
+	selectionStartLine notNil ifTrue:[
+	    cursorLine := selectionStartLine.
+	    cursorVisibleLine := self listLineToVisibleLine:cursorLine.
+	    cursorCol := selectionStartCol.
+	    self makeCursorVisible
+	].
+	self unselect. 
+	(key == #CursorLeft) ifTrue:[
+	    self cursorLeft. ^self
+	].
+	(key == #CursorUp)        ifTrue:[
+	    sensor isNil ifTrue:[
+		n := 1
+	    ] ifFalse:[
+		n := 1 + (sensor compressKeyPressEventsWithKey:#CursorUp).
+	    ].
+	    self cursorUp:n. 
+	    ^ self
+	].
     ].
 
     (key == #Return)    ifTrue:[
-        device shiftDown ifTrue:[
-            self unselect. self cursorReturn. ^self
-        ].
-        self unselect; makeCursorVisible.
-        self insertCharAtCursor:(Character cr). 
-        ^self
+	device shiftDown ifTrue:[
+	    self unselect. self cursorReturn. ^self
+	].
+	self unselect; makeCursorVisible.
+	self insertCharAtCursor:(Character cr). 
+	^self
     ].
     (key == #Tab) ifTrue:[
-        device shiftDown ifTrue:[
-            "
-             the old version used shift-tab as backtab,
-             however, backtab was seldom used.
-             An alternative is to make it a non-inserting tab ...
-            "
-            "/ self unselect. self cursorBacktab. ^self
-            self unselect. self cursorTab. ^self
-        ].
-        "
-         uncomment line below, if you like RAND/INed/MAXed editor behavior
-         (where tab-key is only cursor positioning)
-         this was the original behavior of the TAB key, but many people
-         complained ....
-        "
-        "/ self unselect. self cursorTab. ^self
-        self unselect. self insertTabAtCursor. ^self
+	device shiftDown ifTrue:[
+	    "
+	     the old version used shift-tab as backtab,
+	     however, backtab was seldom used.
+	     An alternative is to make it a non-inserting tab ...
+	    "
+	    "/ self unselect. self cursorBacktab. ^self
+	    self unselect. self cursorTab. ^self
+	].
+	"
+	 uncomment line below, if you like RAND/INed/MAXed editor behavior
+	 (where tab-key is only cursor positioning)
+	 this was the original behavior of the TAB key, but many people
+	 complained ....
+	"
+	"/ self unselect. self cursorTab. ^self
+	self unselect. self insertTabAtCursor. ^self
     ].
     (key == #BackSpace) ifTrue:[
 
 " old version just did unselect here "
 "
-        self unselect. 
+	self unselect. 
 "
 " new version deletes selection if any "
-        selectionStartLine notNil ifTrue:[
-            self setTextSelection:(self selection).
-            self deleteSelection. ^ self
-        ].
-        self makeCursorVisible.
-        self deleteCharBeforeCursor. ^self
+	selectionStartLine notNil ifTrue:[
+	    self setTextSelection:(self selection).
+	    self deleteSelection. ^ self
+	].
+	self makeCursorVisible.
+	self deleteCharBeforeCursor. ^self
     ].
     (key == #Delete)    ifTrue:[
-        selectionStartLine notNil ifTrue:[
-            self setTextSelection:(self selection).
-            self deleteSelection. ^ self
-        ].
-        self makeCursorVisible.
-        self deleteCharAtCursor. ^self
+	selectionStartLine notNil ifTrue:[
+	    self setTextSelection:(self selection).
+	    self deleteSelection. ^ self
+	].
+	self makeCursorVisible.
+	self deleteCharAtCursor. ^self
     ].
     (key == #BeginOfText) ifTrue:[     "i.e. HOME"
-        self unselect. 
-        cursorVisibleLine == 1 ifTrue:[
-            self cursorHome.
-        ] ifFalse:[
-            self cursorToFirstVisibleLine
-        ].
-        ^ self
+	self unselect. 
+	cursorVisibleLine == 1 ifTrue:[
+	    self cursorHome.
+	] ifFalse:[
+	    self cursorToFirstVisibleLine
+	].
+	^ self
     ].
     (key == #EndOfText) ifTrue:[       "i.e. END"
-        self unselect.
-        cursorVisibleLine == nFullLinesShown ifTrue:[
-            self cursorToBottom.
-        ] ifFalse:[
-            self cursorToLastVisibleLine
-        ].
-        ^self
+	self unselect.
+	cursorVisibleLine == nFullLinesShown ifTrue:[
+	    self cursorToBottom.
+	] ifFalse:[
+	    self cursorToLastVisibleLine
+	].
+	^self
     ].
     ((key == #Escape)
     or:[key == #SelectLineFromBeginning])    ifTrue:[
-        self makeCursorVisible.
-        self unselect. self selectCursorLineFromBeginning. ^ self
+	self makeCursorVisible.
+	self unselect. self selectCursorLineFromBeginning. ^ self
     ].
     (key == #SelectLine)    ifTrue:[
-        self makeCursorVisible.
-        self unselect. self selectCursorLine. ^ self
+	self makeCursorVisible.
+	self unselect. self selectCursorLine. ^ self
     ].
     (key == #ExpandSelectionByLine)    ifTrue:[
 "/        self makeCursorVisible.
-        self selectExpandCursorLine. ^ self
+	self selectExpandCursorLine. ^ self
     ].
     (key == #DeleteLine)    ifTrue:[
-        self makeCursorVisible.
-        self unselect. self deleteCursorLine. ^self
+	self makeCursorVisible.
+	self unselect. self deleteCursorLine. ^self
     ].
     (key == #InsertLine)    ifTrue:[
-        self makeCursorVisible.
-        self unselect. self insertLine:nil before:cursorLine. ^self
+	self makeCursorVisible.
+	self unselect. self insertLine:nil before:cursorLine. ^self
     ].
     super keyPress:key x:x y:y
 
@@ -2965,5 +3116,5 @@
 !EditTextView class methodsFor:'documentation'!
 
 version
-    ^ '$Header: /cvs/stx/stx/libwidg/EditTextView.st,v 1.39 1996-01-09 17:29:28 cg Exp $'
+    ^ '$Header: /cvs/stx/stx/libwidg/EditTextView.st,v 1.40 1996-01-18 21:29:07 cg Exp $'
 ! !