*** empty log message ***
authorca
Fri, 21 Feb 1997 20:33:57 +0100
changeset 58 668eb9eae2ac
parent 57 5af567f52811
child 59 0a2b2ff030a0
*** empty log message ***
UIObjectView.st
UIPainter.st
UIPainterTreeView.st
--- a/UIObjectView.st	Fri Feb 21 20:33:18 1997 +0100
+++ b/UIObjectView.st	Fri Feb 21 20:33:57 1997 +0100
@@ -133,12 +133,6 @@
 
 !UIObjectView methodsFor:'event handling'!
 
-doKeyInput:key
-    ^ self
-
-
-!
-
 elementChanged:aView 
     "some element has been changed - kludge to force a resizing
      operation (for child layout recomputation) in its superView"
@@ -163,29 +157,23 @@
     "handle an expose event from device; redraw selection
     "
     super exposeX:x y:y width:w height:h.
-
-    selection notNil ifTrue:[
-        self selectionDo:[:v | self showSelected:v]
-    ]
+    self selectionDo:[:v | self showSelected:v]
 
 
 !
 
 keyPress:key x:x y:y
+    <resource: #keyboard ( #InspectIt #Delete #BackSpace #Cut) >
 
     key == #InspectIt ifTrue:[
         ^ self inspectSelection
     ].
 
-    (key == #Delete or:[key == #BackSpace]) ifTrue: [
-        selection notNil ifTrue:[
-            self deleteSelection
-        ]
-    ] ifFalse:[
-        keyPressAction notNil ifTrue:[
-            keyPressAction value:key
-        ]
-    ]
+    (key == #Cut or:[key == #Delete or:[key == #BackSpace]]) ifTrue: [
+        ^ self deleteSelection
+    ].
+
+    super keyPress:key x:x y:y
 
 
 !
@@ -291,7 +279,7 @@
     shiftPressAction := [:pressPoint | self startSelectMoreOrMove:pressPoint].
     motionAction     := [:movePoint  | nil].
     releaseAction    := [nil].
-    keyPressAction   := [:key | self doKeyInput:key].
+    keyPressAction   := nil.
 
     self cursor:Cursor normal.
 
@@ -414,10 +402,7 @@
     "
     |widget object start frame delta|
 
-    createClass isNil ifTrue:[
-        ^ self setDefaultActions
-    ].
-    (selection isKindOf:Collection) ifTrue:[
+    (createClass isNil or:[self numberOfSelections > 1]) ifTrue:[
         self unselect.
       ^ self setDefaultActions.
     ].
@@ -425,15 +410,16 @@
     motionAction  := [:movePoint| self doDragCreate:movePoint].
     releaseAction := [ self endCreate].
 
-    selection notNil ifTrue:[
-        (    (self isPoint:aPoint containedIn:selection)
-         and:[self supportsSubComponents:selection]
-        ) ifFalse:[
-            self unselect
-        ]
+    widget := self singleSelection.
+
+    (     widget notNil
+     and:[(self isPoint:aPoint containedIn:widget)
+     and:[self supportsSubComponents:widget]]
+    ) ifFalse:[
+        self unselect.
+        widget := self.
     ].
 
-    widget := selection ? self.
     object := createClass new.
     widget addSubView:object.
 
@@ -503,7 +489,7 @@
         dY := delta y.
 
         undoHistory disabledTransitionDo:[
-            self shifLayout:anObject top:dY bottom:dY left:dX right:dX
+            self shiftLayout:anObject top:dY bottom:dY left:dX right:dX
         ]
     ]
 
@@ -513,10 +499,10 @@
 
     self startObjectMove:selection at:aPoint.
 
-    selection size == 0 ifTrue:[
+    selection isCollection ifTrue:[
+        movedObject := selection
+    ] ifFalse:[
         movedObject := Array with:selection
-    ] ifFalse:[
-        movedObject := selection
     ].
     super unselect.
 
@@ -524,12 +510,10 @@
         aPoint - aView computeOrigin
     ].
 
-    selection := movedObject.
-    self transaction:#move selectionDo:[:aView|
+    self transaction:#move objects:movedObject do:[:aView|
         self invertOutlineOf:aView.
         self undoBlockPositionChanged:aView
     ].
-    selection := nil
 
 !
 
@@ -557,13 +541,15 @@
 
     testMode ifTrue:[^ self].
 
-    "if there is one selection and point hits handle, start a resize
+    "if there is one object selected and point hits a handle, start a resize
     "
-    self singleSelection notNil ifTrue:[
-        b := self whichHandleOf:selection isHitBy:aPoint.
+    anObject := self singleSelection.
+
+    anObject notNil ifTrue:[
+        b := self whichHandleOf:anObject isHitBy:aPoint.
 
         (b notNil and:[b ~~ #view]) ifTrue:[
-            ^ self startResizeBorder:b of:selection.
+            ^ self startResizeBorder:b of:anObject.
         ]
     ].
 
@@ -580,7 +566,7 @@
         self select:anObject.
     ].
 
-    selection isCollection ifTrue:[
+    (self numberOfSelections ~~ 1) ifTrue:[
         releaseAction := [
             self setDefaultActions.
             self select:anObject
@@ -654,6 +640,11 @@
     |object|
 
     object := self singleSelection.
+
+    (object geometryLayout) isNil ifTrue:[
+        ^ self setDefaultActions.
+    ].
+
     self actionResize:object selector:b.
 
     self transaction:#extent selectionDo:[:aView|
@@ -785,17 +776,17 @@
 resize:aView bottom:aPoint
 
     undoHistory disabledTransitionDo:[
-        self shifLayout:aView top:0 bottom:((aPoint y) - (aView computeCorner y))
+        self shiftLayout:aView top:0 bottom:((aPoint y) - (aView computeCorner y))
     ]
 !
 
 resize:aView bottomLeft:aPoint
 
     undoHistory disabledTransitionDo:[
-        self shifLayout:aView top:0
-                           bottom:((aPoint y) - (aView computeCorner y))
-                             left:((aPoint x) - (aView computeOrigin x))
-                            right:0
+        self shiftLayout:aView top:0
+                            bottom:((aPoint y) - (aView computeCorner y))
+                              left:((aPoint x) - (aView computeOrigin x))
+                             right:0
 
     ]
 
@@ -808,14 +799,14 @@
     delta := aPoint - aView computeCorner.
 
     undoHistory disabledTransitionDo:[
-        self shifLayout:aView top:0 bottom:(delta y) left:0 right:(delta x)
+        self shiftLayout:aView top:0 bottom:(delta y) left:0 right:(delta x)
     ]
 !
 
 resize:aView left:aPoint
 
     undoHistory disabledTransitionDo:[
-        self shifLayout:aView left:((aPoint x) - (aView computeOrigin x)) right:0
+        self shiftLayout:aView left:((aPoint x) - (aView computeOrigin x)) right:0
     ]
 
 !
@@ -826,7 +817,7 @@
     delta := aPoint - aView computeOrigin.
 
     undoHistory disabledTransitionDo:[
-        self shifLayout:aView top:(delta y) bottom:0 left:(delta x) right:0
+        self shiftLayout:aView top:(delta y) bottom:0 left:(delta x) right:0
     ]
 
 !
@@ -834,24 +825,24 @@
 resize:aView right:aPoint
 
     undoHistory disabledTransitionDo:[
-        self shifLayout:aView left:0 right:((aPoint x) - (aView computeCorner x))
+        self shiftLayout:aView left:0 right:((aPoint x) - (aView computeCorner x))
     ]
 !
 
 resize:aView top:aPoint
 
     undoHistory disabledTransitionDo:[
-        self shifLayout:aView top:((aPoint y) - (aView computeOrigin y)) bottom:0
+        self shiftLayout:aView top:((aPoint y) - (aView computeOrigin y)) bottom:0
     ]
 !
 
 resize:aView topRight:aPoint
 
     undoHistory disabledTransitionDo:[
-        self shifLayout: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))
 
     ]
 
@@ -859,43 +850,51 @@
 
 !UIObjectView methodsFor:'private shift-layout'!
 
-shifLayout:aView left:l right:r
+shiftLayout:aView left:l right:r
     "shift layout for a view; in case of an open transaction, the undo
      action is registered
     "
-    self shifLayout:aView top:0 bottom:0 left:l right:r
+    self shiftLayout:aView top:0 bottom:0 left:l right:r
 
 !
 
-shifLayout:aView top:t bottom:b
+shiftLayout:aView top:t bottom:b
     "shift layout for a view; in case of an open transaction, the undo
      action is registered
     "
-    self shifLayout:aView top:t bottom:b left:0 right:0
+    self shiftLayout:aView top:t bottom:b left:0 right:0
 
 
 !
 
-shifLayout:aView top:t bottom:b left:l right:r
+shiftLayout:aView top:t bottom:b left:l right:r
     "shift layout for a view; in case of an open transaction, the undo
      action is registered
     "
     |layout|
 
-    self undoBlockPositionChanged:aView.
-
     layout := aView geometryLayout.
 
-    layout leftOffset:(layout leftOffset + l)
-            topOffset:(layout topOffset  + t).
-
-    layout isLayoutFrame ifTrue:[
-        layout bottomOffset:(layout bottomOffset + b).
-        layout  rightOffset:(layout rightOffset  + r).
-    ].
-
-    aView geometryLayout:layout.
-
+    layout isLayout ifTrue:[
+        self undoBlockPositionChanged:aView.
+
+        layout leftOffset:(layout leftOffset + l)
+                topOffset:(layout topOffset  + t).
+
+        layout isLayoutFrame ifTrue:[
+            layout bottomOffset:(layout bottomOffset + b).
+            layout  rightOffset:(layout rightOffset  + r).
+        ].
+        aView geometryLayout:layout.
+    ] ifFalse:[
+        |pixelOrigin|
+
+        self undoBlockPositionChanged:aView.
+
+        pixelOrigin := aView pixelOrigin.
+        pixelOrigin := pixelOrigin + (l@t).
+        aView pixelOrigin:pixelOrigin
+    ]
 
 
 ! !
@@ -930,12 +929,18 @@
 isPoint:aPoint containedIn:aView
     "checks whether a point is covered by a view.
     "
-    |org ext|
-
-    org := aView computeOrigin.
-    ext := aView computeExtent.
-
-    ^ ((org extent:ext) containsPoint:aPoint)
+    |p|
+
+    p := device translatePoint:aPoint from:inputView id to:aView id.
+
+    (p x >= 0 and:[p y >= 0]) ifTrue:[
+        p := aView extent - p.
+
+        (p x >= 0 and:[p y >= 0]) ifTrue:[
+            ^ true
+        ]
+    ].
+    ^ false
 !
 
 whichBorderOf:aView isHitBy:aPoint
@@ -966,7 +971,7 @@
 !UIObjectView methodsFor:'selections'!
 
 addToSelection:something
-    (testMode or:[something == selection]) ifFalse:[
+    (self canSelect:something) ifTrue:[
         super addToSelection:something.
         self changed:#selection.
     ]
@@ -978,6 +983,17 @@
     ]
 !
 
+numberOfSelections
+    "return the number of selected entries"
+
+    |sz|
+
+    selection isNil ifTrue:[^ 0].
+
+    selection isCollection ifTrue:[^ selection size]
+                          ifFalse:[^ 1 ]
+!
+
 removeFromSelection:something
     super removeFromSelection:something.
     self changed:#selection
@@ -985,7 +1001,7 @@
 !
 
 select:something
-    (testMode or:[something == selection]) ifFalse:[
+    (self canSelect:something) ifTrue:[
         super select:something.
         self changed:#selection
     ]
@@ -998,21 +1014,6 @@
 
 !
 
-selectionFindMinimum:aOneArgBlock
-    "returns the minimum value from the block evaluated on each view
-     in the selection
-    "
-    |min val|
-
-    self selectionDo:[:aView|
-        val := aOneArgBlock value:aView.
-
-        min isNil ifTrue:[min := val]
-                 ifFalse:[min := min min:val]
-    ].
-    ^ min
-!
-
 selectionHiddenDo:aBlock
     "apply block to every object in selection"
 
@@ -1031,14 +1032,18 @@
 singleSelection
     "returns single selection or nil
     "
-    (selection isKindOf:SimpleView) ifTrue:[^ selection]
-                                   ifFalse:[^ nil]
+    selection isCollection ifFalse:[
+        ^ selection
+    ].
+    selection size == 1 ifTrue:[ ^ selection at:1]
+                       ifFalse:[ ^ nil].
 !
 
 singleSelectionDo:aBlock
-
-    self singleSelection notNil ifTrue:[
-        aBlock value:selection
+    |view|
+
+    (view := self singleSelection) notNil ifTrue:[
+        aBlock value:view
     ]
 !
 
@@ -1077,6 +1082,33 @@
 
 !
 
+canPaste:something
+    "returns true if something could be paste
+    "
+    something notNil ifTrue:[
+        something isCollection ifTrue:[
+            something notEmpty ifTrue:[
+                ^ (something at:1) isKindOf:UISpecification
+            ]
+        ] ifFalse:[
+            ^ something isKindOf:UISpecification
+        ]
+    ].
+    ^ false
+
+!
+
+canSelect:something
+    ^ (testMode not and:[something ~~ selection])
+
+!
+
+hasUndos
+    "returns true if undoHistory not empty
+    "
+    ^ undoHistory notEmpty
+!
+
 isHorizontalResizable:aComponent
     ^ self subclassResponsibility
 
@@ -1150,11 +1182,22 @@
         |layout|
 
         layout := aView geometryLayout copy.
-        undoHistory addUndoBlock:[aView geometryLayout:layout]
+        layout isNil ifFalse:[
+            undoHistory addUndoBlock:[aView geometryLayout:layout]
+        ] ifTrue:[
+            layout := aView pixelOrigin.
+            undoHistory addUndoBlock:[aView pixelOrigin:layout]
+        ]
     ]
 
 !
 
+undoDeleteAll
+    "delete total undo history
+    "
+    undoHistory reinitialize
+!
+
 undoLast
     self undoLast:1
 !
@@ -1171,10 +1214,15 @@
 !UIObjectView methodsFor:'user actions - dimension'!
 
 copyExtent
-    (selection isNil or:[selection isKindOf:Collection]) ifTrue:[
-        ^ self warn:'exactly one element must be selected'.
-    ].
-    copiedExtent := selection computeExtent
+    |object|
+
+    object := self singleSelection.
+
+    object notNil ifTrue:[
+        copiedExtent := object computeExtent
+    ] ifFalse:[
+        self warn:'exactly one element must be selected'.
+    ]
 
 
 
@@ -1264,51 +1312,122 @@
 
 !UIObjectView methodsFor:'user actions - move'!
 
-basicMoveSelectionHorizontal:n
-    "move left:  n < 0
-     move right: n > 0
-    "
+moveSelectionDown:aNumber
+    |gridY|
+
+    gridAlign notNil ifTrue:[
+        gridY := gridAlign y.
+    ].
+
     self selectionHiddenDo:[
-        self transaction:#move selectionDo:[:v| self shifLayout:v left:n right:n].
+        self transaction:#move selectionDo:[:aView|
+            |n d|
+
+            n := aNumber.
+
+            aligning ifTrue:[
+                d := ((aView computeCorner y) \\ gridY).
+                n := n * gridY.
+
+                d ~~ 0 ifTrue:[
+                    n := n - d + 1.
+                ]
+            ].
+            self shiftLayout:aView top:n bottom:n
+        ].
         self changed:#layout
     ]
 
 
 !
 
-basicMoveSelectionVertical:n
-    "move up:   n < 0
-     move down: n > 0
+moveSelectionLeft:aNumber
+    "move selection left
     "
+    |gridX|
+
+    gridAlign notNil ifTrue:[
+        gridX := gridAlign x.
+    ].
+
     self selectionHiddenDo:[
-        self transaction:#move selectionDo:[:v| self shifLayout:v top:n bottom:n ].
+        self transaction:#move selectionDo:[:aView|
+            |n d|
+
+            n := aNumber.
+
+            aligning ifTrue:[
+                d := ((aView computeOrigin x) \\ gridX).
+                d ~~ 0 ifTrue:[
+                    n := n-1.
+                ].
+                n := (n * gridX) + d.
+            ].
+            n := n negated.
+            self shiftLayout:aView left:n right:n
+
+        ].
         self changed:#layout
     ]
-
-
-
-!
-
-moveSelectionDown:n
-    self basicMoveSelectionVertical:n
-
-
 !
 
-moveSelectionLeft:n
-    self basicMoveSelectionHorizontal:(n negated)
-
-
+moveSelectionRight:aNumber
+    "move selection right
+    "
+    |gridX|
+
+    gridAlign notNil ifTrue:[
+        gridX := gridAlign x.
+    ].
+
+    self selectionHiddenDo:[
+        self transaction:#move selectionDo:[:aView|
+            |n d|
+
+            n := aNumber.
+
+            aligning ifTrue:[
+                d := ((aView computeCorner x) \\ gridX).
+                n := n * gridX.
+
+                d ~~ 0 ifTrue:[
+                    n := n - d + 1.
+                ]
+            ].
+            self shiftLayout:aView left:n right:n
+
+        ].
+        self changed:#layout
+    ]
 !
 
