UISelectionPanel.st
author Claus Gittinger <cg@exept.de>
Wed, 30 Apr 1997 16:49:35 +0200
changeset 108 9078a793fd8e
parent 107 e3e9acbe8fe3
child 112 6fe6c4d1672e
permissions -rw-r--r--
*** empty log message ***

"
 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

    [start with:]
        UISelectionPanel defaultPanel

"

!

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'
                   'Slider'
                 )
      selectors:#( #buttonToggleSpec
                   #panelSpec
                   #sliderSpec
                 )
       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@255.

    view := self origin:0.0 @ 0.0 corner:1.0 @ 1.0 in:top.

    view labels:#( 'Button & Toggle'
                   'Panel'
                   'Text'
                   'View'
                   'Menu & Combo'
                   'Slider'
                 )
      selectors:#( #buttonToggleSpec
                   #panelSpec
                   #textSpec
                   #viewsSpec
                   #menuComboSpec
                   #sliderSpec
                 )
       receiver:self.

    top open.

! !

!UISelectionPanel class methodsFor:'interface specs'!

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 439 193)
          )
          #'component:' 
           #(#SpecCollection
              #'collection:' 
               #(
                 #(#ArrowButtonSpec
                    #'name:' 'ArrowButton up'
                    #'layout:' #(#LayoutFrame 237 0 20 0 259 0 42 0)
                    #'hasCharacterOrientedLabel:' false
                    #'isTriggerOnDown:' true
                    #'direction:' #up
                )
                 #(#ActionButtonSpec
                    #'name:' 'Button'
                    #'layout:' #(#LayoutFrame 20 0 20 0 119 0 42 0)
                    #'label:' 'Button'
                    #'isTriggerOnDown:' false
                )
                 #(#RadioButtonSpec
                    #'name:' 'RadioButton'
                    #'layout:' #(#LayoutFrame 127 0.0 20 0 226 0 42 0)
                    #'label:' 'RadioButton'
                    #'isTriggerOnDown:' true
                    #'showLamp:' true
                    #'lampColor:' #(#Color 100.0 100.0 0.0)
                )
                 #(#ArrowButtonSpec
                    #'name:' 'ArrowButton down'
                    #'layout:' #(#LayoutFrame 238 0 51 0 260 0 73 0)
                    #'hasCharacterOrientedLabel:' false
                    #'isTriggerOnDown:' true
                    #'direction:' #down
                )
                 #(#ArrowButtonSpec
                    #'name:' 'ArrowButton left'
                    #'layout:' #(#LayoutFrame 238 0 82 0 260 0 104 0)
                    #'hasCharacterOrientedLabel:' false
                    #'isTriggerOnDown:' true
                    #'direction:' #left
                )
                 #(#ArrowButtonSpec
                    #'name:' 'ArrowButton right'
                    #'layout:' #(#LayoutFrame 238 0 113 0 260 0 135 0)
                    #'hasCharacterOrientedLabel:' false
                    #'isTriggerOnDown:' true
                    #'direction:' #right
                )
                 #(#CheckToggleSpec
                    #'name:' 'CheckToggle'
                    #'layout:' #(#LayoutFrame 297 0 82 0 317 0 102 0)
                    #'hasCharacterOrientedLabel:' false
                    #'isTriggerOnDown:' true
                    #'showLamp:' false
                    #'lampColor:' #(#Color 100.0 100.0 0.0)
                )
                 #(#ToggleSpec
                    #'name:' 'Toggle'
                    #'layout:' #(#LayoutFrame 297 0 20 0 396 0 42 0)
                    #'label:' 'Toggle'
                    #'isTriggerOnDown:' true
                    #'showLamp:' true
                    #'lampColor:' #(#Color 100.0 100.0 0.0)
                )
                 #(#CheckBoxSpec
                    #'name:' 'CheckBox'
                    #'layout:' #(#LayoutFrame 295 0 51 0 396 0 73 0)
                    #'tabable:' false
                    #'label:' 'CheckBox'
                    #'translateLabel:' false
                )
                 #(#ActionButtonSpec
                    #'name:' 'ok'
                    #'layout:' #(#LayoutFrame 20 0 51 0 119 0 73 0)
                    #'label:' 'ok'
                    #'model:' #accept
                    #'isTriggerOnDown:' false
                )
                 #(#ActionButtonSpec
                    #'name:' 'cancel'
                    #'layout:' #(#LayoutFrame 20 0 82 0 119 0 104 0)
                    #'label:' 'cancel'
                    #'model:' #cancel
                    #'isTriggerOnDown:' false
                )
                 #(#ActionButtonSpec
                    #'name:' 'help'
                    #'layout:' #(#LayoutFrame 20 0 113 0 119 0 135 0)
                    #'label:' 'help'
                    #'model:' #help
                    #'isTriggerOnDown:' 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 20 0 20 0 123 0 40 0)
                    #'immediateAccept:' false
                    #'acceptOnLeave:' true
                    #'acceptOnReturn:' true
                    #'acceptOnTab:' true
                    #'acceptOnLostFocus:' true
                    #'hasBorder:' false
                )
                 #(#ComboListSpec
                    #'name:' 'ComboList'
                    #'layout:' #(#LayoutFrame 20 0 51 0 123 0 71 0)
                    #'tabable:' false
                )
                 #(#PopUpListSpec
                    #'name:' 'PopUpList'
                    #'layout:' #(#LayoutFrame 145 0 20 0 248 0 42 0)
                    #'label:' 'PopUpList'
                )
              )
          )
      )
