UISelectionPanel.st
changeset 93 6c3ff0721248
child 94 105fe34f32bc
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/UISelectionPanel.st	Mon Apr 07 17:49:18 1997 +0200
@@ -0,0 +1,1069 @@
+"
+ COPYRIGHT (c) 1997 by eXept Software AG
+              All Rights Reserved
+
+ This software is furnished under a license and may be used
+ only in accordance with the terms of that license and with the
+ inclusion of the above copyright notice.   This software may not
+ be provided or otherwise made available to, or used by, any
+ other person.  No title to or ownership of the software is
+ hereby transferred.
+"
+
+
+View subclass:#UISelectionPanel
+	instanceVariableNames:'action window tabView labelView inputView selection
+		lastClickPoint specification'
+	classVariableNames:''
+	poolDictionaries:''
+	category:'Interface-UIPainter'
+!
+
+DropObject subclass:#DropSpecification
+	instanceVariableNames:''
+	classVariableNames:''
+	poolDictionaries:''
+	privateIn:UISelectionPanel
+!
+
+!UISelectionPanel class methodsFor:'documentation'!
+
+copyright
+"
+ COPYRIGHT (c) 1997 by eXept Software AG
+              All Rights Reserved
+
+ This software is furnished under a license and may be used
+ only in accordance with the terms of that license and with the
+ inclusion of the above copyright notice.   This software may not
+ be provided or otherwise made available to, or used by, any
+ other person.  No title to or ownership of the software is
+ hereby transferred.
+"
+
+!
+
+documentation
+"
+    implements a selection panel, keeping widgets which could be placed
+    into the UIPainter by drag & drop.
+
+    [author:]
+        Claus Atzkern
+
+    [see also:]
+        TabView
+        UIPainter
+"
+
+!
+
+examples
+"
+    creates and opens the default panel
+                                                                        [exBegin]
+    self defaultPanel.
+                                                                        [exEnd]
+
+
+    create a panel with labels and selectors implemented by the receiver
+    which returns a FullSpec.
+                                                                        [exBegin]
+    |top slv inset list view idx frame colSelected colUnselected|
+
+    top := StandardSystemView new
+        label:'UI-Selection Panel';
+        extent:450@150.
+
+    view := self origin:0.0 @ 0.0 corner:1.0 @ 1.0 in:top.
+
+    view labels:#( 'Button & Toggles'
+                   'Panels'
+                   'Scroller'
+                 )
+      selectors:#( #buttonToggleSpec
+                   #scrollerSpec
+                   #panelSpec
+                 )
+       receiver:self.
+
+    top open.
+                                                                        [exEnd]
+"
+! !
+
+!UISelectionPanel class methodsFor:'instance creation'!
+
+defaultPanel
+    |top slv inset list view idx frame colSelected colUnselected|
+
+    top := StandardSystemView new
+        label:'UI-Selection Panel';
+        extent:480@200.
+
+    view := self origin:0.0 @ 0.0 corner:1.0 @ 1.0 in:top.
+
+    view labels:#( 'Button & Toggle'
+                   'Panel'
+                   'Text'
+                   'View'
+                   'Menu & Combo'
+                   'Scroller'
+                 )
+      selectors:#( #buttonToggleSpec
+                   #panelSpec
+                   #textSpec
+                   #viewsSpec
+                   #menuComboSpec
+                   #scrollerSpec
+                 )
+       receiver:self.
+
+    top open.
+
+! !
+
+!UISelectionPanel class methodsFor:'default specifications'!
+
+buttonToggleSpec
+    "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:UISelectionPanel andSelector:#buttonToggleSpec
+     UISelectionPanel new openInterface:#buttonToggleSpec
+    "
+
+    <resource: #canvas>
+
+    ^
+     
+       #(#FullSpec
+          #'window:' 
+           #(#WindowSpec
+              #'name:' 'uIPainterView'
+              #'layout:' #(#LayoutFrame 0 0.0 0 0.0 0 1.0 0 1.0)
+              #'label:' 'unnamed'
+              #'bounds:' #(#Rectangle 0 0 450 100)
+          )
+          #'component:' 
+           #(#SpecCollection
+              #'collection:' 
+               #(
+                 #(#ArrowButtonSpec
+                    #'name:' 'ArrowButton up'
+                    #'layout:' #(#LayoutFrame 16 0 70 0 38 0 92 0)
+                    #'translateLabel:' false
+                    #'tabable:' false
+                    #'hasCharacterOrientedLabel:' false
+                    #'isTriggerOnDown:' true
+                    #'direction:' #up
+                )
+                 #(#ActionButtonSpec
+                    #'name:' 'Button'
+                    #'layout:' #(#LayoutFrame 16 0 8 0 115 0 30 0)
+                    #'label:' 'Button'
+                    #'translateLabel:' false
+                    #'tabable:' false
+                    #'isTriggerOnDown:' false
+                )
+                 #(#RadioButtonSpec
+                    #'name:' 'RadioButton'
+                    #'layout:' #(#LayoutFrame 16 0.0 39 0 115 0 61 0)
+                    #'label:' 'RadioButton'
+                    #'translateLabel:' false
+                    #'tabable:' false
+                    #'isTriggerOnDown:' true
+                    #'showLamp:' true
+                    #'lampColor:' #(#Color 100.0 100.0 0.0)
+                )
+                 #(#ArrowButtonSpec
+                    #'name:' 'ArrowButton down'
+                    #'layout:' #(#LayoutFrame 42 0 70 0 64 0 92 0)
+                    #'translateLabel:' false
+                    #'tabable:' false
+                    #'hasCharacterOrientedLabel:' false
+                    #'isTriggerOnDown:' true
+                    #'direction:' #down
+                )
+                 #(#ArrowButtonSpec
+                    #'name:' 'ArrowButton left'
+                    #'layout:' #(#LayoutFrame 68 0 70 0 90 0 92 0)
+                    #'translateLabel:' false
+                    #'tabable:' false
+                    #'hasCharacterOrientedLabel:' false
+                    #'isTriggerOnDown:' true
+                    #'direction:' #left
+                )
+                 #(#ArrowButtonSpec
+                    #'name:' 'ArrowButton right'
+                    #'layout:' #(#LayoutFrame 93 0 70 0 115 0 92 0)
+                    #'translateLabel:' false
+                    #'tabable:' false
+                    #'hasCharacterOrientedLabel:' false
+                    #'isTriggerOnDown:' true
+                    #'direction:' #right
+                )
+                 #(#CheckToggleSpec
+                    #'name:' 'CheckToggle'
+                    #'layout:' #(#LayoutFrame 147 0 70 0 167 0 90 0)
+                    #'translateLabel:' false
+                    #'tabable:' false
+                    #'hasCharacterOrientedLabel:' false
+                    #'isTriggerOnDown:' true
+                    #'showLamp:' false
+                    #'lampColor:' #(#Color 100.0 100.0 0.0)
+                )
+                 #(#ToggleSpec
+                    #'name:' 'Toggle'
+                    #'layout:' #(#LayoutFrame 147 0 8 0 246 0 30 0)
+                    #'label:' 'Toggle'
+                    #'translateLabel:' false
+                    #'tabable:' false
+                    #'isTriggerOnDown:' true
+                    #'showLamp:' true
+                    #'lampColor:' #(#Color 100.0 100.0 0.0)
+                )
+                 #(#CheckBoxSpec
+                    #'name:' 'CheckBox'
+                    #'layout:' #(#LayoutFrame 145 0 39 0 246 0 61 0)
+                    #'tabable:' false
+                    #'label:' 'CheckBox'
+                    #'translateLabel:' false
+                )
+              )
+          )
+      )
+!
+
+menuComboSpec
+    "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:UISelectionPanel andSelector:#menuComboSpec
+     UISelectionPanel new openInterface:#menuComboSpec
+    "
+
+    <resource: #canvas>
+
+    ^
+     
+       #(#FullSpec
+          #'window:' 
+           #(#WindowSpec
+              #'name:' 'uIPainterView'
+              #'layout:' #(#LayoutFrame 0 0.0 0 0.0 0 1.0 0 1.0)
+              #'label:' 'unnamed'
+              #'bounds:' #(#Rectangle 0 0 450 100)
+          )
+          #'component:' 
+           #(#SpecCollection
+              #'collection:' 
+               #(
+                 #(#ComboBoxSpec
+                    #'name:' 'ComboBox'
+                    #'layout:' #(#LayoutFrame 14 0 15 0 117 0 35 0)
+                    #'immediateAccept:' false
+                    #'acceptOnLeave:' true
+                    #'acceptOnReturn:' true
+                    #'acceptOnTab:' true
+                    #'acceptOnLostFocus:' true
+                    #'hasBorder:' false
+                )
+                 #(#ComboListSpec
+                    #'name:' 'ComboList'
+                    #'layout:' #(#LayoutFrame 14 0 46 0 117 0 66 0)
+                    #'tabable:' false
+                )
+                 #(#PopUpListSpec
+                    #'name:' 'PopUpList'
+                    #'layout:' #(#LayoutFrame 139 0 15 0 242 0 37 0)
+                    #'label:' 'PopUpList'
+                    #'initiallyInvisible:' false
+                    #'translateLabel:' false
+                )
+              )
+          )
+      )
+!
+
+panelSpec
+    "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:UISelectionPanel andSelector:#panelSpec
+     UISelectionPanel new openInterface:#panelSpec
+    "
+
+    <resource: #canvas>
+
+    ^
+     
+       #(#FullSpec
+          #'window:' 
+           #(#WindowSpec
+              #'name:' 'uIPainterView'
+              #'layout:' #(#LayoutFrame 0 0.0 0 0.0 0 1.0 0 1.0)
+              #'label:' 'unnamed'
+              #'bounds:' #(#Rectangle 0 0 450 100)
+          )
+          #'component:' 
+           #(#SpecCollection
+              #'collection:' 
+               #(
+                 #(#HorizontalPanelViewSpec
+                    #'name:' 'HorizontalPanelView'
+                    #'layout:' #(#LayoutFrame 20 0 17 0 104 0 81 0)
+                    #'component:' 
+                     #(#SpecCollection
+                        #'collection:' 
+                         #(
+                           #(#ActionButtonSpec
+                              #'name:' 'button1'
+                              #'label:' 'A'
+                              #'translateLabel:' false
+                              #'tabable:' false
+                              #'isTriggerOnDown:' false
+                              #'extent:' #(#Point 34 23)
+                              #'canUIDrag:' false
+                          )
+                           #(#ActionButtonSpec
+                              #'name:' 'button8'
+                              #'label:' 'B'
+                              #'translateLabel:' false
+                              #'tabable:' false
+                              #'isTriggerOnDown:' false
+                              #'extent:' #(#Point 32 41)
+                              #'canUIDrag:' false
+                          )
+                        )
+                    )
+                    #'level:' 0
+                    #'horizontalLayout:' #center
+                    #'verticalLayout:' #center
+                    #'horizontalSpace:' 3
+                    #'verticalSpace:' 3
+                )
+                 #(#VariableHorizontalPanelSpec
+                    #'name:' 'VariableHorizontalPanel'
+                    #'layout:' #(#LayoutFrame 128 0 17 0 212 0 81 0)
+                    #'component:' 
+                     #(#SpecCollection
+                        #'collection:' 
+                         #(
+                           #(#ActionButtonSpec
+                              #'name:' 'button2'
+                              #'label:' 'A'
+                              #'translateLabel:' false
+                              #'tabable:' false
+                              #'isTriggerOnDown:' false
+                              #'canUIDrag:' false
+                          )
+                           #(#ActionButtonSpec
+                              #'name:' 'button3'
+                              #'label:' 'B'
+                              #'translateLabel:' false
+                              #'tabable:' false
+                              #'isTriggerOnDown:' false
+                              #'canUIDrag:' false
+                          )
+                        )
+                    )
+                )
+                 #(#VerticalPanelViewSpec
+                    #'name:' 'VerticalPanelView'
+                    #'layout:' #(#LayoutFrame 236 0 17 0 320 0 81 0)
+                    #'component:' 
+                     #(#SpecCollection
+                        #'collection:' 
+                         #(
+                           #(#ActionButtonSpec
+                              #'name:' 'button4'
+                              #'label:' 'A'
+                              #'translateLabel:' false
+                              #'tabable:' false
+                              #'isTriggerOnDown:' false
+                              #'extent:' #(#Point 19 18)
+                              #'canUIDrag:' false
+                          )
+                           #(#ActionButtonSpec
+                              #'name:' 'button5'
+                              #'label:' 'B'
+                              #'translateLabel:' false
+                              #'tabable:' false
+                              #'isTriggerOnDown:' false
+                              #'extent:' #(#Point 63 30)
+                              #'canUIDrag:' false
+                          )
+                        )
+                    )
+                    #'level:' 0
+                    #'horizontalLayout:' #center
+                    #'verticalLayout:' #center
+                    #'horizontalSpace:' 3
+                    #'verticalSpace:' 3
+                )
+                 #(#VariableVerticalPanelSpec
+                    #'name:' 'VariableVerticalPanel'
+                    #'layout:' #(#LayoutFrame 344 0 17 0 428 0 81 0)
+                    #'component:' 
+                     #(#SpecCollection
+                        #'collection:' 
+                         #(
+                           #(#ActionButtonSpec
+                              #'name:' 'button6'
+                              #'label:' 'A'
+                              #'translateLabel:' false
+                              #'tabable:' false
+                              #'isTriggerOnDown:' false
+                              #'canUIDrag:' false
+                          )
+                           #(#ActionButtonSpec
+                              #'name:' 'button7'
+                              #'label:' 'B'
+                              #'translateLabel:' false
+                              #'tabable:' false
+                              #'isTriggerOnDown:' false
+                              #'canUIDrag:' false
+                          )
+                        )
+                    )
+                )
+              )
+          )
+      )
+!
+
+scrollerSpec
+    "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:UISelectionPanel andSelector:#scrollerSpec
+     UISelectionPanel new openInterface:#scrollerSpec
+    "
+
+    <resource: #canvas>
+
+    ^
+     
+       #(#FullSpec
+          #'window:' 
+           #(#WindowSpec
+              #'name:' 'uIPainterView'
+              #'layout:' #(#LayoutFrame 0 0.0 0 0.0 0 1.0 0 1.0)
+              #'label:' 'unnamed'
+              #'bounds:' #(#Rectangle 0 0 450 100)
+          )
+          #'component:' 
+           #(#SpecCollection
+              #'collection:' 
+               #(
+                 #(#ArbitraryComponentSpec
+                    #'name:' 'HorizontalMiniScroller'
+                    #'layout:' #(#LayoutFrame 4 0 10 0 105 0 16 0)
+                    #'component:' ''
+                    #'tabable:' false
+                    #'hasHorizontalScrollBar:' false
+                    #'hasVerticalScrollBar:' false
+                    #'hasBorder:' false
+                )
+                 #(#ArbitraryComponentSpec
+                    #'name:' 'HorizontalScrollBar'
+                    #'layout:' #(#LayoutFrame 4 0 23 0 105 0 42 0)
+                    #'component:' ''
+                    #'tabable:' false
+                    #'hasHorizontalScrollBar:' false
+                    #'hasVerticalScrollBar:' false
+                    #'hasBorder:' false
+                )
+                 #(#ArbitraryComponentSpec
+                    #'name:' 'HorizontalScroller'
+                    #'layout:' #(#LayoutFrame 4 0 49 0 105 0 66 0)
+                    #'component:' ''
+                    #'tabable:' false
+                    #'hasHorizontalScrollBar:' false
+                    #'hasVerticalScrollBar:' false
+                    #'hasBorder:' false
+                )
+                 #(#ArbitraryComponentSpec
+                    #'name:' 'HorizontalSlider'
+                    #'layout:' #(#LayoutFrame 4 0 73 0 105 0 90 0)
+                    #'tabable:' false
+                    #'hasHorizontalScrollBar:' false
+                    #'hasVerticalScrollBar:' false
+                    #'hasBorder:' false
+                )
+                 #(#ArbitraryComponentSpec
+                    #'name:' 'MiniScroller'
+                    #'layout:' #(#LayoutFrame 137 0 11 0 143 0 90 0)
+                    #'component:' ''
+                    #'tabable:' false
+                    #'hasHorizontalScrollBar:' false
+                    #'hasVerticalScrollBar:' false
+                    #'hasBorder:' false
+                )
+                 #(#ArbitraryComponentSpec
+                    #'name:' 'ScrollBar'
+                    #'layout:' #(#LayoutFrame 153 0 11 0 172 0 90 0)
+                    #'component:' ''
+                    #'tabable:' false
+                    #'hasHorizontalScrollBar:' false
+                    #'hasVerticalScrollBar:' false
+                    #'hasBorder:' false
+                )
+                 #(#ScrollerSpec
+                    #'name:' 'Scroller'
+                    #'layout:' #(#LayoutFrame 182 0 11 0 212 0 90 0)
+                )
+                 #(#SliderSpec
+                    #'name:' 'Slider'
+                    #'layout:' #(#LayoutFrame 222 0 11 0 252 0 90 0)
+                )
+                 #(#ArbitraryComponentSpec
+                    #'name:' 'ThumbWheel'
+                    #'layout:' #(#LayoutFrame 270 0 11 0 285 0 90 0)
+                    #'component:' ''
+                    #'tabable:' false
+                    #'hasHorizontalScrollBar:' false
+                    #'hasVerticalScrollBar:' false
+                    #'hasBorder:' false
+                )
+              )
+          )
+      )
+!
+
+textSpec
+    "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:UISelectionPanel andSelector:#textSpec
+     UISelectionPanel new openInterface:#textSpec
+    "
+
+    <resource: #canvas>
+
+    ^
+     
+       #(#FullSpec
+          #'window:' 
+           #(#WindowSpec
+              #'name:' 'uIPainterView'
+              #'layout:' #(#LayoutFrame 0 0.0 0 0.0 0 1.0 0 1.0)
+              #'label:' 'unnamed'
+              #'bounds:' #(#Rectangle 0 0 450 100)
+          )
+          #'component:' 
+           #(#SpecCollection
+              #'collection:' 
+               #(
+                 #(#InputFieldSpec
+                    #'name:' 'EditField'
+                    #'layout:' #(#LayoutFrame 13 0 11 0 117 0 29 0)
+                    #'immediateAccept:' false
+                    #'acceptOnLeave:' true
+                    #'acceptOnReturn:' true
+                    #'acceptOnTab:' true
+                    #'acceptOnLostFocus:' true
+                    #'hasBorder:' false
+                )
+                 #(#TextEditorSpec
+                    #'name:' 'EditTextView'
+                    #'layout:' #(#LayoutFrame 171 0 11 0 275 0 91 0)
+                )
+                 #(#SequenceViewSpec
+                    #'name:' 'SelectionInListView'
+                    #'layout:' #(#LayoutFrame 329 0 11 0 433 0 91 0)
+                    #'hasHorizontalScrollBar:' true
+                    #'hasVerticalScrollBar:' true
+                )
+                 #(#LabelSpec
+                    #'name:' 'Text Label'
+                    #'layout:' #(#LayoutFrame 13 0 41 0 117 0 57 0)
+                    #'label:' 'Text Label'
+                    #'initiallyInvisible:' false
+                    #'translateLabel:' false
+                    #'level:' 0
+                    #'adjust:' #center
+                    #'hasCharacterOrientedLabel:' true
+                )
+              )
+          )
+      )
+!
+
+viewsSpec
+    "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:UISelectionPanel andSelector:#viewsSpec
+     UISelectionPanel new openInterface:#viewsSpec
+    "
+
+    <resource: #canvas>
+
+    ^
+     
+       #(#FullSpec
+          #'window:' 
+           #(#WindowSpec
+              #'name:' 'uIPainterView'
+              #'layout:' #(#LayoutFrame 0 0.0 0 0.0 0 1.0 0 1.0)
+              #'label:' 'unnamed'
+              #'bounds:' #(#Rectangle 0 0 450 100)
+          )
+          #'component:' 
+           #(#SpecCollection
+              #'collection:' 
+               #(
+                 #(#FramedBoxSpec
+                    #'name:' 'FramedBox'
+                    #'layout:' #(#LayoutFrame 4 0 11 0 109 0 81 0)
+                    #'label:' 'FramedBox'
+                    #'labelPosition:' #topCenter
+                    #'showFrame:' true
+                )
+                 #(#ViewSpec
+                    #'name:' 'view1'
+                    #'layout:' #(#LayoutFrame 118 0 11 0 223 0 81 0)
+                    #'component:' 
+                     #(#SpecCollection
+                        #'collection:' 
+                         #(
+                           #(#LabelSpec
+                              #'name:' 'label1'
+                              #'layout:' #(#Point 3 2)
+                              #'label:' 'View'
+                              #'initiallyInvisible:' false
+                              #'translateLabel:' false
+                              #'level:' 0
+                              #'adjust:' #center
+                              #'hasCharacterOrientedLabel:' true
+                              #'canUIDrag:' false
+                          )
+                        )
+                    )
+                )
+                 #(#SubCanvasSpec
+                    #'name:' 'subCanvas1'
+                    #'layout:' #(#LayoutFrame 232 0 11 0 337 0 81 0)
+                )
+                 #(#LabelSpec
+                    #'name:' 'label2'
+                    #'layout:' #(#Point 246 20)
+                    #'label:' 'SubCanvas'
+                    #'initiallyInvisible:' false
+                    #'translateLabel:' false
+                    #'level:' 0
+                    #'adjust:' #center
+                    #'hasCharacterOrientedLabel:' true
+                    #'canUIDrag:' false
+                )
+                 #(#DividerSpec
+                    #'name:' 'Horizontal Seperator'
+                    #'layout:' #(#LayoutFrame 373 0 11 0 437 0 28 0)
+                    #'orientation:' #horizontal
+                )
+                 #(#DividerSpec
+                    #'name:' 'Vertical Seperator'
+                    #'layout:' #(#LayoutFrame 345 0 11 0 364 0 81 0)
+                    #'orientation:' #vertical
+                )
+              )
+          )
+      )
+! !
+
+!UISelectionPanel methodsFor:'accessing'!
+
+labels:labels selectors:selectors receiver:receiver
+    "change specification and tabs
+    "
+    tabView action:[:aNrOrNil||spec|
+        aNrOrNil notNil ifTrue:[
+            spec := receiver perform:(selectors at:aNrOrNil).
+        ].
+        self specification:spec.
+    ].
+    tabView list:labels.
+    self recomputeSizes.
+
+
+!
+
+specification:specOrSpecArray
+    "load a spec
+    "
+    |builder|
+
+    self selection:nil.
+    labelView label:''.
+
+    window subViews copy do:[:aSubView|
+        aSubView ~~ inputView ifTrue:[
+            aSubView == labelView ifTrue:[self halt].
+            aSubView destroy
+        ]
+    ].
+
+    specOrSpecArray notNil ifTrue:[
+        specification := UISpecification from:specOrSpecArray.
+
+        builder := UIBuilder new.
+        specification buildViewFor:builder in:window.
+        window realizeAllSubViews.
+        inputView raise.
+    ]
+! !
+
+!UISelectionPanel methodsFor:'change & update'!
+
+recomputeSizes
+    "recompute sizes dependent on list
+    "
+    |y x extent|
+
+    extent := tabView preferredExtent.
+    x := extent x.
+
+    x <= (self extent x) ifTrue:[
+        y := extent y.
+    ] ifFalse:[
+        y := tabView preferredHeight.
+    ].
+    y := y + 8.
+    tabView bottomInset:(y negated).
+    window  topInset:y.
+
+
+!
+
+update:something with:aParameter from:changedObject
+    "tabView might change its size
+    "
+    (something == #preferredHeight and:[changedObject == tabView]) ifFalse:[
+        ^ self
+    ].
+    self recomputeSizes
+
+
+! !
+
+!UISelectionPanel methodsFor:'drag & drop'!
+
+startDrag
+    "start drag of selection
+    "
+    |dragObj spec|
+
+    spec := self findSpecFor:selection.
+
+    spec notNil ifTrue:[
+        spec := self buildSpecFrom:spec.
+
+        self showUnselected.
+        dragObj := DropSpecification for:selection specification:spec.
+        self showSelected.
+
+        DragAndDropManager startDrag:dragObj from:inputView.
+    ]
+
+! !
+
+!UISelectionPanel methodsFor:'event handling'!
+
+buttonMotion:state x:x y:y
+    "start a drag on selection
+    "
+    |obj sensor|
+
+    selection notNil ifTrue:[
+        sensor := self sensor.
+        sensor anyButtonPressed ifTrue:[
+            (lastClickPoint dist:(x@y)) > 10.0 ifTrue:[
+                self startDrag
+            ]
+        ]
+    ] ifFalse:[
+        obj := self findObjectAtX:x y:y.
+
+        obj notNil ifTrue:[
+            labelView label:obj name
+        ]
+    ].
+!
+
+buttonPress:button x:x y:y
+    "change selection
+    "
+    lastClickPoint := Point x:x y:y.
+    self selection:(self findObjectAtX:x y:y).
+
+
+!
+
+doesNotUnderstand:aMessage
+    "any event message not catched; discard message
+    "
+
+
+!
+
+exposeX:x y:y width:w height:h
+    "handle an expose event from device; redraw selection
+    "
+    super exposeX:x y:y width:w height:h.
+    self showSelected.
+
+! !
+
+!UISelectionPanel methodsFor:'initialization'!
+
+initialize
+    |y|
+
+    super initialize.
+    tabView   := TabView           origin:0.0@0.0 corner:1.0@0.0 in:self.
+    window    := NoteBookFrameView origin:0.0@0.0 corner:1.0@1.0 in:self.
+    labelView := Label             origin:0.0@1.0 corner:1.0@1.0 in:self.
+    inputView := InputView         origin:0.0@0.0 extent:1.0@1.0 in:window.
+
+    y := labelView preferredExtent y.
+    window bottomInset:y.
+    labelView topInset:(y negated).
+
+    inputView eventReceiver:self.
+    inputView enableButtonEvents.
+    inputView enableButtonMotionEvents.
+    inputView enableMotionEvents.
+
+    tabView tabWidget:#Window.
+
+    tabView styleAt:#expandSelection   put:6@2.
+    tabView styleAt:#labelBottomInset  put:4.
+    tabView styleAt:#lableTopInset     put:0.
+    tabView font:(Label defaultFont).
+    tabView addDependent:self.
+
+    window     viewBackground:(tabView styleAt:#selectedColor).
+    labelView backgroundColor:(tabView styleAt:#unselectedColor).
+
+! !
+
+!UISelectionPanel methodsFor:'searching'!
+
+buildSpecFrom:aSpec
+    "build spec out of spec
+    "
+    |spec comp coll|
+
+    (aSpec notNil and:[aSpec canUIDrag]) ifFalse:[
+        ^ nil
+    ].
+
+    (aSpec class supportsSubComponents and:[aSpec component notNil]) ifFalse:[
+        ^ aSpec
+    ].
+    comp := aSpec component.
+    spec := aSpec copy.
+    spec component:nil.
+
+    comp canUIDrag ifFalse:[
+      ^ spec
+    ].
+    coll := OrderedCollection new.
+
+    comp do:[:anEntry||spc|
+        (spc := self buildSpecFrom:anEntry) notNil ifTrue:[
+            coll add:spc
+        ]
+    ].
+    coll isEmpty ifTrue:[
+      ^ spec
+    ].
+    comp := comp copy.
+    comp collection:coll.
+    spec component:comp.
+  ^ spec
+!
+
+findObjectAtX:x y:y
+    "find the origin/corner of the currentWidget
+    "
+    |view viewId point|
+
+    point   := Point x:x y:y.
+    point   := device translatePoint:point from:(inputView id)
+                                             to:(inputView device rootView id).
+    inputView lower.
+    viewId := device viewIdFromPoint:point in:(window id).
+    view   := device viewFromId:viewId.
+    inputView raise.
+
+    (view ~~ window and:[view ~~ inputView]) ifTrue:[
+        (self findSpecFor:view) notNil ifTrue:[
+             ^ view
+        ]
+    ].
+    ^ nil
+
+
+!
+
+findSpecFor:anObject
+    "returns subspec assigned to instance or nil
+    "
+    |name components spec|
+
+    anObject notNil ifTrue:[
+        name := anObject name.
+
+        specification do:[:aSpec|
+            aSpec name = name ifTrue:[
+                aSpec canUIDrag ifTrue:[^ aSpec]
+                               ifFalse:[^ nil]
+            ]
+        ]
+    ].
+    ^ nil
+
+! !
+
+!UISelectionPanel methodsFor:'selections'!
+
+handlesOf:aComponent do:aOneArgBlock
+    "evaluate the block on each handle; the argument to the block
+     is a rectangle
+    "
+    aComponent notNil ifTrue:[
+        aOneArgBlock value:(aComponent origin       - (4@4) extent:7@7).
+        aOneArgBlock value:(aComponent corner       - (4@4) extent:7@7).
+        aOneArgBlock value:(aComponent topRight     - (4@4) extent:7@7).
+        aOneArgBlock value:(aComponent bottomLeft   - (4@4) extent:7@7).
+        aOneArgBlock value:(aComponent leftCenter   - (4@4) extent:7@7).
+        aOneArgBlock value:(aComponent rightCenter  - (4@4) extent:7@7).
+        aOneArgBlock value:(aComponent topCenter    - (4@4) extent:7@7).
+        aOneArgBlock value:(aComponent bottomCenter - (4@4) extent:7@7).
+    ]
+
+
+!
+
+selection:anObject
+    "selection changed
+    "
+    |spec|
+
+    selection ~~ anObject ifTrue:[
+        self showUnselected.
+        spec := self findSpecFor:anObject.
+
+        spec notNil ifTrue:[
+            selection := anObject.
+            self showSelected
+        ] ifFalse:[
+            selection := nil
+        ].
+
+        selection notNil ifTrue:[
+            labelView label:(selection name)
+        ]
+    ]
+
+!
+
+showSelected
+    "show selected
+    "
+    selection notNil ifTrue:[
+        window clippedByChildren:false.
+
+        self handlesOf:selection do:[:aRectangle|
+            window fillRectangle:aRectangle
+        ].
+        window clippedByChildren:true.
+    ].
+!
+
+showUnselected
+    "show unselected
+    "
+    |r|
+
+    selection isNil ifTrue:[
+        ^ self
+    ].
+
+    window clippedByChildren:false.
+
+    self handlesOf:selection do:[:aRectangle|
+        window clearRectangle:aRectangle
+    ].
+    window clippedByChildren:true.
+
+"must redraw all components which are affected b the handles
+"
+    r := (selection originRelativeTo:window) - (4@4) extent:(selection extent + (4@4)).
+
+    window subViews do:[:aComponent |
+        |absOrg absFrame|
+
+        aComponent ~~ inputView ifTrue:[
+            absOrg   := aComponent originRelativeTo:window.
+            absFrame := absOrg extent:(aComponent extent).
+
+            (absFrame intersects:r) ifTrue:[
+                aComponent withAllSubViewsDo:[:aView|
+                    aView clear.
+                    aView exposeX:0 y:0 width:9999 height:9999.
+                ]
+            ]
+        ]
+    ]
+
+! !
+
+!UISelectionPanel::DropSpecification class methodsFor:'instance creation'!
+
+for:aView specification:aSpec
+    "create drop object for a view derived from a specification
+    "
+    aView topView raise.
+    aView device sync.
+    aView invalidate.
+    aView windowGroup processExposeEvents.
+    DisplayObject := Image fromView:aView grab:false.
+
+    DisplayObject extent ~= aView extent ifTrue:[
+        DisplayObject := Form extent:(aView extent) depth:1.
+        DisplayObject colorMap:(Array with:Color white with:Color black).
+        DisplayObject fill:(Color colorId:0).
+        DisplayObject paint:(Color colorId:1).
+        DisplayObject displayRectangleX:0 y:0 width:aView extent x height:aView extent y.
+    ].
+
+    ^ self new theObject:aSpec
+! !
+
+!UISelectionPanel class methodsFor:'documentation'!
+
+version
+    ^ '$Header$'
+! !