Tools__ViewTreeModel.st
author Claus Gittinger <cg@exept.de>
Mon, 23 Jun 2008 19:37:51 +0200
changeset 2368 99f14af1d5ec
parent 2176 eef25c370979
child 2404 06d51e254934
permissions -rw-r--r--
oops
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
2176
eef25c370979 initial checkin
ca
parents:
diff changeset
     1
"{ Package: 'stx:libtool2' }"
eef25c370979 initial checkin
ca
parents:
diff changeset
     2
eef25c370979 initial checkin
ca
parents:
diff changeset
     3
"{ NameSpace: Tools }"
eef25c370979 initial checkin
ca
parents:
diff changeset
     4
eef25c370979 initial checkin
ca
parents:
diff changeset
     5
ValueModel subclass:#ViewTreeModel
eef25c370979 initial checkin
ca
parents:
diff changeset
     6
	instanceVariableNames:'lockSema selectedSuperItems selection hiddenLevel listOfItems
eef25c370979 initial checkin
ca
parents:
diff changeset
     7
		inputEventAction mappedViewAction beforeSelectionChangedAction
eef25c370979 initial checkin
ca
parents:
diff changeset
     8
		testMode icons timedUpdateTask selectOnClickHolder'
eef25c370979 initial checkin
ca
parents:
diff changeset
     9
	classVariableNames:''
eef25c370979 initial checkin
ca
parents:
diff changeset
    10
	poolDictionaries:''
eef25c370979 initial checkin
ca
parents:
diff changeset
    11
	category:'A-Views-Support'
eef25c370979 initial checkin
ca
parents:
diff changeset
    12
!
eef25c370979 initial checkin
ca
parents:
diff changeset
    13
eef25c370979 initial checkin
ca
parents:
diff changeset
    14
HierarchicalList subclass:#ItemList
eef25c370979 initial checkin
ca
parents:
diff changeset
    15
	instanceVariableNames:'treeModel eventHook eventHookInitialized'
eef25c370979 initial checkin
ca
parents:
diff changeset
    16
	classVariableNames:''
eef25c370979 initial checkin
ca
parents:
diff changeset
    17
	poolDictionaries:''
eef25c370979 initial checkin
ca
parents:
diff changeset
    18
	privateIn:ViewTreeModel
eef25c370979 initial checkin
ca
parents:
diff changeset
    19
!
eef25c370979 initial checkin
ca
parents:
diff changeset
    20
eef25c370979 initial checkin
ca
parents:
diff changeset
    21
!ViewTreeModel class methodsFor:'documentation'!
eef25c370979 initial checkin
ca
parents:
diff changeset
    22
eef25c370979 initial checkin
ca
parents:
diff changeset
    23
documentation
eef25c370979 initial checkin
ca
parents:
diff changeset
    24
"
eef25c370979 initial checkin
ca
parents:
diff changeset
    25
    Instances of ViewTreeModel can be used as model on a View and all
eef25c370979 initial checkin
ca
parents:
diff changeset
    26
    it contained subviews for a HierarchicalListView.
eef25c370979 initial checkin
ca
parents:
diff changeset
    27
    The model keeps two values, the hierarchical representation of the views
eef25c370979 initial checkin
ca
parents:
diff changeset
    28
    and subviews (ViewTreeItems) and the selection, a list of selected ViewTreeItems's.
eef25c370979 initial checkin
ca
parents:
diff changeset
    29
    It shows the selected items highlighted.
eef25c370979 initial checkin
ca
parents:
diff changeset
    30
eef25c370979 initial checkin
ca
parents:
diff changeset
    31
eef25c370979 initial checkin
ca
parents:
diff changeset
    32
    [Instance variables:]
eef25c370979 initial checkin
ca
parents:
diff changeset
    33
        lockSema            <Semaphore>         lock selection notifications and redraws
eef25c370979 initial checkin
ca
parents:
diff changeset
    34
eef25c370979 initial checkin
ca
parents:
diff changeset
    35
        testMode            <Boolean>           true, the selection is not highlighted and
eef25c370979 initial checkin
ca
parents:
diff changeset
    36
                                                all input events are eaten.
eef25c370979 initial checkin
ca
parents:
diff changeset
    37
eef25c370979 initial checkin
ca
parents:
diff changeset
    38
        selection           <Sequence or nil>   selected items or nil
eef25c370979 initial checkin
ca
parents:
diff changeset
    39
eef25c370979 initial checkin
ca
parents:
diff changeset
    40
        hiddenLevel         <Integer>           internal use; redrawing the selection
eef25c370979 initial checkin
ca
parents:
diff changeset
    41
                                                only is done if the counter is 0.
eef25c370979 initial checkin
ca
parents:
diff changeset
    42
eef25c370979 initial checkin
ca
parents:
diff changeset
    43
        listOfItems         <HierarchicalList>  hiearchical list build from existing items.
eef25c370979 initial checkin
ca
parents:
diff changeset
    44
eef25c370979 initial checkin
ca
parents:
diff changeset
    45
        selectedSuperItems  <Sequence>          list of selected super items; items selected
eef25c370979 initial checkin
ca
parents:
diff changeset
    46
                                                but not contained in another selected item.
eef25c370979 initial checkin
ca
parents:
diff changeset
    47
eef25c370979 initial checkin
ca
parents:
diff changeset
    48
        inputEventAction    <Action>            called for each InputEvent
eef25c370979 initial checkin
ca
parents:
diff changeset
    49
eef25c370979 initial checkin
ca
parents:
diff changeset
    50
        mappedViewAction    <Action>            called for a new mapped view which
eef25c370979 initial checkin
ca
parents:
diff changeset
    51
                                                can not be found in the current item list.
eef25c370979 initial checkin
ca
parents:
diff changeset
    52
eef25c370979 initial checkin
ca
parents:
diff changeset
    53
        beforeSelectionChangedAction <Action>   called before the selection changed
eef25c370979 initial checkin
ca
parents:
diff changeset
    54
eef25c370979 initial checkin
ca
parents:
diff changeset
    55
    [author:]
eef25c370979 initial checkin
ca
parents:
diff changeset
    56
        Claus Atzkern
eef25c370979 initial checkin
ca
parents:
diff changeset
    57
eef25c370979 initial checkin
ca
parents:
diff changeset
    58
    [see also:]
eef25c370979 initial checkin
ca
parents:
diff changeset
    59
        ViewTreeItem
eef25c370979 initial checkin
ca
parents:
diff changeset
    60
"
eef25c370979 initial checkin
ca
parents:
diff changeset
    61
!
eef25c370979 initial checkin
ca
parents:
diff changeset
    62
eef25c370979 initial checkin
ca
parents:
diff changeset
    63
examples
eef25c370979 initial checkin
ca
parents:
diff changeset
    64
"
eef25c370979 initial checkin
ca
parents:
diff changeset
    65
    example 1: pick any window and show views and contained views
eef25c370979 initial checkin
ca
parents:
diff changeset
    66
                                                                                [exBegin]
eef25c370979 initial checkin
ca
parents:
diff changeset
    67
    |top sel model panel|
eef25c370979 initial checkin
ca
parents:
diff changeset
    68
eef25c370979 initial checkin
ca
parents:
diff changeset
    69
    model := ViewTreeModel new.
eef25c370979 initial checkin
ca
parents:
diff changeset
    70
    top   := StandardSystemView new; extent:440@400.
eef25c370979 initial checkin
ca
parents:
diff changeset
    71
    sel   := ScrollableView for:HierarchicalListView miniScroller:true origin:0.0@0.0 corner:1.0@1.0 in:top.
eef25c370979 initial checkin
ca
parents:
diff changeset
    72
    sel bottomInset:24.
eef25c370979 initial checkin
ca
parents:
diff changeset
    73
eef25c370979 initial checkin
ca
parents:
diff changeset
    74
    panel := HorizontalPanelView origin:0.0@1.0 corner:1.0@1.0 in:top.
eef25c370979 initial checkin
ca
parents:
diff changeset
    75
    panel topInset:-24.
eef25c370979 initial checkin
ca
parents:
diff changeset
    76
    panel horizontalLayout:#fitSpace.
eef25c370979 initial checkin
ca
parents:
diff changeset
    77
eef25c370979 initial checkin
ca
parents:
diff changeset
    78
    Button label:'Exit'       action:[model rootItem:nil. top destroy] in:panel.
eef25c370979 initial checkin
ca
parents:
diff changeset
    79
    Button label:'Pick Views' action:[  |win|
eef25c370979 initial checkin
ca
parents:
diff changeset
    80
                                        (     (win := Screen current viewFromUser) notNil
eef25c370979 initial checkin
ca
parents:
diff changeset
    81
                                         and:[(win := win topView) ~~ Screen current rootView
eef25c370979 initial checkin
ca
parents:
diff changeset
    82
                                         and:[win ~~ top]]
eef25c370979 initial checkin
ca
parents:
diff changeset
    83
                                        ) ifTrue:[
eef25c370979 initial checkin
ca
parents:
diff changeset
    84
                                            model rootItem:(ViewTreeItem buildViewsFrom:win)
eef25c370979 initial checkin
ca
parents:
diff changeset
    85
                                        ] ifFalse:[
eef25c370979 initial checkin
ca
parents:
diff changeset
    86
                                            model rootItem:nil
eef25c370979 initial checkin
ca
parents:
diff changeset
    87
                                        ]
eef25c370979 initial checkin
ca
parents:
diff changeset
    88
                                     ] in:panel.
eef25c370979 initial checkin
ca
parents:
diff changeset
    89
eef25c370979 initial checkin
ca
parents:
diff changeset
    90
    sel  multipleSelectOk:true.
eef25c370979 initial checkin
ca
parents:
diff changeset
    91
    sel              list:model listOfItems.
eef25c370979 initial checkin
ca
parents:
diff changeset
    92
    sel             model:model.
eef25c370979 initial checkin
ca
parents:
diff changeset
    93
    sel          useIndex:false.
eef25c370979 initial checkin
ca
parents:
diff changeset
    94
eef25c370979 initial checkin
ca
parents:
diff changeset
    95
    sel doubleClickAction:[:i| |el|
eef25c370979 initial checkin
ca
parents:
diff changeset
    96
        el := model listOfItems at:i.
eef25c370979 initial checkin
ca
parents:
diff changeset
    97
        el spec notNil ifTrue:[ el spec   inspect ] ifFalse:[ el widget inspect ]
eef25c370979 initial checkin
ca
parents:
diff changeset
    98
    ].
eef25c370979 initial checkin
ca
parents:
diff changeset
    99
    sel indicatorAction:[:i| (model listOfItems at:i) toggleExpand ].
eef25c370979 initial checkin
ca
parents:
diff changeset
   100
eef25c370979 initial checkin
ca
parents:
diff changeset
   101
    model inputEventAction:[:anEvent| |item|
eef25c370979 initial checkin
ca
parents:
diff changeset
   102
        anEvent isButtonEvent ifTrue:[
eef25c370979 initial checkin
ca
parents:
diff changeset
   103
            anEvent isButtonPressEvent ifTrue:[
eef25c370979 initial checkin
ca
parents:
diff changeset
   104
                model selectedItem:(model listOfItems detectItemRespondsToView:(anEvent view)).
eef25c370979 initial checkin
ca
parents:
diff changeset
   105
            ] ifFalse:[
eef25c370979 initial checkin
ca
parents:
diff changeset
   106
                anEvent type == #'buttonMultiPress:x:y:' ifTrue:[
eef25c370979 initial checkin
ca
parents:
diff changeset
   107
                    (item := model selectedItem) notNil ifTrue:[item widget inspect]
eef25c370979 initial checkin
ca
parents:
diff changeset
   108
                ]
eef25c370979 initial checkin
ca
parents:
diff changeset
   109
            ]
eef25c370979 initial checkin
ca
parents:
diff changeset
   110
        ]
eef25c370979 initial checkin
ca
parents:
diff changeset
   111
    ].
eef25c370979 initial checkin
ca
parents:
diff changeset
   112
eef25c370979 initial checkin
ca
parents:
diff changeset
   113
    top openAndWait.
eef25c370979 initial checkin
ca
parents:
diff changeset
   114
    [[top shown] whileTrue:[Delay waitForSeconds:0.5]. model rootItem:nil] forkAt:8
eef25c370979 initial checkin
ca
parents:
diff changeset
   115
eef25c370979 initial checkin
ca
parents:
diff changeset
   116
                                                                                [exEnd]
eef25c370979 initial checkin
ca
parents:
diff changeset
   117
"
eef25c370979 initial checkin
ca
parents:
diff changeset
   118
! !
eef25c370979 initial checkin
ca
parents:
diff changeset
   119
eef25c370979 initial checkin
ca
parents:
diff changeset
   120
!ViewTreeModel methodsFor:'accessing'!
eef25c370979 initial checkin
ca
parents:
diff changeset
   121
eef25c370979 initial checkin
ca
parents:
diff changeset
   122
application:anApplication
eef25c370979 initial checkin
ca
parents:
diff changeset
   123
    listOfItems application:anApplication.
eef25c370979 initial checkin
ca
parents:
diff changeset
   124
!
eef25c370979 initial checkin
ca
parents:
diff changeset
   125
eef25c370979 initial checkin
ca
parents:
diff changeset
   126
listOfItems
eef25c370979 initial checkin
ca
parents:
diff changeset
   127
    "hiearchical list build from existing items
eef25c370979 initial checkin
ca
parents:
diff changeset
   128
    "
eef25c370979 initial checkin
ca
parents:
diff changeset
   129
    ^ listOfItems
eef25c370979 initial checkin
ca
parents:
diff changeset
   130
!
eef25c370979 initial checkin
ca
parents:
diff changeset
   131
eef25c370979 initial checkin
ca
parents:
diff changeset
   132
rootItem
eef25c370979 initial checkin
ca
parents:
diff changeset
   133
    "get the rootItem the event viewer is established on
eef25c370979 initial checkin
ca
parents:
diff changeset
   134
    "
eef25c370979 initial checkin
ca
parents:
diff changeset
   135
    ^ listOfItems root
eef25c370979 initial checkin
ca
parents:
diff changeset
   136
!
eef25c370979 initial checkin
ca
parents:
diff changeset
   137
eef25c370979 initial checkin
ca
parents:
diff changeset
   138
rootItem:anItem
eef25c370979 initial checkin
ca
parents:
diff changeset
   139
    "set the rootItem the event viewer is established on
eef25c370979 initial checkin
ca
parents:
diff changeset
   140
    "
eef25c370979 initial checkin
ca
parents:
diff changeset
   141
    |expanded|
eef25c370979 initial checkin
ca
parents:
diff changeset
   142
eef25c370979 initial checkin
ca
parents:
diff changeset
   143
    timedUpdateTask := nil.
eef25c370979 initial checkin
ca
parents:
diff changeset
   144