-moveSelectionRight:n
-    self basicMoveSelectionHorizontal:n
-
-
-!
-
-moveSelectionUp:n
-    self basicMoveSelectionVertical:(n negated)
+moveSelectionUp:aNumber
+    "move selection up
+    "
+    |gridY|
+
+    gridAlign notNil ifTrue:[
+        gridY := gridAlign y.
+    ].
+
+    self selectionHiddenDo:[
+        self transaction:#move selectionDo:[:aView|
+            |n d|
+
+            n := aNumber.
+
+            aligning ifTrue:[
+                d := ((aView computeOrigin x) \\ gridY).
+                d ~~ 0 ifTrue:[
+                    n := n-1.
+                ].
+                n := (n * gridY) + d.
+            ].
+            n := n negated.
+            self shiftLayout:aView top:n bottom:n
+        ].
+        self changed:#layout
+    ]
 
 
 ! !
@@ -1316,15 +1435,32 @@
 !UIObjectView methodsFor:'user actions - position'!
 
 alignSelectionBottom
-    |bmost delta|
-
-    self selectionHiddenDo:[
-        bmost := 0.
-        self selectionDo:[:v| bmost := bmost max:(v computeCorner y)].
-
-        self transaction:#align selectionDo:[:v|
-            (delta := bmost - (v computeCorner y)) ~~ 0 ifTrue:[
-                self shifLayout:v top:delta bottom:delta.
+    |bmost delta layout|
+
+    selection notNil ifTrue:[
+        self selectionHiddenDo:[
+            self numberOfSelections > 1 ifTrue:[
+                bmost := (selection at:1) computeCorner y.
+
+                self transaction:#align selectionDo:[:v|
+                    (delta := bmost - (v computeCorner y)) ~~ 0 ifTrue:[
+                        self shiftLayout:v top:delta bottom:delta.
+                    ]
+                ]
+            ] ifFalse:[
+                layout := selection geometryLayout.
+
+                (layout isLayout and:[layout isLayoutFrame]) ifFalse:[
+                    ^ self
+                ].
+
+                self transaction:#layout selectionDo:[:aView|
+                    self undoBlockDimensionChanged:aView.
+                    layout := aView geometryLayout.
+                    layout bottomOffset:0.
+                    layout bottomFraction:1.0.
+                    aView geometryLayout:layout.
+                ]
             ]
         ].
         self changed:#layout
@@ -1335,28 +1471,32 @@
 !
 
 alignSelectionCenterHor
-    |counter centerX|
-
-    self selectionHiddenDo:[
-        counter := 0.
-        centerX := 0.
-
-        self selectionDo:[:v |
-            centerX := centerX + (v computeCorner x + v computeOrigin x).
-            counter := counter + 1.
-        ].
-        centerX := centerX // (counter * 2).
-
-        self transaction:#align selectionDo:[:v|
-            |newX oldX delta|
-
-            oldX  := v computeOrigin x.
-            newX  := centerX - ((v computeCorner x - oldX) // 2).
-            delta := newX - oldX.
-
-            self shifLayout:v left:delta right:delta
-        ].
-        self changed:#layout
+    |view center|
+
+    selection notNil ifTrue:[
+        self selectionHiddenDo:[
+            view := self singleSelection.
+
+            view notNil ifTrue:[
+                view   := view superView.
+                center := view computeExtent
+            ] ifFalse:[
+                view   := selection at:1.
+                center := view computeCorner + view computeOrigin.
+            ].
+            center := center x // 2.
+
+            self transaction:#align selectionDo:[:v|
+                |newX oldX delta|
+
+                oldX  := v computeOrigin x.
+                newX  := center - ((v computeCorner x - oldX) // 2).
+                delta := newX - oldX.
+
+                self shiftLayout:v left:delta right:delta
+            ].
+            self changed:#layout
+        ]
     ]
 
 
@@ -1364,89 +1504,157 @@
 !
 
 alignSelectionCenterVer
-    |counter centerY|
-
-    self selectionHiddenDo:[
-        counter := 0.
-        centerY := 0.
-
-        self selectionDo:[:v |
-            centerY := centerY + (v computeCorner y + v computeOrigin y).
-            counter := counter + 1.
-        ].
-        centerY := centerY // (counter * 2).
-
-        self transaction:#align selectionDo:[:v|
-            |newY oldY delta|
-
-            oldY  := v computeOrigin y.
-            newY  := centerY - ((v computeCorner y - oldY) // 2).
-            delta := newY - oldY.
-
-            self shifLayout:v top:delta bottom:delta
-        ].
-        self changed:#layout
+    |view center|
+
+    selection notNil ifTrue:[
+        self selectionHiddenDo:[
+            view := self singleSelection.
+
+            view notNil ifTrue:[
+                view   := view superView.
+                center := view computeExtent
+            ] ifFalse:[
+                view   := selection at:1.
+                center := view computeCorner + view computeOrigin.
+            ].
+            center := center y // 2.
+
+            self transaction:#align selectionDo:[:v|
+                |newY oldY delta|
+
+                oldY  := v computeOrigin y.
+                newY  := center - ((v computeCorner y - oldY) // 2).
+                delta := newY - oldY.
+
+                self shiftLayout:v top:delta bottom:delta
+            ].
+            self changed:#layout
+        ]
     ]
 !
 
 alignSelectionLeft
-    |lmost delta|
-
-    self selectionHiddenDo:[
-        lmost := self selectionFindMinimum:[:v| v computeOrigin x].
-
-        self transaction:#align selectionDo:[:v|
-            (delta := lmost - (v computeOrigin x)) ~~ 0 ifTrue:[
-                self shifLayout:v left:delta right:delta
+    |lmost delta layout|
+
+    selection notNil ifTrue:[
+        self selectionHiddenDo:[
+            self numberOfSelections > 1 ifTrue:[
+                lmost := (selection at:1) computeOrigin x.
+
+                self transaction:#align selectionDo:[:v|
+                    (delta := lmost - (v computeOrigin x)) ~~ 0 ifTrue:[
+                        self shiftLayout:v left:delta right:delta
+                    ]
+                ]
+            ] ifFalse:[
+                self transaction:#layout selectionDo:[:aView|
+                    layout := aView geometryLayout.
+
+                    layout isLayout ifTrue:[
+                        self undoBlockDimensionChanged:aView.
+                        layout leftOffset:0.
+                        layout leftFraction:0.0.
+                        aView geometryLayout:layout.
+                    ]
+                ]
             ]
         ].
         self changed:#layout
     ]
-
 !
 
 alignSelectionLeftAndRight
-    |lmost rmost|
-
-    self selectionHiddenDo:[
-        lmost := self selectionFindMinimum:[:v| v computeOrigin x].
-        rmost := 0.
-        self selectionDo:[:v | rmost := rmost max:(v computeCorner x)].
-
-        self transaction:#align selectionDo:[:v|
-            self shifLayout:v left:(lmost - (v computeOrigin x))
-                             right:(rmost - (v computeCorner x))
+    |lmost rmost layout|
+
+    selection notNil ifTrue:[
+        self selectionHiddenDo:[
+            self numberOfSelections > 1 ifTrue:[
+                lmost := (selection at:1) computeOrigin x.
+                rmost := (selection at:1) computeCorner x.
+
+                self transaction:#align selectionDo:[:v|
+                    self shiftLayout:v left:(lmost - (v computeOrigin x))
+                                     right:(rmost - (v computeCorner x))
+                ]
+            ] ifFalse:[
+                self transaction:#layout selectionDo:[:aView|
+                    layout := aView geometryLayout.
+
+                    layout isLayout ifTrue:[
+                        self undoBlockDimensionChanged:aView.
+                        layout leftOffset:0.
+                        layout leftFraction:0.0.
+
+                        (layout isLayout and:[layout isLayoutFrame]) ifTrue:[
+                            layout rightOffset:0.
+                            layout rightFraction:1.0.
+                        ].
+                        aView geometryLayout:layout.
+                    ]
+                ]
+            ]
         ].
         self changed:#layout
     ]
 !
 
 alignSelectionRight
-    |rmost delta|
-
-    self selectionHiddenDo:[
-        rmost := 0.
-        self selectionDo:[:v| rmost := rmost max:(v computeCorner x)].
-
-        self transaction:#align selectionDo:[:v|
-            (delta := rmost - (v computeCorner x)) ~~ 0 ifTrue:[
-                self shifLayout:v left:delta right:delta
+    |rmost delta layout|
+
+    selection notNil ifTrue:[
+        self selectionHiddenDo:[
+            self numberOfSelections > 1 ifTrue:[
+                rmost := (selection at:1) computeCorner x.
+
+                self transaction:#align selectionDo:[:v|
+                    (delta := rmost - (v computeCorner x)) ~~ 0 ifTrue:[
+                        self shiftLayout:v left:delta right:delta
+                    ]
+                ]
+            ] ifFalse:[
+                layout := selection geometryLayout.
+
+                (layout isLayout and:[layout isLayoutFrame]) ifFalse:[
+                    ^ self
+                ].
+
+                self transaction:#layout selectionDo:[:aView|
+                    self undoBlockDimensionChanged:aView.
+                    layout := aView geometryLayout.
+                    layout rightOffset:0.
+                    layout rightFraction:1.0.
+                    aView geometryLayout:layout.
+                ]
             ]
         ].
         self changed:#layout
     ]
-
 !
 
 alignSelectionTop
-    |tmost delta|
-
-    self selectionHiddenDo:[
-        tmost := self selectionFindMinimum:[:v| v computeOrigin y].
-
-        self transaction:#align selectionDo:[:v|
-            (delta := tmost - (v computeOrigin y)) ~~ 0 ifTrue:[
-                self shifLayout:v top:delta bottom:delta
+    |tmost delta layout|
+
+    selection notNil ifTrue:[
+        self selectionHiddenDo:[
+            self numberOfSelections > 1 ifTrue:[
+                tmost := (selection at:1) computeOrigin y.
+
+                self transaction:#align selectionDo:[:v|
+                    (delta := tmost - (v computeOrigin y)) ~~ 0 ifTrue:[
+                        self shiftLayout:v top:delta bottom:delta
+                    ]
+                ]
+            ] ifFalse:[
+                self transaction:#layout selectionDo:[:aView|
+                    layout := aView geometryLayout.
+
+                    layout isLayout ifTrue:[
+                        self undoBlockDimensionChanged:aView.
+                        layout topOffset:0.
+                        layout topFraction:0.0.
+                        aView geometryLayout:layout.
+                    ]
+                ]
             ]
         ].
         self changed:#layout
@@ -1455,16 +1663,35 @@
 !
 
 alignSelectionTopAndBottom
-    |tmost bmost|
-
-    self selectionHiddenDo:[
-        tmost := self selectionFindMinimum:[:v| v computeOrigin y].
-        bmost := 0.
-        self selectionDo:[:v| bmost := bmost max:(v computeCorner y)].
-
-        self transaction:#align selectionDo:[:v|
-            self shifLayout:v top:(tmost - (v computeOrigin y))
-                           bottom:(bmost - (v computeCorner y))
+    |tmost bmost layout|
+
+    selection notNil ifTrue:[
+        self selectionHiddenDo:[
+            self numberOfSelections > 1 ifTrue:[
+                tmost := (selection at:1) computeOrigin y.
+                bmost := (selection at:1) computeCorner y.
+
+                self transaction:#align selectionDo:[:v|
+                    self shiftLayout:v top:(tmost - (v computeOrigin y))
+                                    bottom:(bmost - (v computeCorner y))
+                ]
+            ] ifFalse:[
+                self transaction:#layout selectionDo:[:aView|
+                    layout := aView geometryLayout.
+
+                    layout isLayout ifTrue:[
+                        self undoBlockDimensionChanged:aView.
+                        layout topOffset:0.
+                        layout topFraction:0.0.
+
+                        (layout isLayout and:[layout isLayoutFrame]) ifTrue:[
+                            layout bottomOffset:0.
+                            layout bottomFraction:1.0.
+                        ].
+                        aView geometryLayout:layout.
+                    ]
+                ]
+            ]
         ].
         self changed:#layout
     ]
@@ -1504,9 +1731,9 @@
 
             self transaction:#center selectionDo:[:v|
                 orientation == #y ifTrue:[
-                    self shifLayout:v top:delta bottom:delta
+                    self shiftLayout:v top:delta bottom:delta
                 ] ifFalse:[
-                    self shifLayout:v left:delta right:delta
+                    self shiftLayout:v left:delta right:delta
                 ]
             ].
             self changed:#layout
