cleaned up the code and fixed many bugs;
authorClaus Gittinger <cg@exept.de>
Sun, 10 May 2009 13:00:09 +0200
changeset 2501 43386f544f3d
parent 2500 3e2feb544801
child 2502 c27a926cbe67
cleaned up the code and fixed many bugs; support components; redraw during size/move
UIObjectView.st
--- a/UIObjectView.st	Sun May 10 12:59:24 2009 +0200
+++ b/UIObjectView.st	Sun May 10 13:00:09 2009 +0200
@@ -195,23 +195,25 @@
     type := self layoutType:aView.
 
     (type == #LayoutFrame or:[type == #Rectangle]) ifTrue:[
-	v := self isVerticalResizable:aView.
-	h := self isHorizontalResizable:aView.
-
-	h ifTrue:[  aBlock value:(aView leftCenter ) value:#left.
-		    aBlock value:(aView rightCenter) value:#right.
-		 ].
-	v ifTrue:[  aBlock value:(aView topCenter   ) value:#top.
-		    aBlock value:(aView bottomCenter) value:#bottom.
-		 ].
-
-	(h and:[v]) ifTrue:[
-	    aBlock value:(aView origin    ) value:#origin.
-	    aBlock value:(aView topRight  ) value:#topRight.
-	    aBlock value:(aView bottomLeft) value:#bottomLeft.
-	    aBlock value:(aView corner    ) value:#corner.
-	  ^ self
-	]
+        v := self isVerticalResizable:aView.
+        h := self isHorizontalResizable:aView.
+
+        h ifTrue:[  
+            aBlock value:(aView leftCenter ) value:#left.
+            aBlock value:(aView rightCenter) value:#right
+        ].
+        v ifTrue:[  
+            aBlock value:(aView topCenter   ) value:#top.
+            aBlock value:(aView bottomCenter) value:#bottom.
+        ].
+
+        (h and:[v]) ifTrue:[
+            aBlock value:(aView origin    ) value:#origin.
+            aBlock value:(aView topRight  ) value:#topRight.
+            aBlock value:(aView bottomLeft) value:#bottomLeft.
+            aBlock value:(aView corner    ) value:#corner.
+            ^ self
+        ]
     ].
 
     aBlock value:(aView origin    ) value:#view.
@@ -219,20 +221,18 @@
     aBlock value:(aView bottomLeft) value:#view.
 
     type == #Extent ifTrue:[