eef25c370979 initial checkin
ca
parents:
diff changeset
   145
    lockSema critical:[
eef25c370979 initial checkin
ca
parents:
diff changeset
   146
        anItem notNil ifTrue:[ expanded := anItem isExpanded ]
eef25c370979 initial checkin
ca
parents:
diff changeset
   147
                     ifFalse:[ expanded := false ].
eef25c370979 initial checkin
ca
parents:
diff changeset
   148
eef25c370979 initial checkin
ca
parents:
diff changeset
   149
        self value:nil.
eef25c370979 initial checkin
ca
parents:
diff changeset
   150
        listOfItems root:anItem.
eef25c370979 initial checkin
ca
parents:
diff changeset
   151
eef25c370979 initial checkin
ca
parents:
diff changeset
   152
        anItem notNil ifTrue:[
eef25c370979 initial checkin
ca
parents:
diff changeset
   153
            timedUpdateTask := Process for:[ self timedUpdateTaskCycle ] priority:8.
eef25c370979 initial checkin
ca
parents:
diff changeset
   154
            timedUpdateTask name:'Update'.
eef25c370979 initial checkin
ca
parents:
diff changeset
   155
            timedUpdateTask resume.
eef25c370979 initial checkin
ca
parents:
diff changeset
   156
        ].
eef25c370979 initial checkin
ca
parents:
diff changeset
   157
    ].
eef25c370979 initial checkin
ca
parents:
diff changeset
   158
eef25c370979 initial checkin
ca
parents:
diff changeset
   159
    (expanded and:[anItem notNil]) ifTrue:[
eef25c370979 initial checkin
ca
parents:
diff changeset
   160
        anItem expand
eef25c370979 initial checkin
ca
parents:
diff changeset
   161
    ].
eef25c370979 initial checkin
ca
parents:
diff changeset
   162
    ^ anItem
eef25c370979 initial checkin
ca
parents:
diff changeset
   163
!
eef25c370979 initial checkin
ca
parents:
diff changeset
   164
eef25c370979 initial checkin
ca
parents:
diff changeset
   165
rootView
eef25c370979 initial checkin
ca
parents:
diff changeset
   166
    "get the top widget the event viewer is established on, a View
eef25c370979 initial checkin
ca
parents:
diff changeset
   167
    "
eef25c370979 initial checkin
ca
parents:
diff changeset
   168
    ^ listOfItems rootView
eef25c370979 initial checkin
ca
parents:
diff changeset
   169
! !
eef25c370979 initial checkin
ca
parents:
diff changeset
   170
eef25c370979 initial checkin
ca
parents:
diff changeset
   171
!ViewTreeModel methodsFor:'accessing actions'!
eef25c370979 initial checkin
ca
parents:
diff changeset
   172
eef25c370979 initial checkin
ca
parents:
diff changeset
   173
beforeSelectionChangedAction
eef25c370979 initial checkin
ca
parents:
diff changeset
   174
    "none argument action which is called before
eef25c370979 initial checkin
ca
parents:
diff changeset
   175
     the selection changed
eef25c370979 initial checkin
ca
parents:
diff changeset
   176
    "
eef25c370979 initial checkin
ca
parents:
diff changeset
   177
    ^ beforeSelectionChangedAction
eef25c370979 initial checkin
ca
parents:
diff changeset
   178
!
eef25c370979 initial checkin
ca
parents:
diff changeset
   179
eef25c370979 initial checkin
ca
parents:
diff changeset
   180
beforeSelectionChangedAction:aNoneArgBlock
eef25c370979 initial checkin
ca
parents:
diff changeset
   181
    "none argument action which is called before
eef25c370979 initial checkin
ca
parents:
diff changeset
   182
     the selection changed
eef25c370979 initial checkin
ca
parents:
diff changeset
   183
    "
eef25c370979 initial checkin
ca
parents:
diff changeset
   184
    beforeSelectionChangedAction := aNoneArgBlock.
eef25c370979 initial checkin
ca
parents:
diff changeset
   185
!
eef25c370979 initial checkin
ca
parents:
diff changeset
   186
eef25c370979 initial checkin
ca
parents:
diff changeset
   187
inputEventAction
eef25c370979 initial checkin
ca
parents:
diff changeset
   188
    "called for each input event; the argument to the action is the WindowEvent
eef25c370979 initial checkin
ca
parents:
diff changeset
   189
    "
eef25c370979 initial checkin
ca
parents:
diff changeset
   190
    ^ inputEventAction
eef25c370979 initial checkin
ca
parents:
diff changeset
   191
!
eef25c370979 initial checkin
ca
parents:
diff changeset
   192
eef25c370979 initial checkin
ca
parents:
diff changeset
   193
inputEventAction:aOneArgActionTheEvent
eef25c370979 initial checkin
ca
parents:
diff changeset
   194
    "called for each input event; the argument to the action is the WindowEvent
eef25c370979 initial checkin
ca
parents:
diff changeset
   195
    "
eef25c370979 initial checkin
ca
parents:
diff changeset
   196
    inputEventAction := aOneArgActionTheEvent.
eef25c370979 initial checkin
ca
parents:
diff changeset
   197
!
eef25c370979 initial checkin
ca
parents:
diff changeset
   198
eef25c370979 initial checkin
ca
parents:
diff changeset
   199
mappedViewAction
eef25c370979 initial checkin
ca
parents:
diff changeset
   200
    "called for a new mapped view which can not be found
eef25c370979 initial checkin
ca
parents:
diff changeset
   201
     in the current item list
eef25c370979 initial checkin
ca
parents:
diff changeset
   202
    "
eef25c370979 initial checkin
ca
parents:
diff changeset
   203
    ^ mappedViewAction
eef25c370979 initial checkin
ca
parents:
diff changeset
   204
!
eef25c370979 initial checkin
ca
parents:
diff changeset
   205
eef25c370979 initial checkin
ca
parents:
diff changeset
   206
mappedViewAction:aOneArgBlockTheMappedView
eef25c370979 initial checkin
ca
parents:
diff changeset
   207
    "called for a new mapped view which can not be found
eef25c370979 initial checkin
ca
parents:
diff changeset
   208
     in the current item list
eef25c370979 initial checkin
ca
parents:
diff changeset
   209
    "
eef25c370979 initial checkin
ca
parents:
diff changeset
   210
    mappedViewAction := aOneArgBlockTheMappedView
eef25c370979 initial checkin
ca
parents:
diff changeset
   211
! !
eef25c370979 initial checkin
ca
parents:
diff changeset
   212
eef25c370979 initial checkin
ca
parents:
diff changeset
   213
!ViewTreeModel methodsFor:'accessing look'!
eef25c370979 initial checkin
ca
parents:
diff changeset
   214
eef25c370979 initial checkin
ca
parents:
diff changeset
   215
iconAt:aKey ifNonePut:aNoneArgBlock
eef25c370979 initial checkin
ca
parents:
diff changeset
   216
    |icon view|
eef25c370979 initial checkin
ca
parents:
diff changeset
   217
eef25c370979 initial checkin
ca
parents:
diff changeset
   218
    icon := icons at:aKey ifAbsent:nil.
eef25c370979 initial checkin
ca
parents:
diff changeset
   219
    icon notNil ifTrue:[^ icon].
eef25c370979 initial checkin
ca
parents:
diff changeset
   220
eef25c370979 initial checkin
ca
parents:
diff changeset
   221
    icon := aNoneArgBlock value.
eef25c370979 initial checkin
ca
parents:
diff changeset
   222
    icon isNil ifTrue:[^ nil].
eef25c370979 initial checkin
ca
parents:
diff changeset
   223
eef25c370979 initial checkin
ca
parents:
diff changeset
   224
    view := self rootView.
eef25c370979 initial checkin
ca
parents:
diff changeset
   225
    view isNil ifTrue:[^ icon].
eef25c370979 initial checkin
ca
parents:
diff changeset
   226
eef25c370979 initial checkin
ca
parents:
diff changeset
   227
    icon := icon copy onDevice:(view device).
eef25c370979 initial checkin
ca
parents:
diff changeset
   228
    icon isImage ifTrue:[
eef25c370979 initial checkin
ca
parents:
diff changeset
   229
        icon clearMaskedPixels.
eef25c370979 initial checkin
ca
parents:
diff changeset
   230
    ].
eef25c370979 initial checkin
ca
parents:
diff changeset
   231
    icons at:aKey put:icon.
eef25c370979 initial checkin
ca
parents:
diff changeset
   232
    ^ icon
eef25c370979 initial checkin
ca
parents:
diff changeset
   233
! !
eef25c370979 initial checkin
ca
parents:
diff changeset
   234
eef25c370979 initial checkin
ca
parents:
diff changeset
   235
!ViewTreeModel methodsFor:'accessing visibility'!
eef25c370979 initial checkin
ca
parents:
diff changeset
   236
eef25c370979 initial checkin
ca
parents:
diff changeset
   237
selectOnClickHolder
eef25c370979 initial checkin
ca
parents:
diff changeset
   238
    "boolean holder, which indicates whether the selection will change on click
eef25c370979 initial checkin
ca
parents:
diff changeset
   239
    "
eef25c370979 initial checkin
ca
parents:
diff changeset
   240
    ^ selectOnClickHolder
eef25c370979 initial checkin
ca
parents:
diff changeset
   241
!
eef25c370979 initial checkin
ca
parents:
diff changeset
   242
eef25c370979 initial checkin
ca
parents:
diff changeset
   243
signalHiddenLevel
eef25c370979 initial checkin
ca
parents:
diff changeset
   244
    "show the selection if signaled; increments hiddenLevel
eef25c370979 initial checkin
ca
parents:
diff changeset
   245
     see: #waitHiddenLevel
eef25c370979 initial checkin
ca
parents:
diff changeset
   246
    "
eef25c370979 initial checkin
ca
parents:
diff changeset
   247
    (hiddenLevel := hiddenLevel - 1) < 1 ifTrue:[
eef25c370979 initial checkin
ca
parents:
diff changeset
   248
        hiddenLevel := 0.
eef25c370979 initial checkin
ca
parents:
diff changeset
   249
        self invalidateSelection.
eef25c370979 initial checkin
ca
parents:
diff changeset
   250
    ].
eef25c370979 initial checkin
ca
parents:
diff changeset
   251
!
eef25c370979 initial checkin
ca
parents:
diff changeset
   252
eef25c370979 initial checkin
ca
parents:
diff changeset
   253
testMode
eef25c370979 initial checkin
ca
parents:
diff changeset
   254
    "false, than all input events are eaten and the selection
eef25c370979 initial checkin
ca
parents:
diff changeset
   255
     is shown on the target view
eef25c370979 initial checkin
ca
parents:
diff changeset
   256
    "
eef25c370979 initial checkin
ca
parents:
diff changeset
   257
    ^ testMode
eef25c370979 initial checkin
ca
parents:
diff changeset
   258
!
eef25c370979 initial checkin
ca
parents:
diff changeset
   259
eef25c370979 initial checkin
ca
parents:
diff changeset
   260
testMode:aBoolean
eef25c370979 initial checkin
ca
parents:
diff changeset
   261
    "false, than all input events are eaten and the selection
eef25c370979 initial checkin
ca
parents:
diff changeset
   262
     is shown on the target view
eef25c370979 initial checkin
ca
parents:
diff changeset
   263
    "
eef25c370979 initial checkin
ca
parents:
diff changeset
   264
    testMode ~~ aBoolean ifTrue:[
eef25c370979 initial checkin
ca
parents:
diff changeset
   265
        self withSelectionHiddenDo:[
eef25c370979 initial checkin
ca
parents:
diff changeset
   266
            self value:nil.
eef25c370979 initial checkin
ca
parents:
diff changeset
   267
            testMode := aBoolean.
eef25c370979 initial checkin
ca
parents:
diff changeset
   268
        ].
eef25c370979 initial checkin
ca
parents:
diff changeset
   269
    ].
eef25c370979 initial checkin
ca
parents:
diff changeset
   270
!
eef25c370979 initial checkin
ca
parents:
diff changeset
   271
eef25c370979 initial checkin
ca
parents:
diff changeset
   272
waitHiddenLevel
eef25c370979 initial checkin
ca
parents:
diff changeset
   273
    "hide the selection until signaled; increments hiddenLevel
eef25c370979 initial checkin
ca
parents:
diff changeset
   274
     see: #signalHiddenLevel
eef25c370979 initial checkin
ca
parents:
diff changeset
   275
    "
eef25c370979 initial checkin
ca
parents:
diff changeset
   276
    self redrawUnselected:selection andLock:true
eef25c370979 initial checkin
ca
parents:
diff changeset
   277
!
eef25c370979 initial checkin
ca
parents:
diff changeset
   278
eef25c370979 initial checkin
ca
parents:
diff changeset
   279
withSelectionHiddenDo:aNoneArgumentBlock
eef25c370979 initial checkin
ca
parents:
diff changeset
   280
    "apply block with selection hidden
eef25c370979 initial checkin
ca
parents:
diff changeset
   281
    "
eef25c370979 initial checkin
ca
parents:
diff changeset
   282
eef25c370979 initial checkin
ca
parents:
diff changeset
   283
    [   self waitHiddenLevel.
eef25c370979 initial checkin
ca
parents:
diff changeset
   284
eef25c370979 initial checkin
ca
parents:
diff changeset
   285
        aNoneArgumentBlock value
eef25c370979 initial checkin
ca
parents:
diff changeset
   286
eef25c370979 initial checkin
ca
parents:
diff changeset
   287
    ] valueNowOrOnUnwindDo:[
eef25c370979 initial checkin
ca
parents:
diff changeset
   288
        self signalHiddenLevel.
eef25c370979 initial checkin
ca
parents:
diff changeset
   289
    ].
eef25c370979 initial checkin
ca
parents:
diff changeset
   290
! !
eef25c370979 initial checkin
ca
parents:
diff changeset
   291
eef25c370979 initial checkin
ca
parents:
diff changeset
   292
!ViewTreeModel methodsFor:'change & update'!
eef25c370979 initial checkin
ca
parents:
diff changeset
   293
eef25c370979 initial checkin
ca
parents:
diff changeset
   294
timedUpdateTaskCycle
eef25c370979 initial checkin
ca
parents:
diff changeset
   295
    |view myTaskId|
eef25c370979 initial checkin
ca
parents:
diff changeset
   296
eef25c370979 initial checkin
ca
parents:
diff changeset
   297
    myTaskId := timedUpdateTask.
eef25c370979 initial checkin
ca
parents:
diff changeset
   298
eef25c370979 initial checkin
ca
parents:
diff changeset
   299
    listOfItems root notNil ifTrue:[
eef25c370979 initial checkin
ca
parents:
diff changeset
   300
        view := listOfItems root widget.
eef25c370979 initial checkin
ca
parents:
diff changeset
   301
    ].
eef25c370979 initial checkin
ca
parents:
diff changeset
   302
eef25c370979 initial checkin
ca
parents:
diff changeset
   303
    [ view notNil ] whileTrue:[
eef25c370979 initial checkin
ca
parents:
diff changeset
   304
        Delay waitForSeconds:0.5.
eef25c370979 initial checkin
ca
parents:
diff changeset
   305
        
eef25c370979 initial checkin
ca
parents:
diff changeset
   306
        (myTaskId == timedUpdateTask and:[view id notNil]) ifFalse:[
eef25c370979 initial checkin
ca
parents:
diff changeset
   307
            view := nil.
eef25c370979 initial checkin
ca
parents:
diff changeset
   308
        ] ifTrue:[
eef25c370979 initial checkin
ca
parents:
diff changeset
   309
            (view sensor hasUserEvent:#updateChildren for:self) ifFalse:[
eef25c370979 initial checkin
ca
parents:
diff changeset
   310
                view sensor pushUserEvent:#updateChildren for:self.
eef25c370979 initial checkin
ca
parents:
diff changeset
   311
            ].
eef25c370979 initial checkin
ca
parents:
diff changeset
   312
        ].
eef25c370979 initial checkin
ca
parents:
diff changeset
   313
    ].
