UILayoutTool.st
changeset 1339 b989732e3610
parent 1334 36c1ee53aede
child 1343 7d97b214f2ac
--- a/UILayoutTool.st	Wed Feb 09 13:45:04 2000 +0100
+++ b/UILayoutTool.st	Wed Feb 09 16:46:09 2000 +0100
@@ -21,7 +21,14 @@
 	category:'Interface-UIPainter'
 !
 
-ApplicationModel subclass:#Extent
+ApplicationModel subclass:#Rectangle
+	instanceVariableNames:''
+	classVariableNames:''
+	poolDictionaries:''
+	privateIn:UILayoutTool
+!
+
+ApplicationModel subclass:#AlignmentOrigin
 	instanceVariableNames:''
 	classVariableNames:''
 	poolDictionaries:''
@@ -35,13 +42,6 @@
 	privateIn:UILayoutTool
 !
 
-ApplicationModel subclass:#AlignmentOrigin
-	instanceVariableNames:''
-	classVariableNames:''
-	poolDictionaries:''
-	privateIn:UILayoutTool
-!
-
 ApplicationModel subclass:#Point
 	instanceVariableNames:''
 	classVariableNames:''
@@ -56,7 +56,7 @@
 	privateIn:UILayoutTool
 !
 
-ApplicationModel subclass:#Rectangle
+ApplicationModel subclass:#Extent
 	instanceVariableNames:''
 	classVariableNames:''
 	poolDictionaries:''
@@ -137,16 +137,22 @@
 'Relative origin x of the selected widget.'
 
 #makeLeftAbsolute
-'Computes current left offset and relative origin x to an absolute origin x.'
+'Compute pure-absolute x'
 
 #makeLeftRelative
-'Compute current relative origin x and offset of the left edge to a relative origin x.'
+'Compute pure-fraction x.'
+
+#makeLeftRelativeFromRight
+'Compute fraction+offset for x relative to containers right.'
 
 #makeTopAbsolute
-'Computes current top offset and relative origin y to an absolute origin y.'
+'Compute pure-absolute y.'
 
 #makeTopRelative
-'Computes current relative origin y and offset of the top edge to a relative origin y.'
+'Computes pure-fractional y.'
+
+#makeTopRelativeFromBottom
+'Compute fraction+offset for y relative to containers bottom.'
 
 #originX
 'Absolute origin x of the selected widget.'
@@ -188,7 +194,7 @@
           #name: 'UILayoutTool'
           #min: #(#Point 10 10)
           #max: #(#Point 1152 900)
-          #bounds: #(#Rectangle 506 24 851 206)
+          #bounds: #(#Rectangle 37 37 382 219)
         )
         #component: 
        #(#SpecCollection
@@ -204,25 +210,29 @@
                  #(#LabelSpec
                     #label: 'Relative:'
                     #name: 'labelRelative'
-                    #layout: #(#Point 87 6)
+                    #layout: #(#Point 103 6)
                   )
                  #(#LabelSpec
                     #label: 'Offset:'
                     #name: 'labelAbsolute'
-                    #layout: #(#Point 187 6)
+                    #layout: #(#Point 203 6)
                   )
                  #(#LabelSpec
                     #label: 'Left:'
                     #name: 'labelLeft'
-                    #layout: #(#AlignmentOrigin 85 0 27 0 1 0)
+                    #layout: #(#AlignmentOrigin 68 0 27 0 1 0)
+                  )
+                 #(#ActionButtonSpec
+                    #label: '>'
+                    #name: 'actionRelativeLeft'
+                    #layout: #(#LayoutFrame 77 0 24 0 99 0 46 0)
+                    #activeHelpKey: #makeLeftRelative
+                    #tabable: true
+                    #model: #relativeLeft
                   )
                  #(#InputFieldSpec
-                    #attributes: 
-                   #(#tabable
-                      true
-                    )
                     #name: 'fieldLeftFraction'
-                    #layout: #(#LayoutFrame 87 0 24 0 137 0 46 0)
+                    #layout: #(#LayoutFrame 103 0 24 0 153 0 46 0)
                     #activeHelpKey: #leftRelative
                     #tabable: true
                     #model: #leftFraction
@@ -233,23 +243,16 @@
                     #acceptOnPointerLeave: false
                   )
                  #(#ActionButtonSpec
-                    #attributes: 
-                   #(#tabable
-                      true
-                    )
-                    #name: 'actionRelativeLeft'
-                    #layout: #(#LayoutFrame 142 0 24 0 164 0 46 0)
-                    #activeHelpKey: #makeLeftRelative
+                    #label: '<'
+                    #name: 'actionRightRelativeLeft'
+                    #layout: #(#LayoutFrame 158 0 24 0 180 0 46 0)
+                    #activeHelpKey: #makeLeftRelativeFromRight
                     #tabable: true
-                    #model: #relativeLeft
+                    #model: #rightRelativeLeft
                   )
                  #(#InputFieldSpec
-                    #attributes: 
-                   #(#tabable
-                      true
-                    )
                     #name: 'fieldLeftOffset'
-                    #layout: #(#LayoutFrame 187 0 24 0 237 0 46 0)
+                    #layout: #(#LayoutFrame 203 0 24 0 253 0 46 0)
                     #activeHelpKey: #leftAbsolute
                     #tabable: true
                     #model: #leftOffset
@@ -260,12 +263,9 @@
                     #acceptOnPointerLeave: false
                   )
                  #(#ActionButtonSpec
-                    #attributes: 
-                   #(#tabable
-                      true
-                    )
+                    #label: '>'
                     #name: 'actionAbsoluteLeft'