-	v := self isVerticalResizable:aView.
-	h := self isHorizontalResizable:aView.
-
-	v ifTrue:[aBlock value:(aView bottomCenter) value:#bottom].
-	h ifTrue:[aBlock value:(aView rightCenter ) value:#right ].
-
-	(h and:[v]) ifTrue:[
-	    aBlock value:(aView corner) value:#corner.
-	  ^ self
-	]
+        v := self isVerticalResizable:aView.
+        h := self isHorizontalResizable:aView.
+
+        v ifTrue:[ aBlock value:(aView bottomCenter) value:#bottom ].
+        h ifTrue:[ aBlock value:(aView rightCenter ) value:#right ].
+
+        (h and:[v]) ifTrue:[
+            aBlock value:(aView corner) value:#corner.
+            ^ self
+        ]
     ].
     aBlock value:(aView corner) value:#view.
-
-
 ! !
 
 !UIObjectView class methodsFor:'queries'!
@@ -478,21 +478,30 @@
 !
 
 elementChangedSize:aView
-    "some element has changed its size; collect them during selectionHiddenLevel 
-     is on
-    "
+    "some element has changed its size; collect them while selectionHiddenLevel is on"
+
     |spv|
 
     spv := self findContainerOfView:aView.
 
-    selectionHiddenLevel ~~ 0 ifTrue:[setOfSuperViewsSizeChanged add:spv]
-			     ifFalse:[spv sizeChanged:nil]
+    aView isView ifFalse:[
+        spv invalidate.
+    ].
+
+    spv := self findContainerOfView:aView.
+
+    selectionHiddenLevel ~~ 0 ifTrue:[
+        setOfSuperViewsSizeChanged add:spv
+    ] ifFalse:[
+        spv sizeChanged:nil
+    ]
 !
 
 exposeX:x y:y width:w height:h
     "handle an expose event from device; redraw selection
     "
-    resizeData isNil ifTrue:[
+
+"/    resizeData isNil ifTrue:[
         super exposeX:x y:y width:w height:h.
 
         "/ handle any expose events (for subcomponents) before
@@ -508,7 +517,7 @@
 "/            ].
 "/            self showSelected:aComponent
 "/        ]
-    ].
+"/    ].
 
     "Modified: / 9.11.1998 / 12:50:34 / cg"
 !
@@ -565,30 +574,35 @@
      the redraw when this happens.
      Return true, if I have eaten the event"
 
-    |evView p|
+    |evView widget p|
 
     self testMode ifTrue:[^ false].
 
+    anEvent isInputEvent ifFalse:[^ false].
+    anEvent isPointerEnterLeaveEvent ifTrue:[^ true. ^ false].
+    anEvent isKeyboardFocusEvent ifTrue:[^ true. ^ false].
+
     evView := anEvent view.
-    (evView isNil or:[evView == self]) ifTrue:[
-        ^ false
-    ].
-
-    (evView isComponentOf:self) ifFalse:[
+    evView isNil ifTrue:[
         ^ false
     ].
-
-    anEvent isInputEvent ifFalse:[
-        "/ #isDamage: handled in PostEventHandler
-
-"/        (shown and:[anEvent isDamage]) ifTrue:[
-"/            (self isSelected:evView) ifTrue:[
-"/                self showSelected:evView
-"/            ].
-"/        ].
+    (evView == self) ifTrue:[
+        "/ new: check for a component to be hit by the event
+        components notEmptyOrNil ifTrue:[
+            p := (anEvent x @ anEvent y).        
+            
+            widget := components detect:[:c | c bounds containsPoint:p ] ifNone:nil.
+        ].
+        widget isNil ifTrue:[
+            ^ false
+        ].
+    ] ifFalse:[
+        widget := evView.
+    ].
+
+    (widget isComponentOf:self) ifFalse:[
         ^ false
     ].
-
     (anEvent isButtonEvent or:[anEvent isKeyEvent])  ifFalse:[
         ^ true
     ].
@@ -599,7 +613,7 @@
         p := self sensor mousePoint.
         p := device translatePoint:p fromView:nil toView:self.
     ] ifFalse:[
-        p := Point x:(anEvent x) y:(anEvent y).
+        p := (anEvent x) @ (anEvent y).
         p := device translatePoint:p fromView:evView toView:self.
     ].
 
@@ -614,7 +628,8 @@
     |redrawFrame|
 
     redrawFrame := Rectangle left:nx top:ny width:nw height:nh.
-    self clearRectangle:redrawFrame.
+    "/ self clearRectangle:redrawFrame.
+    super redrawX:nx y:ny width:nw height:nh.
 
     self selectionDo:[:aComponent |
         |anyHandleToRedraw|
@@ -692,10 +707,11 @@
 !UIObjectView methodsFor:'misc'!
 
 invertOutlineOf:something
-    "invert outline of an object or collection of objects
-    "
+    "invert outline of an object or collection of objects"
+
     |wasClipped|
 
+^ self.
     (wasClipped := clipChildren) ifTrue:[
         self clippedByChildren:(clipChildren := false).
     ].
@@ -705,14 +721,10 @@
 
         something isCollection ifTrue:[
             something do:[:v |
-                |p|
-
                 p := v originRelativeTo:self.
                 self displayRectangle:(p extent:v extent).
             ].
         ] ifFalse:[
-            |p|
-
             p := something originRelativeTo:self.
             self displayRectangle:(p extent:something extent).
         ]
@@ -740,10 +752,11 @@
 !
 
 redrawObjectsInVisible:redrawFrame
-    "my objects are views - they redraw themself"
-
+    "my objects are views - they redraw themself.
+     - no longer - all non-views MUST be redrawn."
+
+    super redrawObjectsInVisible:redrawFrame.
     ^ self
-
 !
 
 setDefaultActions
@@ -763,17 +776,22 @@
 !UIObjectView methodsFor:'object moving'!
 
 doObjectMove:aPoint
-    "move selection
-    "
+    "move selection"
+
     movedObject notNil ifTrue:[
-	self invertOutlineOf:movedObject.
-
-	movedObject keysAndValuesDo:[:i :v|
-	    self moveObject:v to:(aPoint - (moveDelta at:i)).
-	].
-	self invertOutlineOf:movedObject.
+        self hideSelection.
+        self repairDamage.
+
+        self invertOutlineOf:movedObject.
+
+        movedObject keysAndValuesDo:[:i :v|
+            self moveObject:v to:(aPoint - (moveDelta at:i)).
+        ].
+        self invertOutlineOf:movedObject.
+
+        self showSelection.
+        self repairDamage.
     ]
-
 !
 
 endObjectMove
@@ -791,6 +809,9 @@
     self withSelectionHiddenDo:[
         self setSelection:newSel withRedraw:false.
 
+        components notEmptyOrNil ifTrue:[
+            self invalidate.
+        ].
         self allSubViewsDo:[:v|
             v shown ifTrue:[
                 v fill:v viewBackground.
@@ -823,19 +844,18 @@
 !
 
 startObjectMoveAt:aPoint
-    "start object(s) move at a point
-    "
+    "start object(s) move at a point"
+
     self startObjectMove:(self selection) at:aPoint.
     movedObject := self selection.
 
     movedObject isCollection ifFalse:[
         movedObject := Array with:movedObject
     ].
-    self setSelection:nil withRedraw:true.
-
-    moveDelta := movedObject collect:[:aView|
-        aPoint - aView computeOrigin
-    ].
+"/    self setSelection:nil withRedraw:true.
+
+    moveDelta := movedObject collect:[:aView | aPoint - aView computeOrigin].
+
     self transaction:#move objects:movedObject do:[:v|self createUndoLayout:v].
     self invertOutlineOf:movedObject.
 !
@@ -861,7 +881,7 @@
     "a button is pressed at a point; start moving or selecting"
 
     |selectedView containerOfSelectedView
-     clickedView viewOperatedUpon b pView|
+     clickedView viewOperatedUpon borderHandleSelector pView|
 
     self enabled ifFalse:[^ self].
 
@@ -874,13 +894,15 @@
 "/        selectedView := nil.    
 "/    ].
 
+    "/ if there is already a selection, see if user clicked onto a handle
+    "/ then, this may be the start of a resize operation.
     selectedView notNil ifTrue:[
         containerOfSelectedView := self findContainerOfView:selectedView.
 
         containerOfSelectedView specClass canResizeSubComponents ifTrue:[
-            b := self whichHandleOf:selectedView isHitBy:aPoint.
-            (b notNil and:[b ~~ #view]) ifTrue:[
-                self startResizeBorder:b of:selectedView.
+            borderHandleSelector := self whichHandleOf:selectedView isHitBy:aPoint.
+            (borderHandleSelector notNil and:[borderHandleSelector ~~ #view]) ifTrue:[
+                self startResizeBorder:borderHandleSelector.
                 ^ self
             ]
         ].
@@ -972,6 +994,8 @@
 
     object := resizeData object.
 
+self hideSelection.
+self repairDamage.
     self invertOutlineOf:object.
     p := (self alignToGrid:aPoint) - (resizeData delta).
 
@@ -982,7 +1006,10 @@
     ].
 
    "/ object geometryLayout:(object geometryLayout).
-    self invertOutlineOf:object
+    self invertOutlineOf:object.
+
+self showSelection.
+self repairDamage.
 !
 
 endResize
@@ -1014,21 +1041,24 @@
 layoutChanged
 !
 
-startResizeBorder:b of:selection
-    "resize selected view
-    "
+startResizeBorder:borderHandleSelector
+    "start resizing the selected view at the given borderHandle"
+
     |object|
 
     object := self singleSelection.
-    self actionResize:object selector:b.
-
-    self transaction:#resize selectionDo:[:aView|
-        self createUndoLayout:aView
-    ].
-    self setSelection:nil withRedraw:true.
+    self actionResize:object selector:borderHandleSelector.
+
+    self 
+        transaction:#resize 
+        selectionDo:[:aView|
+            self createUndoLayout:aView
+        ].
+    "/ self setSelection:nil withRedraw:true.
 
     motionAction  := [:movePoint | self doDragResize:movePoint].
     releaseAction := [self endResize].
+
     self invertOutlineOf:object
 ! !
 
@@ -1055,12 +1085,12 @@
 !
 
 whichHandleOf:aComponent isHitBy:aPoint
-    "returns kind of handle or nil
-    "
+    "returns kind of handle or nil"
+
     self handlesOf:aComponent do:[:rectangle :what|
-	(rectangle containsPoint:aPoint) ifTrue:[^ what]
+        (rectangle containsPoint:aPoint) ifTrue:[^ what]
     ].
-  ^ nil
+    ^ nil
 ! !
 
 !UIObjectView methodsFor:'private-resizing subviews'!
@@ -1136,7 +1166,9 @@
     "resize a views top"
 
     undoHistory withoutTransactionDo:[
-        self shiftLayout:aView top:((aPoint y) - (aView computeOrigin y)) bottom:0
+        self shiftLayout:aView 
+                top:((aPoint y) - (aView computeOrigin y)) 
+                bottom:0
     ]
 !
 
@@ -1144,10 +1176,11 @@
     "resize a views top and right"
 
     undoHistory withoutTransactionDo:[
-        self shiftLayout:aView top:((aPoint y) - (aView computeOrigin y))
-                            bottom:0
-                              left:0
-                             right:((aPoint x) - (aView computeCorner x))
+        self shiftLayout:aView 
+                top:((aPoint y) - (aView computeOrigin y))
+                bottom:0
+                left:0
+                right:((aPoint x) - (aView computeCorner x))
 
     ]
 ! !
@@ -1215,43 +1248,61 @@
 !UIObjectView methodsFor:'searching'!
 
 findObjectAt:aPoint
-    |view viewId lastId point|
-
-    point  := aPoint + (device translatePoint:0@0 fromView:self toView:rootView).
-
-    viewId := rootView id.
-    [viewId notNil] whileTrue:[
-        lastId := viewId.
-        viewId := device viewIdFromPoint:point in:lastId
-    ].
-
-    view := device viewFromId:lastId.
-    view == self ifTrue:[ ^ nil].
-    ^ view
-"/    view ~~ inputView ifTrue:[^ view].
+    |view viewId lastId point component componentOrView|
+
+    componentOrView := self findObjectAt:aPoint in:self.
+
+    componentOrView == self ifTrue:[^ nil].
+    ^ componentOrView.
+
+"/ cg: old code, which I do not understand
+"/    point := device translatePoint:aPoint fromView:self toView:rootView.
 "/
-"/    "/ look for 'hidden' views ...
-"/
-"/    listOfViews := OrderedCollection new.
-"/    self allSubViewsDo:[:aView |
-"/        |org|
-"/
-"/        aView ~~ inputView ifTrue:[
-"/            org := device translatePoint:0@0 fromView:aView toView:self.
-"/            ((org extent:aView extent) containsPoint:aPoint) ifTrue:[
-"/                listOfViews add:aView.
-"/            ]
-"/        ]
+"/    viewId := rootView id.
+"/    [viewId notNil] whileTrue:[
+"/        lastId := viewId.
+"/        viewId := device viewIdFromPoint:point in:lastId. "/ must be rootView coordinate
 "/    ].
 "/
-"/    listOfViews size > 0 ifTrue:[
-"/        ^ listOfViews last
+"/    view := device viewFromId:lastId.
+"/    (view isNil or:[view == self]) ifTrue:[ 
+"/        "/ used to return nil here;
+"/        "/ now support a mix of views and components...
+"/        components notEmptyOrNil ifTrue:[
+"/            component := components detect:[:c | c bounds containsPoint:aPoint] ifNone:nil.
+"/            ^ component
+"/        ].
+"/        ^ nil
 "/    ].
-"/    ^ nil
-"/
-"/    "Modified: / 10.10.2001 / 14:05:07 / cg"
-"/
-"/
+"/    ^ view
+!
+
+findObjectAt:aPoint in:aView
+    |lastHit lastRelPoint view point|
+
+    "/ reverse search, to find covering ones first.
+    aView subViews reverseDo:[:aSubView |
+        |innerObject relPoint|
+
+        ((aSubView origin extent:aSubView extent) containsPoint:aPoint) ifTrue:[
+            relPoint := device translatePoint:aPoint fromView:aView toView:aSubView.
+            innerObject := self findObjectAt:relPoint in:aSubView.
+            innerObject notNil ifTrue:[ ^ innerObject ].
+            lastHit := aSubView.
+            lastRelPoint := relPoint.
+        ]
+    ].
+    view := lastHit ? aView.
+    point := lastRelPoint ? aPoint.
+
+    view components notEmptyOrNil ifTrue:[
+        view components reverseDo:[:eachComponent |
+            (eachComponent frame containsPoint:point) ifTrue:[
+                ^ eachComponent
+            ].
+        ].
+    ].
+    ^ view
 ! !
 
 !UIObjectView methodsFor:'selections'!
@@ -1259,7 +1310,8 @@
 hideSelection
     "hide the selection - undraw hilights - whatever that is
     "
-    self showUnselected:selection.
+super hideSelection.
+"/    self showUnselected:selection.
 !
 
 moveableSelection
@@ -1322,10 +1374,10 @@
 !
 
 showSelection
-    "show the selection - draw handles
-    "
+    "show the selection - draw handles"
+
     selectionHiddenLevel == 0 ifTrue:[
-	self selectionDo:[:el| self showSelected:el ]
+        super showSelection
     ].
 !
 
@@ -1439,6 +1491,7 @@
 
     (aView shown and:[theDamages notEmpty]) ifFalse:[ ^ self ].
 
+    aView components notEmptyOrNil ifTrue:[ self halt ].
     aView subViews notNil ifTrue:[
         aView subViews reverseDo:[:v| self recursiveRepair:theDamages startIn:v ].
         theDamages isEmpty ifTrue:[ ^ self ].
@@ -1529,9 +1582,9 @@
 !
 
 showUnselected:something
-    "show a component ot list of components unselected
-    "
-    |damages oldClipped|
+    "show a component or list of components unselected"
+
+    |damages oldClipped savedSelection|
 
     (selectionHiddenLevel ~~ 0 or:[something isNil]) ifTrue:[
         ^ self
@@ -1555,7 +1608,7 @@
         ]
     ].
 
-    damages do:[:el| self clearRectangle:el ].
+    damages do:[:el| self clearRectangle:el. ].
 
     (oldClipped := clipChildren) ifFalse:[
         self clippedByChildren:(clipChildren := true)
@@ -1565,7 +1618,17 @@
     oldClipped ~~ clipChildren ifTrue:[
         self clippedByChildren:(clipChildren := oldClipped).
     ].
-    device "sync" flush.
+
+    device flush.
+
+    savedSelection := selection.
+    [
+        selection := nil.
+        damages do:[:el| self invalidate:el ].
+        self repairDamage.
+    ] ensure:[
+        selection := savedSelection
+    ].
 ! !
 
 !UIObjectView methodsFor:'testing'!
@@ -1804,9 +1867,8 @@
     "change layout for all selected objects
     "
     self transaction:#layout dimensionDo:[:v|
-	v geometryLayout:(aLayout copy)
+        v geometryLayout:(aLayout copy)
     ].    
-
 !
 
 setToDefaultExtent