eef25c370979 initial checkin
ca
parents:
diff changeset
   314
    timedUpdateTask == myTaskId ifTrue:[
eef25c370979 initial checkin
ca
parents:
diff changeset
   315
        timedUpdateTask := nil.
eef25c370979 initial checkin
ca
parents:
diff changeset
   316
        listOfItems root:nil.
eef25c370979 initial checkin
ca
parents:
diff changeset
   317
    ].
eef25c370979 initial checkin
ca
parents:
diff changeset
   318
!
eef25c370979 initial checkin
ca
parents:
diff changeset
   319
eef25c370979 initial checkin
ca
parents:
diff changeset
   320
updateChildren
eef25c370979 initial checkin
ca
parents:
diff changeset
   321
    |rootItem|
eef25c370979 initial checkin
ca
parents:
diff changeset
   322
eef25c370979 initial checkin
ca
parents:
diff changeset
   323
    rootItem := listOfItems root.
eef25c370979 initial checkin
ca
parents:
diff changeset
   324
    rootItem isNil ifTrue:[^ self].
eef25c370979 initial checkin
ca
parents:
diff changeset
   325
eef25c370979 initial checkin
ca
parents:
diff changeset
   326
    rootItem exists ifFalse:[
eef25c370979 initial checkin
ca
parents:
diff changeset
   327
        listOfItems root:nil.
eef25c370979 initial checkin
ca
parents:
diff changeset
   328
    ] ifTrue:[
eef25c370979 initial checkin
ca
parents:
diff changeset
   329
        rootItem updateChildren.
eef25c370979 initial checkin
ca
parents:
diff changeset
   330
    ].
eef25c370979 initial checkin
ca
parents:
diff changeset
   331
! !
eef25c370979 initial checkin
ca
parents:
diff changeset
   332
eef25c370979 initial checkin
ca
parents:
diff changeset
   333
!ViewTreeModel methodsFor:'event processing'!
eef25c370979 initial checkin
ca
parents:
diff changeset
   334
eef25c370979 initial checkin
ca
parents:
diff changeset
   335
processEvent:anEvent
eef25c370979 initial checkin
ca
parents:
diff changeset
   336
    "catch and process all WindowEvents for the rootComponent and its contained
eef25c370979 initial checkin
ca
parents:
diff changeset
   337
     widgets; redraw selection in case of damage ....
eef25c370979 initial checkin
ca
parents:
diff changeset
   338
    "
eef25c370979 initial checkin
ca
parents:
diff changeset
   339
    |evView item rootView|
eef25c370979 initial checkin
ca
parents:
diff changeset
   340
eef25c370979 initial checkin
ca
parents:
diff changeset
   341
    evView := anEvent view.
eef25c370979 initial checkin
ca
parents:
diff changeset
   342
    evView isNil ifTrue:[
eef25c370979 initial checkin
ca
parents:
diff changeset
   343
        (anEvent isMessageSendEvent and:[anEvent receiver == self]) ifFalse:[
eef25c370979 initial checkin
ca
parents:
diff changeset
   344
            ^ false
eef25c370979 initial checkin
ca
parents:
diff changeset
   345
        ].
eef25c370979 initial checkin
ca
parents:
diff changeset
   346
        anEvent value.
eef25c370979 initial checkin
ca
parents:
diff changeset
   347
        ^ true.
eef25c370979 initial checkin
ca
parents:
diff changeset
   348
    ].
eef25c370979 initial checkin
ca
parents:
diff changeset
   349
    rootView := listOfItems rootView.
eef25c370979 initial checkin
ca
parents:
diff changeset
   350
    rootView isNil ifTrue:[ ^ false ].
eef25c370979 initial checkin
ca
parents:
diff changeset
   351
eef25c370979 initial checkin
ca
parents:
diff changeset
   352
    anEvent isConfigureEvent ifTrue:[
eef25c370979 initial checkin
ca
parents:
diff changeset
   353
        hiddenLevel == 0 ifTrue:[
eef25c370979 initial checkin
ca
parents:
diff changeset
   354
            self redrawUnselected:selection andLock:false.
eef25c370979 initial checkin
ca
parents:
diff changeset
   355
        ].
eef25c370979 initial checkin
ca
parents:
diff changeset
   356
        ^ false
eef25c370979 initial checkin
ca
parents:
diff changeset
   357
    ].
eef25c370979 initial checkin
ca
parents:
diff changeset
   358
eef25c370979 initial checkin
ca
parents:
diff changeset
   359
    "/ check whether view is contained within the rootView
eef25c370979 initial checkin
ca
parents:
diff changeset
   360
    (evView == rootView or:[evView isComponentOf:rootView]) ifFalse:[
eef25c370979 initial checkin
ca
parents:
diff changeset
   361
        ^ false
eef25c370979 initial checkin
ca
parents:
diff changeset
   362
    ].
eef25c370979 initial checkin
ca
parents:
diff changeset
   363
eef25c370979 initial checkin
ca
parents:
diff changeset
   364
    anEvent isInputEvent ifFalse:[
eef25c370979 initial checkin
ca
parents:
diff changeset
   365
        anEvent isDamage ifTrue:[
eef25c370979 initial checkin
ca
parents:
diff changeset
   366
            hiddenLevel == 0 ifTrue:[self invalidateSelection].
eef25c370979 initial checkin
ca
parents:
diff changeset
   367
            ^ false
eef25c370979 initial checkin
ca
parents:
diff changeset
   368
        ].
eef25c370979 initial checkin
ca
parents:
diff changeset
   369
eef25c370979 initial checkin
ca
parents:
diff changeset
   370
        anEvent isMapEvent ifTrue:[
eef25c370979 initial checkin
ca
parents:
diff changeset
   371
            mappedViewAction notNil ifTrue:[
eef25c370979 initial checkin
ca
parents:
diff changeset
   372
                item := listOfItems recursiveDetect:[:el| el widget == evView].
eef25c370979 initial checkin
ca
parents:
diff changeset
   373
                item isNil ifTrue:[ mappedViewAction value:evView ]
eef25c370979 initial checkin
ca
parents:
diff changeset
   374
            ].
eef25c370979 initial checkin
ca
parents:
diff changeset
   375
            ^ false
eef25c370979 initial checkin
ca
parents:
diff changeset
   376
        ].
eef25c370979 initial checkin
ca
parents:
diff changeset
   377
eef25c370979 initial checkin
ca
parents:
diff changeset
   378
        anEvent type == #terminate ifTrue:[
eef25c370979 initial checkin
ca
parents:
diff changeset
   379
            item := listOfItems recursiveDetect:[:el| el widget == evView].
eef25c370979 initial checkin
ca
parents:
diff changeset
   380
            item notNil ifTrue:[ self processTerminateForItem:item ].
eef25c370979 initial checkin
ca
parents:
diff changeset
   381
            ^ false
eef25c370979 initial checkin
ca
parents:
diff changeset
   382
        ].
eef25c370979 initial checkin
ca
parents:
diff changeset
   383
        ^ false
eef25c370979 initial checkin
ca
parents:
diff changeset
   384
    ].
eef25c370979 initial checkin
ca
parents:
diff changeset
   385
    anEvent isFocusEvent ifTrue:[
eef25c370979 initial checkin
ca
parents:
diff changeset
   386
        evView == rootView ifTrue:[
eef25c370979 initial checkin
ca
parents:
diff changeset
   387
            self invalidateSelection
eef25c370979 initial checkin
ca
parents:
diff changeset
   388
        ].
eef25c370979 initial checkin
ca
parents:
diff changeset
   389
        ^ testMode not.
eef25c370979 initial checkin
ca
parents:
diff changeset
   390
    ].
eef25c370979 initial checkin
ca
parents:
diff changeset
   391
    anEvent isPointerEnterLeaveEvent ifTrue:[ ^ testMode not ].
eef25c370979 initial checkin
ca
parents:
diff changeset
   392
eef25c370979 initial checkin
ca
parents:
diff changeset
   393
    testMode ifFalse:[
eef25c370979 initial checkin
ca
parents:
diff changeset
   394
        inputEventAction notNil ifTrue:[ inputEventAction value:anEvent ].
eef25c370979 initial checkin
ca
parents:
diff changeset
   395
    ] ifTrue:[
eef25c370979 initial checkin
ca
parents:
diff changeset
   396
        anEvent isButtonPressEvent ifTrue:[
eef25c370979 initial checkin
ca
parents:
diff changeset
   397
            selectOnClickHolder value ifTrue:[
eef25c370979 initial checkin
ca
parents:
diff changeset
   398
                self selectItem:(listOfItems detectItemRespondsToView:evView).
eef25c370979 initial checkin
ca
parents:
diff changeset
   399
            ].
eef25c370979 initial checkin
ca
parents:
diff changeset
   400
        ]
eef25c370979 initial checkin
ca
parents:
diff changeset
   401
    ].
eef25c370979 initial checkin
ca
parents:
diff changeset
   402
eef25c370979 initial checkin
ca
parents:
diff changeset
   403
    (hiddenLevel ~~ 0 and:[anEvent isButtonReleaseEvent]) ifTrue:[
eef25c370979 initial checkin
ca
parents:
diff changeset
   404
        hiddenLevel := 1.
eef25c370979 initial checkin
ca
parents:
diff changeset
   405
        self signalHiddenLevel.
eef25c370979 initial checkin
ca
parents:
diff changeset
   406
    ].
eef25c370979 initial checkin
ca
parents:
diff changeset
   407
eef25c370979 initial checkin
ca
parents:
diff changeset
   408
    ^ testMode not
eef25c370979 initial checkin
ca
parents:
diff changeset
   409
!
eef25c370979 initial checkin
ca
parents:
diff changeset
   410
eef25c370979 initial checkin
ca
parents:
diff changeset
   411
processTerminateForItem:anItem
eef25c370979 initial checkin
ca
parents:
diff changeset
   412
    "received terminate for an item
eef25c370979 initial checkin
ca
parents:
diff changeset
   413
    "
eef25c370979 initial checkin
ca
parents:
diff changeset
   414
    anItem remove.
eef25c370979 initial checkin
ca
parents:
diff changeset
   415
! !
eef25c370979 initial checkin
ca
parents:
diff changeset
   416
eef25c370979 initial checkin
ca
parents:
diff changeset
   417
!ViewTreeModel methodsFor:'initialization'!
eef25c370979 initial checkin
ca
parents:
diff changeset
   418
eef25c370979 initial checkin
ca
parents:
diff changeset
   419
initialize
eef25c370979 initial checkin
ca
parents:
diff changeset
   420
    "setup the default attributes
eef25c370979 initial checkin
ca
parents:
diff changeset
   421
    "
eef25c370979 initial checkin
ca
parents:
diff changeset
   422
    super initialize.
eef25c370979 initial checkin
ca
parents:
diff changeset
   423
eef25c370979 initial checkin
ca
parents:
diff changeset
   424
    hiddenLevel         := 0.
eef25c370979 initial checkin
ca
parents:
diff changeset
   425
    lockSema            := RecursionLock new.
eef25c370979 initial checkin
ca
parents:
diff changeset
   426
    listOfItems         := ItemList new on:self.
eef25c370979 initial checkin
ca
parents:
diff changeset
   427
    selectedSuperItems  := #().
eef25c370979 initial checkin
ca
parents:
diff changeset
   428
    testMode            := false.
eef25c370979 initial checkin
ca
parents:
diff changeset
   429
    icons               := IdentityDictionary new.
eef25c370979 initial checkin
ca
parents:
diff changeset
   430
    selectOnClickHolder := true asValue.
eef25c370979 initial checkin
ca
parents:
diff changeset
   431
! !
eef25c370979 initial checkin
ca
parents:
diff changeset
   432
eef25c370979 initial checkin
ca
parents:
diff changeset
   433
!ViewTreeModel methodsFor:'private selection'!
eef25c370979 initial checkin
ca
parents:
diff changeset
   434
eef25c370979 initial checkin
ca
parents:
diff changeset
   435
invalidateSelection
eef25c370979 initial checkin
ca
parents:
diff changeset
   436
    "invalidate the current selection
eef25c370979 initial checkin
ca
parents:
diff changeset
   437
    "
eef25c370979 initial checkin
ca
parents:
diff changeset
   438
    |topView|
eef25c370979 initial checkin
ca
parents:
diff changeset
   439
eef25c370979 initial checkin
ca
parents:
diff changeset
   440
    testMode ifTrue:[ ^ self ]. "/ test whether running testMode
eef25c370979 initial checkin
ca
parents:
diff changeset
   441
eef25c370979 initial checkin
ca
parents:
diff changeset
   442
    (     hiddenLevel == 0
eef25c370979 initial checkin
ca
parents:
diff changeset
   443
     and:[selection notNil
eef25c370979 initial checkin
ca
parents:
diff changeset
   444
     and:[(topView := listOfItems rootView) notNil
eef25c370979 initial checkin
ca
parents:
diff changeset
   445
     and:[topView shown]]]
eef25c370979 initial checkin
ca
parents:
diff changeset
   446
    ) ifTrue:[
eef25c370979 initial checkin
ca
parents:
diff changeset
   447
        topView sensor pushUserEvent:#redrawSelection for:self withArguments:#()
eef25c370979 initial checkin
ca
parents:
diff changeset
   448
    ]
eef25c370979 initial checkin
ca
parents:
diff changeset
   449
!
eef25c370979 initial checkin
ca
parents:
diff changeset
   450
eef25c370979 initial checkin
ca
parents:
diff changeset
   451
recursiveRepair:theDamages startIn:aView relativeTo:aRootView
eef25c370979 initial checkin
ca
parents:
diff changeset
   452
    "repair all views and contained views, which intersects the damage.
eef25c370979 initial checkin
ca
parents:
diff changeset
   453
     !!!! all damages repaired are removed from the list of damages !!!!
eef25c370979 initial checkin
ca
parents:
diff changeset
   454
    "
eef25c370979 initial checkin
ca
parents:
diff changeset
   455
    |color relOrg damage subViews repaired
eef25c370979 initial checkin
ca
parents:
diff changeset
   456
     bwWidth    "{ Class:SmallInteger }"
eef25c370979 initial checkin
ca
parents:
diff changeset
   457
     x          "{ Class:SmallInteger }"
eef25c370979 initial checkin
ca
parents:
diff changeset
   458
     y          "{ Class:SmallInteger }"
eef25c370979 initial checkin
ca
parents:
diff changeset
   459
     w          "{ Class:SmallInteger }"
eef25c370979 initial checkin
ca
parents:
diff changeset
   460
     h          "{ Class:SmallInteger }"
eef25c370979 initial checkin
ca
parents:
diff changeset
   461
     relOrgX    "{ Class:SmallInteger }"
eef25c370979 initial checkin
ca
parents:
diff changeset
   462
     relOrgY    "{ Class:SmallInteger }"