-                    #layout: #(#LayoutFrame 242 0 24 0 264 0 46 0)
+                    #layout: #(#LayoutFrame 258 0 24 0 280 0 46 0)
                     #activeHelpKey: #makeLeftAbsolute
                     #tabable: true
                     #model: #absoluteLeft
@@ -273,15 +273,19 @@
                  #(#LabelSpec
                     #label: 'Top:'
                     #name: 'labelTop'
-                    #layout: #(#AlignmentOrigin 85 0 54 0 1 0)
+                    #layout: #(#AlignmentOrigin 68 0 54 0 1 0)
+                  )
+                 #(#ActionButtonSpec
+                    #label: 'v'
+                    #name: 'actionRelativeTop'
+                    #layout: #(#LayoutFrame 77 0 51 0 99 0 73 0)
+                    #activeHelpKey: #makeTopRelative
+                    #tabable: true
+                    #model: #relativeTop
                   )
                  #(#InputFieldSpec
-                    #attributes: 
-                   #(#tabable
-                      true
-                    )
                     #name: 'fieldTopFraction'
-                    #layout: #(#LayoutFrame 87 0 51 0 137 0 73 0)
+                    #layout: #(#LayoutFrame 103 0 51 0 153 0 73 0)
                     #activeHelpKey: #topRelative
                     #tabable: true
                     #model: #topFraction
@@ -292,23 +296,16 @@
                     #acceptOnPointerLeave: false
                   )
                  #(#ActionButtonSpec
-                    #attributes: 
-                   #(#tabable
-                      true
-                    )
-                    #name: 'actionRelativeTop'
-                    #layout: #(#LayoutFrame 142 0 51 0 164 0 73 0)
-                    #activeHelpKey: #makeTopRelative
+                    #label: '^'
+                    #name: 'actionBottomRelativeTop'
+                    #layout: #(#LayoutFrame 158 0 51 0 180 0 73 0)
+                    #activeHelpKey: #makeTopRelativeFromBottom
                     #tabable: true
-                    #model: #relativeTop
+                    #model: #bottomRelativeTop
                   )
                  #(#InputFieldSpec
-                    #attributes: 
-                   #(#tabable
-                      true
-                    )
                     #name: 'fieldTopOffset'
-                    #layout: #(#LayoutFrame 187 0 51 0 237 0 73 0)
+                    #layout: #(#LayoutFrame 203 0 51 0 253 0 73 0)
                     #activeHelpKey: #topAbsolute
                     #tabable: true
                     #model: #topOffset
@@ -319,12 +316,9 @@
                     #acceptOnPointerLeave: false
                   )
                  #(#ActionButtonSpec
-                    #attributes: 
-                   #(#tabable
-                      true
-                    )
+                    #label: 'v'
                     #name: 'actionAbsoluteTop'
-                    #layout: #(#LayoutFrame 242 0 51 0 264 0 73 0)
+                    #layout: #(#LayoutFrame 258 0 51 0 280 0 73 0)
                     #activeHelpKey: #makeTopAbsolute
                     #tabable: true
                     #model: #absoluteTop
@@ -653,7 +647,75 @@
 !UILayoutTool methodsFor:'converting absolute'!
 
 absolute:what xOrY:xOrY
-    |extent fraction offset fractSymb offsetSymb fractHolder offsetHolder|
+    "compute what as absolute (i.e. fraction=0, offset >= 0)"
+
+    |extent fraction offset fractSymb offsetSymb 
+     newOffset newFraction fractHolder offsetHolder|
+
+    extent     := (self layoutView superView computeExtent) perform:xOrY.
+    fractSymb  := (what, 'Fraction') asSymbol.
+    offsetSymb := (what,   'Offset') asSymbol.
+    fractHolder := (self aspectFor:fractSymb).
+    offsetHolder := (self aspectFor:offsetSymb).
+    fraction   := fractHolder  value.
+    offset     := offsetHolder value.
+
+    newOffset := offset + ((fraction * extent) asInteger).
+    newFraction := 0.
+
+    offsetHolder value:offset.
+    fractHolder  value:newFraction.
+!
+
+absoluteBottom
+    "compute bottom as absolute (i.e. fraction=0, offset >= 0)"
+
+    self absolute:'bottom' xOrY:#y
+
+!
+
+absoluteLeft
+    "compute left as absolute (i.e. fraction=0, offset >= 0)"
+
+    self absolute:'left' xOrY:#x
+
+!
+
+absoluteRight
+    "compute right as absolute (i.e. fraction=0, offset >= 0)"
+
+    self absolute:'right' xOrY:#x
+
+!
+
+absoluteTop
+    "compute top as absolute (i.e. fraction=0, offset >= 0)"
+
+    self absolute:'top' xOrY:#y
+
+! !
+
+!UILayoutTool methodsFor:'converting absolute from corner'!
+
+bottomRelativeBottom
+    "compute bottom relative to containers bottom (fraction=1, offset negative)"
+
+    self cornerRelative:'bottom' xOrY:#y
+
+!
+
+bottomRelativeTop
+    "compute top relative to containers bottom (fraction=1, offset negative)"
+
+    self cornerRelative:'top' xOrY:#y
+
+!
+
+cornerRelative:what xOrY:xOrY
+    "compute what relative to the corner (i.e. fraction=1, offset negative)"
+
+    |extent fraction offset fractSymb offsetSymb 
+     newFraction newOffset fractHolder offsetHolder|
 
     extent     := (self layoutView superView computeExtent) perform:xOrY.
     fractSymb  := (what, 'Fraction') asSymbol.
@@ -662,39 +724,40 @@
     offsetHolder := (self aspectFor:offsetSymb).
     fraction   := fractHolder  value.
     offset     := offsetHolder value.