!

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 475 136)
          )
          #'component:' 
           #(#SpecCollection
              #'collection:' 
               #(
                 #(#HorizontalPanelViewSpec
                    #'name:' 'HorizontalPanelView'
                    #'layout:' #(#LayoutFrame 20 0 20 0 104 0 105 0)
                    #'component:' 
                     #(#SpecCollection
                        #'collection:' 
                         #(
                           #(#ActionButtonSpec
                              #'name:' 'button1'
                              #'label:' 'A'
                              #'isTriggerOnDown:' false
                              #'extent:' #(#Point 22 23)
                              #'canUIDrag:' false
                          )
                           #(#ActionButtonSpec
                              #'name:' 'button8'
                              #'label:' 'B'
                              #'isTriggerOnDown:' false
                              #'extent:' #(#Point 22 23)
                              #'canUIDrag:' false
                          )
                           #(#ActionButtonSpec
                              #'name:' 'button9'
                              #'label:' 'C'
                              #'isTriggerOnDown:' false
                              #'extent:' #(#Point 22 23)
                              #'canUIDrag:' false
                          )
                        )
                    )
                    #'level:' 0
                    #'horizontalLayout:' #center
                    #'verticalLayout:' #center
                    #'horizontalSpace:' 3
                    #'verticalSpace:' 3
                )
                 #(#VariableHorizontalPanelSpec
                    #'name:' 'VariableHorizontalPanel'
                    #'layout:' #(#LayoutFrame 275 0 20 0 363 0 105 0)
                    #'component:' 
                     #(#SpecCollection
                        #'collection:' 
                         #(
                           #(#ActionButtonSpec
                              #'name:' 'button2'
                              #'label:' 'A'
                              #'isTriggerOnDown:' false
                              #'canUIDrag:' false
                          )
                           #(#ActionButtonSpec
                              #'name:' 'button3'
                              #'label:' 'B'
                              #'isTriggerOnDown:' false
                              #'canUIDrag:' false
                          )
                        )
                    )
                )
                 #(#VerticalPanelViewSpec
                    #'name:' 'VerticalPanelView'
                    #'layout:' #(#LayoutFrame 110 0 20 0 191 0 105 0)
                    #'component:' 
                     #(#SpecCollection
                        #'collection:' 
                         #(
                           #(#ActionButtonSpec
                              #'name:' 'button4'
                              #'label:' 'A'
                              #'isTriggerOnDown:' false
                              #'extent:' #(#Point 22 23)
                              #'canUIDrag:' false
                          )
                           #(#ActionButtonSpec
                              #'name:' 'button5'
                              #'label:' 'B'
                              #'isTriggerOnDown:' false
                              #'extent:' #(#Point 22 23)
                              #'canUIDrag:' false
                          )
                           #(#ActionButtonSpec
                              #'name:' 'button10'
                              #'label:' 'C'
                              #'isTriggerOnDown:' false
                              #'extent:' #(#Point 22 23)
                              #'canUIDrag:' false
                          )
                        )
                    )
                    #'level:' 0
                    #'horizontalLayout:' #center
                    #'verticalLayout:' #center
                    #'horizontalSpace:' 3
                    #'verticalSpace:' 3
                )
                 #(#VariableVerticalPanelSpec
                    #'name:' 'VariableVerticalPanel'
                    #'layout:' #(#LayoutFrame 372 0 20 0 456 0 105 0)
                    #'component:' 
                     #(#SpecCollection
                        #'collection:' 
                         #(
                           #(#ActionButtonSpec
                              #'name:' 'button6'
                              #'label:' 'A'
                              #'isTriggerOnDown:' false
                              #'canUIDrag:' false
                          )
                           #(#ActionButtonSpec
                              #'name:' 'button7'
                              #'label:' 'B'
                              #'isTriggerOnDown:' false
                              #'canUIDrag:' false
                          )
                        )
                    )
                )
                 #(#PanelViewSpec
                    #'name:' 'PanelView'
                    #'layout:' #(#LayoutFrame 197 0 20 0 255 0 105 0)
                    #'component:' 
                     #(#SpecCollection
                        #'collection:' 
                         #(
                           #(#ActionButtonSpec
                              #'name:' 'button11'
                              #'label:' 'A'
                              #'isTriggerOnDown:' false
                              #'extent:' #(#Point 22 23)
                              #'canUIDrag:' false
                          )
                           #(#ActionButtonSpec
                              #'name:' 'button12'
                              #'label:' 'B'
                              #'isTriggerOnDown:' false
                              #'extent:' #(#Point 22 23)
                              #'canUIDrag:' false
                          )
                           #(#ActionButtonSpec
                              #'name:' 'button13'
                              #'label:' 'C'
                              #'isTriggerOnDown:' false
                              #'extent:' #(#Point 22 23)
                              #'canUIDrag:' false
                          )
                           #(#ActionButtonSpec
                              #'name:' 'button14'
                              #'label:' 'D'
                              #'isTriggerOnDown:' false
                              #'extent:' #(#Point 22 23)
                              #'canUIDrag:' false
                          )
                           #(#ActionButtonSpec
                              #'name:' 'button15'
                              #'label:' 'E'
                              #'isTriggerOnDown:' false
                              #'extent:' #(#Point 22 23)
                              #'canUIDrag:' false
                          )
                        )
                    )
                    #'level:' 0
                    #'horizontalLayout:' #fitSpace
                    #'verticalLayout:' #fitSpace
                    #'horizontalSpace:' 3
                    #'verticalSpace:' 3
                )
              )
          )
      )