eef25c370979 initial checkin
ca
parents:
diff changeset
   463
     width      "{ Class:SmallInteger }"
eef25c370979 initial checkin
ca
parents:
diff changeset
   464
     height     "{ Class:SmallInteger }"
eef25c370979 initial checkin
ca
parents:
diff changeset
   465
     size       "{ Class:SmallInteger }"
eef25c370979 initial checkin
ca
parents:
diff changeset
   466
    |
eef25c370979 initial checkin
ca
parents:
diff changeset
   467
    (aView shown and:[theDamages notEmpty]) ifFalse:[ ^ self ].
eef25c370979 initial checkin
ca
parents:
diff changeset
   468
eef25c370979 initial checkin
ca
parents:
diff changeset
   469
    subViews := aView subViews.
eef25c370979 initial checkin
ca
parents:
diff changeset
   470
eef25c370979 initial checkin
ca
parents:
diff changeset
   471
    subViews size ~~ 0 ifTrue:[
eef25c370979 initial checkin
ca
parents:
diff changeset
   472
        subViews reverseDo:[:v| self recursiveRepair:theDamages startIn:v relativeTo:aRootView ].
eef25c370979 initial checkin
ca
parents:
diff changeset
   473
        theDamages isEmpty ifTrue:[ ^ self ].
eef25c370979 initial checkin
ca
parents:
diff changeset
   474
    ].
eef25c370979 initial checkin
ca
parents:
diff changeset
   475
eef25c370979 initial checkin
ca
parents:
diff changeset
   476
    relOrg  := aView originRelativeTo:aRootView.
eef25c370979 initial checkin
ca
parents:
diff changeset
   477
    bwWidth := aView borderWidth.
eef25c370979 initial checkin
ca
parents:
diff changeset
   478
    size    := theDamages size.
eef25c370979 initial checkin
ca
parents:
diff changeset
   479
eef25c370979 initial checkin
ca
parents:
diff changeset
   480
    "/ compute relative origin starting from border left@top
eef25c370979 initial checkin
ca
parents:
diff changeset
   481
    relOrgX := relOrg x - bwWidth.
eef25c370979 initial checkin
ca
parents:
diff changeset
   482
    relOrgY := relOrg y - bwWidth.
eef25c370979 initial checkin
ca
parents:
diff changeset
   483
    width   := aView width  + bwWidth + bwWidth.
eef25c370979 initial checkin
ca
parents:
diff changeset
   484
    height  := aView height + bwWidth + bwWidth.
eef25c370979 initial checkin
ca
parents:
diff changeset
   485
eef25c370979 initial checkin
ca
parents:
diff changeset
   486
    size to:1 by:-1 do:[:anIndex|
eef25c370979 initial checkin
ca
parents:
diff changeset
   487
        repaired := damage := theDamages at:anIndex.
eef25c370979 initial checkin
ca
parents:
diff changeset
   488
eef25c370979 initial checkin
ca
parents:
diff changeset
   489
        "/ compute the rectangle into the view
eef25c370979 initial checkin
ca
parents:
diff changeset
   490
        y := damage top  - relOrgY.
eef25c370979 initial checkin
ca
parents:
diff changeset
   491
        x := damage left - relOrgX.
eef25c370979 initial checkin
ca
parents:
diff changeset
   492
        w := damage width.
eef25c370979 initial checkin
ca
parents:
diff changeset
   493
        h := damage height.
eef25c370979 initial checkin
ca
parents:
diff changeset
   494
eef25c370979 initial checkin
ca
parents:
diff changeset
   495
        x     < 0      ifTrue:[ w := w + x. x := 0. repaired := nil ].
eef25c370979 initial checkin
ca
parents:
diff changeset
   496
        y     < 0      ifTrue:[ h := h + y. y := 0. repaired := nil ].
eef25c370979 initial checkin
ca
parents:
diff changeset
   497
        x + w > width  ifTrue:[ w := width  - x.    repaired := nil ].
eef25c370979 initial checkin
ca
parents:
diff changeset
   498
        y + h > height ifTrue:[ h := height - y.    repaired := nil ].
eef25c370979 initial checkin
ca
parents:
diff changeset
   499
eef25c370979 initial checkin
ca
parents:
diff changeset
   500
        (w > 0 and:[h > 0]) ifTrue:[
eef25c370979 initial checkin
ca
parents:
diff changeset
   501
            bwWidth ~~ 0 ifTrue:[
eef25c370979 initial checkin
ca
parents:
diff changeset
   502
                color isNil ifTrue:[
eef25c370979 initial checkin
ca
parents:
diff changeset
   503
                    "/ must force redraw of border
eef25c370979 initial checkin
ca
parents:
diff changeset
   504
                    color := aView borderColor.
eef25c370979 initial checkin
ca
parents:
diff changeset
   505
                    aView borderColor:(Color colorId:1).
eef25c370979 initial checkin
ca
parents:
diff changeset
   506
                    aView borderColor:color.
eef25c370979 initial checkin
ca
parents:
diff changeset
   507
                ].
eef25c370979 initial checkin
ca
parents:
diff changeset
   508
                w := w - bwWidth.
eef25c370979 initial checkin
ca
parents:
diff changeset
   509
                h := h - bwWidth.
eef25c370979 initial checkin
ca
parents:
diff changeset
   510
eef25c370979 initial checkin
ca
parents:
diff changeset
   511
                (x := x - bwWidth) < 0 ifTrue:[w := w + x. x := 0].
eef25c370979 initial checkin
ca
parents:
diff changeset
   512
                (y := y - bwWidth) < 0 ifTrue:[h := h + y. y := 0].
eef25c370979 initial checkin
ca
parents:
diff changeset
   513
eef25c370979 initial checkin
ca
parents:
diff changeset
   514
                h > 0 ifFalse:[w := 0].         "/ later testing on width only
eef25c370979 initial checkin
ca
parents:
diff changeset
   515
            ].
eef25c370979 initial checkin
ca
parents:
diff changeset
   516
eef25c370979 initial checkin
ca
parents:
diff changeset
   517
            w > 0 ifTrue:[
eef25c370979 initial checkin
ca
parents:
diff changeset
   518
                aView clearRectangleX:x y:y width:w height:h.
eef25c370979 initial checkin
ca
parents:
diff changeset
   519
                aView exposeX:x y:y width:w height:h
eef25c370979 initial checkin
ca
parents:
diff changeset
   520
            ].
eef25c370979 initial checkin
ca
parents:
diff changeset
   521
            repaired notNil ifTrue:[ theDamages removeFromIndex:anIndex toIndex:anIndex ].
eef25c370979 initial checkin
ca
parents:
diff changeset
   522
        ]
eef25c370979 initial checkin
ca
parents:
diff changeset
   523
    ].
eef25c370979 initial checkin
ca
parents:
diff changeset
   524
!
eef25c370979 initial checkin
ca
parents:
diff changeset
   525
eef25c370979 initial checkin
ca
parents:
diff changeset
   526
redrawSelection
eef25c370979 initial checkin
ca
parents:
diff changeset
   527
    "redraw all items selected
eef25c370979 initial checkin
ca
parents:
diff changeset
   528
    "
eef25c370979 initial checkin
ca
parents:
diff changeset
   529
    |topView size|
eef25c370979 initial checkin
ca
parents:
diff changeset
   530
eef25c370979 initial checkin
ca
parents:
diff changeset
   531
    testMode ifTrue:[ ^ self ]. "/ test whether running testMode
eef25c370979 initial checkin
ca
parents:
diff changeset
   532