@@ -1533,7 +1760,9 @@
 spreadSelectionHor
     |sumWidths min max viewsInOrder topsInOrder count space|
 
-    (selection isKindOf:Collection) ifFalse:[^ self].
+    (self numberOfSelections > 1) ifFalse:[
+        ^ self
+    ].
 
     self selectionHiddenDo:[
         count := 0.
@@ -1559,7 +1788,7 @@
             |delta|
 
             delta := min - aView computeOrigin x.
-            self shifLayout:aView left:delta right:delta.
+            self shiftLayout:aView left:delta right:delta.
             min := min + aView computeExtent x + space
         ].
         self changed:#layout
@@ -1570,7 +1799,9 @@
 spreadSelectionVer
     |sumHeights min max viewsInOrder topsInOrder count space|
 
-    (selection isKindOf:Collection) ifFalse:[^ self].
+    (self numberOfSelections > 1) ifFalse:[
+        ^ self
+    ].
 
     self selectionHiddenDo:[
         count := 0.
@@ -1596,7 +1827,7 @@
             |delta|
 
             delta := min - aView computeOrigin y.
-            self shifLayout:aView top:delta bottom:delta.
+            self shiftLayout:aView top:delta bottom:delta.
             min := min + aView height + space
         ].
         self changed:#layout
--- a/UIPainter.st	Fri Feb 21 20:33:18 1997 +0100
+++ b/UIPainter.st	Fri Feb 21 20:33:57 1997 +0100
@@ -13,19 +13,21 @@
 ApplicationModel subclass:#UIPainter
 	instanceVariableNames:'menu nameField elementMenu workView treeView outletView stringBox
 		actionBox listBox fileBox currentFileName topView propertyFrame
-		whichProperty changeSelectorHolder changeChannel
-		aspectSelectorHolder aspectChannel nameChannel applyAction
-		leftFractionHolder leftOffsetHolder rightFractionHolder
-		rightOffsetHolder topFractionHolder topOffsetHolder
-		bottomFractionHolder bottomOffsetHolder specClass specSelector
-		specSuperclass leftAlignmentFractionHolder
-		topAlignmentFractionHolder classNameHolder methodNameHolder
-		aspectHolders propertyShown specShown'
+		whichProperty nameChannel applyAction specClass specSelector
+		specSuperclass aspectHolders specShown specSpecificAspectHolders
+		claus'
 	classVariableNames:''
 	poolDictionaries:''
 	category:'Interface-UIPainter'
 !
 
+HorizontalPanelView subclass:#ButtonPanel
+	instanceVariableNames:'receiver argumentToSelector'
+	classVariableNames:''
+	poolDictionaries:''
+	privateIn:UIPainter
+!
+
 !UIPainter class methodsFor:'documentation'!
 
 copyright
@@ -138,12 +140,54 @@
       )
 !
 
+cancelAndApplySpec
+    "this window spec was automatically generated by the ST/X UIPainter"
+
+    "do not manually edit this - the painter/builder may not be able to
+     handle the specification if its corrupted."
+
+    "
+     UIPainter new openOnClass:UIPainter andSelector:#cancelAndApplySpec
+     UIPainter new openInterface:#cancelAndApplySpec
+    "
+
+    <resource: #canvas>
+
+    ^
+     
+       #(#FullSpec
+          #'window:' 
+           #(#WindowSpec
+              #'layout:' #(#LayoutFrame 0 0.0 0 0.0 0 1.0 0 1.0)
+              #'label:' 'unnamed'
+              #'bounds:' #(#Rectangle 0 0 225 45)
+          )
+          #'component:' 
+           #(#SpecCollection
+              #'collection:' 
+               #(
+                 #(#ActionButtonSpec
+                    #'name:' 'cancel'
+                    #'layout:' #(#LayoutFrame 26 0 13 0 77 0 35 0)
+                    #'label:' 'cancel'
+                    #'model:' #cancel
+                )
+                 #(#ActionButtonSpec
+                    #'name:' 'apply'
+                    #'layout:' #(#LayoutFrame 139 0 13 0 190 0 35 0)
+                    #'label:' 'apply'
+                    #'model:' #apply
+                )
+              )
+          )
+      )
+!
+
 colorSpec
     "UIBuilder new openOnClass:self andSelector:#colorSpec"
     "Builder new openInterface:#colorSpec"
 
     <resource: #canvas>
-
     ^
      
        #(#FullSpec
@@ -186,14 +230,14 @@
                                    #(
                                      #(#InputFieldSpec
                                         #'layout:' #(#LayoutFrame 0 0 49 0 163 0 69 0)
-                                        #model: #foregroundChannel
+                                        #model: #foregroundColor
                                         #acceptOnLostFocus: true
                                         #tabable: true
 
                                     )
                                      #(#InputFieldSpec
                                         #'layout:' #(#LayoutFrame 0 0 119 0 163 0 142 0)
-                                        #model: #backgroundChannel
+                                        #model: #backgroundColor
                                         #acceptOnLostFocus: true
                                         #tabable: true
 
@@ -227,491 +271,527 @@
 !
 
 geometrySpecForAlignmentOrigin
-    "UIBuilder new openOnClass:self andSelector:#geometrySpecForAlignmentOrigin"
-    "Builder new openInterface:#geometrySpecForAlignmentOrigin"
-
+    "
+    UIPainter new openOnClass:self andSelector:#geometrySpecForAlignmentOrigin
+    "
     <resource: #canvas>
 
     ^
-     
+
        #(#FullSpec
+          #'window:' 
+           #(#WindowSpec
+              #'layout:' #(#LayoutFrame 0 0.0 0 0.0 0 1.0 0 1.0)
+              #'label:' 'unnamed'
+              #'bounds:' #(#Rectangle 0 0 248 304)
+          )
           #'component:' 
            #(#SpecCollection
               #'collection:' 
                #(
-                 #(#FramedBoxSpec
-                    #'layout:' #(#LayoutFrame 0 0 -1 0 253 0 291 0)
-                    #'component:' 
-                     #(#SpecCollection
-                        #'collection:' 
-                         #(
-                           #(#VerticalPanelViewSpec
-                              #'layout:' #(#LayoutFrame 6 0 26 0 85 0 219 0)
-                              #'component:' 
-                               #(#SpecCollection
-                                  #'collection:' 
-                                   #(
-                                     #(#LabelSpec
-                                        #'layout:' #(#LayoutFrame 0 0 19 0 30 0 43 0)
-                                        #'label:' 'left'
-                                        #'adjust:' #left
-                                    )
-                                     #(#LabelSpec
-                                        #'layout:' #(#LayoutFrame 0 0 63 0 31 0 87 0)
-                                        #'label:' 'top'
-                                        #'adjust:' #left
-                                    )
-                                     #(#LabelSpec
-                                        #'layout:' #(#LayoutFrame 0 0 107 0 41 0 131 0)
-                                        #'label:' 'align H'
-                                        #'adjust:' #left
-                                    )
-                                     #(#LabelSpec
-                                        #'layout:' #(#LayoutFrame 0 0 151 0 61 0 175 0)
-                                        #'label:' 'align V'
-                                        #'adjust:' #left
-                                    )
-                                  )
-                              )
-                              #'horizontalLayout:' #left
-                              #'verticalLayout:' #spreadSpace
-                          )
-                           #(#VerticalPanelViewSpec
-                              #'layout:' #(#LayoutFrame 80 0 24 0 124 0 217 0)
-                              #'component:' 
-                               #(#SpecCollection
-                                  #'collection:' 
-                                   #(
-                                     #(#InputFieldSpec
-                                        #'layout:' #(#LayoutFrame 0 0 21 0 71 0 42 0)
-                                        #'type:' #numberOrNil
-                                        #model: #leftFractionChannel
-                                        #acceptOnLostFocus: true
-                                        #tabable: true
-                                    )
-                                     #(#InputFieldSpec
-                                        #'layout:' #(#LayoutFrame 0 0 64 0 71 0 85 0)
-                                        #'type:' #numberOrNil
-                                        #'model:' #'topFractionChannel'
-                                        #acceptOnLostFocus: true
-                                        #tabable: true
-                                    )
-                                     #(#InputFieldSpec
-                                        #'layout:' #(#LayoutFrame 0 0 107 0 71 0 128 0)
-                                        #'type:' #numberOrNil
-                                        #model:  #'leftAlignmentFractionChannel'
-                                        #acceptOnLostFocus: true
-                                        #tabable: true
-                                    )
-                                     #(#InputFieldSpec
-                                        #'layout:' #(#LayoutFrame 0 0 150 0 71 0 171 0)
-                                        #'type:' #numberOrNil
-                                        #'model:' #'topAlignmentFractionChannel'
-                                        #acceptOnLostFocus: true
-                                        #tabable: true
-                                    )
-                                  )
-                              )
-                              #'horizontalLayout:' #fit
-                              #'verticalLayout:' #spreadSpace
-                          )
-                           #(#VerticalPanelViewSpec
-                              #'layout:' #(#LayoutFrame 150 0 24 0 220 0 216 0)
-                              #'component:' 
-                               #(#SpecCollection
-                                  #'collection:' 
-                                   #(
-                                     #(#InputFieldSpec
-                                        #'layout:' #(#LayoutFrame 0 0 21 0 114 0 42 0)
-                                        #'type:' #numberOrNil
-                                        #model: #leftOffsetChannel
-                                        #acceptOnLostFocus: true
-                                        #tabable: true
-                                    )
-                                     #(#InputFieldSpec
-                                        #'layout:' #(#LayoutFrame 0 0 64 0 114 0 85 0)
-                                        #'type:' #numberOrNil
-                                        #model: #topOffsetChannel
-                                        #acceptOnLostFocus: true
-                                        #tabable: true
-                                    )
-                                  )
-                              )
-                              #'horizontalLayout:' #fit
-                              #'verticalLayout:' #spreadSpace
-                          )
-                           #(#ActionButtonSpec
-                              #'name:' 'button'
-                              #'layout:' #(#LayoutFrame 16 0 210 0 76 0 240 0)
-                              #'label:' 'frame'
-                              #'model:' #setLayoutFrame
-                          )
-                           #(#ActionButtonSpec
-                              #'name:' 'button'
-                              #'layout:' #(#LayoutFrame 96 0 210 0 156 0 240 0)
-                              #'label:' 'origin'
-                              #'model:' #setLayoutOrigin
-                          )
-                           #(#ActionButtonSpec
-                              #'name:' 'button'
-                              #'layout:' #(#LayoutFrame 176 0 210 0 236 0 240 0)
-                              #'label:' 'align'
-                              #'model:' #setAlignmentOrigin
-                              #'initiallyDisabled:' true
-                          )
-
-                           #(#ActionButtonSpec
-                              #'layout:' #(#LayoutFrame 96 0 260 0 156 0 290 0)
-                              #'label:' 'apply'
-                              #'model:' #setDimensionForAlignmentOrigin
-                              #tabable: true
-                          )
-                           #(#LabelSpec
-                              #'layout:' #(#LayoutFrame 77 0 9 0 137 0 31 0)
-                              #'label:' 'relative'
-                          )
-                           #(#LabelSpec
-                              #'layout:' #(#LayoutFrame 167 0 9 0 213 0 30 0)
-                              #'label:' 'offset'
-                          )
-                        )
-                    )
-                    #'labelPosition:' #topLeft
-                    #'showFrame:' false
+                 #(#LabelSpec
+                    #'name:' 'label1'
+                    #'layout:' #(#LayoutFrame 5 0 42 0 48 0 60 0)
+                    #'label:' 'left'
+                )
+                 #(#LabelSpec
+                    #'name:' 'label2'
+                    #'layout:' #(#LayoutFrame 5 0 69 0 48 0 87 0)
+                    #'label:' 'top'
+                )
+                 #(#LabelSpec
+                    #'name:' 'label3'
+                    #'layout:' #(#LayoutFrame 57 0 10 0 103 0 27 0)
+                    #'label:' 'relative'
+                )
+                 #(#LabelSpec
+                    #'name:' 'label4'
+                    #'layout:' #(#LayoutFrame 154 0 11 0 190 0 28 0)
+                    #'label:' 'offset'
+                )
+                 #(#LabelSpec
+                    #'name:' 'label5'
+                    #'layout:' #(#LayoutFrame 5 0 96 0 48 0 114 0)
+                    #'label:' 'align H'
+                )
+                 #(#LabelSpec
+                    #'name:' 'label6'
+                    #'layout:' #(#LayoutFrame 5 0 122 0 48 0 140 0)
+                    #'label:' 'align V'
+                )
+                 #(#InputFieldSpec
+                    #'name:' 'editField1'
+                    #'type:' #numberOrNil
+                    #'layout:' #(#LayoutFrame 57 0 42 0 114 0 60 0)
+                    #'model:' #leftFraction
+                    #acceptOnLostFocus: true
+                    #tabable: true
+                )
+                 #(#InputFieldSpec
+                    #'name:' 'editField2'
+                    #'type:' #numberOrNil
+                    #'layout:' #(#LayoutFrame 57 0 69 0 114 0 87 0)
+                    #'model:' #topFraction
+                    #acceptOnLostFocus: true
+                    #tabable: true
+                )
+                 #(#InputFieldSpec
+                    #'name:' 'editField5'
+                    #'type:' #numberOrNil
+                    #'layout:' #(#LayoutFrame 57 0 96 0 114 0 114 0)
+                    #'model:' #leftAlignmentFraction
+                    #acceptOnLostFocus: true
+                    #tabable: true
+                )
+                 #(#InputFieldSpec
+                    #'name:' 'editField6'
+                    #'type:' #numberOrNil
+                    #'layout:' #(#LayoutFrame 56 0 122 0 113 0 140 0)
+                    #'model:' #topAlignmentFraction
+                    #acceptOnLostFocus: true
+                    #tabable: true
                 )