!

sliderSpec
    "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:#sliderSpec
     UISelectionPanel new openInterface:#sliderSpec
    "

    <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 445 162)
          )
          #'component:' 
           #(#SpecCollection
              #'collection:' 
               #(
                 #(#SliderSpec
                    #'name:' 'Vertical Slider'
                    #'layout:' #(#LayoutFrame 20 0 20 0 38 0 108 0)
                    #'orientation:' #vertical
                )
                 #(#ThumbWheelSpec
                    #'name:' 'Vertical ThumbWheel'
                    #'layout:' #(#LayoutFrame 48 0 20 0 63 0 108 0)
                    #'orientation:' #vertical
                    #'start:' 0
                    #'stop:' 360
                )
                 #(#ThumbWheelSpec
                    #'name:' 'Horizontal ThumbWheel'
                    #'layout:' #(#LayoutFrame 102 0 20 0 191 0 35 0)
                    #'orientation:' #horizontal
                    #'start:' 0
                    #'stop:' 360
                )
                 #(#SliderSpec
                    #'name:' 'Horizontal Slider'
                    #'layout:' #(#LayoutFrame 102 0 47 0 191 0 65 0)
                    #'orientation:' #horizontal
                    #'start:' 0
                    #'stop:' 100
                )
              )
          )
      )
!

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 573 264)
          )
          #'component:' 
           #(#SpecCollection
              #'collection:' 
               #(
                 #(#InputFieldSpec
                    #'name:' 'EditField'
                    #'layout:' #(#LayoutFrame 20 0 20 0 115 0 42 0)
                    #'immediateAccept:' false
                    #'acceptOnLeave:' true
                    #'acceptOnReturn:' true
                    #'acceptOnTab:' true
                    #'acceptOnLostFocus:' true
                    #'hasBorder:' false
                )
                 #(#LabelSpec
                    #'name:' 'Text Label'
                    #'layout:' #(#LayoutFrame 20 0 50 0 115 0 66 0)
                    #'label:' 'Text Label'
                    #'level:' 0
                    #'adjust:' #center
                    #'hasCharacterOrientedLabel:' true
                )
                 #(#TextEditorSpec
                    #'name:' 'EditTextView'
                    #'layout:' #(#LayoutFrame 130 0 20 0 234 0 100 0)
                    #'hasHorizontalScrollBar:' true
                    #'hasVerticalScrollBar:' true
                    #'miniScrollerHorizontal:' false
                    #'miniScrollerVertical:' false
                )
                 #(#TextEditorSpec
                    #'name:' 'EditTextView miniH'
                    #'layout:' #(#LayoutFrame 246 0 20 0 350 0 100 0)
                    #'hasHorizontalScrollBar:' true
                    #'hasVerticalScrollBar:' true
                    #'miniScrollerHorizontal:' true
                    #'miniScrollerVertical:' false
                )
                 #(#SequenceViewSpec
                    #'name:' 'SelectionInListView miniH'
                    #'layout:' #(#LayoutFrame 246 0 116 0 350 0 196 0)
                    #'hasHorizontalScrollBar:' true
                    #'hasVerticalScrollBar:' true
                    #'miniScrollerHorizontal:' true
                    #'miniScrollerVertical:' false
                )
                 #(#SequenceViewSpec
                    #'name:' 'SelectionInListView'
                    #'layout:' #(#LayoutFrame 130 0 116 0 234 0 196 0)
                    #'hasHorizontalScrollBar:' true
                    #'hasVerticalScrollBar:' true
                    #'miniScrollerHorizontal:' false
                    #'miniScrollerVertical:' false
                )
                 #(#TextEditorSpec
                    #'name:' 'EditTextView noH'
                    #'layout:' #(#LayoutFrame 364 0 20 0 468 0 100 0)
                    #'hasHorizontalScrollBar:' false
                    #'hasVerticalScrollBar:' true
                    #'miniScrollerHorizontal:' false
                    #'miniScrollerVertical:' false
                )
                 #(#SequenceViewSpec
                    #'name:' 'scrollableView2'
                    #'layout:' #(#LayoutFrame 365 0 116 0 469 0 196 0)
                    #'hasHorizontalScrollBar:' false
                    #'hasVerticalScrollBar:' true
                    #'miniScrollerHorizontal:' false
                    #'miniScrollerVertical:' false
                )
              )
          )
      )