-    offset     := offset + ((fraction * extent) asInteger).
-
-    offsetHolder value:offset.
-    fractHolder  value:0.
+
+    newOffset := offset + ((fraction * extent) asInteger).
+    newOffset := newOffset - extent.
+    newFraction := 1.
+
+    fractHolder  value:newFraction.
+    offsetHolder value:newOffset.
 
 
 
 !
 
-absoluteBottom
-    self absolute:'bottom' xOrY:#y
-
-!
-
-absoluteLeft
-    self absolute:'left' xOrY:#x
+rightRelativeLeft
+    "compute left relative to containers right (fraction=1, offset negative)"
+
+    self cornerRelative:'left' xOrY:#x
 
 !
 
-absoluteRight
-    self absolute:'right' xOrY:#x
-
-!
-
-absoluteTop
-    self absolute:'top' xOrY:#y
+rightRelativeRight
+    "compute right relative to containers right (fraction=1, offset negative)"
+
+    self cornerRelative:'right' xOrY:#x
 
 ! !
 
 !UILayoutTool methodsFor:'converting relative'!
 
 relative:what xOrY:xOrY
-    |extent fraction offset fractSymb offsetSymb fractHolder offsetHolder|
+    "compute what relative to the origin (i.e. fraction=0..1, offset 0)"
+
+    |extent fraction offset fractSymb offsetSymb 
+     newFraction newOffset
+     fractHolder offsetHolder|
 
     extent     := (self layoutView superView computeExtent) perform:xOrY.
     fractSymb  := (what, 'Fraction') asSymbol.
@@ -703,35 +766,45 @@
     offsetHolder := (self aspectFor:offsetSymb).
     fraction   := fractHolder  value.
     offset     := offsetHolder value.
-    fraction   := (fraction + (offset / extent)) asFloat.
-
-    (fraction > 1.0) ifTrue:[ fraction := 1.0 ].
-    (fraction < 0.0) ifTrue:[ fraction := 0 ].
-
-    offsetHolder value:0.
-    fractHolder  value:fraction.
+
+    newFraction   := (fraction + (offset / extent)) asFloat.
+    newOffset := 0.
+
+    (newFraction > 1.0) ifTrue:[newFraction := 1.0].
+    (newFraction < 0.0) ifTrue:[newFraction := 0].
+
+    offsetHolder value:newOffset.
+    fractHolder  value:newFraction.
 
 
 
 !
 
 relativeBottom
+    "compute bottom relative to the origin (i.e. fraction=0..1, offset 0)"
+
     self relative:'bottom' xOrY:#y
 
 
 !
 
 relativeLeft
+    "compute left relative to the origin (i.e. fraction=0..1, offset 0)"
+
     self relative:'left' xOrY:#x
 
 !
 
 relativeRight
+    "compute right relative to the origin (i.e. fraction=0..1, offset 0)"
+
     self relative:'right' xOrY:#x
 
 !
 
 relativeTop
+    "compute top relative to the origin (i.e. fraction=0..1, offset 0)"
+
     self relative:'top' xOrY:#y
 
 ! !
@@ -834,33 +907,7 @@
     "Modified: / 4.2.2000 / 22:31:41 / cg"
 ! !
 
-!UILayoutTool::Extent class methodsFor:'help specs'!
-
-helpSpec
-    "This resource specification was automatically generated
-     by the UIHelpTool of ST/X."
-
-    "Do not manually edit this!! If it is corrupted,
-     the UIHelpTool may not be able to read the specification."
-
-    "
-     UIHelpTool openOnClass:UILayoutTool::Extent    
-    "
-
-    <resource: #help>
-
-    ^super helpSpec addPairsFrom:#(
-
-#hrzExtent
-'Horizontal extent of the selected widget.'
-
-#vrtExtent
-'Vertical extent of the selected widget.'
-
-)
-! !
-
-!UILayoutTool::Extent class methodsFor:'interface specs'!
+!UILayoutTool::Rectangle class methodsFor:'interface specs'!
 
 windowSpec
     "This resource specification was automatically generated
@@ -870,142 +917,9 @@
      the UIPainter may not be able to read the specification."
 
     "