+                 #(#InputFieldSpec
+                    #'name:' 'editField3'
+                    #'type:' #numberOrNil
+                    #'layout:' #(#LayoutFrame 154 0 42 0 212 0 60 0)
+                    #'model:' #leftOffset
+                    #acceptOnLostFocus: true
+                    #tabable: true
+                )
+                 #(#InputFieldSpec
+                    #'name:' 'editField4'
+                    #'type:' #numberOrNil
+                    #'layout:' #(#LayoutFrame 154 0 69 0 212 0 87 0)
+                    #'model:' #topOffset
+                    #acceptOnLostFocus: true
+                    #tabable: true
+                )
+                 #(#ActionButtonSpec
+                    #'name:' 'button1'
+                    #'layout:' #(#LayoutFrame 119 0 42 0 138 0 60 0)
+                    #'label:' ''
+                    #'model:' #makeRelativeLeft
+                )
+                 #(#ActionButtonSpec
+                    #'name:' 'button2'
+                    #'layout:' #(#LayoutFrame 119 0 69 0 138 0 87 0)
+                    #'label:' ''
+                    #'model:' #makeRelativeTop
+                )
+                 #(#ActionButtonSpec
+                    #'name:' 'button3'
+                    #'layout:' #(#LayoutFrame 216 0 42 0 235 0 60 0)
+                    #'label:' ''
+                    #'model:' #makeOffsetLeft
+                )
+                 #(#ActionButtonSpec
+                    #'name:' 'button4'
+                    #'layout:' #(#LayoutFrame 216 0 69 0 235 0 87 0)
+                    #'label:' ''
+                    #'model:' #makeOffsetTop
+                )
+
+
+               #(#ActionButtonSpec
+                  #'name:' 'button'
+                  #'layout:' #(#LayoutFrame 16 0 210 0 76 0 240 0)
+                  #'label:' 'frame'
+                  #'model:' #setLayoutFrame
+                )
+               #(#ActionButtonSpec
+                  #'name:' 'button'
+                  #'layout:' #(#LayoutFrame 96 0 210 0 156 0 240 0)
+                  #'label:' 'origin'
+                  #'model:' #setLayoutOrigin
+                )
+               #(#ActionButtonSpec
+                  #'name:' 'button'
+                  #'layout:' #(#LayoutFrame 176 0 210 0 236 0 240 0)
+                  #'label:' 'align'
+                  #'model:' #setAlignmentOrigin
+                  #'initiallyDisabled:' true
+                )
+               #(#ActionButtonSpec
+                  #'layout:' #(#LayoutFrame 96 0 260 0 156 0 290 0)
+                  #'label:' 'apply'
+                  #'model:' #setDimensionForLayoutFrame
+                  #tabable: true
+                )
+
               )
           )
-          #'window:' 
-           #(#WindowSpec
-              #'label:' 'indy: unnamed'
-              #'bounds:' #(#Rectangle 0 0 255 292)
-          )
       )
+
+
 !
 
 geometrySpecForLayoutFrame
-    "UIBuilder new openOnClass:self andSelector:#geometrySpecForLayoutFrame"
-    "Builder new openInterface:#geometrySpecForLayoutFrame"
-
-    <resource: #canvas>
-
-    ^
-     
-       #(#FullSpec
-          #'component:' 
-           #(#SpecCollection
-              #'collection:' 
-               #(
-                 #(#FramedBoxSpec
-                    #'layout:' #(#LayoutFrame 0 0 -1 0 253 0 291 0)
-                    #'component:' 
-                     #(#SpecCollection
-                        #'collection:' 
-                         #(
-                           #(#VerticalPanelViewSpec
-                              #'layout:' #(#LayoutFrame 6 0 26 0 85 0 219 0)
-                              #'component:' 
-                               #(#SpecCollection
-                                  #'collection:' 
-                                   #(
-                                     #(#LabelSpec
-                                        #'layout:' #(#LayoutFrame 0 0 19 0 30 0 43 0)
-                                        #'label:' 'left'
-                                        #'adjust:' #left
-                                    )
-                                     #(#LabelSpec
-                                        #'layout:' #(#LayoutFrame 0 0 63 0 30 0 87 0)
-                                        #'label:' 'top'
-                                        #'adjust:' #left
-                                    )
-                                     #(#LabelSpec
-                                        #'layout:' #(#LayoutFrame 0 0 107 0 40 0 131 0)
-                                        #'label:' 'right'
-                                        #'adjust:' #left
-                                    )
-                                     #(#LabelSpec
-                                        #'layout:' #(#LayoutFrame 0 0 151 0 40 0 175 0)
-                                        #'label:' 'bottom'
-                                        #'adjust:' #left
-                                    )
-                                  )
-                              )
-                              #'horizontalLayout:' #left
-                              #'verticalLayout:' #spreadSpace
-                          )
-                           #(#VerticalPanelViewSpec
-                              #'layout:' #(#LayoutFrame 80 0 24 0 124 0 217 0)
-                              #'component:' 
-                               #(#SpecCollection
-                                  #'collection:' 
-                                   #(
-                                     #(#InputFieldSpec
-                                        #'layout:' #(#LayoutFrame 0 0 21 0 71 0 42 0)
-                                        #'type:' #numberOrNil
-                                        #model: #leftFractionChannel
-                                        #acceptOnLostFocus: true
-                                        #tabable: true
-                                    )
-                                     #(#InputFieldSpec
-                                        #'layout:' #(#LayoutFrame 0 0 64 0 71 0 85 0)
-                                        #'type:' #numberOrNil
-                                        #'model:' #'topFractionChannel'
-                                        #acceptOnLostFocus: true
-                                        #tabable: true
-                                    )
-                                     #(#InputFieldSpec
-                                        #'layout:' #(#LayoutFrame 0 0 107 0 71 0 128 0)
-                                        #'type:' #numberOrNil
-                                        #model:  #'rightFractionChannel'
-                                        #acceptOnLostFocus: true
-                                        #tabable: true
-                                    )
-                                     #(#InputFieldSpec
-                                        #'layout:' #(#LayoutFrame 0 0 150 0 71 0 171 0)
-                                        #'type:' #numberOrNil
-                                        #'model:' #'bottomFractionChannel'
-                                        #acceptOnLostFocus: true
-                                        #tabable: true
-                                    )
-                                  )
-                              )
-                              #'horizontalLayout:' #fit
-                              #'verticalLayout:' #spreadSpace
-                          )
-                           #(#VerticalPanelViewSpec
-                              #'layout:' #(#LayoutFrame 150 0 24 0 220 0 216 0)
-                              #'component:' 
-                               #(#SpecCollection
-                                  #'collection:' 
-                                   #(
-                                     #(#InputFieldSpec
-                                        #'layout:' #(#LayoutFrame 0 0 21 0 114 0 42 0)
-                                        #'type:' #numberOrNil
-                                        #model: #leftOffsetChannel
-                                        #acceptOnLostFocus: true
-                                        #tabable: true
-                                    )
-                                     #(#InputFieldSpec
-                                        #'layout:' #(#LayoutFrame 0 0 64 0 114 0 85 0)
-                                        #'type:' #numberOrNil
-                                        #model: #topOffsetChannel
-                                        #acceptOnLostFocus: true
-                                        #tabable: true
-                                    )
-                                     #(#InputFieldSpec
-                                        #'layout:' #(#LayoutFrame 0 0 107 0 114 0 128 0)
-                                        #'type:' #numberOrNil
-                                        #'model:' #rightOffsetChannel
-                                        #acceptOnLostFocus: true
-                                        #tabable: true
-                                    )
-                                     #(#InputFieldSpec
-                                        #'layout:' #(#LayoutFrame 0 0 150 0 114 0 171 0)
-                                        #'type:' #numberOrNil
-                                        #'model:' #bottomOffsetChannel
-                                        #acceptOnLostFocus: true
-                                        #tabable: true
-                                    )
-                                  )
-                              )
-                              #'horizontalLayout:' #fit
-                              #'verticalLayout:' #spreadSpace
-                          )
-
-                           #(#ActionButtonSpec
-                              #'name:' 'button'
-                              #'layout:' #(#LayoutFrame 16 0 210 0 76 0 240 0)
-                              #'label:' 'frame'
-                              #'model:' #setLayoutFrame
-                              #'initiallyDisabled:' true
-                          )
-                           #(#ActionButtonSpec
-                              #'name:' 'button'
-                              #'layout:' #(#LayoutFrame 96 0 210 0 156 0 240 0)
-                              #'label:' 'origin'
-                              #'model:' #setLayoutOrigin
-                          )
-                           #(#ActionButtonSpec
-                              #'name:' 'button'
-                              #'layout:' #(#LayoutFrame 176 0 210 0 236 0 240 0)
-                              #'label:' 'align'
-                              #'model:' #setAlignmentOrigin
-                          )
-
-                           #(#ActionButtonSpec
-                              #'layout:' #(#LayoutFrame 96 0 260 0 156 0 290 0)
-                              #'label:' 'apply'
-                              #'model:' #setDimensionForLayoutFrame
-                              #tabable: true
-                          )
-                           #(#LabelSpec
-                              #'layout:' #(#LayoutFrame 77 0 9 0 137 0 31 0)
-                              #'label:' 'relative'
-                          )
-                           #(#LabelSpec
-                              #'layout:' #(#LayoutFrame 167 0 9 0 213 0 30 0)
-                              #'label:' 'offset'
-                          )
-                        )
-                    )
-                    #'labelPosition:' #topLeft
-                    #'showFrame:' false
-                )
-              )
-          )
-          #'window:' 
-           #(#WindowSpec
-              #'label:' 'indy: unnamed'
-              #'bounds:' #(#Rectangle 0 0 255 292)
-          )
-      )
-!
-
-geometrySpecForLayoutOrigin
-    "UIPainter new openOnClass:self andSelector:#geometrySpecForLayoutOrigin"
-    "Builder new openInterface:#geometrySpecForLayoutOrigin"
-
+    "
+    UIPainter new openOnClass:self andSelector:#geometrySpecForLayoutFrame
+    "
     <resource: #canvas>
 
     ^
 
        #(#FullSpec
+          #'window:' 
+           #(#WindowSpec
+              #'layout:' #(#LayoutFrame 0 0.0 0 0.0 0 1.0 0 1.0)
+              #'label:' 'unnamed'
+              #'bounds:' #(#Rectangle 0 0 300 300)
+          )
           #'component:' 
            #(#SpecCollection
               #'collection:' 
                #(