!

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 457 177)
          )
          #'component:' 
           #(#SpecCollection
              #'collection:' 
               #(
                 #(#FramedBoxSpec
                    #'name:' 'FramedBox'
                    #'layout:' #(#LayoutFrame 20 0 20 0 125 0 75 0)
                    #'label:' 'FramedBox'
                    #'labelPosition:' #topCenter
                    #'showFrame:' true
                )
                 #(#ViewSpec
                    #'name:' 'View'
                    #'layout:' #(#LayoutFrame 134 0 20 0 239 0 75 0)
                    #'component:' 
                     #(#SpecCollection
                        #'collection:' 
                         #(
                           #(#LabelSpec
                              #'name:' 'label1'
                              #'layout:' #(#Point 3 2)
                              #'label:' 'View'
                              #'level:' 0
                              #'adjust:' #center
                              #'hasCharacterOrientedLabel:' true
                              #'canUIDrag:' false
                          )
                        )
                    )
                )
                 #(#SubCanvasSpec
                    #'name:' 'SubCanvas'
                    #'layout:' #(#LayoutFrame 134 0 87 0 239 0 142 0)
                )
                 #(#LabelSpec
                    #'name:' 'label2'
                    #'layout:' #(#Point 136 87)
                    #'label:' 'SubCanvas'
                    #'level:' 0
                    #'adjust:' #center
                    #'hasCharacterOrientedLabel:' true
                    #'canUIDrag:' false
                )
                 #(#DividerSpec
                    #'name:' 'Horizontal Seperator'
                    #'layout:' #(#LayoutFrame 292 0 20 0 356 0 37 0)
                    #'orientation:' #horizontal
                )
                 #(#DividerSpec
                    #'name:' 'Vertical Seperator'
                    #'layout:' #(#LayoutFrame 267 0 20 0 286 0 75 0)
                    #'orientation:' #vertical
                )
                 #(#TabViewSpec
                    #'name:' 'TabView'
                    #'layout:' #(#LayoutFrame 20 0 87 0 125 0 142 0)
                    #'tabWidget:' #Window
                    #'direction:' #top
                    #'fitLastRow:' true
                    #'moveSelectedRow:' true
                )
                 #(#LabelSpec
                    #'name:' 'label3'
                    #'layout:' #(#Point 23 87)
                    #'label:' 'TabView'
                    #'level:' 0
                    #'adjust:' #center
                    #'hasCharacterOrientedLabel:' true
                    #'canUIDrag:' false
                )
              )
          )
      )
! !

!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 preferredSizeXorY.
    ].
    tabView bottomInset:(y negated).
    window  topInset:y.


!

update:something with:aParameter from:changedObject
    "tabView might change its size
    "
    (something == #preferredExtent 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|

    (state ~~ 0 and:[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.
    inputView delegate:(KeyboardForwarder from:inputView toView:tabView).


    tabView tabWidget:#Window.
    tabView useIndex:true.

    tabView styleAt:#expandSelection   put:6@2.
    tabView font:(Label defaultFont).
    tabView addDependent:self.
    self delegate:(KeyboardForwarder from:self toView:tabView).

    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$'
! !