-     UIPainter new openOnClass:UILayoutTool::Extent andSelector:#windowSpec
-     UILayoutTool::Extent new openInterface:#windowSpec
-     UILayoutTool::Extent open
-    "
-
-    <resource: #canvas>
-
-    ^ 
-     #(#FullSpec
-        #name: #windowSpec
-        #window: 
-       #(#WindowSpec
-          #label: 'UILayoutTool-Extent'
-          #name: 'UILayoutTool-Extent'
-          #min: #(#Point 10 10)
-          #max: #(#Point 1152 900)
-          #bounds: #(#Rectangle 506 24 832 173)
-        )
-        #component: 
-       #(#SpecCollection
-          #collection: #(
-           #(#FramedBoxSpec
-              #label: 'Extent'
-              #name: 'FramedBox'
-              #layout: #(#LayoutFrame 0 0.0 6 0.0 0 1.0 137 0)
-              #labelPosition: #topLeft
-              #component: 
-             #(#SpecCollection
-                #collection: #(
-                 #(#LabelSpec
-                    #label: 'Width:'
-                    #name: 'labelWidth'
-                    #layout: #(#AlignmentOrigin 89 0 24 0 1 0.5)
-                    #adjust: #right
-                  )
-                 #(#InputFieldSpec
-                    #attributes: 
-                   #(#tabable
-                      true
-                    )
-                    #name: 'fieldLeftOffset'
-                    #layout: #(#LayoutFrame 90 0 13 0 140 0 35 0)
-                    #activeHelpKey: #hrzExtent
-                    #enableChannel: #notUsingDefaultExtent
-                    #tabable: true
-                    #model: #leftOffset
-                    #group: #inputGroup
-                    #type: #numberOrNil
-                    #acceptOnLostFocus: true
-                    #acceptChannel: #acceptChannel
-                    #modifiedChannel: #modifiedChannel
-                    #acceptOnPointerLeave: false
-                  )
-                 #(#LabelSpec
-                    #label: 'Height:'
-                    #name: 'labelHeight'
-                    #layout: #(#AlignmentOrigin 89 0 49 0 1 0.5)
-                    #adjust: #right
-                  )
-                 #(#InputFieldSpec
-                    #attributes: 
-                   #(#tabable
-                      true
-                    )
-                    #name: 'fieldRightOffset'
-                    #layout: #(#LayoutFrame 90 0 38 0 140 0 60 0)
-                    #activeHelpKey: #vrtExtent
-                    #enableChannel: #notUsingDefaultExtent
-                    #tabable: true
-                    #model: #rightOffset
-                    #group: #inputGroup
-                    #type: #numberOrNil
-                    #acceptOnLostFocus: true
-                    #acceptChannel: #acceptChannel
-                    #modifiedChannel: #modifiedChannel
-                    #acceptOnPointerLeave: false
-                  )
-                 #(#CheckBoxSpec
-                    #attributes: 
-                   #(#tabable
-                      true
-                    )
-                    #label: 'Use Widgets Default Extent'
-                    #name: 'useDefaultExtentCheckBox'
-                    #layout: #(#Point 5 74)
-                    #enableChannel: #defaultExtentEnabled
-                    #tabable: true
-                    #model: #useDefaultExtent
-                    #translateLabel: true
-                  )
-                 )
-               
-              )
-            )
-           )
-         
-        )
-      )
-! !
-
-!UILayoutTool::Extent methodsFor:'accessing'!
-
-fetch:aView spec:aSpec
-    "fetch extent
-    "
-    |extent|
-
-    extent  := aView computeExtent.
-
-    (self aspectFor:#leftOffset)  value:(extent x).
-    (self aspectFor:#rightOffset) value:(extent y).
-
-    (self aspectFor:#useDefaultExtent) value:aSpec useDefaultExtent 
-!
-
-layout
-    "returns current extent
-    "
-  ^ Smalltalk::Point x:(((self aspectFor:#leftOffset)   value) ? 0)
-                     y:(((self aspectFor:#rightOffset)  value) ? 0)
-
-! !
-
-!UILayoutTool::LayoutOrigin class methodsFor:'interface specs'!
-
-windowSpec
-    "This resource specification was automatically generated
-     by the UIPainter of ST/X."
-
-    "Do not manually edit this!! If it is corrupted,
-     the UIPainter may not be able to read the specification."
-
-    "
-     UIPainter new openOnClass:UILayoutTool::LayoutOrigin andSelector:#windowSpec
-     UILayoutTool::LayoutOrigin new openInterface:#windowSpec
-     UILayoutTool::LayoutOrigin open
+     UIPainter new openOnClass:UILayoutTool::Rectangle andSelector:#windowSpec
+     UILayoutTool::Rectangle new openInterface:#windowSpec
+     UILayoutTool::Rectangle open
     "
 
     <resource: #canvas>
@@ -1015,12 +929,12 @@
        #(#FullSpec
           #window: 
            #(#WindowSpec
-              #name: 'UILayoutTool-LayoutOrigin'
-              #layout: #(#LayoutFrame 290 0 420 0 647 0 565 0)
-              #label: 'UILayoutTool-LayoutOrigin'
+              #name: 'UILayoutTool-Rectangle'
+              #layout: #(#LayoutFrame 291 0 130 0 632 0 328 0)
+              #label: 'UILayoutTool-Rectangle'
               #min: #(#Point 10 10)
               #max: #(#Point 1152 900)
-              #bounds: #(#Rectangle 290 420 648 566)
+              #bounds: #(#Rectangle 291 130 633 329)
               #usePreferredExtent: false
           )
           #component: 
@@ -1028,46 +942,92 @@
               #collection: 
                #(
                  #(#UISubSpecification
-                    #name: 'layoutOriginSpec'
-                    #layout: #(#LayoutFrame 1 0.0 6 0 0 1.0 110 0)
+                    #name: 'subSpecification'
+                    #layout: #(#LayoutFrame 1 0.0 6 0 0 1.0 96 0)
                     #majorKey: #UILayoutTool
-                    #minorKey: #layoutOriginSpec
+                    #minorKey: #layoutPointSpec
+                )
+                 #(#FramedBoxSpec
+                    #name: 'FramedBox'
+                    #layout: #(#LayoutFrame 1 0.0 99 0 0 1.0 194 0)
+                    #component: 
+                     #(#SpecCollection
+                        #collection: 
+                         #(
+                           #(#LabelSpec
+                              #name: 'labelCornerY'
+                              #layout: #(#AlignmentOrigin 83 0 16 0 1 0)
+                              #label: 'Right:'
+                              #adjust: #left
+                          )
+                           #(#InputFieldSpec
+                              #name: 'fieldCornerX'
+                              #layout: #(#LayoutFrame 85 0 13 0 135 0 35 0)
+                              #activeHelpKey: #cornerX
+                              #tabable: true
+                              #model: #rightOffset
+                              #group: #inputGroup
+                              #type: #numberOrNil
+                              #acceptOnLostFocus: true
+                    #acceptChannel: #acceptChannel
+                    #modifiedChannel: #modifiedChannel
+                          )
+                           #(#LabelSpec
+                              #name: 'labelCornerX'
+                              #layout: #(#AlignmentOrigin 83 0 41 0 1 0)
+                              #label: 'Bottom:'
+                              #adjust: #left
+                          )
+                           #(#InputFieldSpec
+                              #name: 'fieldCornerY'
+                              #layout: #(#LayoutFrame 85 0 38 0 135 0 60 0)
+                              #activeHelpKey: #cornerY
+                              #tabable: true
+                              #model: #bottomOffset
+                              #group: #inputGroup
+                              #type: #numberOrNil
+                              #acceptOnLostFocus: true
+                    #acceptChannel: #acceptChannel
+                    #modifiedChannel: #modifiedChannel
+                          )
+                        )
+                    )
+                    #label: 'Corner'
+                    #labelPosition: #topLeft
                 )
               )
           )
       )