-                 #(#FramedBoxSpec
-                    #'name:' 'framedBox'
-                    #'layout:' #(#LayoutFrame 0 0 -1 0 253 0 291 0)
-                    #'component:' 
-                     #(#SpecCollection
-                        #'collection:' 
-                         #(
-                           #(#VerticalPanelViewSpec
-                              #'name:' 'verticalPanelView'
-                              #'layout:' #(#LayoutFrame 6 0 26 0 85 0 219 0)
-                              #'component:' 
-                               #(#SpecCollection
-                                  #'collection:' 
-                                   #(
-                                     #(#LabelSpec
-                                        #'name:' 'label'
-                                        #'layout:' #(#LayoutFrame 0 0 19 0 30 0 43 0)
-                                        #'label:' 'left'
-                                        #'adjust:' #left
-                                    )
-                                     #(#LabelSpec
-                                        #'name:' 'label'
-                                        #'layout:' #(#LayoutFrame 0 0 63 0 31 0 87 0)
-                                        #'label:' 'top'
-                                        #'adjust:' #left
-                                    )
-                                  )
-                              )
-                              #'horizontalLayout:' #left
-                              #'verticalLayout:' #spreadSpace
-                          )
-                           #(#VerticalPanelViewSpec
-                              #'name:' 'verticalPanelView'
-                              #'layout:' #(#LayoutFrame 80 0 24 0 124 0 217 0)
-                              #'component:' 
-                               #(#SpecCollection
-                                  #'collection:' 
-                                   #(
-                                     #(#InputFieldSpec
-                                        #'layout:' #(#LayoutFrame 0 0 21 0 71 0 42 0)
-                                        #'type:' #numberOrNil
-                                        #model: #leftFractionChannel
-                                        #'acceptOnLostFocus:' true
-                                        #tabable: true
-                                    )
-                                     #(#InputFieldSpec
-                                        #'layout:' #(#LayoutFrame 0 0 64 0 71 0 85 0)
-                                        #'type:' #numberOrNil
-                                        #'model:' #'topFractionChannel'
-                                        #acceptOnLostFocus: true
-                                        #tabable: true
-                                    )
-                                  )
-                              )
-                              #'horizontalLayout:' #fit
-                              #'verticalLayout:' #spreadSpace
-                          )
-                           #(#VerticalPanelViewSpec
-                              #'name:' 'verticalPanelView'
-                              #'layout:' #(#LayoutFrame 150 0 24 0 220 0 216 0)
-                              #'component:' 
-                               #(#SpecCollection
-                                  #'collection:' 
-                                   #(
-                                     #(#InputFieldSpec
-                                        #'layout:' #(#LayoutFrame 0 0 21 0 114 0 42 0)
-                                        #'type:' #numberOrNil
-                                        #model: #leftOffsetChannel
-                                        #acceptOnLostFocus: true
-                                        #tabable: true
-                                    )
-                                     #(#InputFieldSpec
-                                        #'layout:' #(#LayoutFrame 0 0 64 0 114 0 85 0)
-                                        #'type:' #numberOrNil
-                                        #model: #topOffsetChannel
-                                        #acceptOnLostFocus: true
-                                        #tabable: true
-                                    )
-                                  )
-                              )
-                              #'horizontalLayout:' #fit
-                              #'verticalLayout:' #spreadSpace
-                          )
-                           #(#ActionButtonSpec
-                              #'name:' 'button'
-                              #'layout:' #(#LayoutFrame 16 0 210 0 76 0 240 0)
-                              #'label:' 'frame'
-                              #'model:' #setLayoutFrame
-                          )
-                           #(#ActionButtonSpec
-                              #'name:' 'button'
-                              #'layout:' #(#LayoutFrame 96 0 210 0 156 0 240 0)
-                              #'label:' 'origin'
-                              #'model:' #setLayoutOrigin
-                              #'initiallyDisabled:' true
-                          )
-                           #(#ActionButtonSpec
-                              #'name:' 'button'
-                              #'layout:' #(#LayoutFrame 176 0 210 0 236 0 240 0)
-                              #'label:' 'align'
-                              #'model:' #setAlignmentOrigin
-                          )
-                           #(#ActionButtonSpec
-                              #'name:' 'button'
-                              #'layout:' #(#LayoutFrame 96 0 260 0 156 0 290 0)
-                              #'label:' 'apply'
-                              #'model:' #setDimensionForLayoutOrigin
-                          )
-                           #(#LabelSpec
-                              #'name:' 'label'
-                              #'layout:' #(#LayoutFrame 77 0 9 0 137 0 31 0)
-                              #'label:' 'relative'
-                          )
-                           #(#LabelSpec
-                              #'name:' 'label'
-                              #'layout:' #(#LayoutFrame 159 0 9 0 205 0 30 0)
-                              #'label:' 'offset'
-                          )
-                        )
-                    )
-                    #'labelPosition:' #topLeft
-                    #'showFrame:' false
+                 #(#LabelSpec
+                    #'name:' 'label left'
+                    #'layout:' #(#LayoutFrame 12 0 39 0 53 0 57 0)
+                    #'label:' 'left'
+                )
+                 #(#LabelSpec
+                    #'name:' 'label top'
+                    #'layout:' #(#LayoutFrame 12 0 67 0 53 0 85 0)
+                    #'label:' 'top'
+                )
+                 #(#LabelSpec
+                    #'name:' 'label right'
+                    #'layout:' #(#LayoutFrame 12 0 95 0 53 0 113 0)
+                    #'label:' 'right'
+                )
+                 #(#LabelSpec
+                    #'name:' 'label bottom'
+                    #'layout:' #(#LayoutFrame 12 0 123 0 53 0 141 0)
+                    #'label:' 'bottom'
+                )
+                 #(#LabelSpec
+                    #'name:' 'label relative'
+                    #'layout:' #(#LayoutFrame 65 0 6 0 110 0 24 0)
+                    #'label:' 'relative'
+                )
+                 #(#LabelSpec
+                    #'name:' 'label offset'
+                    #'layout:' #(#LayoutFrame 159 0 6 0 190 0 24 0)
+                    #'label:' 'offset'
+                )
+                 #(#LabelSpec
+                    #'name:' 'label all relative'
+                    #'layout:' #(#LayoutFrame 12 0 157 0 53 0 175 0)
+                    #'label:' 'all'
+                )
+                 #(#LabelSpec
+                    #'name:' 'label all absolute'
+                    #'layout:' #(#LayoutFrame 159 0 157 0 210 0 175 0)
+                    #'label:' 'all'
+                )
+                 #(#InputFieldSpec
+                    #'name:' 'relative E1'
+                    #'layout:' #(#LayoutFrame 65 0 39 0 113 0 57 0)
+                    #'model:' #leftFraction
+                    #'type:' #numberOrNil
+                    #'immediateAccept:' false
+                    #'acceptOnLeave:' true
+                    #'acceptOnReturn:' true
+                    #'acceptOnTab:' true
+                    #'acceptOnLostFocus:' true
+                )
+                 #(#InputFieldSpec
+                    #'name:' 'relative E2'
+                    #'layout:' #(#LayoutFrame 65 0 67 0 113 0 85 0)
+                    #'model:' #topFraction
+                    #'type:' #numberOrNil
+                    #'immediateAccept:' false
+                    #'acceptOnLeave:' true
+                    #'acceptOnReturn:' true
+                    #'acceptOnTab:' true
+                    #'acceptOnLostFocus:' true
+                )
+                 #(#InputFieldSpec
+                    #'name:' 'relative E3'
+                    #'layout:' #(#LayoutFrame 65 0 95 0 113 0 113 0)
+                    #'model:' #rightFraction
+                    #'type:' #numberOrNil
+                    #'immediateAccept:' false
+                    #'acceptOnLeave:' true
+                    #'acceptOnReturn:' true
+                    #'acceptOnTab:' true
+                    #'acceptOnLostFocus:' true
+                )
+                 #(#InputFieldSpec
+                    #'name:' 'relative E4'
+                    #'layout:' #(#LayoutFrame 65 0 123 0 113 0 141 0)
+                    #'model:' #bottomFraction
+                    #'type:' #numberOrNil
+                    #'immediateAccept:' false
+                    #'acceptOnLeave:' true
+                    #'acceptOnReturn:' true
+                    #'acceptOnTab:' true
+                    #'acceptOnLostFocus:' true
+                )
+                 #(#InputFieldSpec
+                    #'name:' 'offset E1'
+                    #'layout:' #(#LayoutFrame 159 0 39 0 210 0 57 0)
+                    #'model:' #leftOffset
+                    #'type:' #numberOrNil
+                    #'immediateAccept:' false
+                    #'acceptOnLeave:' true
+                    #'acceptOnReturn:' true
+                    #'acceptOnTab:' true
+                    #'acceptOnLostFocus:' true
+                )
+                 #(#InputFieldSpec
+                    #'name:' 'offset E2'
+                    #'layout:' #(#LayoutFrame 159 0 67 0 210 0 85 0)
+                    #'model:' #topOffset
+                    #'type:' #numberOrNil
+                    #'immediateAccept:' false
+                    #'acceptOnLeave:' true
+                    #'acceptOnReturn:' true
+                    #'acceptOnTab:' true
+                    #'acceptOnLostFocus:' true
+                )
+                 #(#InputFieldSpec
+                    #'name:' 'offset E3'
+                    #'layout:' #(#LayoutFrame 159 0 95 0 210 0 113 0)
+                    #'model:' #rightOffset
+                    #'type:' #numberOrNil
+                    #'immediateAccept:' false
+                    #'acceptOnLeave:' true
+                    #'acceptOnReturn:' true
+                    #'acceptOnTab:' true
+                    #'acceptOnLostFocus:' true
+                )
+                 #(#InputFieldSpec
+                    #'name:' 'offset E4'
+                    #'layout:' #(#LayoutFrame 159 0 123 0 210 0 141 0)
+                    #'model:' #bottomOffset
+                    #'type:' #numberOrNil
+                    #'immediateAccept:' false
+                    #'acceptOnLeave:' true
+                    #'acceptOnReturn:' true
+                    #'acceptOnTab:' true
+                    #'acceptOnLostFocus:' true
+                )
+                 #(#ActionButtonSpec
+                    #'name:' 'relative B1'
+                    #'layout:' #(#LayoutFrame 117 0 39 0 136 0 57 0)
+                    #'label:' ''
+                    #'model:' #makeRelativeLeft
+                )
+                 #(#ActionButtonSpec
+                    #'name:' 'relative B2'
+                    #'layout:' #(#LayoutFrame 117 0 67 0 136 0 85 0)
+                    #'label:' ''
+                    #'model:' #makeRelativeTop
+                )
+                 #(#ActionButtonSpec
+                    #'name:' 'relative B3'
+                    #'layout:' #(#LayoutFrame 117 0 95 0 136 0 113 0)
+                    #'label:' ''
+                    #'model:' #makeRelativeRight
+                )
+                 #(#ActionButtonSpec
+                    #'name:' 'relative B4'
+                    #'layout:' #(#LayoutFrame 117 0 123 0 136 0 141 0)
+                    #'label:' ''
+                    #'model:' #makeRelativeBottom
+                )
+                 #(#ActionButtonSpec
+                    #'name:' 'relative BAll'
+                    #'layout:' #(#LayoutFrame 117 0 157 0 136 0 175 0)
+                    #'label:' ''
+                    #'model:' #makeRelativeAll
+                )
+                 #(#ActionButtonSpec
+                    #'name:' 'offset B1'
+                    #'layout:' #(#LayoutFrame 214 0 39 0 233 0 57 0)
+                    #'label:' ''
+                    #'model:' #makeOffsetLeft
+                )
+                 #(#ActionButtonSpec
+                    #'name:' 'offset B2'
+                    #'layout:' #(#LayoutFrame 214 0 67 0 233 0 85 0)
+                    #'label:' ''
+                    #'model:' #makeOffsetTop
+                )
+                 #(#ActionButtonSpec
+                    #'name:' 'offset B3'
+                    #'layout:' #(#LayoutFrame 214 0 95 0 233 0 113 0)
+                    #'label:' ''
+                    #'model:' #makeOffsetRight
+                )
+                 #(#ActionButtonSpec
+                    #'name:' 'offset B4'
+                    #'layout:' #(#LayoutFrame 214 0 123 0 233 0 141 0)
+                    #'label:' ''
+                    #'model:' #makeOffsetBottom
+                )
+                 #(#ActionButtonSpec
+                    #'name:' 'offset BAll'
+                    #'layout:' #(#LayoutFrame 214 0 157 0 233 0 175 0)
+                    #'label:' ''
+                    #'model:' #makeOffsetAll
+                )
+                 #(#ActionButtonSpec
+                    #'name:' 'button'
+                    #'layout:' #(#LayoutFrame 16 0 210 0 76 0 240 0)
+                    #'label:' 'frame'
+                    #'model:' #setLayoutFrame
+                )
+                 #(#ActionButtonSpec
+                    #'name:' 'button10'
+                    #'layout:' #(#LayoutFrame 96 0 210 0 156 0 240 0)
+                    #'label:' 'origin'
+                    #'model:' #setLayoutOrigin
+                )
+                 #(#ActionButtonSpec
+                    #'name:' 'button11'
+                    #'layout:' #(#LayoutFrame 176 0 210 0 236 0 240 0)
+                    #'label:' 'align'
+                    #'model:' #setAlignmentOrigin
+                )
+                 #(#ActionButtonSpec
+                    #'name:' 'button12'
+                    #'layout:' #(#LayoutFrame 96 0 260 0 156 0 290 0)
+                    #'label:' 'apply'
+                    #'model:' #setDimensionForLayoutFrame
                 )
               )
           )
+      )
+
+
+!
+
+geometrySpecForLayoutOrigin
+    "
+    UIPainter new openOnClass:self andSelector:#geometrySpecForLayoutOrigin
+    "
+    <resource: #canvas>
+
+    ^
+
+       #(#FullSpec
           #'window:' 
            #(#WindowSpec
-              #'label:' 'indy: unnamed'
-              #'bounds:' #(#Rectangle 0 0 255 292)
+              #'layout:' #(#LayoutFrame 0 0.0 0 0.0 0 1.0 0 1.0)
+              #'label:' 'unnamed'
+              #'bounds:' #(#Rectangle 0 0 248 304)
+          )
+          #'component:' 
+           #(#SpecCollection
+              #'collection:' 
+               #(
+                 #(#LabelSpec
+                    #'name:' 'label1'
+                    #'layout:' #(#LayoutFrame 16 0 42 0 44 0 60 0)
+                    #'label:' 'left'
+                )
+                 #(#LabelSpec
+                    #'name:' 'label2'
+                    #'layout:' #(#LayoutFrame 16 0 69 0 44 0 87 0)
+                    #'label:' 'top'
+                )
+                 #(#LabelSpec
+                    #'name:' 'label3'
+                    #'layout:' #(#LayoutFrame 57 0 10 0 103 0 27 0)
+                    #'label:' 'relative'
+                )
+                 #(#LabelSpec
+                    #'name:' 'label4'
+                    #'layout:' #(#LayoutFrame 154 0 11 0 190 0 28 0)
+                    #'label:' 'offset'
+                )
+                 #(#InputFieldSpec
+                    #'name:' 'editField1'
+                    #'type:' #numberOrNil
+                    #'layout:' #(#LayoutFrame 57 0 42 0 114 0 60 0)
+                    #'model:' #leftFraction
+                    #acceptOnLostFocus: true
+                    #tabable: true
+                )
+                 #(#InputFieldSpec
+                    #'name:' 'editField2'
+                    #'type:' #numberOrNil
+                    #'layout:' #(#LayoutFrame 57 0 69 0 114 0 87 0)
+                    #'model:' #topFraction
+                    #acceptOnLostFocus: true
+                    #tabable: true
+                )
+                 #(#InputFieldSpec
+                    #'name:' 'editField3'
+                    #'type:' #numberOrNil
+                    #'layout:' #(#LayoutFrame 154 0 42 0 212 0 60 0)
+                    #'model:' #leftOffset
+                    #acceptOnLostFocus: true
+                    #tabable: true
+                )
+                 #(#InputFieldSpec
+                    #'name:' 'editField4'
+                    #'type:' #numberOrNil
+                    #'layout:' #(#LayoutFrame 154 0 69 0 212 0 87 0)
+                    #'model:' #topOffset
+                    #acceptOnLostFocus: true
+                    #tabable: true
+                )
+                 #(#ActionButtonSpec
+                    #'name:' 'button1'
+                    #'layout:' #(#LayoutFrame 119 0 42 0 138 0 60 0)
+                    #'label:' ''
+                    #'model:' #makeRelativeLeft
+                )
+                 #(#ActionButtonSpec
+                    #'name:' 'button2'
+                    #'layout:' #(#LayoutFrame 119 0 69 0 138 0 87 0)
+                    #'label:' ''
+                    #'model:' #makeRelativeTop
+                )
+                 #(#ActionButtonSpec
+                    #'name:' 'button3'
+                    #'layout:' #(#LayoutFrame 216 0 42 0 235 0 60 0)
+                    #'label:' ''
+                    #'model:' #makeOffsetLeft
+                )
+                 #(#ActionButtonSpec
+                    #'name:' 'button4'
+                    #'layout:' #(#LayoutFrame 216 0 69 0 235 0 87 0)
+                    #'label:' ''
+                    #'model:' #makeOffsetTop
+                )
+
+
+               #(#ActionButtonSpec
+                  #'name:' 'button'
+                  #'layout:' #(#LayoutFrame 16 0 210 0 76 0 240 0)
+                  #'label:' 'frame'
+                  #'model:' #setLayoutFrame
+                )
+               #(#ActionButtonSpec
+                  #'name:' 'button'
+                  #'layout:' #(#LayoutFrame 96 0 210 0 156 0 240 0)
+                  #'label:' 'origin'
+                  #'model:' #setLayoutOrigin
+                  #'initiallyDisabled:' true
+                )
+               #(#ActionButtonSpec
+                  #'name:' 'button'
+                  #'layout:' #(#LayoutFrame 176 0 210 0 236 0 240 0)
+                  #'label:' 'align'
+                  #'model:' #setAlignmentOrigin
+                )
+               #(#ActionButtonSpec
+                  #'layout:' #(#LayoutFrame 96 0 260 0 156 0 290 0)
+                  #'label:' 'apply'
+                  #'model:' #setDimensionForLayoutFrame
+                  #tabable: true
+                )
+
+              )
           )
       )
 