eef25c370979 initial checkin
ca
parents:
diff changeset
   533
    (     hiddenLevel == 0
eef25c370979 initial checkin
ca
parents:
diff changeset
   534
     and:[(size := selection size) > 0
eef25c370979 initial checkin
ca
parents:
diff changeset
   535
     and:[(topView := listOfItems rootView) notNil
eef25c370979 initial checkin
ca
parents:
diff changeset
   536
     and:[topView shown
eef25c370979 initial checkin
ca
parents:
diff changeset
   537
     and:[(topView sensor hasEvent:#redrawSelection for:self) not]]]]
eef25c370979 initial checkin
ca
parents:
diff changeset
   538
    ) ifFalse:[
eef25c370979 initial checkin
ca
parents:
diff changeset
   539
        ^ self
eef25c370979 initial checkin
ca
parents:
diff changeset
   540
    ].
eef25c370979 initial checkin
ca
parents:
diff changeset
   541
eef25c370979 initial checkin
ca
parents:
diff changeset
   542
    lockSema critical:[
eef25c370979 initial checkin
ca
parents:
diff changeset
   543
        topView paint:(Color black).
eef25c370979 initial checkin
ca
parents:
diff changeset
   544
eef25c370979 initial checkin
ca
parents:
diff changeset
   545
        topView clippedByChildren:false.
eef25c370979 initial checkin
ca
parents:
diff changeset
   546
eef25c370979 initial checkin
ca
parents:
diff changeset
   547
        selection keysAndValuesReverseDo:[:anIndex :anItem|
eef25c370979 initial checkin
ca
parents:
diff changeset
   548
            (anIndex == 1 and:[size > 1]) ifTrue:[ topView paint:(Color red) ].
eef25c370979 initial checkin
ca
parents:
diff changeset
   549
eef25c370979 initial checkin
ca
parents:
diff changeset
   550
            anItem handlesDo:[:aRect :what|
eef25c370979 initial checkin
ca
parents:
diff changeset
   551
                what isNil ifTrue:[topView displayRectangle:aRect]
eef25c370979 initial checkin
ca
parents:
diff changeset
   552
                          ifFalse:[topView    fillRectangle:aRect]
eef25c370979 initial checkin
ca
parents:
diff changeset
   553
            ]
eef25c370979 initial checkin
ca
parents:
diff changeset
   554
        ].
eef25c370979 initial checkin
ca
parents:
diff changeset
   555
        topView clippedByChildren:true.
eef25c370979 initial checkin
ca
parents:
diff changeset
   556
    ].
eef25c370979 initial checkin
ca
parents:
diff changeset
   557
!
eef25c370979 initial checkin
ca
parents:
diff changeset
   558
eef25c370979 initial checkin
ca
parents:
diff changeset
   559
redrawUnselected:aList andLock:doLock
eef25c370979 initial checkin
ca
parents:
diff changeset
   560
    "redraw all items unselected; if doLock is true, the hiddenLevel
eef25c370979 initial checkin
ca
parents:
diff changeset
   561
     is incremented and thus the select mechanism is locked.
eef25c370979 initial checkin
ca
parents:
diff changeset
   562
    "
eef25c370979 initial checkin
ca
parents:
diff changeset
   563
    |rootView damages subViews x y w h|
eef25c370979 initial checkin
ca
parents:
diff changeset
   564
eef25c370979 initial checkin
ca
parents:
diff changeset
   565
    doLock ifTrue:[
eef25c370979 initial checkin
ca
parents:
diff changeset
   566
        hiddenLevel := hiddenLevel + 1.
eef25c370979 initial checkin
ca
parents:
diff changeset
   567
        hiddenLevel ~~ 1 ifTrue:[^ self].
eef25c370979 initial checkin
ca
parents:
diff changeset
   568
    ] ifFalse:[
eef25c370979 initial checkin
ca
parents:
diff changeset
   569
        hiddenLevel ~~ 0 ifTrue:[^ self].
eef25c370979 initial checkin
ca
parents:
diff changeset
   570
    ].
eef25c370979 initial checkin
ca
parents:
diff changeset
   571
    testMode ifTrue:[ ^ self ]. "/ test whether running testMode
eef25c370979 initial checkin
ca
parents:
diff changeset
   572
eef25c370979 initial checkin
ca
parents:
diff changeset
   573
    (     aList size ~~ 0
eef25c370979 initial checkin
ca
parents:
diff changeset
   574
     and:[(rootView := listOfItems rootView) notNil
eef25c370979 initial checkin
ca
parents:
diff changeset
   575
     and:[rootView shown]]
eef25c370979 initial checkin
ca
parents:
diff changeset
   576
    ) ifFalse:[
eef25c370979 initial checkin
ca
parents:
diff changeset
   577
        ^ self
eef25c370979 initial checkin
ca
parents:
diff changeset
   578
    ].
eef25c370979 initial checkin
ca
parents:
diff changeset
   579
eef25c370979 initial checkin
ca
parents:
diff changeset
   580
    lockSema critical:[
eef25c370979 initial checkin
ca
parents:
diff changeset
   581
        damages := OrderedCollection new:(8 * aList size).
eef25c370979 initial checkin
ca
parents:
diff changeset
   582
eef25c370979 initial checkin
ca
parents:
diff changeset
   583
        aList do:[:item|
eef25c370979 initial checkin
ca
parents:
diff changeset
   584
            item handlesDo:[:handle :what|
eef25c370979 initial checkin
ca
parents:
diff changeset
   585
                damages reverseDo:[:el|
eef25c370979 initial checkin
ca
parents:
diff changeset
   586
                    (el intersects:handle) ifTrue:[
eef25c370979 initial checkin
ca
parents:
diff changeset
   587
                        damages removeIdentical:el.
eef25c370979 initial checkin
ca
parents:
diff changeset
   588
eef25c370979 initial checkin
ca
parents:
diff changeset
   589
                        handle left:(handle left   min:el left)
eef25c370979 initial checkin
ca
parents:
diff changeset
   590
                              right:(handle right  max:el right)
eef25c370979 initial checkin
ca
parents:
diff changeset
   591
                                top:(handle top    min:el top)
eef25c370979 initial checkin
ca
parents:
diff changeset
   592
                             bottom:(handle bottom max:el bottom)
eef25c370979 initial checkin
ca
parents:
diff changeset
   593
                    ]
eef25c370979 initial checkin
ca
parents:
diff changeset
   594
                ].                        
eef25c370979 initial checkin
ca
parents:
diff changeset
   595
                damages add:handle
eef25c370979 initial checkin
ca
parents:
diff changeset
   596
            ]
eef25c370979 initial checkin
ca
parents:
diff changeset
   597
        ].
eef25c370979 initial checkin
ca
parents:
diff changeset
   598
        rootView clippedByChildren:false.
eef25c370979 initial checkin
ca
parents:
diff changeset
   599
eef25c370979 initial checkin
ca
parents:
diff changeset
   600
        damages do:[:el|
eef25c370979 initial checkin
ca
parents:
diff changeset
   601
            x := el left.
eef25c370979 initial checkin
ca
parents:
diff changeset
   602
            y := el top.
eef25c370979 initial checkin
ca
parents:
diff changeset
   603
            w := el width.
eef25c370979 initial checkin
ca
parents:
diff changeset
   604
            h := el height.
eef25c370979 initial checkin
ca
parents:
diff changeset
   605
eef25c370979 initial checkin
ca
parents:
diff changeset
   606
            rootView clearRectangleX:x y:y width:w height:h.
eef25c370979 initial checkin
ca
parents:
diff changeset
   607
            rootView         exposeX:x y:y width:w height:h.
eef25c370979 initial checkin
ca
parents:
diff changeset
   608
        ].
eef25c370979 initial checkin
ca
parents:
diff changeset
   609
        rootView clippedByChildren:true.
eef25c370979 initial checkin
ca
parents:
diff changeset
   610
eef25c370979 initial checkin
ca
parents:
diff changeset
   611
        (subViews := rootView subViews) notNil ifTrue:[
eef25c370979 initial checkin
ca
parents:
diff changeset
   612
            subViews reverseDo:[:v| self recursiveRepair:damages startIn:v relativeTo:rootView ].
eef25c370979 initial checkin
ca
parents:
diff changeset
   613
        ].
eef25c370979 initial checkin
ca
parents:
diff changeset
   614
    ].
eef25c370979 initial checkin
ca
parents:
diff changeset
   615
! !
eef25c370979 initial checkin
ca
parents:
diff changeset
   616
eef25c370979 initial checkin
ca
parents:
diff changeset
   617
!ViewTreeModel methodsFor:'selection accessing'!
eef25c370979 initial checkin
ca
parents:
diff changeset
   618
eef25c370979 initial checkin
ca
parents:
diff changeset
   619
at:anIndex
eef25c370979 initial checkin
ca
parents:
diff changeset
   620
    "returns the selected item at an index or nil
eef25c370979 initial checkin
ca
parents:
diff changeset
   621
    "
eef25c370979 initial checkin
ca
parents:
diff changeset
   622
    selection notNil ifTrue:[
eef25c370979 initial checkin
ca
parents:
diff changeset
   623
        ^ selection at:anIndex ifAbsent:nil
eef25c370979 initial checkin
ca
parents:
diff changeset
   624
    ].
eef25c370979 initial checkin
ca
parents:
diff changeset
   625
    ^ nil
eef25c370979 initial checkin
ca
parents:
diff changeset
   626
!
eef25c370979 initial checkin
ca
parents:
diff changeset
   627
eef25c370979 initial checkin
ca
parents:
diff changeset
   628
at:anIndex ifAbsent:aBlock
eef25c370979 initial checkin
ca
parents:
diff changeset
   629
    "returns the selected item at an index or the result of the block
eef25c370979 initial checkin
ca
parents:
diff changeset
   630
    "
eef25c370979 initial checkin
ca
parents:
diff changeset
   631
    selection notNil ifTrue:[
eef25c370979 initial checkin
ca
parents:
diff changeset
   632
        ^ selection at:anIndex ifAbsent:aBlock
eef25c370979 initial checkin
ca
parents:
diff changeset
   633
    ].
eef25c370979 initial checkin
ca
parents:
diff changeset
   634
    ^ aBlock value
eef25c370979 initial checkin
ca
parents:
diff changeset
   635
!
eef25c370979 initial checkin
ca
parents:
diff changeset
   636
eef25c370979 initial checkin
ca
parents:
diff changeset
   637
first
eef25c370979 initial checkin
ca
parents:
diff changeset
   638
    "returns the first selected item or nil
eef25c370979 initial checkin
ca
parents:
diff changeset
   639
    "
eef25c370979 initial checkin
ca
parents:
diff changeset
   640
    ^ self at:1
eef25c370979 initial checkin
ca
parents:
diff changeset
   641
!
eef25c370979 initial checkin
ca
parents:
diff changeset
   642
eef25c370979 initial checkin
ca
parents:
diff changeset
   643
last
eef25c370979 initial checkin
ca
parents:
diff changeset
   644
    "returns the last selected item or nil
eef25c370979 initial checkin
ca
parents:
diff changeset
   645
    "
eef25c370979 initial checkin
ca
parents:
diff changeset
   646
    ^ selection notNil ifTrue:[selection last] ifFalse:[nil]
eef25c370979 initial checkin
ca
parents:
diff changeset
   647
!
eef25c370979 initial checkin
ca
parents:
diff changeset
   648
eef25c370979 initial checkin
ca
parents:
diff changeset
   649
selectedItem
eef25c370979 initial checkin
ca
parents:
diff changeset
   650
    "returns the single selected item or nil (size ~~ 1 nil is returned)
eef25c370979 initial checkin
ca
parents:
diff changeset
   651
    "
eef25c370979 initial checkin
ca
parents:
diff changeset
   652
    ^ selection size == 1 ifTrue:[selection at:1] ifFalse:[nil]
eef25c370979 initial checkin
ca
parents:
diff changeset
   653
!
eef25c370979 initial checkin
ca
parents:
diff changeset
   654
eef25c370979 initial checkin
ca
parents:
diff changeset
   655
selectedSuperItems
eef25c370979 initial checkin
ca
parents:
diff changeset
   656
    "returs the list of selected superItems; items selected
eef25c370979 initial checkin
ca
parents:
diff changeset
   657
     but not contained in another selected item.
eef25c370979 initial checkin
ca
parents:
diff changeset
   658
    "
eef25c370979 initial checkin
ca
parents:
diff changeset
   659
    ^ selectedSuperItems
eef25c370979 initial checkin
ca
parents:
diff changeset
   660
!
eef25c370979 initial checkin
ca
parents:
diff changeset
   661
eef25c370979 initial checkin
ca
parents:
diff changeset
   662
size
eef25c370979 initial checkin
ca
parents:
diff changeset
   663
    "returns the number of items selected
eef25c370979 initial checkin
ca
parents:
diff changeset
   664
    "
eef25c370979 initial checkin
ca
parents:
diff changeset
   665
    ^ selection size
eef25c370979 initial checkin
ca
parents:
diff changeset
   666
! !
eef25c370979 initial checkin
ca
parents:
diff changeset
   667
eef25c370979 initial checkin
ca
parents:
diff changeset
   668
!ViewTreeModel methodsFor:'selection adding & removing'!
eef25c370979 initial checkin
ca
parents:
diff changeset
   669
eef25c370979 initial checkin
ca
parents:
diff changeset
   670
add:item
eef25c370979 initial checkin
ca
parents:
diff changeset
   671
    "add an item to the current selection
eef25c370979 initial checkin
ca
parents:
diff changeset
   672
    "
eef25c370979 initial checkin
ca
parents:
diff changeset
   673
    |newSelect|
eef25c370979 initial checkin
ca
parents:
diff changeset
   674
eef25c370979 initial checkin
ca
parents:
diff changeset
   675
    item isNil ifTrue:[^ item].
eef25c370979 initial checkin
ca
parents:
diff changeset
   676
eef25c370979 initial checkin
ca
parents:
diff changeset
   677
    lockSema critical:[
eef25c370979 initial checkin
ca
parents:
diff changeset
   678
        selection isNil ifTrue:[
eef25c370979 initial checkin
ca
parents:
diff changeset
   679
            newSelect := Array with:item.
eef25c370979 initial checkin
ca
parents:
diff changeset
   680
        ] ifFalse:[
eef25c370979 initial checkin
ca
parents:
diff changeset
   681
            (self includes:item) ifFalse:[
eef25c370979 initial checkin
ca
parents:
diff changeset
   682
                newSelect := selection copyWith:item
eef25c370979 initial checkin
ca
parents:
diff changeset
   683
            ]
eef25c370979 initial checkin
ca
parents:
diff changeset
   684
        ].
eef25c370979 initial checkin
ca
parents:
diff changeset
   685
eef25c370979 initial checkin
ca
parents:
diff changeset
   686
        newSelect size ~~ selection size ifTrue:[
eef25c370979 initial checkin
ca
parents:
diff changeset
   687
            item makeVisible.
eef25c370979 initial checkin
ca
parents:
diff changeset
   688
            self value:newSelect
eef25c370979 initial checkin
ca
parents:
diff changeset
   689
        ]
eef25c370979 initial checkin
ca
parents:
diff changeset
   690
    ].
eef25c370979 initial checkin
ca
parents:
diff changeset
   691
    ^ item
eef25c370979 initial checkin
ca
parents:
diff changeset
   692
!
eef25c370979 initial checkin
ca
parents:
diff changeset
   693
eef25c370979 initial checkin
ca
parents:
diff changeset
   694
addAll:aCollectionOfItems
eef25c370979 initial checkin
ca
parents:
diff changeset
   695
    "add a collection of items to the current selection
eef25c370979 initial checkin
ca
parents:
diff changeset
   696
    "
eef25c370979 initial checkin
ca
parents:
diff changeset
   697
    |newSelect|
eef25c370979 initial checkin
ca
parents:
diff changeset
   698
eef25c370979 initial checkin
ca
parents:
diff changeset
   699
    aCollectionOfItems size == 0 ifTrue:[ ^ aCollectionOfItems ].
eef25c370979 initial checkin
ca
parents:
diff changeset
   700
eef25c370979 initial checkin
ca
parents:
diff changeset
   701
    lockSema critical:[
eef25c370979 initial checkin
ca
parents:
diff changeset
   702
        selection isNil ifTrue:[
eef25c370979 initial checkin
ca
parents:
diff changeset
   703
            newSelect := Array withAll:aCollectionOfItems.
eef25c370979 initial checkin
ca
parents:
diff changeset
   704
        ] ifFalse:[
eef25c370979 initial checkin
ca
parents:
diff changeset
   705
            newSelect := OrderedCollection withAll:selection.
eef25c370979 initial checkin
ca
parents:
diff changeset
   706
eef25c370979 initial checkin
ca
parents:
diff changeset
   707
            aCollectionOfItems do:[:el|
eef25c370979 initial checkin
ca
parents:
diff changeset
   708
                (selection includesIdentical:el) ifFalse:[newSelect add:el]
eef25c370979 initial checkin
ca
parents:
diff changeset
   709
            ].
eef25c370979 initial checkin
ca
parents:
diff changeset
   710
        ].
eef25c370979 initial checkin
ca
parents:
diff changeset
   711
        self value:newSelect.
eef25c370979 initial checkin
ca
parents:
diff changeset
   712
    ].
eef25c370979 initial checkin
ca
parents:
diff changeset
   713
    ^ aCollectionOfItems
eef25c370979 initial checkin
ca
parents:
diff changeset
   714
!
eef25c370979 initial checkin
ca
parents:
diff changeset
   715
eef25c370979 initial checkin
ca
parents:
diff changeset
   716
deselect
eef25c370979 initial checkin
ca
parents:
diff changeset
   717
    "clear the selection
eef25c370979 initial checkin
ca
parents:
diff changeset
   718
    "
eef25c370979 initial checkin
ca
parents:
diff changeset
   719
    self value:nil.
eef25c370979 initial checkin
ca
parents:
diff changeset
   720
!
eef25c370979 initial checkin
ca
parents:
diff changeset
   721
eef25c370979 initial checkin
ca
parents:
diff changeset
   722
remove:item
eef25c370979 initial checkin
ca
parents:
diff changeset
   723
    "remove the item from the current selection
eef25c370979 initial checkin
ca
parents:
diff changeset
   724
    "
eef25c370979 initial checkin
ca
parents:
diff changeset
   725
    |newSelect|
eef25c370979 initial checkin
ca
parents:
diff changeset
   726
eef25c370979 initial checkin
ca
parents:
diff changeset
   727
    item isNil ifTrue:[^ nil].
eef25c370979 initial checkin
ca
parents:
diff changeset
   728
eef25c370979 initial checkin
ca
parents:
diff changeset
   729
    lockSema critical:[
eef25c370979 initial checkin
ca
parents:
diff changeset
   730
        (selection notNil and:[selection includesIdentical:item]) ifTrue:[
eef25c370979 initial checkin
ca
parents:
diff changeset
   731
            selection size == 1 ifTrue:[ newSelect := nil ]
eef25c370979 initial checkin
ca
parents:
diff changeset
   732
                               ifFalse:[ newSelect := selection copyWithout:item ].
eef25c370979 initial checkin
ca
parents:
diff changeset
   733
eef25c370979 initial checkin
ca
parents:
diff changeset
   734
            self value:newSelect
eef25c370979 initial checkin
ca
parents:
diff changeset
   735
        ].
eef25c370979 initial checkin
ca
parents:
diff changeset
   736
    ].
eef25c370979 initial checkin
ca
parents:
diff changeset
   737
    ^ item
eef25c370979 initial checkin
ca
parents:
diff changeset
   738
!
eef25c370979 initial checkin
ca
parents:
diff changeset
   739
eef25c370979 initial checkin
ca
parents:
diff changeset
   740
removeAll
eef25c370979 initial checkin
ca
parents:
diff changeset
   741
    "clear the selection
eef25c370979 initial checkin
ca
parents:
diff changeset
   742
    "
eef25c370979 initial checkin
ca
parents:
diff changeset
   743
    self deselect.
eef25c370979 initial checkin
ca
parents:
diff changeset
   744
!
eef25c370979 initial checkin
ca
parents:
diff changeset
   745
eef25c370979 initial checkin
ca
parents:
diff changeset
   746
removeAll:loItems
eef25c370979 initial checkin
ca
parents:
diff changeset
   747
    "remove all items of the collection from the current selection
eef25c370979 initial checkin
ca
parents:
diff changeset
   748
    "
eef25c370979 initial checkin
ca
parents:
diff changeset
   749
    |newSelect|
eef25c370979 initial checkin
ca
parents:
diff changeset
   750
eef25c370979 initial checkin
ca
parents:
diff changeset
   751
    selection   isNil ifTrue:[ ^ loItems ].
eef25c370979 initial checkin
ca
parents:
diff changeset
   752
    loItems size == 0 ifTrue:[ ^ loItems ].
eef25c370979 initial checkin
ca
parents:
diff changeset
   753
eef25c370979 initial checkin
ca
parents:
diff changeset
   754
    lockSema critical:[
eef25c370979 initial checkin
ca
parents:
diff changeset
   755
        selection notNil ifTrue:[
eef25c370979 initial checkin
ca
parents:
diff changeset
   756
            newSelect := selection select:[:el| (loItems includesIdentical:el) not ].
eef25c370979 initial checkin
ca
parents:
diff changeset
   757
            self value:newSelect.
eef25c370979 initial checkin
ca
parents:
diff changeset
   758
        ]
eef25c370979 initial checkin
ca
parents:
diff changeset
   759
    ].
eef25c370979 initial checkin
ca
parents:
diff changeset
   760
    ^ loItems
eef25c370979 initial checkin
ca
parents:
diff changeset
   761
!
eef25c370979 initial checkin
ca
parents:
diff changeset
   762
eef25c370979 initial checkin
ca
parents:
diff changeset
   763
selectAll
eef25c370979 initial checkin
ca
parents:
diff changeset
   764
    "select all items
eef25c370979 initial checkin
ca
parents:
diff changeset
   765
    "
eef25c370979 initial checkin
ca
parents:
diff changeset
   766
    |root newSelection|
eef25c370979 initial checkin
ca
parents:
diff changeset
   767
eef25c370979 initial checkin
ca
parents:
diff changeset
   768
    root := listOfItems root.
eef25c370979 initial checkin
ca
parents:
diff changeset
   769
eef25c370979 initial checkin
ca
parents:
diff changeset
   770
    root isNil ifTrue:[
eef25c370979 initial checkin
ca
parents:
diff changeset
   771
        newSelection := nil
eef25c370979 initial checkin
ca
parents:
diff changeset
   772
    ] ifFalse:[
eef25c370979 initial checkin
ca
parents:
diff changeset
   773
        newSelection := OrderedCollection new.
eef25c370979 initial checkin
ca
parents:
diff changeset
   774
        root recursiveDo:[:el| newSelection add:el ].
eef25c370979 initial checkin
ca
parents:
diff changeset
   775
    ].
eef25c370979 initial checkin
ca
parents:
diff changeset
   776
    self value:newSelection.
eef25c370979 initial checkin
ca
parents:
diff changeset
   777
!
eef25c370979 initial checkin
ca
parents:
diff changeset
   778
eef25c370979 initial checkin
ca
parents:
diff changeset
   779
selectItem:anItem
eef25c370979 initial checkin
ca
parents:
diff changeset
   780
    "set the current selection to the item
eef25c370979 initial checkin
ca
parents:
diff changeset
   781
    "
eef25c370979 initial checkin
ca
parents:
diff changeset
   782
    self value:anItem
eef25c370979 initial checkin
ca
parents:
diff changeset
   783
!
eef25c370979 initial checkin
ca
parents:
diff changeset
   784
eef25c370979 initial checkin
ca
parents:
diff changeset
   785
selectRootItem
eef25c370979 initial checkin
ca
parents:
diff changeset
   786
    "set the current selection to the root item
eef25c370979 initial checkin
ca
parents:
diff changeset
   787
    "
eef25c370979 initial checkin
ca
parents:
diff changeset
   788
    self value:(self rootItem).
eef25c370979 initial checkin
ca
parents:
diff changeset
   789
!
eef25c370979 initial checkin
ca
parents:
diff changeset
   790
eef25c370979 initial checkin
ca
parents:
diff changeset
   791
selectedItem:anItem
eef25c370979 initial checkin
ca
parents:
diff changeset
   792
    "set the current selection to the item
eef25c370979 initial checkin
ca
parents:
diff changeset
   793
    "
eef25c370979 initial checkin
ca
parents:
diff changeset
   794
    self selectItem:anItem.
eef25c370979 initial checkin
ca
parents:
diff changeset
   795
!
eef25c370979 initial checkin
ca
parents:
diff changeset
   796
eef25c370979 initial checkin
ca
parents:
diff changeset
   797
toggleSelectItem:anItem
eef25c370979 initial checkin
ca
parents:
diff changeset
   798
    "toggle selection-state of the item; add or remove the item from the
eef25c370979 initial checkin
ca
parents:
diff changeset
   799
     current selection.
eef25c370979 initial checkin
ca
parents:
diff changeset
   800
    "
eef25c370979 initial checkin
ca
parents:
diff changeset
   801
    anItem notNil ifTrue:[
eef25c370979 initial checkin
ca
parents:
diff changeset
   802
        (self includes:anItem) ifTrue:[self remove:anItem]
eef25c370979 initial checkin
ca
parents:
diff changeset
   803
                              ifFalse:[self add:anItem]
eef25c370979 initial checkin
ca
parents:
diff changeset
   804
    ].
eef25c370979 initial checkin
ca
parents:
diff changeset
   805
    ^ anItem
eef25c370979 initial checkin
ca
parents:
diff changeset
   806
! !
eef25c370979 initial checkin
ca
parents:
diff changeset
   807
eef25c370979 initial checkin
ca
parents:
diff changeset
   808
!ViewTreeModel methodsFor:'selection enumerating'!
eef25c370979 initial checkin
ca
parents:
diff changeset
   809
eef25c370979 initial checkin
ca
parents:
diff changeset
   810
collect:aBlock
eef25c370979 initial checkin
ca
parents:
diff changeset
   811
    "for each element in the selection, evaluate the argument, aBlock
eef25c370979 initial checkin
ca
parents:
diff changeset
   812
     and return a new collection with the results
eef25c370979 initial checkin
ca
parents:
diff changeset
   813
    "
eef25c370979 initial checkin
ca
parents:
diff changeset
   814
    |res|
eef25c370979 initial checkin
ca
parents:
diff changeset
   815
eef25c370979 initial checkin
ca
parents:
diff changeset
   816
    res := OrderedCollection new.
eef25c370979 initial checkin
ca
parents:
diff changeset
   817
    self do:[:el| res add:(aBlock value:el)].
eef25c370979 initial checkin
ca
parents:
diff changeset
   818
  ^ res
eef25c370979 initial checkin
ca
parents:
diff changeset
   819
!
eef25c370979 initial checkin
ca
parents:
diff changeset
   820
eef25c370979 initial checkin
ca
parents:
diff changeset
   821
do:aOneArgBlock
eef25c370979 initial checkin
ca
parents:
diff changeset
   822
    "evaluate the argument, aBlock for each item in the selection
eef25c370979 initial checkin
ca
parents:
diff changeset
   823
    "
eef25c370979 initial checkin
ca
parents:
diff changeset
   824
    |cashedSelection|
eef25c370979 initial checkin
ca
parents:
diff changeset
   825
eef25c370979 initial checkin
ca
parents:
diff changeset
   826
    cashedSelection := selection.
eef25c370979 initial checkin
ca
parents:
diff changeset
   827
    cashedSelection isNil ifTrue:[^ nil].
eef25c370979 initial checkin
ca
parents:
diff changeset
   828
  ^ cashedSelection do:aOneArgBlock
eef25c370979 initial checkin
ca
parents:
diff changeset
   829
!
eef25c370979 initial checkin
ca
parents:
diff changeset
   830
eef25c370979 initial checkin
ca
parents:
diff changeset
   831
from:start do:aOneArgBlock
eef25c370979 initial checkin
ca
parents:
diff changeset
   832
    "evaluate the argument, aBlock for the items starting at index start
eef25c370979 initial checkin
ca
parents:
diff changeset
   833
    "
eef25c370979 initial checkin
ca
parents:
diff changeset
   834
    |cashedSelection|
eef25c370979 initial checkin
ca
parents:
diff changeset
   835
eef25c370979 initial checkin
ca
parents:
diff changeset
   836
    cashedSelection := selection.
eef25c370979 initial checkin
ca
parents:
diff changeset
   837
    cashedSelection isNil ifTrue:[^ nil].
eef25c370979 initial checkin
ca
parents:
diff changeset
   838
  ^ cashedSelection from:start do:aOneArgBlock
eef25c370979 initial checkin
ca
parents:
diff changeset
   839
!
eef25c370979 initial checkin
ca
parents:
diff changeset
   840
eef25c370979 initial checkin
ca
parents:
diff changeset
   841
from:start to:stop do:aOneArgBlock
eef25c370979 initial checkin
ca
parents:
diff changeset
   842
    "evaluate the argument, aBlock for the items with index start to
eef25c370979 initial checkin
ca
parents:
diff changeset
   843
     stop in the selection.
eef25c370979 initial checkin
ca
parents:
diff changeset
   844
    "
eef25c370979 initial checkin
ca
parents:
diff changeset
   845
    |cashedSelection|
eef25c370979 initial checkin
ca
parents:
diff changeset
   846
eef25c370979 initial checkin
ca
parents:
diff changeset
   847
    cashedSelection := selection.
eef25c370979 initial checkin
ca
parents:
diff changeset
   848
    cashedSelection isNil ifTrue:[^ nil].
eef25c370979 initial checkin
ca
parents:
diff changeset
   849
  ^ cashedSelection from:start to:stop do:aOneArgBlock
eef25c370979 initial checkin
ca
parents:
diff changeset
   850
!
eef25c370979 initial checkin
ca
parents:
diff changeset
   851
eef25c370979 initial checkin
ca
parents:
diff changeset
   852
reverseDo:aOneArgBlock
eef25c370979 initial checkin
ca
parents:
diff changeset
   853
    "evaluate the argument, aBlock for each item in the selection
eef25c370979 initial checkin
ca
parents:
diff changeset
   854
    "
eef25c370979 initial checkin
ca
parents:
diff changeset
   855
    |cashedSelection|
eef25c370979 initial checkin
ca
parents:
diff changeset
   856
eef25c370979 initial checkin
ca
parents:
diff changeset
   857
    cashedSelection := selection.
eef25c370979 initial checkin
ca
parents:
diff changeset
   858
    cashedSelection isNil ifTrue:[^ nil].
eef25c370979 initial checkin
ca
parents:
diff changeset
   859
  ^ cashedSelection reverseDo:aOneArgBlock
eef25c370979 initial checkin
ca
parents:
diff changeset
   860
!
eef25c370979 initial checkin
ca
parents:
diff changeset
   861
eef25c370979 initial checkin
ca
parents:
diff changeset
   862
select:aBlock
eef25c370979 initial checkin
ca
parents:
diff changeset
   863
    "return a new collection with all elements from the selection, for which
eef25c370979 initial checkin
ca
parents:
diff changeset
   864
     the argument aBlock evaluates to true.
eef25c370979 initial checkin
ca
parents:
diff changeset
   865
    "
eef25c370979 initial checkin
ca
parents:
diff changeset
   866
    |res|
eef25c370979 initial checkin
ca
parents:
diff changeset
   867
eef25c370979 initial checkin
ca
parents:
diff changeset
   868
    res := OrderedCollection new.
eef25c370979 initial checkin
ca
parents:
diff changeset
   869
    self do:[:el| (aBlock value:el) ifTrue:[res add:el] ].
eef25c370979 initial checkin
ca
parents:
diff changeset
   870
  ^ res
eef25c370979 initial checkin
ca
parents:
diff changeset
   871
! !
eef25c370979 initial checkin
ca
parents:
diff changeset
   872
eef25c370979 initial checkin
ca
parents:
diff changeset
   873
!ViewTreeModel methodsFor:'selection protocol'!
eef25c370979 initial checkin
ca
parents:
diff changeset
   874
eef25c370979 initial checkin
ca
parents:
diff changeset
   875
changed:aParameter with:oldSelection
eef25c370979 initial checkin
ca
parents:
diff changeset
   876
    "update the visibility staus of the current selection
eef25c370979 initial checkin
ca
parents:
diff changeset
   877
    "
eef25c370979 initial checkin
ca
parents:
diff changeset
   878
    |unselected rootView rootItem selSize|
eef25c370979 initial checkin
ca
parents:
diff changeset
   879
eef25c370979 initial checkin
ca
parents:
diff changeset
   880
    selSize := selection size.
eef25c370979 initial checkin
ca
parents:
diff changeset
   881
eef25c370979 initial checkin
ca
parents:
diff changeset
   882
    selSize == 0 ifTrue:[
eef25c370979 initial checkin
ca
parents:
diff changeset
   883
        selectedSuperItems := #().
eef25c370979 initial checkin
ca
parents:
diff changeset
   884
    ] ifFalse:[
eef25c370979 initial checkin
ca
parents:
diff changeset
   885
        selSize == 1 ifTrue:[
eef25c370979 initial checkin
ca
parents:
diff changeset
   886
            selectedSuperItems := Array with:(selection at:1).
eef25c370979 initial checkin
ca
parents:
diff changeset
   887
        ] ifFalse:[
eef25c370979 initial checkin
ca
parents:
diff changeset
   888
            rootItem := listOfItems root.
eef25c370979 initial checkin
ca
parents:
diff changeset
   889
eef25c370979 initial checkin
ca
parents:
diff changeset
   890
            (selection includesIdentical:rootItem) ifTrue:[
eef25c370979 initial checkin
ca
parents:
diff changeset
   891
                selectedSuperItems := Array with:rootItem.
eef25c370979 initial checkin
ca
parents:
diff changeset
   892
            ] ifFalse:[
eef25c370979 initial checkin
ca
parents:
diff changeset
   893
                selectedSuperItems := OrderedCollection new:selSize.
eef25c370979 initial checkin
ca
parents:
diff changeset
   894
eef25c370979 initial checkin
ca
parents:
diff changeset
   895
                selection do:[:anItem|
eef25c370979 initial checkin
ca
parents:
diff changeset
   896
                    anItem parentsDetect:[:el| selection includesIdentical:el ]
eef25c370979 initial checkin
ca
parents:
diff changeset
   897
                                  ifNone:[ selectedSuperItems add:anItem ].
eef25c370979 initial checkin
ca
parents:
diff changeset
   898
                ].
eef25c370979 initial checkin
ca
parents:
diff changeset
   899
            ]
eef25c370979 initial checkin
ca
parents:
diff changeset
   900
        ]
eef25c370979 initial checkin
ca
parents:
diff changeset
   901
    ].
eef25c370979 initial checkin
ca
parents:
diff changeset
   902
eef25c370979 initial checkin
ca
parents:
diff changeset
   903
    (     hiddenLevel == 0
eef25c370979 initial checkin
ca
parents:
diff changeset
   904
     and:[(rootView := listOfItems rootView) notNil
eef25c370979 initial checkin
ca
parents:
diff changeset
   905
     and:[rootView shown]]
eef25c370979 initial checkin
ca
parents:
diff changeset
   906
    ) ifTrue:[
eef25c370979 initial checkin
ca
parents:
diff changeset
   907
        selSize == 0 ifTrue:[
eef25c370979 initial checkin
ca
parents:
diff changeset
   908
            "/ must redraw the old selection unselected
eef25c370979 initial checkin
ca
parents:
diff changeset
   909
            self redrawUnselected:oldSelection andLock:false
eef25c370979 initial checkin
ca
parents:
diff changeset
   910
        ] ifFalse:[
eef25c370979 initial checkin
ca
parents:
diff changeset
   911
            self invalidateSelection.
eef25c370979 initial checkin
ca
parents:
diff changeset
   912
eef25c370979 initial checkin
ca
parents:
diff changeset
   913
            oldSelection size ~~ 0 ifTrue:[
eef25c370979 initial checkin
ca
parents:
diff changeset
   914
                "/ must redraw all elements no longer in the selection
eef25c370979 initial checkin
ca
parents:
diff changeset
   915
                unselected := oldSelection select:[:el| (selection includesIdentical:el) not ].
eef25c370979 initial checkin
ca
parents:
diff changeset
   916
                self redrawUnselected:unselected andLock:false.
eef25c370979 initial checkin
ca
parents:
diff changeset
   917
            ]
eef25c370979 initial checkin
ca
parents:
diff changeset
   918
        ]
eef25c370979 initial checkin
ca
parents:
diff changeset
   919
    ].
eef25c370979 initial checkin
ca
parents:
diff changeset
   920
    super changed:aParameter with:oldSelection.
eef25c370979 initial checkin
ca
parents:
diff changeset
   921
!
eef25c370979 initial checkin
ca
parents:
diff changeset
   922
eef25c370979 initial checkin
ca
parents:
diff changeset
   923
setValue:aNewSelection 
eef25c370979 initial checkin
ca
parents:
diff changeset
   924
    "set the selection without notifying
eef25c370979 initial checkin
ca
parents:
diff changeset
   925
    "
eef25c370979 initial checkin
ca
parents:
diff changeset
   926
    |newSelect idx|
eef25c370979 initial checkin
ca
parents:
diff changeset
   927
eef25c370979 initial checkin
ca
parents:
diff changeset
   928
    newSelect := nil.
eef25c370979 initial checkin
ca
parents:
diff changeset
   929
eef25c370979 initial checkin
ca
parents:
diff changeset
   930
    aNewSelection notNil ifTrue:[
eef25c370979 initial checkin
ca
parents:
diff changeset
   931
        lockSema critical:[
eef25c370979 initial checkin
ca
parents:
diff changeset
   932
            aNewSelection isCollection ifFalse:[
eef25c370979 initial checkin
ca
parents:
diff changeset
   933
                (selection size == 1 and:[selection first == aNewSelection]) ifTrue:[
eef25c370979 initial checkin
ca
parents:
diff changeset
   934
                    newSelect := selection
eef25c370979 initial checkin
ca
parents:
diff changeset
   935
                ] ifFalse:[
eef25c370979 initial checkin
ca
parents:
diff changeset
   936
                    newSelect := Array with:aNewSelection.
eef25c370979 initial checkin
ca
parents:
diff changeset
   937
                ]
eef25c370979 initial checkin
ca
parents:
diff changeset
   938
            ] ifTrue:[
eef25c370979 initial checkin
ca
parents:
diff changeset
   939
                aNewSelection notEmpty ifTrue:[
eef25c370979 initial checkin
ca
parents:
diff changeset
   940
                    aNewSelection size ~~ selection size ifTrue:[
eef25c370979 initial checkin
ca
parents:
diff changeset
   941
                        newSelect := aNewSelection copy.
eef25c370979 initial checkin
ca
parents:
diff changeset
   942
                    ] ifFalse:[
eef25c370979 initial checkin
ca
parents:
diff changeset
   943
                        idx := selection findFirst:[:el| (aNewSelection includesIdentical:el) not ].
eef25c370979 initial checkin
ca
parents:
diff changeset
   944
eef25c370979 initial checkin
ca
parents:
diff changeset
   945
                        idx ~~ 0 ifTrue:[newSelect := aNewSelection copy]
eef25c370979 initial checkin
ca
parents:
diff changeset
   946
                                ifFalse:[newSelect := selection ].
eef25c370979 initial checkin
ca
parents:
diff changeset
   947
                    ]
eef25c370979 initial checkin
ca
parents:
diff changeset
   948
                ]
eef25c370979 initial checkin
ca
parents:
diff changeset
   949
            ]
eef25c370979 initial checkin
ca
parents:
diff changeset
   950
        ].
eef25c370979 initial checkin
ca
parents:
diff changeset
   951
    ].
eef25c370979 initial checkin
ca
parents:
diff changeset
   952
    newSelect ~~ selection ifTrue:[
eef25c370979 initial checkin
ca
parents:
diff changeset
   953
        beforeSelectionChangedAction value.
eef25c370979 initial checkin
ca
parents:
diff changeset
   954
        selection := newSelect.
eef25c370979 initial checkin
ca
parents:
diff changeset
   955
        selection notNil ifTrue:[selection do:[:el| el makeVisible]]
eef25c370979 initial checkin
ca
parents:
diff changeset
   956
    ].
eef25c370979 initial checkin
ca
parents:
diff changeset
   957
!
eef25c370979 initial checkin
ca
parents:
diff changeset
   958
eef25c370979 initial checkin
ca
parents:
diff changeset
   959
triggerValue:aValue
eef25c370979 initial checkin
ca
parents:
diff changeset
   960
    "set my value & send change notifications to my dependents.
eef25c370979 initial checkin
ca
parents:
diff changeset
   961
     Send the change message even if the value didn't change.
eef25c370979 initial checkin
ca
parents:
diff changeset
   962
    "
eef25c370979 initial checkin
ca
parents:
diff changeset
   963
    |oldSelection|
eef25c370979 initial checkin
ca
parents:
diff changeset
   964
eef25c370979 initial checkin
ca
parents:
diff changeset
   965
    lockSema critical:[
eef25c370979 initial checkin
ca
parents:
diff changeset
   966
        oldSelection := selection.
eef25c370979 initial checkin
ca
parents:
diff changeset
   967
        self setValue:aValue.
eef25c370979 initial checkin
ca
parents:
diff changeset
   968
        self changed:#value with:oldSelection
eef25c370979 initial checkin
ca
parents:
diff changeset
   969
    ]
eef25c370979 initial checkin
ca
parents:
diff changeset
   970
!
eef25c370979 initial checkin
ca
parents:
diff changeset
   971
eef25c370979 initial checkin
ca
parents:
diff changeset
   972
value
eef25c370979 initial checkin
ca
parents:
diff changeset
   973
    "returns the current selection
eef25c370979 initial checkin
ca
parents:
diff changeset
   974
    "
eef25c370979 initial checkin
ca
parents:
diff changeset
   975
    ^ selection ? #()
eef25c370979 initial checkin
ca
parents:
diff changeset
   976
!
eef25c370979 initial checkin
ca
parents:
diff changeset
   977
eef25c370979 initial checkin
ca
parents:
diff changeset
   978
value:aValue
eef25c370979 initial checkin
ca
parents:
diff changeset
   979
    "change the current selection and send change notifications to my
eef25c370979 initial checkin
ca
parents:
diff changeset
   980
     dependents if it changed.
eef25c370979 initial checkin
ca
parents:
diff changeset
   981
    "
eef25c370979 initial checkin
ca
parents:
diff changeset
   982
    |oldSelection|
eef25c370979 initial checkin
ca
parents:
diff changeset
   983
eef25c370979 initial checkin
ca
parents:
diff changeset
   984
    lockSema critical:[
eef25c370979 initial checkin
ca
parents:
diff changeset
   985
        oldSelection := selection.
eef25c370979 initial checkin
ca
parents:
diff changeset
   986
        self setValue:aValue.
eef25c370979 initial checkin
ca
parents:
diff changeset
   987
eef25c370979 initial checkin
ca
parents:
diff changeset
   988
        oldSelection == selection ifFalse:[
eef25c370979 initial checkin
ca
parents:
diff changeset
   989
            self changed:#value with:oldSelection
eef25c370979 initial checkin
ca
parents:
diff changeset
   990
        ]
eef25c370979 initial checkin
ca
parents:
diff changeset
   991
    ].
eef25c370979 initial checkin
ca
parents:
diff changeset
   992
! !
eef25c370979 initial checkin
ca
parents:
diff changeset
   993
eef25c370979 initial checkin
ca
parents:
diff changeset
   994
!ViewTreeModel methodsFor:'selection searching'!
eef25c370979 initial checkin
ca
parents:
diff changeset
   995
eef25c370979 initial checkin
ca
parents:
diff changeset
   996
detect:aBlock
eef25c370979 initial checkin
ca
parents:
diff changeset
   997
    "evaluate the argument, aBlock for each item in the selection until
eef25c370979 initial checkin
ca
parents:
diff changeset
   998
     the block returns true; in this case return the element which caused
eef25c370979 initial checkin
ca
parents:
diff changeset
   999
     the true evaluation.
eef25c370979 initial checkin
ca
parents:
diff changeset
  1000
     If none of the evaluations returns true, an error is raised
eef25c370979 initial checkin
ca
parents:
diff changeset
  1001
    "
eef25c370979 initial checkin
ca
parents:
diff changeset
  1002
    ^ self detect:aBlock ifNone:[self errorNotFound]
eef25c370979 initial checkin
ca
parents:
diff changeset
  1003
!
eef25c370979 initial checkin
ca
parents:
diff changeset
  1004
eef25c370979 initial checkin
ca
parents:
diff changeset
  1005
detect:aBlock ifNone:exceptionBlock
eef25c370979 initial checkin
ca
parents:
diff changeset
  1006
    "evaluate the argument, aBlock for each item in the selection until the
eef25c370979 initial checkin
ca
parents:
diff changeset
  1007
     block returns true; in this case return the element which caused the
eef25c370979 initial checkin
ca
parents:
diff changeset
  1008
     true evaluation.
eef25c370979 initial checkin
ca
parents:
diff changeset
  1009
     If none of the evaluations returns true, the result of the evaluation
eef25c370979 initial checkin
ca
parents:
diff changeset
  1010
     of the exceptionBlock is returned
eef25c370979 initial checkin
ca
parents:
diff changeset
  1011
    "
eef25c370979 initial checkin
ca
parents:
diff changeset
  1012
    |cashedSelection|
eef25c370979 initial checkin
ca
parents:
diff changeset
  1013
eef25c370979 initial checkin
ca
parents:
diff changeset
  1014
    cashedSelection := selection.
eef25c370979 initial checkin
ca
parents:
diff changeset
  1015
    cashedSelection isNil ifTrue:[ ^ exceptionBlock value ].
eef25c370979 initial checkin
ca
parents:
diff changeset
  1016
  ^ cashedSelection detect:aBlock ifNone:exceptionBlock
eef25c370979 initial checkin
ca
parents:
diff changeset
  1017
!
eef25c370979 initial checkin
ca
parents:
diff changeset
  1018
eef25c370979 initial checkin
ca
parents:
diff changeset
  1019
detectLast:aBlock
eef25c370979 initial checkin
ca
parents:
diff changeset
  1020
    "evaluate the argument, aBlock for each item in the selection until
eef25c370979 initial checkin
ca
parents:
diff changeset
  1021
     the block returns true; in this case return the element which caused
eef25c370979 initial checkin
ca
parents:
diff changeset
  1022
     the true evaluation. The items are processed in reverse order.
eef25c370979 initial checkin
ca
parents:
diff changeset
  1023
     If none of the evaluations returns true, an error is raised
eef25c370979 initial checkin
ca
parents:
diff changeset
  1024
    "
eef25c370979 initial checkin
ca
parents:
diff changeset
  1025
    ^ self detectLast:aBlock ifNone:[self errorNotFound]
eef25c370979 initial checkin
ca
parents:
diff changeset
  1026
!
eef25c370979 initial checkin
ca
parents:
diff changeset
  1027
eef25c370979 initial checkin
ca
parents:
diff changeset
  1028
detectLast:aBlock ifNone:exceptionBlock
eef25c370979 initial checkin
ca
parents:
diff changeset
  1029
    "evaluate the argument, aBlock for each item in the selection until
eef25c370979 initial checkin
ca
parents:
diff changeset
  1030
     the block returns true; in this case return the element which caused
eef25c370979 initial checkin
ca
parents:
diff changeset
  1031
     the true evaluation. The items are processed in reverse order.
eef25c370979 initial checkin
ca
parents:
diff changeset
  1032
     If none of the evaluations returns true, the result of the evaluation
eef25c370979 initial checkin
ca
parents:
diff changeset
  1033
     of the exceptionBlock is returned
eef25c370979 initial checkin
ca
parents:
diff changeset
  1034
    "
eef25c370979 initial checkin
ca
parents:
diff changeset
  1035
    |cashedSelection|
eef25c370979 initial checkin
ca
parents:
diff changeset
  1036
eef25c370979 initial checkin
ca
parents:
diff changeset
  1037
    cashedSelection := selection.
eef25c370979 initial checkin
ca
parents:
diff changeset
  1038
    cashedSelection isNil ifTrue:[ ^ exceptionBlock value ].
eef25c370979 initial checkin
ca
parents:
diff changeset
  1039
  ^ cashedSelection detectLast:aBlock ifNone:exceptionBlock
eef25c370979 initial checkin
ca
parents:
diff changeset
  1040
! !
eef25c370979 initial checkin
ca
parents:
diff changeset
  1041
eef25c370979 initial checkin
ca
parents:
diff changeset
  1042
!ViewTreeModel methodsFor:'selection testing'!
eef25c370979 initial checkin
ca
parents:
diff changeset
  1043
eef25c370979 initial checkin
ca
parents:
diff changeset
  1044
includes:anItem
eef25c370979 initial checkin
ca
parents:
diff changeset
  1045
    "returns true if the item is in the current selection
eef25c370979 initial checkin
ca
parents:
diff changeset
  1046
    "
eef25c370979 initial checkin
ca
parents:
diff changeset
  1047
    |cashedSelection|
eef25c370979 initial checkin
ca
parents:
diff changeset
  1048
eef25c370979 initial checkin
ca
parents:
diff changeset
  1049
    cashedSelection := selection.
eef25c370979 initial checkin
ca
parents:
diff changeset
  1050
    cashedSelection isNil ifTrue:[^ false].
eef25c370979 initial checkin
ca
parents:
diff changeset
  1051
 ^  cashedSelection includesIdentical:anItem
eef25c370979 initial checkin
ca
parents:
diff changeset
  1052
!
eef25c370979 initial checkin
ca
parents:
diff changeset
  1053
eef25c370979 initial checkin
ca
parents:
diff changeset
  1054
includesAll:aCollection
eef25c370979 initial checkin
ca
parents:
diff changeset
  1055
    "return true, if all items of the collection are included in the current selection
eef25c370979 initial checkin
ca
parents:
diff changeset
  1056
    "
eef25c370979 initial checkin
ca
parents:
diff changeset
  1057
    |cashedSelection|
eef25c370979 initial checkin
ca
parents:
diff changeset
  1058
eef25c370979 initial checkin
ca
parents:
diff changeset
  1059
    aCollection size ~~ 0 ifTrue:[
eef25c370979 initial checkin
ca
parents:
diff changeset
  1060
        cashedSelection := selection.
eef25c370979 initial checkin
ca
parents:
diff changeset
  1061
        cashedSelection isNil ifTrue:[ ^ false ].
eef25c370979 initial checkin
ca
parents:
diff changeset
  1062
eef25c370979 initial checkin
ca
parents:
diff changeset
  1063
        aCollection do:[:el|
eef25c370979 initial checkin
ca
parents:
diff changeset
  1064
            (cashedSelection includesIdentical:el) ifFalse:[^ false]
eef25c370979 initial checkin
ca
parents:
diff changeset
  1065
        ]
eef25c370979 initial checkin
ca
parents:
diff changeset
  1066
    ].
eef25c370979 initial checkin
ca
parents:
diff changeset
  1067
    ^ true
eef25c370979 initial checkin
ca
parents:
diff changeset
  1068
!
eef25c370979 initial checkin
ca
parents:
diff changeset
  1069
eef25c370979 initial checkin
ca
parents:
diff changeset
  1070
includesAny:aCollection
eef25c370979 initial checkin
ca
parents:
diff changeset
  1071
    "return true, if the any item of the collection is in the current selection
eef25c370979 initial checkin
ca
parents:
diff changeset
  1072
    "
eef25c370979 initial checkin
ca
parents:
diff changeset
  1073
    |cashedSelection|
eef25c370979 initial checkin
ca
parents:
diff changeset
  1074
eef25c370979 initial checkin
ca
parents:
diff changeset
  1075
    aCollection notNil ifTrue:[
eef25c370979 initial checkin
ca
parents:
diff changeset
  1076
        cashedSelection := selection.
eef25c370979 initial checkin
ca
parents:
diff changeset
  1077
eef25c370979 initial checkin
ca
parents:
diff changeset
  1078
        cashedSelection notNil ifTrue:[
eef25c370979 initial checkin
ca
parents:
diff changeset
  1079
            aCollection do:[:el|
eef25c370979 initial checkin
ca
parents:
diff changeset
  1080
                (cashedSelection includesIdentical:el) ifTrue:[^ true]
eef25c370979 initial checkin
ca
parents:
diff changeset
  1081
            ]
eef25c370979 initial checkin
ca
parents:
diff changeset
  1082
        ]
eef25c370979 initial checkin
ca
parents:
diff changeset
  1083
    ].
eef25c370979 initial checkin
ca
parents:
diff changeset
  1084
    ^ false
eef25c370979 initial checkin
ca
parents:
diff changeset
  1085
!
eef25c370979 initial checkin
ca
parents:
diff changeset
  1086
eef25c370979 initial checkin
ca
parents:
diff changeset
  1087
includesIdentical:anItem
eef25c370979 initial checkin
ca
parents:
diff changeset
  1088
    "returns true if the item is in the current selection
eef25c370979 initial checkin
ca
parents:
diff changeset
  1089
    "
eef25c370979 initial checkin
ca
parents:
diff changeset
  1090
    ^ self includes:anItem
eef25c370979 initial checkin
ca
parents:
diff changeset
  1091
!
eef25c370979 initial checkin
ca
parents:
diff changeset
  1092
eef25c370979 initial checkin
ca
parents:
diff changeset
  1093
isEmpty
eef25c370979 initial checkin
ca
parents:
diff changeset
  1094
    "returns true if the current selection is empty
eef25c370979 initial checkin
ca
parents:
diff changeset
  1095
    "
eef25c370979 initial checkin
ca
parents:
diff changeset
  1096
    ^ selection size == 0
eef25c370979 initial checkin
ca
parents:
diff changeset
  1097
!
eef25c370979 initial checkin
ca
parents:
diff changeset
  1098
eef25c370979 initial checkin
ca
parents:
diff changeset
  1099
isSelected:anItem
eef25c370979 initial checkin
ca
parents:
diff changeset
  1100
    "returns true if the item is in the current selection
eef25c370979 initial checkin
ca
parents:
diff changeset
  1101
    "
eef25c370979 initial checkin
ca
parents:
diff changeset
  1102
    ^ self includes:anItem
eef25c370979 initial checkin
ca
parents:
diff changeset
  1103
!
eef25c370979 initial checkin
ca
parents:
diff changeset
  1104
eef25c370979 initial checkin
ca
parents:
diff changeset
  1105
notEmpty
eef25c370979 initial checkin
ca
parents:
diff changeset
  1106
    "returns true if the current selection is not empty
eef25c370979 initial checkin
ca
parents:
diff changeset
  1107
    "
eef25c370979 initial checkin
ca
parents:
diff changeset
  1108
    ^ selection size ~~ 0
eef25c370979 initial checkin
ca
parents:
diff changeset
  1109
! !
eef25c370979 initial checkin
ca
parents:
diff changeset
  1110
eef25c370979 initial checkin
ca
parents:
diff changeset
  1111
!ViewTreeModel::ItemList class methodsFor:'documentation'!
eef25c370979 initial checkin
ca
parents:
diff changeset
  1112
eef25c370979 initial checkin
ca
parents:
diff changeset
  1113
documentation
eef25c370979 initial checkin
ca
parents:
diff changeset
  1114
"
eef25c370979 initial checkin
ca
parents:
diff changeset
  1115
    Kind of HierarchicalList class which contains all the visible
eef25c370979 initial checkin
ca
parents:
diff changeset
  1116
    ViewTreeItem's and the root, the anchor of the hierarchical list.
eef25c370979 initial checkin
ca
parents:
diff changeset
  1117
eef25c370979 initial checkin
ca
parents:
diff changeset
  1118
    [Instance variables:]
eef25c370979 initial checkin
ca
parents:
diff changeset
  1119
        treeModel       <ViewTreeModel>         all events are delegated to
eef25c370979 initial checkin
ca
parents:
diff changeset
  1120
        eventHook       <BlockValue>            save and resore the pre/post -EventHook
eef25c370979 initial checkin
ca
parents:
diff changeset
  1121
eef25c370979 initial checkin
ca
parents:
diff changeset
  1122
eef25c370979 initial checkin
ca
parents:
diff changeset
  1123
    [author:]
eef25c370979 initial checkin
ca
parents:
diff changeset
  1124
        Claus Atzkern
eef25c370979 initial checkin
ca
parents:
diff changeset
  1125
eef25c370979 initial checkin
ca
parents:
diff changeset
  1126
    [see also:]
eef25c370979 initial checkin
ca
parents:
diff changeset
  1127
        HierarchicalList
eef25c370979 initial checkin
ca
parents:
diff changeset
  1128
        ViewTreeModel
eef25c370979 initial checkin
ca
parents:
diff changeset
  1129
        ViewTreeItem
eef25c370979 initial checkin
ca
parents:
diff changeset
  1130
"
eef25c370979 initial checkin
ca
parents:
diff changeset
  1131
! !
eef25c370979 initial checkin
ca
parents:
diff changeset
  1132
eef25c370979 initial checkin
ca
parents:
diff changeset
  1133
!ViewTreeModel::ItemList methodsFor:'accessing'!
eef25c370979 initial checkin
ca
parents:
diff changeset
  1134
eef25c370979 initial checkin
ca
parents:
diff changeset
  1135
root:theRoot
eef25c370979 initial checkin
ca
parents:
diff changeset
  1136
    "set the root item; delegate events to my treeModel
eef25c370979 initial checkin
ca
parents:
diff changeset
  1137
    "
eef25c370979 initial checkin
ca
parents:
diff changeset
  1138
    |rootView|
eef25c370979 initial checkin
ca
parents:
diff changeset
  1139
eef25c370979 initial checkin
ca
parents:
diff changeset
  1140
    theRoot == root ifTrue:[^ self].
eef25c370979 initial checkin
ca
parents:
diff changeset
  1141
eef25c370979 initial checkin
ca
parents:
diff changeset
  1142
    rootView := self rootView.
eef25c370979 initial checkin
ca
parents:
diff changeset
  1143
    super root:theRoot.
eef25c370979 initial checkin
ca
parents:
diff changeset
  1144
eef25c370979 initial checkin
ca
parents:
diff changeset
  1145
    rootView notNil ifTrue:[ |wgrp|
eef25c370979 initial checkin
ca
parents:
diff changeset
  1146
        wgrp := rootView windowGroup.
eef25c370979 initial checkin
ca
parents:
diff changeset
  1147
eef25c370979 initial checkin
ca
parents:
diff changeset
  1148
        wgrp notNil ifTrue:[
eef25c370979 initial checkin
ca
parents:
diff changeset
  1149
           wgrp removePreEventHook:treeModel.
eef25c370979 initial checkin
ca
parents:
diff changeset
  1150
           wgrp removePostEventHook:self.
eef25c370979 initial checkin
ca
parents:
diff changeset
  1151
        ].
eef25c370979 initial checkin
ca
parents:
diff changeset
  1152
    ].
eef25c370979 initial checkin
ca
parents:
diff changeset
  1153
eef25c370979 initial checkin
ca
parents:
diff changeset
  1154
    super root:theRoot.
eef25c370979 initial checkin
ca
parents:
diff changeset
  1155
    rootView := self rootView.
eef25c370979 initial checkin
ca
parents:
diff changeset
  1156
eef25c370979 initial checkin
ca
parents:
diff changeset
  1157
    rootView notNil ifTrue:[
eef25c370979 initial checkin
ca
parents:
diff changeset
  1158
        "must setup a task because there might not exist a windowGroup at the moment
eef25c370979 initial checkin
ca
parents:
diff changeset
  1159
        "
eef25c370979 initial checkin
ca
parents:
diff changeset
  1160
        [   |wgrp|
eef25c370979 initial checkin
ca
parents:
diff changeset
  1161
eef25c370979 initial checkin
ca
parents:
diff changeset
  1162
            [rootView == self rootView] whileTrue:[
eef25c370979 initial checkin
ca
parents:
diff changeset
  1163
                wgrp := rootView windowGroup.
eef25c370979 initial checkin
ca
parents:
diff changeset
  1164
                wgrp notNil ifTrue:[
eef25c370979 initial checkin
ca
parents:
diff changeset
  1165
                    rootView := nil.
eef25c370979 initial checkin
ca
parents:
diff changeset
  1166
                    wgrp addPreEventHook:treeModel.
eef25c370979 initial checkin
ca
parents:
diff changeset
  1167
                    wgrp addPostEventHook:self.
eef25c370979 initial checkin
ca
parents:
diff changeset
  1168
                ] ifFalse:[
eef25c370979 initial checkin
ca
parents:
diff changeset
  1169
                    Delay waitForMilliseconds:100.
eef25c370979 initial checkin
ca
parents:
diff changeset
  1170
                ].
eef25c370979 initial checkin
ca
parents:
diff changeset
  1171
            ].
eef25c370979 initial checkin
ca
parents:
diff changeset
  1172
eef25c370979 initial checkin
ca
parents:
diff changeset
  1173
        ] forkAt:(Processor userSchedulingPriority + 2).
eef25c370979 initial checkin
ca
parents:
diff changeset
  1174
    ].
eef25c370979 initial checkin
ca
parents:
diff changeset
  1175
    ^ root.
eef25c370979 initial checkin
ca
parents:
diff changeset
  1176
!
eef25c370979 initial checkin
ca
parents:
diff changeset
  1177
eef25c370979 initial checkin
ca
parents:
diff changeset
  1178
rootView
eef25c370979 initial checkin
ca
parents:
diff changeset
  1179
    "returns the widget assigned to the root or nil
eef25c370979 initial checkin
ca
parents:
diff changeset
  1180
    "
eef25c370979 initial checkin
ca
parents:
diff changeset
  1181
    ^ root notNil ifTrue:[root widget] ifFalse:[nil]
eef25c370979 initial checkin
ca
parents:
diff changeset
  1182
!
eef25c370979 initial checkin
ca
parents:
diff changeset
  1183
eef25c370979 initial checkin
ca
parents:
diff changeset
  1184
treeModel
eef25c370979 initial checkin
ca
parents:
diff changeset
  1185
    "returne the treeModel, a ViewTreeModel
eef25c370979 initial checkin
ca
parents:
diff changeset
  1186
    "
eef25c370979 initial checkin
ca
parents:
diff changeset
  1187
    ^ treeModel
eef25c370979 initial checkin
ca
parents:
diff changeset
  1188
! !
eef25c370979 initial checkin
ca
parents:
diff changeset
  1189
eef25c370979 initial checkin
ca
parents:
diff changeset
  1190
!ViewTreeModel::ItemList methodsFor:'event processing'!
eef25c370979 initial checkin
ca
parents:
diff changeset
  1191
eef25c370979 initial checkin
ca
parents:
diff changeset
  1192
processEvent:anEvent
eef25c370979 initial checkin
ca
parents:
diff changeset
  1193
    "post process event
eef25c370979 initial checkin
ca
parents:
diff changeset
  1194
    "
eef25c370979 initial checkin
ca
parents:
diff changeset
  1195
    ^ treeModel testMode not
eef25c370979 initial checkin
ca
parents:
diff changeset
  1196
! !
eef25c370979 initial checkin
ca
parents:
diff changeset
  1197
eef25c370979 initial checkin
ca
parents:
diff changeset
  1198
!ViewTreeModel::ItemList methodsFor:'instance creation'!
eef25c370979 initial checkin
ca
parents:
diff changeset
  1199
eef25c370979 initial checkin
ca
parents:
diff changeset
  1200
on:aModel
eef25c370979 initial checkin
ca
parents:
diff changeset
  1201
    "set the model, a ViewTreeModel
eef25c370979 initial checkin
ca
parents:
diff changeset
  1202
    "
eef25c370979 initial checkin
ca
parents:
diff changeset
  1203
    treeModel := aModel.
eef25c370979 initial checkin
ca
parents:
diff changeset
  1204
    showRoot  := true.
eef25c370979 initial checkin
ca
parents:
diff changeset
  1205
! !
eef25c370979 initial checkin
ca
parents:
diff changeset
  1206
eef25c370979 initial checkin
ca
parents:
diff changeset
  1207
!ViewTreeModel::ItemList methodsFor:'searching'!
eef25c370979 initial checkin
ca
parents:
diff changeset
  1208
eef25c370979 initial checkin
ca
parents:
diff changeset
  1209
detectItemRespondsToView:aView
eef25c370979 initial checkin
ca
parents:
diff changeset
  1210
    "returns the bottom-most item which contains the view
eef25c370979 initial checkin
ca
parents:
diff changeset
  1211
    "
eef25c370979 initial checkin
ca
parents:
diff changeset
  1212
    |view item topView|
eef25c370979 initial checkin
ca
parents:
diff changeset
  1213
eef25c370979 initial checkin
ca
parents:
diff changeset
  1214
    root notNil ifTrue:[
eef25c370979 initial checkin
ca
parents:
diff changeset
  1215
        view    := aView.
eef25c370979 initial checkin
ca
parents:
diff changeset
  1216
        topView := root widget.
eef25c370979 initial checkin
ca
parents:
diff changeset
  1217
eef25c370979 initial checkin
ca
parents:
diff changeset
  1218
        [ view notNil ] whileTrue:[
eef25c370979 initial checkin
ca
parents:
diff changeset
  1219
            topView == view ifTrue:[^ root].
eef25c370979 initial checkin
ca
parents:
diff changeset
  1220
            item := root recursiveDetect:[:el| el widget == view ].
eef25c370979 initial checkin
ca
parents:
diff changeset
  1221
            item notNil ifTrue:[^ item].
eef25c370979 initial checkin
ca
parents:
diff changeset
  1222
            view := view superView
eef25c370979 initial checkin
ca
parents:
diff changeset
  1223
        ]
eef25c370979 initial checkin
ca
parents:
diff changeset
  1224
    ].
eef25c370979 initial checkin
ca
parents:
diff changeset
  1225
    ^ nil
eef25c370979 initial checkin
ca
parents:
diff changeset
  1226
!
eef25c370979 initial checkin
ca
parents:
diff changeset
  1227
eef25c370979 initial checkin
ca
parents:
diff changeset
  1228
recursiveDetect:aOneOrgBlock
eef25c370979 initial checkin
ca
parents:
diff changeset
  1229
    "recursive find the first child, for which evaluation 
eef25c370979 initial checkin
ca
parents:
diff changeset
  1230
     of the block returns true; if none nil is returned
eef25c370979 initial checkin
ca
parents:
diff changeset
  1231
    "
eef25c370979 initial checkin
ca
parents:
diff changeset
  1232
    root notNil ifTrue:[
eef25c370979 initial checkin
ca
parents:
diff changeset
  1233
        (aOneOrgBlock value:root) ifTrue:[ ^ root ].
eef25c370979 initial checkin
ca
parents:
diff changeset
  1234
      ^ root recursiveDetect:aOneOrgBlock
eef25c370979 initial checkin
ca
parents:
diff changeset
  1235
    ].
eef25c370979 initial checkin
ca
parents:
diff changeset
  1236
    ^ nil
eef25c370979 initial checkin
ca
parents:
diff changeset
  1237
! !
eef25c370979 initial checkin
ca
parents:
diff changeset
  1238
eef25c370979 initial checkin
ca
parents:
diff changeset
  1239
!ViewTreeModel class methodsFor:'documentation'!
eef25c370979 initial checkin
ca
parents:
diff changeset
  1240
eef25c370979 initial checkin
ca
parents:
diff changeset
  1241
version
eef25c370979 initial checkin
ca
parents:
diff changeset
  1242
    ^ '$Header$'
eef25c370979 initial checkin
ca
parents:
diff changeset
  1243
! !