+
+    "Modified: / 13.8.1998 / 19:59:16 / cg"
 ! !
 
-!UILayoutTool::LayoutOrigin methodsFor:'accessing'!
+!UILayoutTool::Rectangle methodsFor:'accessing'!
 
 fetch:aView spec:aSpec
-    "fetch layoutOrigin
+    "fetch rectangle
     "
-    |layout|
-
-    layout  := UIPainterView asLayoutFrameFromView:aView.
-
-    (self aspectFor:#leftOffset)   value:(layout leftOffset).
-    (self aspectFor:#leftFraction) value:(layout leftFraction).
-    (self aspectFor:#topOffset)    value:(layout topOffset).
-    (self aspectFor:#topFraction)  value:(layout topFraction).
+    |origin corner|
+
+    origin := aView computeOrigin.
+    corner := aView computeCorner.
+
+    (self aspectFor:#leftOffset)   value:(origin x).
+    (self aspectFor:#rightOffset)  value:(corner x).
+    (self aspectFor:#topOffset)    value:(origin y).
+    (self aspectFor:#bottomOffset) value:(corner y).
 
 
 !
 
 layout
-    "returns current layout as layoutOrigin
+    "returns current layout as rectangle
     "
-    |layout|
-
-    layout  := Smalltalk::LayoutOrigin new.
-
-    layout   leftOffset:((self aspectFor:#leftOffset)   value) ? 0.
-    layout    topOffset:((self aspectFor:#topOffset)    value) ? 0.
-    layout leftFraction:((self aspectFor:#leftFraction) value) ? 0.
-    layout  topFraction:((self aspectFor:#topFraction)  value) ? 0.
-
-  ^ layout
+  ^ Smalltalk::Rectangle left:(((self aspectFor:#leftOffset)   value) ? 0)
+                          top:(((self aspectFor:#topOffset)    value) ? 0)
+                        right:(((self aspectFor:#rightOffset)  value) ? 0)
+                       bottom:(((self aspectFor:#bottomOffset) value) ? 0)
+
 
 ! !
 
@@ -1487,6 +1447,84 @@
 
 ! !
 
+!UILayoutTool::LayoutOrigin class methodsFor:'interface specs'!
+
+windowSpec
+    "This resource specification was automatically generated
+     by the UIPainter of ST/X."
+
+    "Do not manually edit this!! If it is corrupted,
+     the UIPainter may not be able to read the specification."
+
+    "
+     UIPainter new openOnClass:UILayoutTool::LayoutOrigin andSelector:#windowSpec
+     UILayoutTool::LayoutOrigin new openInterface:#windowSpec
+     UILayoutTool::LayoutOrigin open
+    "
+
+    <resource: #canvas>
+
+    ^
+     
+       #(#FullSpec
+          #window: 
+           #(#WindowSpec
+              #name: 'UILayoutTool-LayoutOrigin'
+              #layout: #(#LayoutFrame 290 0 420 0 647 0 565 0)
+              #label: 'UILayoutTool-LayoutOrigin'
+              #min: #(#Point 10 10)
+              #max: #(#Point 1152 900)
+              #bounds: #(#Rectangle 290 420 648 566)
+              #usePreferredExtent: false
+          )
+          #component: 
+           #(#SpecCollection
+              #collection: 
+               #(
+                 #(#UISubSpecification
+                    #name: 'layoutOriginSpec'
+                    #layout: #(#LayoutFrame 1 0.0 6 0 0 1.0 110 0)
+                    #majorKey: #UILayoutTool
+                    #minorKey: #layoutOriginSpec
+                )
+              )
+          )
+      )
+! !
+
+!UILayoutTool::LayoutOrigin methodsFor:'accessing'!
+
+fetch:aView spec:aSpec
+    "fetch layoutOrigin
+    "
+    |layout|
+
+    layout  := UIPainterView asLayoutFrameFromView:aView.
+
+    (self aspectFor:#leftOffset)   value:(layout leftOffset).
+    (self aspectFor:#leftFraction) value:(layout leftFraction).
+    (self aspectFor:#topOffset)    value:(layout topOffset).
+    (self aspectFor:#topFraction)  value:(layout topFraction).
+
+
+!
+
+layout
+    "returns current layout as layoutOrigin
+    "
+    |layout|
+
+    layout  := Smalltalk::LayoutOrigin new.
+
+    layout   leftOffset:((self aspectFor:#leftOffset)   value) ? 0.
+    layout    topOffset:((self aspectFor:#topOffset)    value) ? 0.
+    layout leftFraction:((self aspectFor:#leftFraction) value) ? 0.
+    layout  topFraction:((self aspectFor:#topFraction)  value) ? 0.
+
+  ^ layout
+
+! !
+
 !UILayoutTool::Point class methodsFor:'interface specs'!
 
 windowSpec
@@ -1581,23 +1619,35 @@
 #bottomHalfLayout
 'Set the layout for the bottom half of the widgets containers space'
 
+#bottomLeftQuarterLayout
+'Set the layout for the bottom-left quarter of the widgets containers space'
+
 #bottomRelative
 'Relative corner y of the selected widget.'
 
+#bottomRightQuarterLayout
+'Set the layout for the bottom-right quarter of the widgets containers space'
+
 #leftHalfLayout
 'Set the layout for the left half of the widgets containers space'
 
 #makeBottomAbsolute
-'Computes current bottom offset and relative corner y to an absolute corner y.'
+'Compute pure-absolute y.'
 
 #makeBottomRelative
-'Computes current relative corner y and offset of the bottom edge to a relative corner y.'
+'Computes pure-fractional y.'
+
+#makeBottomRelativeFromBottom
+'Compute fraction+offset for y relative to containers bottom.'
 
 #makeRightAbsolute
-'Computes current right offset and relative corner x to an absolute corner x.'
+'Compute pure-absolute x.'
 
 #makeRightRelative
-'Computes current relative corner x and offset of the right edge to a relative corner x.'
+'Compute pure-fraction x.'
+
+#makeRightRelativeFromRight
+'Compute fraction+offset for x relative to containers right.'
 
 #rightAbsolute
 'Offset of the right edge; positive is to the right, negative to the left.'
@@ -1620,12 +1670,6 @@
 #topRightQuarterLayout
 'Set the layout for the top-right quarter of the widgets containers space'
 
-#bottomRightQuarterLayout
-'Set the layout for the bottom-right quarter of the widgets containers space'
-
-#bottomLeftQuarterLayout
-'Set the layout for the bottom-left quarter of the widgets containers space'
-
 )
 ! !
 
@@ -1837,7 +1881,7 @@
           #name: 'UILayoutTool-LayoutFrame'
           #min: #(#Point 10 10)
           #max: #(#Point 1152 900)
-          #bounds: #(#Rectangle 12 22 411 325)
+          #bounds: #(#Rectangle 12 36 411 339)
           #forceRecursiveBackground: false
         )
         #component: 
@@ -1860,16 +1904,19 @@
                  #(#LabelSpec
                     #label: 'Right:'
                     #name: 'labelRight'
-                    #layout: #(#AlignmentOrigin 88 0 25 0 1 0.5)
+                    #layout: #(#AlignmentOrigin 68 0 25 0 1 0.5)
+                  )
+                 #(#ActionButtonSpec
+                    #label: '>'
+                    #name: 'actionRelativeRight'
+                    #layout: #(#LayoutFrame 78 0 14 0 100 0 36 0)
+                    #activeHelpKey: #makeRightRelative
+                    #tabable: true
+                    #model: #relativeRight
                   )
                  #(#InputFieldSpec
-                    #attributes: 
-                   #(#fieldRightFraction
-                      nil #tabable
-                      true
-                    )
                     #name: 'fieldRightFraction'
-                    #layout: #(#LayoutFrame 90 0 14 0 140 0 36 0)
+                    #layout: #(#LayoutFrame 103 0 14 0 153 0 36 0)
                     #activeHelpKey: #rightRelative
                     #tabable: true
                     #model: #rightFraction
@@ -1881,24 +1928,16 @@
                     #acceptOnPointerLeave: false
                   )
                  #(#ActionButtonSpec
-                    #attributes: 
-                   #(#tabable
-                      true
-                    )
-                    #name: 'actionRelativeRight'
-                    #layout: #(#LayoutFrame 145 0 14 0 167 0 36 0)
-                    #activeHelpKey: #makeRightRelative
+                    #label: '<'
+                    #name: 'actionRightRelativeRight'
+                    #layout: #(#LayoutFrame 158 0 14 0 180 0 36 0)
+                    #activeHelpKey: #makeRightRelativeFromRight
                     #tabable: true
-                    #model: #relativeRight
+                    #model: #rightRelativeRight
                   )
                  #(#InputFieldSpec
-                    #attributes: 
-                   #(#fieldRightOffset
-                      nil #tabable
-                      true
-                    )
                     #name: 'fieldRightOffset'
-                    #layout: #(#LayoutFrame 190 0 14 0 240 0 36 0)
+                    #layout: #(#LayoutFrame 203 0 14 0 253 0 36 0)
                     #activeHelpKey: #rightAbsolute
                     #tabable: true
                     #model: #rightOffset
@@ -1910,12 +1949,9 @@
                     #acceptOnPointerLeave: false
                   )
                  #(#ActionButtonSpec
-                    #attributes: 
-                   #(#tabable
-                      true
-                    )
+                    #label: '>'
                     #name: 'actionAbsoluteRight'
-                    #layout: #(#LayoutFrame 245 0 14 0 267 0 36 0)
+                    #layout: #(#LayoutFrame 258 0 14 0 280 0 36 0)
                     #activeHelpKey: #makeRightAbsolute
                     #tabable: true
                     #model: #absoluteRight
@@ -1923,16 +1959,19 @@
                  #(#LabelSpec
                     #label: 'Bottom:'
                     #name: 'labelBottom'
-                    #layout: #(#AlignmentOrigin 88 0 53 0 1 0.5)
+                    #layout: #(#AlignmentOrigin 68 0 53 0 1 0.5)
+                  )
+                 #(#ActionButtonSpec
+                    #label: 'v'
+                    #name: 'actionRelativeBottom'
+                    #layout: #(#LayoutFrame 78 0 42 0 100 0 64 0)
+                    #activeHelpKey: #makeBottomRelative
+                    #tabable: true
+                    #model: #relativeBottom
                   )
                  #(#InputFieldSpec
-                    #attributes: 
-                   #(#fieldBottomFraction
-                      nil #tabable
-                      true
-                    )
                     #name: 'fieldBottomFraction'
-                    #layout: #(#LayoutFrame 90 0 42 0 140 0 64 0)
+                    #layout: #(#LayoutFrame 103 0 42 0 153 0 64 0)
                     #activeHelpKey: #bottomRelative
                     #tabable: true
                     #model: #bottomFraction
@@ -1944,24 +1983,16 @@
                     #acceptOnPointerLeave: false
                   )
                  #(#ActionButtonSpec
-                    #attributes: 
-                   #(#tabable
-                      true
-                    )
-                    #name: 'actionRelativeBottom'
-                    #layout: #(#LayoutFrame 145 0 42 0 167 0 64 0)
-                    #activeHelpKey: #makeBottomRelative
+                    #label: '^'
+                    #name: 'actionBottomRelativeBottom'
+                    #layout: #(#LayoutFrame 158 0 42 0 180 0 64 0)
+                    #activeHelpKey: #makeBottomRelativeFromBottom
                     #tabable: true
-                    #model: #relativeBottom
+                    #model: #bottomRelativeBottom
                   )
                  #(#InputFieldSpec
-                    #attributes: 
-                   #(#fieldBottomOffset
-                      nil #tabable
-                      true
-                    )
                     #name: 'fieldBottomOffset'
-                    #layout: #(#LayoutFrame 190 0 42 0 240 0 64 0)
+                    #layout: #(#LayoutFrame 203 0 42 0 253 0 64 0)
                     #activeHelpKey: #bottomAbsolute
                     #tabable: true
                     #model: #bottomOffset
@@ -1973,12 +2004,9 @@
                     #acceptOnPointerLeave: false
                   )
                  #(#ActionButtonSpec
-                    #attributes: 
-                   #(#tabable
-                      true
-                    )
+                    #label: 'v'
                     #name: 'actionAbsoluteBottom'
-                    #layout: #(#LayoutFrame 245 0 42 0 267 0 64 0)
+                    #layout: #(#LayoutFrame 258 0 42 0 280 0 64 0)
                     #activeHelpKey: #makeBottomAbsolute
                     #tabable: true
                     #model: #absoluteBottom
@@ -1988,10 +2016,6 @@
               )
             )
            #(#MenuPanelSpec
-              #attributes: 
-             #(#tabable
-                true
-              )
               #name: 'commonLayoutToolBar'
               #layout: #(#LayoutFrame 6 0.0 231 0 -4 1.0 263 0)
               #level: 0
@@ -2259,7 +2283,33 @@
         bottom:0.5       offset:0
 ! !
 
-!UILayoutTool::Rectangle class methodsFor:'interface specs'!
+!UILayoutTool::Extent class methodsFor:'help specs'!
+
+helpSpec
+    "This resource specification was automatically generated
+     by the UIHelpTool of ST/X."
+
+    "Do not manually edit this!! If it is corrupted,
+     the UIHelpTool may not be able to read the specification."
+
+    "
+     UIHelpTool openOnClass:UILayoutTool::Extent    
+    "
+
+    <resource: #help>
+
+    ^super helpSpec addPairsFrom:#(
+
+#hrzExtent
+'Horizontal extent of the selected widget.'
+
+#vrtExtent
+'Vertical extent of the selected widget.'
+
+)
+! !
+
+!UILayoutTool::Extent class methodsFor:'interface specs'!
 
 windowSpec
     "This resource specification was automatically generated
@@ -2269,117 +2319,126 @@
      the UIPainter may not be able to read the specification."
 
     "
-     UIPainter new openOnClass:UILayoutTool::Rectangle andSelector:#windowSpec
-     UILayoutTool::Rectangle new openInterface:#windowSpec
-     UILayoutTool::Rectangle open
+     UIPainter new openOnClass:UILayoutTool::Extent andSelector:#windowSpec
+     UILayoutTool::Extent new openInterface:#windowSpec
+     UILayoutTool::Extent open
     "
 
     <resource: #canvas>
 
-    ^
-     
-       #(#FullSpec
-          #window: 
-           #(#WindowSpec
-              #name: 'UILayoutTool-Rectangle'
-              #layout: #(#LayoutFrame 291 0 130 0 632 0 328 0)
-              #label: 'UILayoutTool-Rectangle'
-              #min: #(#Point 10 10)
-              #max: #(#Point 1152 900)
-              #bounds: #(#Rectangle 291 130 633 329)
-              #usePreferredExtent: false
-          )
-          #component: 
-           #(#SpecCollection
-              #collection: 
-               #(
-                 #(#UISubSpecification
-                    #name: 'subSpecification'
-                    #layout: #(#LayoutFrame 1 0.0 6 0 0 1.0 96 0)
-                    #majorKey: #UILayoutTool
-                    #minorKey: #layoutPointSpec
-                )
-                 #(#FramedBoxSpec
-                    #name: 'FramedBox'
-                    #layout: #(#LayoutFrame 1 0.0 99 0 0 1.0 194 0)
-                    #component: 
-                     #(#SpecCollection
-                        #collection: 
-                         #(
-                           #(#LabelSpec
-                              #name: 'labelCornerY'
-                              #layout: #(#AlignmentOrigin 83 0 16 0 1 0)
-                              #label: 'Right:'
-                              #adjust: #left
-                          )
-                           #(#InputFieldSpec
-                              #name: 'fieldCornerX'
-                              #layout: #(#LayoutFrame 85 0 13 0 135 0 35 0)
-                              #activeHelpKey: #cornerX
-                              #tabable: true
-                              #model: #rightOffset
-                              #group: #inputGroup
-                              #type: #numberOrNil
-                              #acceptOnLostFocus: true
+    ^ 
+     #(#FullSpec
+        #name: #windowSpec
+        #window: 
+       #(#WindowSpec
+          #label: 'UILayoutTool-Extent'
+          #name: 'UILayoutTool-Extent'
+          #min: #(#Point 10 10)
+          #max: #(#Point 1152 900)
+          #bounds: #(#Rectangle 506 24 832 173)
+        )
+        #component: 
+       #(#SpecCollection
+          #collection: #(
+           #(#FramedBoxSpec
+              #label: 'Extent'
+              #name: 'FramedBox'
+              #layout: #(#LayoutFrame 0 0.0 6 0.0 0 1.0 137 0)
+              #labelPosition: #topLeft
+              #component: 
+             #(#SpecCollection
+                #collection: #(
+                 #(#LabelSpec
+                    #label: 'Width:'
+                    #name: 'labelWidth'
+                    #layout: #(#AlignmentOrigin 89 0 24 0 1 0.5)
+                    #adjust: #right
+                  )
+                 #(#InputFieldSpec
+                    #attributes: 
+                   #(#tabable
+                      true
+                    )
+                    #name: 'fieldLeftOffset'
+                    #layout: #(#LayoutFrame 90 0 13 0 140 0 35 0)
+                    #activeHelpKey: #hrzExtent
+                    #enableChannel: #notUsingDefaultExtent
+                    #tabable: true
+                    #model: #leftOffset
+                    #group: #inputGroup
+                    #type: #numberOrNil
+                    #acceptOnLostFocus: true
                     #acceptChannel: #acceptChannel
                     #modifiedChannel: #modifiedChannel
-                          )
-                           #(#LabelSpec
-                              #name: 'labelCornerX'
-                              #layout: #(#AlignmentOrigin 83 0 41 0 1 0)
-                              #label: 'Bottom:'
-                              #adjust: #left
-                          )
-                           #(#InputFieldSpec
-                              #name: 'fieldCornerY'
-                              #layout: #(#LayoutFrame 85 0 38 0 135 0 60 0)
-                              #activeHelpKey: #cornerY
-                              #tabable: true
-                              #model: #bottomOffset
-                              #group: #inputGroup
-                              #type: #numberOrNil
-                              #acceptOnLostFocus: true
+                    #acceptOnPointerLeave: false
+                  )
+                 #(#LabelSpec
+                    #label: 'Height:'
+                    #name: 'labelHeight'
+                    #layout: #(#AlignmentOrigin 89 0 49 0 1 0.5)
+                    #adjust: #right
+                  )
+                 #(#InputFieldSpec
+                    #attributes: 
+                   #(#tabable
+                      true
+                    )
+                    #name: 'fieldRightOffset'
+                    #layout: #(#LayoutFrame 90 0 38 0 140 0 60 0)
+                    #activeHelpKey: #vrtExtent
+                    #enableChannel: #notUsingDefaultExtent
+                    #tabable: true
+                    #model: #rightOffset
+                    #group: #inputGroup
+                    #type: #numberOrNil
+                    #acceptOnLostFocus: true
                     #acceptChannel: #acceptChannel
                     #modifiedChannel: #modifiedChannel