+
 !
 
 miscSpec
@@ -878,9 +958,7 @@
     "do not manually edit this - the painter/builder may not be able to
      handle the specification if its corrupted."
 
-    "UIPainter new openOnClass:NewApplication andSelector:#windowSpec"
-    "NewApplication new openInterface:#windowSpec"
-    "NewApplication open"
+    "UIPainter new openOnClass:self andSelector:#nameAndSelectorSpec"
 
     <resource: #canvas>
 
@@ -1009,6 +1087,10 @@
 
     singleSelection := workView singleSelection.
 
+    something == #selection ifTrue:[
+        claus setupView:singleSelection.
+    ].
+
     (something == #layout or:[something == #any]) ifTrue:[
         singleSelection notNil ifTrue:[
             self fetchLayoutFrom:singleSelection
@@ -1042,39 +1124,11 @@
 !UIPainter methodsFor:'aspects'!
 
 aspectFor:aKey
-    ^ aspectHolders at:aKey ifAbsent:[super aspectFor:aKey]
-!
-
-backgroundChannel
-    ^ self aspectFor:#backgroundChannel
-!
-
-bottomFractionChannel
-    ^ bottomFractionHolder
-!
-
-bottomOffsetChannel
-    ^ bottomOffsetHolder
-
-!
-
-foregroundChannel
-    ^ self aspectFor:#foregroundChannel
-
-!
-
-leftAlignmentFractionChannel
-    ^ leftAlignmentFractionHolder
-
-!
-
-leftFractionChannel
-    ^ leftFractionHolder
-
-!
-
-leftOffsetChannel
-    ^ leftOffsetHolder
+    ^ specSpecificAspectHolders at:aKey ifAbsent:[
+        aspectHolders at:aKey ifAbsent:[
+            super aspectFor:aKey
+        ]
+    ]
 
 !
 
@@ -1085,31 +1139,6 @@
     ^ nameChannel
 
     "Modified: 6.9.1995 / 00:38:00 / claus"
-!
-
-rightFractionChannel
-    ^ rightFractionHolder
-
-!
-
-rightOffsetChannel
-    ^ rightOffsetHolder
-
-!
-
-topAlignmentFractionChannel
-    ^ topAlignmentFractionHolder
-
-!
-
-topFractionChannel
-    ^ topFractionHolder
-
-!
-
-topOffsetChannel
-    ^ topOffsetHolder
-
 ! !
 
 !UIPainter methodsFor:'filein & fileout'!
@@ -1156,30 +1185,6 @@
 
 !UIPainter methodsFor:'initialization'!
 
-buttonPanelSpec
-    "return a spec for the buttons in the panel;
-     entries consists of selector and bitmap-filename.
-     nil selectors are taken as separators (see setupButtonPanel)"
-
-    ^ #(
-        #( alignSelectionLeft         'b_alignL.xbm'    )
-        #( alignSelectionRight        'b_alignR.xbm'    )
-        #( alignSelectionLeftAndRight 'b_alignLR.xbm'   )
-        #( nil )
-        #( alignSelectionTop          'b_alignT.xbm'    )
-        #( alignSelectionBottom       'b_alignB.xbm'    )
-        #( alignSelectionTopAndBottom 'b_alignTB.xbm'   )
-        #( nil )
-        #( alignSelectionCenterHor    'b_alignCH.xbm'   )
-        #( alignSelectionCenterVer    'b_alignCV.xbm'   )
-        #( nil )
-        #( moveSelectionLeft:         'b_moveLeft.xbm'  )
-        #( moveSelectionRight:        'b_moveRight.xbm' )
-        #( moveSelectionUp:           'b_moveUp.xbm'    )
-        #( moveSelectionDown:         'b_moveDown.xbm'  )
-       )
-!
-
 createCanvas 
     |topView|
 
@@ -1220,30 +1225,41 @@
 !
 
 initChannels
+    |cls|
+
+    specSpecificAspectHolders := IdentityDictionary new.
     aspectHolders := IdentityDictionary new.
 
-    aspectHolders at:#classNameChannel put:((specClass notNil ifTrue:[specClass name] ifFalse:['NewApplication']) asValue).
-    aspectHolders at:#superclassNameChannel put:((specClass notNil ifTrue:[specClass superclass] ifFalse:[ApplicationModel]) name asValue).
-    aspectHolders at:#methodNameChannel put:((specSelector notNil ifTrue:[specSelector] ifFalse:[#windowSpec]) asValue).
+    aspectHolders at:#classNameChannel put:(
+        (specClass notNil ifTrue:[specClass]
+                         ifFalse:['NewApplication']) asValue
+    ).
+    specSuperclass isNil ifTrue:[
+        specClass notNil ifTrue:[
+            (cls := Smalltalk at:specClass asSymbol) notNil ifTrue:[
+                specSuperclass := cls superclass name.
+            ]
+        ]
+    ].
+    aspectHolders at:#superclassNameChannel put:(
+        (specSuperclass notNil ifTrue:[specSuperclass]
+                         ifFalse:['ApplicationModel']) asValue
+    ).
+    aspectHolders at:#methodNameChannel put:(
+        (specSelector notNil ifTrue:[specSelector]
+                            ifFalse:[#windowSpec]) asValue
+    ).
 
     aspectHolders at:#aspectChannel put:(ValueHolder new).
     aspectHolders at:#changeChannel put:(ValueHolder new).
 
-    aspectHolders at:#foregroundChannel put:(ValueHolder new).
-    aspectHolders at:#backgroundChannel put:(ValueHolder new).
-
-
-    bottomFractionHolder        := nil asValue.
-    bottomOffsetHolder          := nil asValue.
-    leftFractionHolder          := nil asValue.
-    leftOffsetHolder            := nil asValue.
-    rightFractionHolder         := nil asValue.
-    rightOffsetHolder           := nil asValue.
-    topFractionHolder           := nil asValue.
-    topOffsetHolder             := nil asValue.
-    leftAlignmentFractionHolder := nil asValue.
-    topAlignmentFractionHolder  := nil asValue.
-
+    aspectHolders at:#foregroundColor put:(ValueHolder new).
+    aspectHolders at:#backgroundColor put:(ValueHolder new).
+
+    #( bottomFraction leftFraction topFraction rightFraction leftAlignmentFraction
+       bottomOffset   leftOffset   topOffset   rightOffset   topAlignmentFraction
+     )
+     do:[:aChannel| aspectHolders at:aChannel put:(ValueHolder new) ].
 !
 
 initPullDownMenu
@@ -1306,29 +1322,7 @@
                        )
              receiver:self.
 
-    menu at:#font 
-            putLabels:(resources  array:#(
-                        'larger' 
-                        'smaller'
-                        '-'
-                        'normal'
-                        'bold'
-                        'italic'
-                        'bold italic'
-                        '-'
-                        'font panel'
-                       ) )
-            selectors:#(largerFont 
-                        smallerFont
-                        nil
-                        normalFont
-                        boldFont
-                        italicFont
-                        boldItalicFont
-                        nil
-                        showFontPanel
-                       )
-             receiver:workView.
+    menu at:#font putMenu:(workView subMenuFont menuView).
 
     menu at:#type 
             putLabels:(resources  array:#(
@@ -1358,11 +1352,15 @@
     menu at:#special 
             putLabels:(resources  array:#(
                         'group radioButtons' 
-                        'group enterFields' 
+                        'group enterFields'
+                        '-'
+                        'delete undo history'
                        ) )
             selectors:#(
                         groupRadioButtons 
                         groupEnterFields
+                        nil
+                        undoDeleteAll
                        )
              receiver:workView.
 
@@ -1385,16 +1383,16 @@
 !
 
 openInterface 
-    |list panel topPane botPanel v 
-     leftPanel middlePanel rightPanel buttonPanel propSelector|
+    |list v topInset menuInset leftPanel middlePanel rightPanel buttonPanel propSelector|
 
     super initialize.
 
     self initChannels.
 
     whichProperty := SelectionInList new.
-    whichProperty list:#('dimension' 'colors' 'model' 'misc' 'attribute list').
-    whichProperty onChangeSend:#propertySelectionChanged to:self.
+"/    whichProperty list:#('dimension' 'colors' 'model' 'misc' 'attribute list').
+    whichProperty list:(UISpecification slices collect:[:slice | slice first asString]).
+    whichProperty onChangeSend:#showPropertyView to:self.
 
     workView :=self createCanvas.
 
@@ -1403,21 +1401,20 @@
     topView icon:(Image fromFile:'bitmaps/Builder.xbm' resolution:100).
     topView extent:(600 @ 400).
 
-    menu := PullDownMenu in:topView.
-
-    buttonPanel := self setupButtonPanelIn:topView below:menu.
-
-    leftPanel := View in:topView.
-    leftPanel origin:(0.0 @ 0.0) corner:0.3@1.0.
-    leftPanel topInset:menu height + buttonPanel height + View viewSpacing.
-
-    middlePanel := View in:topView.
-    middlePanel origin:(0.3 @ 0.0) corner:0.6@1.0.
-    middlePanel topInset:menu height + buttonPanel height + View viewSpacing.
-
-    rightPanel := View in:topView.
-    rightPanel origin:(0.6 @ 0.0) corner:1.0@1.0.
-    rightPanel topInset:menu height + buttonPanel height + View viewSpacing.
+    menu        := PullDownMenu in:topView.
+    buttonPanel := ButtonPanel in:topView.
+
+    menuInset := menu preferredExtent y.
+    topInset  := menuInset + buttonPanel preferredExtent y.
+
+    buttonPanel origin:0.0@menuInset corner:1.0@topInset.
+    buttonPanel receiver:workView.
+    leftPanel   := View origin:(0.0 @ 0.0) corner:0.3@1.0 in:topView.
+    leftPanel   topInset:topInset.
+    middlePanel := View origin:(0.3 @ 0.0) corner:0.6@1.0 in:topView.
+    middlePanel topInset:topInset.
+    rightPanel  := View origin:(0.6 @ 0.0) corner:1.0@1.0 in:topView.
+    rightPanel  topInset:topInset.
 
     v := HVScrollableView for:UIPainterTreeView miniScrollerH:true in:middlePanel.
     v origin:(0.0 @ 0.0) corner:(1.0 @ 1.0).
@@ -1432,33 +1429,11 @@
     propertyFrame origin:(0.0 @ 0.0) corner:1.0@1.0.
     propertyFrame topInset:propSelector height + View viewSpacing.
 
-"/    panel := VariableVerticalPanel in:topView.
-"/    panel origin:(0.0 @ 0.0) corner:0.5@1.0.
-"/    panel topInset:menu height + buttonPanel height + View viewSpacing.
-
-"/    topPane := View in:panel.
-"/    topPane origin:(0.0 @ 0.0) corner:(1.0 @ 0.5).
-"/    topPane borderWidth:0.
-
-"/    botPanel := VariableHorizontalPanel in:panel.
-"/    botPanel origin:(0.0 @ 0.5) corner:(1.0 @ 1.0).
-"/    botPanel borderWidth:0.
+    claus := View origin:(0.0 @ 0.0) corner:1.0@1.0 in:rightPanel.
+    claus := UIPropertyView in:claus receiver:workView.
 
     elementMenu := self createPaletteIn:leftPanel.
 
-"/    v := ScrollableView for:UIPainterTreeView in:botPanel.
-"/    v origin:(0.0 @ 0.0) corner:(0.5 @ 1.0).
-"/    treeView := v scrolledView.
-
-"/    v := ScrollableView for:SelectionInListView in:botPanel.
-"/    v origin:(0.5 @ 0.0) corner:(1.0 @ 1.0).
-"/    outletView := v scrolledView.
-"/    outletView action:[:lineNr | self selectOutlet:lineNr].
-
-"/    v := ScrollableView for:TextCollector in:topPane.
-"/    v origin:(0.0 @ 0.0) corner:(1.0 @ 1.0).
-"/    infoView := v scrolledView.
-
     treeView builderView:workView.  "link workview with treeview"
 
     workView addDependent:treeView.
@@ -1512,8 +1487,8 @@
 
     |specArray|
 
-    specClass := aClass.
-    specSuperclass := aClass superclass.
+    specClass := aClass name.
+    specSuperclass := aClass superclass name.
     specSelector :=  aSelector.
 
     self openInterface.
@@ -1528,68 +1503,105 @@
     |newBuilder|
 
     newBuilder := self new.