-                          )
-                        )
+                    #acceptOnPointerLeave: false
+                  )
+                 #(#CheckBoxSpec
+                    #attributes: 
+                   #(#tabable
+                      true
                     )
-                    #label: 'Corner'
-                    #labelPosition: #topLeft
-                )
+                    #label: 'Use Widgets Default Extent'
+                    #name: 'useDefaultExtentCheckBox'
+                    #layout: #(#Point 5 74)
+                    #enableChannel: #defaultExtentEnabled
+                    #tabable: true
+                    #model: #useDefaultExtent
+                    #translateLabel: true
+                  )
+                 )
+               
               )
-          )
+            )
+           )
+         
+        )
       )
-
-    "Modified: / 13.8.1998 / 19:59:16 / cg"
 ! !
 
-!UILayoutTool::Rectangle methodsFor:'accessing'!
+!UILayoutTool::Extent methodsFor:'accessing'!
 
 fetch:aView spec:aSpec
-    "fetch rectangle
+    "fetch extent
     "
-    |origin corner|
-
-    origin := aView computeOrigin.
-    corner := aView computeCorner.
-
-    (self aspectFor:#leftOffset)   value:(origin x).
-    (self aspectFor:#rightOffset)  value:(corner x).
-    (self aspectFor:#topOffset)    value:(origin y).
-    (self aspectFor:#bottomOffset) value:(corner y).
-
-
+    |extent|
+
+    extent  := aView computeExtent.
+
+    (self aspectFor:#leftOffset)  value:(extent x).
+    (self aspectFor:#rightOffset) value:(extent y).
+
+    (self aspectFor:#useDefaultExtent) value:aSpec useDefaultExtent 
 !
 
 layout
-    "returns current layout as rectangle
+    "returns current extent
     "
-  ^ Smalltalk::Rectangle left:(((self aspectFor:#leftOffset)   value) ? 0)
-                          top:(((self aspectFor:#topOffset)    value) ? 0)
-                        right:(((self aspectFor:#rightOffset)  value) ? 0)
-                       bottom:(((self aspectFor:#bottomOffset) value) ? 0)
-
+  ^ Smalltalk::Point x:(((self aspectFor:#leftOffset)   value) ? 0)
+                     y:(((self aspectFor:#rightOffset)  value) ? 0)
 
 ! !