+! !
+
+!UIPainter methodsFor:'make layout'!
+
+makeLayout:what xOrY:xOrY offset:aBool
+    |view layout extent fraction offset fractSymb offsetSymb|
+
+    view := workView singleSelection.
+
+    view isNil ifTrue:[
+        ^ self
+    ].
+    layout := view geometryLayout.
+
+    layout isLayout ifFalse:[
+        ^ self
+    ].
+    fractSymb  := (what, 'Fraction') asSymbol.
+    offsetSymb := (what,   'Offset') asSymbol.
+
+    (    (layout respondsTo:fractSymb)
+     and:[layout respondsTo:offsetSymb]
+    ) ifTrue:[
+
+        fraction := layout perform:fractSymb.
+        offset   := layout perform:offsetSymb.
+        extent   := (view superView computeExtent) perform:xOrY.
+
+        aBool ifTrue:[
+            offset := offset + ((fraction * extent) asInteger).
+            (aspectHolders at:offsetSymb) value:offset.
+            (aspectHolders at:fractSymb)  value:0.
+        ] ifFalse:[
+            fraction   := (fraction + (offset / extent)) asFloat.
+
+            (fraction > 1.0) ifTrue:[ fraction := 1.0 ].
+            (fraction < 0.0) ifTrue:[ fraction := 0.0 ].
+
+            (aspectHolders at:offsetSymb) value:0.
+            (aspectHolders at:fractSymb)  value:fraction.
+        ]
+    ]
 !
 
-setupButtonPanelIn:aTopView below:aMenu
-    "create the buttonPanel
-    "
-    |spc mh buttonPanel pressAction|
-
-    spc := View viewSpacing // 2.
-    buttonPanel := HorizontalPanelView in:aTopView.
-    buttonPanel level:-1; borderWidth:0.
-    buttonPanel horizontalLayout:#leftSpace.
-
-    pressAction := [:aButton :aSelector|
-        |menu org top|
-
-        workView selection notNil ifTrue:[
-            top := aButton topView.
-
-            org := top origin + (aButton originRelativeTo:top) 
-                              + (0@((spc + aButton extent y))).
-
-            menu := PopUpMenu labels:#( '1' '2' '4' '10' '..' )
-                                args:#(  1   2   4   10   nil ).
-
-            menu action:[:anArg||no|
-                (no := anArg) isNil ifTrue:[
-                    no := EnterBox request:'number'.
-                    no := SmallInteger readFrom:no onError:0.
-                ].
-                no ~~ 0 ifTrue:[
-                    workView perform:aSelector with:no
-                ]
-            ].
-            menu showAt:org.
-        ].
-        aButton turnOff
-    ].
-
-    self buttonPanelSpec do:[:anArray| |selector image button|
-        selector := anArray at:1.
-
-        selector notNil ifTrue:[
-            image  := Image fromFile:( anArray at:2 ).
-            button := Button label:image in:buttonPanel.
-
-            selector last == $: ifFalse:[
-                button action:[ workView perform:selector ]
-            ] ifTrue:[
-                button pressAction:[ pressAction value:button value:selector ] 
-            ]
-        ] ifFalse:[|sep|
-            sep := View in:buttonPanel.
-            sep extent:20@1; borderWidth:0.
-        ]
-    ].
-
-    mh := aMenu height.
-    buttonPanel origin:0.0 @ (mh + spc)
-                corner:(1.0 @ (mh + spc + buttonPanel preferredExtent y)).
-
-    buttonPanel leftInset:spc; rightInset:spc.
-  ^ buttonPanel
+makeOffsetAll
+    self makeOffsetLeft.
+    self makeOffsetTop.
+    self makeOffsetRight.
+    self makeOffsetBottom.
+
+!
+
+makeOffsetBottom
+    self makeLayout:'bottom' xOrY:#y offset:true.
+
+!
+
+makeOffsetLeft
+    self makeLayout:'left' xOrY:#x offset:true.
+
+!
+
+makeOffsetRight
+    self makeLayout:'right' xOrY:#x offset:true.
+
+!
+
+makeOffsetTop
+    self makeLayout:'top' xOrY:#y offset:true.
+
+
+!
+
+makeRelativeAll
+    self makeRelativeLeft.
+    self makeRelativeTop.
+    self makeRelativeRight.
+    self makeRelativeBottom.
+
+!
+
+makeRelativeBottom
+    self makeLayout:'bottom' xOrY:#y offset:false.
+
+!
+
+makeRelativeLeft
+    self makeLayout:'left' xOrY:#x offset:false.
+
+!
+
+makeRelativeRight
+    self makeLayout:'right' xOrY:#x offset:false.
+
+!
+
+makeRelativeTop
+    self makeLayout:'top' xOrY:#y offset:false.
+
 ! !
 
 !UIPainter methodsFor:'misc'!
@@ -1769,12 +1781,33 @@
 !
 
 setupPropertyFromSpec:aSpec
+    "apply is pressed in the geometry-sub view, with a alignmentOrigin selected
+    "
+    |aViewsSpec|
+
+    workView singleSelectionDo:[:selectedView |
+        aViewsSpec := workView generateSpecFor:selectedView.
+        aViewsSpec := aViewsSpec first.
+    ].
+
+    self setupPropertyFromSpec:aSpec for:aViewsSpec
+
+!
+
+setupPropertyFromSpec:aSpec for:aViewsSpec
     "setup menu from spec
     "
+    |specBindings|
+
     outletView := nil.
 
     specShown ~= aSpec ifTrue:[
         propertyFrame destroySubViews.
+
+        "/ get aspects from specClass
+        specSpecificAspectHolders := IdentityDictionary new.
+        aViewsSpec class addBindingsTo:specSpecificAspectHolders for:aViewsSpec channel:nil.
+        
         builder buildFromSpec:aSpec in:propertyFrame.
         propertyFrame realizeAllSubViews.
     ].
@@ -1803,13 +1836,13 @@
 fetchColorsFrom:aView
     |holder|
 
-    holder := self aspectFor:#foregroundChannel.
+    holder := self aspectFor:#foregroundColor.
     (aView respondsTo:#foregroundColor) ifTrue:[
         holder value:(aView foregroundColor storeString).
     ] ifFalse:[
         holder value:nil
     ].
-    holder := self aspectFor:#backgroundChannel.
+    holder := self aspectFor:#backgroundColor.
     (aView respondsTo:#backgroundColor) ifTrue:[
         holder value:(aView backgroundColor storeString).
     ] ifFalse:[
@@ -1826,48 +1859,48 @@
 
     layout isLayout ifFalse:[
         layout isRectangle ifTrue:[
-            leftOffsetHolder   value:(layout left).
-            rightOffsetHolder  value:(layout right).
-            topOffsetHolder    value:(layout top).
-            bottomOffsetHolder value:(layout bottom).
-            ^ self
+            (aspectHolders at:#leftOffset)   value:(layout left).
+            (aspectHolders at:#rightOffset)  value:(layout right).
+            (aspectHolders at:#topOffset)    value:(layout top).
+            (aspectHolders at:#bottomOffset) value:(layout bottom).
+          ^ self
         ].
         layout isPoint ifTrue:[
-            leftOffsetHolder   value:(layout left).
-            rightOffsetHolder  value:(layout right).
-            ^ self
+            (aspectHolders at:#leftOffset)  value:(layout left).
+            (aspectHolders at:#rightOffset) value:(layout right).
+          ^ self
         ].
     ].
 
-    leftOffsetHolder   value:(layout leftOffset).
-    leftFractionHolder value:(layout leftFraction).
-    topFractionHolder  value:(layout topFraction).
-    topOffsetHolder    value:(layout topOffset).
+    (aspectHolders at:#leftOffset)   value:(layout leftOffset).
+    (aspectHolders at:#leftFraction) value:(layout leftFraction).
+    (aspectHolders at:#topOffset)    value:(layout topOffset).
+    (aspectHolders at:#topFraction)  value:(layout topFraction).
 
     layout isLayoutFrame ifTrue:[
-        rightOffsetHolder    value:(layout rightOffset).
-        bottomOffsetHolder   value:(layout bottomOffset).
-        rightFractionHolder  value:(layout rightFraction).
-        bottomFractionHolder value:(layout bottomFraction).
-
-        leftAlignmentFractionHolder value:0.
-        topAlignmentFractionHolder  value:0.
-
+        (aspectHolders at:#rightOffset)    value:(layout rightOffset).
+        (aspectHolders at:#bottomOffset)   value:(layout bottomOffset).
+
+        (aspectHolders at:#rightFraction)  value:(layout rightFraction).
+        (aspectHolders at:#bottomFraction) value:(layout bottomFraction).
+
+        (aspectHolders at:#leftAlignmentFraction) value:0.
+        (aspectHolders at:#topAlignmentFraction)  value:0.
     ] ifFalse:[
         extent := aView extent.
 
-        rightOffsetHolder    value:(layout leftOffset + extent x).
-        bottomOffsetHolder   value:(layout topOffset  + extent y).
-
-        rightFractionHolder  value:0.
-        bottomFractionHolder value:0.
+        (aspectHolders at:#rightOffset)    value:(layout leftOffset + extent x).
+        (aspectHolders at:#bottomOffset)   value:(layout topOffset  + extent y).
+
+        (aspectHolders at:#rightFraction)  value:0.
+        (aspectHolders at:#bottomFraction) value:0.
 
         layout isAlignmentOrigin ifTrue:[
-            leftAlignmentFractionHolder value:(layout leftAlignmentFraction).
-            topAlignmentFractionHolder  value:(layout topAlignmentFraction)
+            (aspectHolders at:#leftAlignmentFraction) value:(layout leftAlignmentFraction).
+            (aspectHolders at:#topAlignmentFraction)  value:(layout topAlignmentFraction).
         ] ifFalse:[
-            leftAlignmentFractionHolder value:0.
-            topAlignmentFractionHolder  value:0
+            (aspectHolders at:#leftAlignmentFraction) value:0.
+            (aspectHolders at:#topAlignmentFraction)  value:0.
         ]
     ].
 
@@ -1996,13 +2029,13 @@
     view notNil ifTrue:[
         layout := AlignmentOrigin new.
 
-        layout   leftOffset:(leftOffsetHolder   value) ? 0.
-        layout    topOffset:(topOffsetHolder    value) ? 0.
-        layout leftFraction:(leftFractionHolder value) ? 0.
-        layout  topFraction:(topFractionHolder  value) ? 0.
-
-        layout leftAlignmentFraction:(leftAlignmentFractionHolder value) ? 0.
-        layout  topAlignmentFraction:(topAlignmentFractionHolder  value) ? 0.
+        layout   leftOffset:((aspectHolders at:#leftOffset)   value) ? 0.
+        layout    topOffset:((aspectHolders at:#topOffset)    value) ? 0.
+        layout leftFraction:((aspectHolders at:#leftFraction) value) ? 0.
+        layout  topFraction:((aspectHolders at:#topFraction)  value) ? 0.
+
+        layout leftAlignmentFraction:((aspectHolders at:#leftAlignmentFraction) value) ? 0.
+        layout  topAlignmentFraction:((aspectHolders at:#topAlignmentFraction)  value) ? 0.
 
         workView setDimension:layout.
     ]
@@ -2016,14 +2049,14 @@
     view notNil ifTrue:[
         layout := LayoutFrame new.
 
-        layout leftOffset:(leftOffsetHolder value) ? 0.
-        layout rightOffset:(rightOffsetHolder value) ? 0.
-        layout topOffset:(topOffsetHolder value) ? 0.
-        layout bottomOffset:(bottomOffsetHolder value) ? 0.
-        layout leftFraction:(leftFractionHolder value) ? 0.
-        layout rightFraction:(rightFractionHolder value) ? 0.
-        layout topFraction:(topFractionHolder value) ? 0.
-        layout bottomFraction:(bottomFractionHolder value) ? 0.
+        layout leftOffset:((aspectHolders at:#leftOffset) value) ? 0.
+        layout rightOffset:((aspectHolders at:#rightOffset) value) ? 0.
+        layout topOffset:((aspectHolders at:#topOffset) value) ? 0.
+        layout bottomOffset:((aspectHolders at:#bottomOffset) value) ? 0.
+        layout leftFraction:((aspectHolders at:#leftFraction) value) ? 0.
+        layout rightFraction:((aspectHolders at:#rightFraction) value) ? 0.
+        layout topFraction:((aspectHolders at:#topFraction) value) ? 0.
+        layout bottomFraction:((aspectHolders at:#bottomFraction) value) ? 0.
 
         workView setDimension:layout.
     ]
@@ -2037,11 +2070,11 @@
     view notNil ifTrue:[
         layout := LayoutOrigin new.
 
-        layout leftOffset:(leftOffsetHolder value) ? 0.
-        layout topOffset:(topOffsetHolder value) ? 0.
-
-        layout leftFraction:(leftFractionHolder value) ? 0.
-        layout topFraction:(topFractionHolder value) ? 0.
+        layout leftOffset:((aspectHolders at:#leftOffset) value) ? 0.
+        layout topOffset:((aspectHolders at:#topOffset) value) ? 0.
+
+        layout leftFraction:((aspectHolders at:#leftFraction) value) ? 0.
+        layout topFraction:((aspectHolders at:#topFraction) value) ? 0.
 
         workView setDimension:layout.
     ]
@@ -2074,13 +2107,6 @@
     super closeRequestFor:aTopView
 !
 
-propertySelectionChanged
-    workView singleSelectionDo:[:selectedView |
-        propertyShown   := whichProperty selection.
-        self showPropertyView
-    ]
-!
-
 selectOutlet:nr
     |outlet type sel text box action initialText initialList
      view prop t val|
@@ -2388,14 +2414,16 @@
 setColors
     |fg bg|
 
-    fg := self foregroundChannel value.
+    fg := (self aspectFor:#foregroundColor) value.
+
     (fg notNil and:[fg notEmpty]) ifTrue:[
         fg := Color readFrom:fg.
         workView singleSelectionDo:[:selectedView |
             selectedView foregroundColor:fg
         ].
     ].
-    bg := self backgroundChannel value.
+    bg := (self aspectFor:#backgroundColor) value.
+
     (bg notNil and:[bg notEmpty]) ifTrue:[
         bg := Color readFrom:bg.
         workView singleSelectionDo:[:selectedView |
@@ -2496,10 +2524,38 @@
 !
 
 showPropertyView
-    |v l spec|
+    |v l spec shown possibleProperties slices specIndex slice specSymbol|
+
+    shown := whichProperty selection.
 
     workView singleSelectionDo:[:selectedView |
-        propertyShown = 'dimension' ifTrue:[
+        |aViewsSpec|
+
+        aViewsSpec := workView generateSpecFor:selectedView.
+        aViewsSpec := aViewsSpec first.
+
+        slices := selectedView specClass slices.
+        possibleProperties := slices collect:[:slice | slice first asString].
+        possibleProperties := possibleProperties, #('dimension' 'colors' 'model' 'misc' 'attribute list').
+        possibleProperties ~= whichProperty list ifTrue:[
+            whichProperty list:possibleProperties.
+
+            (possibleProperties includes:shown) ifFalse:[
+                shown := nil.
+            ].
+        ].
+
+        specIndex := slices findFirst:[:slice | slice first = shown].
+        specIndex ~~ 0 ifTrue:[
+            slice := slices at:specIndex.
+            specSymbol := slice at:2.
+            (selectedView specClass respondsTo:specSymbol) ifTrue:[
+                spec := selectedView specClass perform:specSymbol.
+                ^ self setupPropertyFromSpec:spec for:aViewsSpec
+            ]
+        ].
+
+        (shown = 'dimension' or:[shown = 'Position']) ifTrue:[
             (l := selectedView geometryLayout) notNil ifTrue:[
                 l isLayout ifTrue:[
                     l isAlignmentOrigin ifTrue:[
@@ -2514,24 +2570,26 @@
             spec isNil ifTrue:[
                 spec := self class geometrySpecForLayoutFrame
             ].
-            ^ self setupPropertyFromSpec:spec
+            ^ self setupPropertyFromSpec:spec for:aViewsSpec
         ].
 
-        propertyShown = 'colors' ifTrue:[
-            ^ self setupPropertyFromSpec:(self class colorSpec)
+        shown = 'colors' ifTrue:[
+            ^ self setupPropertyFromSpec:(self class colorSpec) for:aViewsSpec
         ].
 
-        propertyShown = 'model' ifTrue:[
-            ^ self setupPropertyFromSpec:(self class modelSpec)
+        shown = 'model' ifTrue:[
+            ^ self setupPropertyFromSpec:(self class modelSpec) for:aViewsSpec
         ].
 
-        propertyShown = 'misc' ifTrue:[
-            ^ self setupPropertyFromSpec:(self class miscSpec)
+        shown = 'misc' ifTrue:[
+            ^ self setupPropertyFromSpec:(self class miscSpec) for:aViewsSpec
         ].
 
-        propertyShown = 'attribute list' ifTrue:[
+        shown = 'attribute list' ifTrue:[
             specShown ~~ #attributeList ifTrue:[
                 propertyFrame destroySubViews.
+                specSpecificAspectHolders := IdentityDictionary new.
+
                 v := ScrollableView for:SelectionInListView in:propertyFrame.
                 v origin:(0.0 @ 0.0) corner:(1.0 @ 1.0).
                 outletView := v scrolledView.
@@ -2547,6 +2605,7 @@
     propertyFrame destroySubViews.
     outletView := nil.
     specShown := nil.
+    specSpecificAspectHolders := IdentityDictionary new.
 
 ! !
 
@@ -2557,7 +2616,14 @@
 
     |superclass cls|
 
-    (cls := Smalltalk at:specClass asSymbol) isNil ifTrue:[
+    specClass isNil ifTrue:[^ false].
+
+    specClass isBehavior ifFalse:[
+        cls := Smalltalk at:specClass asSymbol
+    ] ifTrue:[
+        cls := specClass
+    ].
+    cls isNil ifTrue:[
         (superclass := Smalltalk at:specSuperclass asSymbol) isNil ifTrue:[
             self warn:'no class named ' , specSuperclass , ' exists.'.
             ^ false.
@@ -2577,8 +2643,13 @@
         ^ false.
     ].
 
+    specSuperclass isBehavior ifFalse:[
+        superclass := Smalltalk at:specSuperclass asSymbol
+    ] ifTrue:[
+        superclass := specSuperclass
+    ].
     specSuperclass notNil ifTrue:[
-        (superclass := Smalltalk at:specSuperclass asSymbol) isNil ifTrue:[
+        superclass isNil ifTrue:[
             self warn:'no class named ' , specSuperclass , ' exists.'.
             ^ false.
         ].
@@ -2723,6 +2794,7 @@
     view isNil ifTrue:[^ self].
 
     spec := UISpecification fromView:view topView.
+    self halt.
 
     "/ ok, got it
     workView setupFromSpec:spec.
@@ -2803,6 +2875,115 @@
     workView testMode:t
 ! !
 
+!UIPainter::ButtonPanel methodsFor:'accessing'!
+
+receiver
+    ^ receiver
+!
+
+receiver:aReceiver
+    receiver := aReceiver
+! !
+
+!UIPainter::ButtonPanel methodsFor:'initialization'!
+
+initialize
+    "initialize and setup buttons
+    "
+    super initialize.
+
+    self level:-1.
+    self borderWidth:0.
+    self horizontalLayout:#leftSpace.
+    argumentToSelector := 1.
+
+    self specification do:[:anArray|
+        |selector image button seperator|
+
+        selector := anArray at:1.
+
+        selector notNil ifTrue:[
+            image  := Image fromFile:( anArray at:2 ).
+            button := Button label:image in:self.
+
+            selector last == $: ifFalse:[
+                button action:[
+                    receiver notNil ifTrue:[
+                        receiver perform:selector
+                    ]
+                ]
+            ] ifTrue:[
+                button pressAction:[
+                    receiver notNil ifTrue:[
+                        receiver perform:selector with:argumentToSelector
+                    ]
+                ].
+                button autoRepeat:true.
+                button menuHolder:self; menuMessage:#editMenu; menuPerformer:self.
+            ]
+        ] ifFalse:[
+            seperator := View in:self.
+            seperator extent:20@1.
+            seperator borderWidth:0.
+        ]
+    ].
+
+!
+
+specification
+    "return a spec for the buttons in the panel;
+     entries consists of selector and bitmap-filename.
+     nil selectors are taken as separators (see setupButtonPanel)"
+
+    ^ #(
+        #( alignSelectionLeft         'b_alignL.xbm'    )
+        #( alignSelectionRight        'b_alignR.xbm'    )
+        #( alignSelectionLeftAndRight 'b_alignLR.xbm'   )
+        #( nil )
+        #( alignSelectionTop          'b_alignT.xbm'    )
+        #( alignSelectionBottom       'b_alignB.xbm'    )
+        #( alignSelectionTopAndBottom 'b_alignTB.xbm'   )
+        #( nil )
+        #( alignSelectionCenterHor    'b_alignCH.xbm'   )
+        #( alignSelectionCenterVer    'b_alignCV.xbm'   )
+        #( nil )
+        #( moveSelectionLeft:         'b_moveLeft.xbm'  )
+        #( moveSelectionRight:        'b_moveRight.xbm' )
+        #( moveSelectionUp:           'b_moveUp.xbm'    )
+        #( moveSelectionDown:         'b_moveDown.xbm'  )
+       )
+
+
+! !
+
+!UIPainter::ButtonPanel methodsFor:'menu'!
+
+editMenu
+    "edit menu used by buttons using an argument for the receiver; the argumentToSelector
+    "
+    |menu|
+
+    menu := PopUpMenu labels:#( '1' '2' '4' '10' '20' '..' )
+                        args:#(  1   2   4   10   20  nil  ).
+
+    menu action:[:anArg||no|
+        (no := anArg) isNil ifTrue:[
+            no := EnterBox request:'number'.
+            no := SmallInteger readFrom:no onError:0.
+        ].
+        no ~~ 0 ifTrue:[
+            |index view|
+
+            view := (WindowGroup lastEventQuerySignal raise) view.
+            view := view menuPerformer.
+            argumentToSelector := no.
+            view pressAction value.
+            argumentToSelector := 1.
+        ]
+    ].
+    ^ menu
+! !
+
 !UIPainter class methodsFor:'documentation'!
 
 version
--- a/UIPainterTreeView.st	Fri Feb 21 20:33:18 1997 +0100
+++ b/UIPainterTreeView.st	Fri Feb 21 20:33:57 1997 +0100
@@ -54,7 +54,7 @@
 defaultMenuMessage   
     "This message is the default yo be sent to the menuHolder to get a menu
     "
-    ^ #editMenu
+    ^ #menu
 
 
 ! !
@@ -70,7 +70,7 @@
 indexOf:aString
     "returns the index of the string entry into my list
     "
-    ^ list findFirst:[:aName| aName withoutSeparators = aString ]
+    ^ list findFirst:[:aName| aName string withoutSeparators = aString ]
 
 
 ! !
@@ -84,12 +84,12 @@
 
     selection notNil ifTrue:[
         selection size == 1 ifTrue:[
-            sel := (list at:(selection first)) withoutSeparators
+            sel := (list at:(selection first)) string withoutSeparators
         ] ifFalse:[
             sel := OrderedCollection new.
             selection do:[:aNumber|
                 aNumber ~~ 1 ifTrue:[
-                    sel add:((list at:aNumber) withoutSeparators)
+                    sel add:((list at:aNumber) string withoutSeparators)
                 ]
             ]
         ]
@@ -98,14 +98,23 @@
 
 !
 
+selectionChangedFrom:oldSelection
+    "redraw master
+    "
+    self disableMaster:oldSelection.
+    super selectionChangedFrom:oldSelection
+
+!
+
 update:something
 
     (something == #tree or:[something == #widgetName]) ifTrue:[
         self updateTree
     ] ifFalse:[
-        something == #selection ifFalse:[
+        something ~~ #selection ifTrue:[
             ^ self
         ].
+        self disableMaster:selection.
         self setSelection:nil.
     ].
 
@@ -115,6 +124,16 @@
         idx := self indexOf:(builderView variableNameOf:aView).
 
         idx ~~ 0 ifTrue:[
+            selection isNil ifTrue:[
+                |m i|
+
+                m := list at:idx.
+                i := m indexOfNonSeparatorStartingAt:1.
+                i == 0 ifTrue:[ i := 1 ].
+                m := Text string:m.
+                m emphasizeFrom:i with:#(#bold #underline).
+                list at:idx put:m
+            ].
             self addToSelection:idx
         ]
     ].
@@ -138,15 +157,65 @@
 
 !UIPainterTreeView methodsFor:'menu & actions'!
 
-editMenu
+inspectProps
+    builderView inspectAttributes
+!
+
+inspectSpec
+    builderView inspectSpec
+!
+
+inspectView
+    builderView inspectSelection
+!
+
+menu
+    |menu noSel|
+
+    noSel := builderView numberOfSelections.
+
+    menu := PopUpMenu labels:(
+              resources array:#(
+                                'cut'
+                                'undo'
+                                '-'
+                                'misc'
+                               )
+                             )
+                  selectors:#(
+                                #cut
+                                #undo
+                                nil
+                                #misc
+                             )
+                    receiver:self.
+
+    noSel == 1 ifTrue:[ menu subMenuAt:#misc put:(self menuMisc)]
+              ifFalse:[ menu disable:#misc].
+
+    noSel == 0 ifTrue:[ menu disable:#cut]
+              ifFalse:[ menu actionAt:#cut put:[builderView deleteSelection]].
+
+    builderView hasUndos ifFalse:[ menu disable:#undo]
+                          ifTrue:[ menu actionAt:#undo put:[builderView undoLast]].
+
+
+
+  ^ menu
+
+
+!
+
+menuMisc
+
     |menu ispMenu|
 
-    menu := PopUpMenu labels:( resources array:#('inspect') )
-                   selectors:#( #inspect  )
+    menu := PopUpMenu labels:( resources array:#('inspect' 'ordering' 'remove layout' ) )
+                   selectors:#( #inspect #ordering #removeLayout )
                     receiver:self.
 
-    ispMenu := PopUpMenu labels:( resources array:#('view' 'property') )
-                      selectors:#( #inspectView  #inspectProps  )
+    ispMenu := PopUpMenu labels:( resources array:#('view' 'spec' 'property') )
+                      selectors:#( #inspectView  #inspectSpec #inspectProps  )
                        receiver:self.
 
     menu subMenuAt:#inspect put:ispMenu.
@@ -155,12 +224,85 @@
 
 !
 
-inspectProps
-    builderView inspectAttributes
+ordering
+    "change selected view to an index in its subview subviews collection
+    "
+    |myIdx view spView index names values|
+
+    view := builderView singleSelection.
+    view isNil ifTrue:[^ self].
+
+    spView := view superView.
+    names  := OrderedCollection new.
+    values := OrderedCollection new.
+    index  := 1.
+
+    spView allSubViewsDo:[:aView||props|
+        aView ~~ view ifTrue:[
+            props := builderView propertyOfView:aView.
+
+            props notNil ifTrue:[
+                names  add:(props name).
+                values add:index
+            ]
+        ] ifFalse:[
+            myIdx := index
+        ].
+        index := index + 1
+    ].
+
+    names isEmpty ifTrue:[
+        ^ self
+    ].
+
+    index := Dialog choose:'before name:' 
+                  fromList:names
+                    values:values
+                     lines:20
+                    cancel:[nil].
+
+    index isNil ifTrue:[
+        ^ self
+    ].
+    myIdx < index ifTrue:[
+        index := index - 1
+    ].
+    (spView changeSequenceOrderFor:view to:index) ifTrue:[
+        self update:#tree
+    ]
 !
 
-inspectView
-    builderView inspectSelection
+removeLayout
+    builderView selectionHiddenDo:[
+        builderView selectionDo:[:aView|
+            aView geometryLayout:nil.
+            aView superView sizeChanged:nil
+        ]
+    ].
+! !
+
+!UIPainterTreeView methodsFor:'redrawing'!
+
+disableMaster:aLineNrOrCollection
+    "find and redraw line from master as no master
+    "
+    |line|
+
+    aLineNrOrCollection notNil ifTrue:[
+        aLineNrOrCollection isCollection ifFalse:[
+            (line := list at:aLineNrOrCollection) isText ifTrue:[
+                list at:aLineNrOrCollection put:(line string).
+                self redrawLine:aLineNrOrCollection.
+            ]
+        ] ifTrue:[
+            aLineNrOrCollection do:[:aNumber|
+                (line := list at:aNumber) isText ifTrue:[
+                    list at:aNumber put:(line string).
+                  ^ self redrawLine:aNumber.
+                ]
+            ]
+        ]
+    ]
 ! !
 
 !UIPainterTreeView methodsFor:'update'!