--- a/HierarchicalItem.st Mon Feb 11 20:52:06 2002 +0100
+++ b/HierarchicalItem.st Fri Feb 15 13:01:52 2002 +0100
@@ -73,8 +73,23 @@
^ (self basicNew) initialize
! !
+!HierarchicalItem class methodsFor:'protocol'!
+
+doResetExtentOnChange
+ "true: the extent of the item is reset if a change
+ notification is raised from the item. the default is true
+ "
+ ^ true
+! !
+
!HierarchicalItem methodsFor:'accessing'!
+getChildren
+ "returns the children at it is; not going to the model ...
+ "
+ ^ children
+!
+
level
"returns the level starting with 1
"
@@ -138,29 +153,35 @@
at:anIndex put:anItem
"replace a child by a new item
"
- |oldItem itemExpanded size|
-
- size := self children size.
-
- (anIndex between:1 and:size) ifFalse:[
- ^ self subscriptBoundsError
- ].
+ |item list|
anItem isNil ifTrue:[
^ self removeFromIndex:anIndex toIndex:anIndex.
].
- self criticalDo:[
- oldItem := children at:anIndex.
- oldItem collapse.
- itemExpanded := anItem isExpanded.
- anItem setExpanded:false.
- children at:anIndex put:anItem.
- self changed.
+
+ ( (list := self children) isNil
+ or:[(item := list at:anIndex ifAbsent:nil) isNil]
+ ) ifTrue:[
+ ^ self subscriptBoundsError
+ ].
+
+ self criticalDo:[ |expFlag newIdx|
+ item collapse.
- itemExpanded ifTrue:[
- anItem expand
- ]
+ (list := self children) notNil ifTrue:[
+ newIdx := list identityIndexOf:item.
+
+ newIdx ~~ 0 ifTrue:[
+ expFlag := anItem isExpanded.
+ anItem setExpanded:false.
+ list at:anIndex put:anItem.
+ self changed.
+
+ expFlag ifTrue:[anItem expand].
+ ].
+ ].
].
+ ^ anItem
!
children:aListOfChildren
@@ -182,7 +203,7 @@
last
"returns the last child
"
- ^ self at:(self children size)
+ ^ self at:(self size)
!
second
@@ -194,18 +215,19 @@
!HierarchicalItem methodsFor:'accessing-hierarchy'!
collapse
- "hide children
+ "hide all my subitems
"
- |visChd model index|
+ |visChd index|
self canCollapse ifTrue:[
isExpanded := false.
self criticalDo:[
(index := self listIndex) notNil ifTrue:[
+ "/ do not call :#size: children will be autoloaded !!!!
(visChd := children size) ~~ 0 ifTrue:[
- children do:[:aChild|
- visChd := visChd + aChild numberOfVisibleChildren
+ self noneCriticalFrom:1 to:nil do:[:el|
+ visChd := visChd + el numberOfVisibleChildren
].
self model itemRemoveFromIndex:(index + 1) toIndex:(index + visChd).
index ~~ 0 ifTrue:[self hierarchyChanged]
@@ -218,19 +240,18 @@
expand
"expand children
"
- |index list|
-
self canExpand ifTrue:[
- self criticalDo:[
+ self criticalDo:[ |index list|
(index := self listIndex) notNil ifTrue:[
"/ must set expand-flag to false, otherwise change notifications
"/ are raised durring lazy auto creation (to the list).
isExpanded := false.
+ list := self children.
- (children notNil or:[self children notNil]) ifTrue:[
+ list notNil ifTrue:[
isExpanded := true.
- children notEmpty ifTrue:[
+ list notEmpty ifTrue:[
list := OrderedCollection new:64.
self addVisibleChildrenTo:list.
self model itemAddAll:list beforeIndex:(index + 1).
@@ -257,7 +278,7 @@
!
recursiveCollapse
- "collapse children and sub-children
+ "collapse all item and sub items
**** must be expanded
"
|visChd index|
@@ -265,10 +286,11 @@
self canCollapse ifTrue:[
self criticalDo:[
(index := self listIndex) notNil ifTrue:[
+ "/ do not call :#size: children will be autoloaded !!!!
(visChd := children size) ~~ 0 ifTrue:[
- children do:[:aChild|
- visChd := visChd + aChild numberOfVisibleChildren
- ]
+ self noneCriticalFrom:1 to:nil do:[:el|
+ visChd := visChd + el numberOfVisibleChildren
+ ].
].
self recursiveSetCollapsed.
@@ -284,22 +306,23 @@
]
]
]
-
!
recursiveExpand
"expand children and sub-children
**** must be collapsed
"
- |model index list|
+ |index list|
self canExpand ifTrue:[
isExpanded := true.
self criticalDo:[
- self children size ~~ 0 ifTrue:[
+ self size ~~ 0 ifTrue:[
(index := self listIndex) isNil ifTrue:[
- children do:[:aChild| aChild setExpanded:true ]
+ self noneCriticalFrom:1 to:nil do:[:el|
+ el setExpanded:true
+ ].
] ifFalse:[
list := OrderedCollection new:512.
self recursiveSetExpandedAndAddToList:list.
@@ -313,29 +336,25 @@
!
recursiveToggleExpand
- "if the item is collapsed, the children and all sub-children
+ "if the item is collapsed, the item and all its sub-items
are expanded otherwise collapsed
"
- (isExpanded == true) ifTrue:[
+ isExpanded == true ifTrue:[
self recursiveCollapse
] ifFalse:[
self recursiveExpand
]
-
!
toggleExpand
- "if the item is collapsed, the children are expanded
- otherwise collapsed
+ "if the item is collapsed, the item is expanded otherwise
+ collapsed.
"
- self criticalDo:[
- (isExpanded == true) ifTrue:[
- self collapse
- ] ifFalse:[
- self expand
- ]
- ]
-
+ isExpanded == true ifTrue:[
+ self collapse
+ ] ifFalse:[
+ self expand
+ ].
! !
!HierarchicalItem methodsFor:'accessing-mvc'!
@@ -724,7 +743,9 @@
what ~~ #redraw ifTrue:[
(what ~~ #hierarchy and:[what ~~ #icon]) ifTrue:[
- width := height := nil
+ self class doResetExtentOnChange ifTrue:[
+ width := height := nil
+ ].
].
why := what
].
@@ -764,64 +785,105 @@
"
|coll|
- coll := #().
-
- self criticalNoneEmptyChildren:[:list|
- coll := OrderedCollection new.
- list do:[:aChild| coll add:(aBlock value:aChild) ]
- ].
- ^ coll
+ coll := OrderedCollection new.
+ self do:[:el| coll add:(aBlock value:el) ].
+ ^ coll
!
do:aOneArgBlock
"evaluate a block on each child
"
- ^ self criticalNoneEmptyChildren:[:list|
- list do:aOneArgBlock
- ].
+ ^ self from:1 do:aOneArgBlock
!
from:startIndex do:aOneArgBlock
"evaluate a block on each child starting with the
child at startIndex to the end.
"
- ^ self from:startIndex to:self size do:aOneArgBlock
+ |res|
+
+ self size < startIndex ifTrue:[^ nil].
+ res := nil.
+
+ self criticalDo:[
+ res := self noneCriticalFrom:startIndex to:nil do:aOneArgBlock
+ ].
+ ^ res
+!
+
+from:startIndex reverseDo:aOneArgBlock
+ "evaluate a block on each child starting at end to the startIndex
+ "
+ |res|
+
+ self size < startIndex ifTrue:[^ nil].
+ res := nil.
+
+ self criticalDo:[
+ res := self noneCriticalFrom:startIndex to:nil reverseDo:aOneArgBlock
+ ].
+ ^ res
!
from:startIndex to:endIndex do:aOneArgBlock
"evaluate a block on each child starting with the
child at startIndex to the endIndex.
"
- ^ self criticalNoneEmptyChildren:[:list|
- list from:startIndex to:endIndex do:aOneArgBlock
+ |res|
+
+ self size < startIndex ifTrue:[^ nil].
+ res := nil.
+
+ self criticalDo:[
+ res := self noneCriticalFrom:startIndex to:endIndex do:aOneArgBlock
].
+ ^ res
!
from:startIndex to:endIndex reverseDo:aOneArgBlock
"evaluate a block on each child starting with the
child at endIndex to the startIndex.
"
- ^ self criticalNoneEmptyChildren:[:list|
- list from:startIndex to:endIndex reverseDo:aOneArgBlock
+ |res|
+
+ self size < startIndex ifTrue:[^ nil].
+ res := nil.
+
+ self criticalDo:[
+ res := self noneCriticalFrom:startIndex to:endIndex reverseDo:aOneArgBlock
].
+ ^ res
!
keysAndValuesDo:aTwoArgBlock
"evaluate the argument, aBlock for every child,
- passing both index and element as arguments."
+ passing both index and element as arguments.
+ "
+ |key res|
- ^ self criticalNoneEmptyChildren:[:list|
- list keysAndValuesDo:aTwoArgBlock
+ key := 1.
+ res := nil.
+
+ self do:[:el|
+ res := el value:key value:el.
+ key := key + 1.
].
+ ^ res
!
keysAndValuesReverseDo:aTwoArgBlock
"evaluate the argument, aBlock in reverse order for every
- child, passing both index and element as arguments."
+ child, passing both index and element as arguments.
+ "
+ |res|
- ^ self criticalNoneEmptyChildren:[:list|
- list keysAndValuesReverseDo:aTwoArgBlock
+ self size == 0 ifTrue:[^ nil].
+ res := nil.
+
+ self criticalDo:[
+ res := self noneCriticalKeysAndValuesReverseDo:aTwoArgBlock
].
+ ^ res
!
recursiveCollect:aBlock
@@ -866,34 +928,30 @@
!
reverseDo:aOneArgBlock
- "evaluate a block on each child
- proccesing children in reverse direction
+ "evaluate a block on each child in reverse direction
"
- ^ self criticalNoneEmptyChildren:[:list|
- list reverseDo:aOneArgBlock
- ].
+ ^ self from:1 reverseDo:aOneArgBlock
!
select:aBlock
- "return a new collection with all children from the receiver, for which
+ "return a new collection with all items from the receiver, for which
the argument aBlock evaluates to true.
"
|coll|
- coll := #().
-
- self criticalNoneEmptyChildren:[:list|
- coll := OrderedCollection new.
- list do:[:el| (aBlock value:el) ifTrue:[coll add:el] ].
- ].
- ^ coll
+ coll := OrderedCollection new.
+ self do:[:el| (aBlock value:el) ifTrue:[coll add:el] ].
+ ^ coll
!
withAllDo:aOneArgBlock
- "evaluate the block on each item including self
+ "evaluate the block on each item and subitem including self
"
- ^ self criticalDo:[
- self noneCriticalWithAllDo:aOneArgBlock
+ aOneArgBlock value:self.
+
+ self do:[:el|
+ aOneArgBlock value:el.
+ el noneCriticalRecursiveDo:aOneArgBlock.
].
! !
@@ -947,19 +1005,12 @@
addVisibleChildrenTo:aList
"add all visible children and sub-children to the list
"
- isExpanded == true ifTrue:[
- (children notNil or:[self children notNil]) ifTrue:[
- children do:[:aChild|
- aList add:aChild.
- aChild addVisibleChildrenTo:aList
- ]
- ]
- ]
+ isExpanded == true ifFalse:[^ self].
-
-
-
-
+ self noneCriticalFrom:1 to:nil do:[:el|
+ aList add:el.
+ el addVisibleChildrenTo:aList.
+ ].
!
criticalDo:aBlock
@@ -972,24 +1023,6 @@
]
!
-criticalNoneEmptyChildren:aOneArgBlockTheChildren
- "evaluate the block on the list of children if not empty
- within a critical region
- "
- |resp|
-
- self children size ~~ 0 ifTrue:[
- self criticalDo:[ |list|
- list := self children.
-
- list size ~~ 0 ifTrue:[
- resp := aOneArgBlockTheChildren value:list
- ]
- ]
- ].
- ^ resp
-!
-
listIndex
"returns the visible index or nil; for a none visible root
0 is returned
@@ -1009,23 +1042,15 @@
numberOfVisibleChildren
"returns number of all visible children including subchildren
"
- |size "{ Class: SmallInteger }"
- |
- (isExpanded == true) ifTrue:[
- (children notNil or:[self children notNil]) ifTrue:[
- (size := children size) ~~ 0 ifTrue:[
- self criticalDo:[
- children do:[:el| size := size + el numberOfVisibleChildren ].
- ].
- ^ size
- ]
- ]
+ |size|
+
+ isExpanded == true ifFalse:[^ 0].
+ size := 0.
+
+ self noneCriticalFrom:1 to:nil do:[:el|
+ size := 1 + size + el numberOfVisibleChildren
].
- ^ 0
-
-
-
-
+ ^ size
!
parentOrModel
@@ -1117,18 +1142,74 @@
!HierarchicalItem methodsFor:'private enumerating'!
+noneCriticalFrom:startIndex to:endIndex do:aOneArgBlock
+ "evaluate a block none critical on each child starting with the
+ child at startIndex to the endIndex (if nil to end of list).
+ "
+ |list size resp|
+
+ list := self children.
+ size := list size.
+
+ startIndex > size ifTrue:[^ nil].
+ resp := nil.
+
+ endIndex notNil ifTrue:[
+ size := size min:endIndex
+ ].
+ startIndex to:size do:[:i| |item|
+ item := list at:i ifAbsent:nil.
+ item isNil ifTrue:[^ resp].
+ resp := aOneArgBlock value:item.
+ ].
+ ^ resp
+!
+
+noneCriticalFrom:startIndex to:endIndex reverseDo:aOneArgBlock
+ "evaluate a block none critical on each child starting with the
+ child at endIndex (if nil to end of list) to startIndex.
+ "
+ |list size resp|
+
+ list := self children.
+ size := list size.
+ resp := nil.
+
+ endIndex notNil ifTrue:[
+ size := size min:endIndex
+ ].
+ size to:startIndex by:-1 do:[:i| |item|
+ item := list at:i ifAbsent:nil.
+ item isNil ifTrue:[^ resp].
+ resp := aOneArgBlock value:item.
+ ].
+ ^ resp
+!
+
+noneCriticalKeysAndValuesReverseDo:aOneArgBlock
+ "evaluate the argument, aBlock in reverse order for every
+ child, passing both index and element as arguments.
+ "
+ |list size resp|
+
+ list := self children.
+ size := list size.
+ resp := nil.
+
+ size to:1 by:-1 do:[:i| |item|
+ item := list at:i ifAbsent:nil.
+ item isNil ifTrue:[^ resp].
+ resp := aOneArgBlock value:i value:item.
+ ].
+ ^ resp
+!
+
noneCriticalRecursiveDo:anOneArgBlock
"evaluate the block none critical on each item and all the sub-items
"
- |loe|
-
- loe := self children.
-
- loe size ~~ 0 ifTrue:[
- loe do:[:aChild|
- anOneArgBlock value:aChild.
- aChild noneCriticalRecursiveDo:anOneArgBlock
- ]
+ self noneCriticalFrom:1 to:nil do:[:aChild|
+ anOneArgBlock value:aChild.
+ aChild noneCriticalRecursiveDo:anOneArgBlock
].
!
@@ -1136,29 +1217,9 @@
"evaluate the block none critical on each item and all the sub-items;
proccesing children in reverse direction
"
- |loe|
-
- loe := self children.
-
- loe size ~~ 0 ifTrue:[
- loe reverseDo:[:aChild|
- aChild noneCriticalRecursiveReverseDo:anOneArgBlock.
- anOneArgBlock value:aChild.
- ]
- ].
-!
-
-noneCriticalWithAllDo:aOneArgBlock
- "evaluate the block none critical on each item including self
- "
- |loe|
-
- aOneArgBlock value:self.
-
- loe := self children.
-
- loe size ~~ 0 ifTrue:[
- loe do:[:el| el withAllDo:aOneArgBlock ]
+ self noneCriticalFrom:1 to:nil reverseDo:[:aChild|
+ aChild noneCriticalRecursiveReverseDo:anOneArgBlock.
+ anOneArgBlock value:aChild.
].
! !
@@ -1169,8 +1230,9 @@
"
isExpanded := false.
- children notNil ifTrue:[
- children do:[:aChild| aChild recursiveSetCollapsed ]
+ "/ do not call :#size: children will be autoloaded !!!!
+ children size ~~ 0 ifTrue:[
+ self noneCriticalFrom:1 to:nil do:[:el| el recursiveSetCollapsed ].
]
!
@@ -1180,15 +1242,10 @@
"
isExpanded := true.
- (children notNil or:[self children notNil]) ifTrue:[
- self criticalDo:[
- children do:[:aChild|
- aList add:aChild.
- aChild recursiveSetExpandedAndAddToList:aList.
- ]
- ]
- ]
-
+ self do:[:anItem|
+ aList add:anItem.
+ anItem recursiveSetExpandedAndAddToList:aList.
+ ].
! !
!HierarchicalItem methodsFor:'protocol accessing'!
@@ -1331,8 +1388,7 @@
be loaded yet( ex. FileDirectory ).
*** to optimize:redefine by subClass
"
- ^ children notNil ifTrue:[children notEmpty]
- ifFalse:[self children size ~~ 0]
+ ^ self children size ~~ 0
!
string
@@ -1433,8 +1489,7 @@
size
"return the number of children
"
- ^ children notNil ifTrue:[children size]
- ifFalse:[self children size]
+ ^ self children size
! !
!HierarchicalItem methodsFor:'searching'!
@@ -1447,23 +1502,12 @@
!
-detect:aOneArgBlock ifNone:anExceptionBlock
+detect:anOneArgBlock ifNone:anExceptionBlock
"find the first child, for which evaluation of the block returns
true; if none does so, return the evaluation of anExceptionBlock
"
- |item|
-
- self children size ~~ 0 ifTrue:[
- self criticalDo:[
- item := children detect:aOneArgBlock ifNone:nil
- ].
- item notNil ifTrue:[
- ^ item
- ]
- ].
- ^ anExceptionBlock value
-
-
+ self do:[:el| (anOneArgBlock value:el) ifTrue:[^ el] ].
+ ^ anExceptionBlock value
!
detectLast:aOneArgBlock
@@ -1474,43 +1518,28 @@
!
-detectLast:aOneArgBlock ifNone:anExceptionBlock
+detectLast:anOneArgBlock ifNone:anExceptionBlock
"find the last child, for which evaluation of the block returns
true; if none does so, return the evaluation of anExceptionBlock
"
- |item|
-
- self children size ~~ 0 ifTrue:[
- self criticalDo:[
- item := children detectLast:aOneArgBlock ifNone:nil
- ].
- item notNil ifTrue:[
- ^ item
- ]
- ].
- ^ anExceptionBlock value
-
-
+ self reverseDo:[:el| (anOneArgBlock value:el) ifTrue:[^ el] ].
+ ^ anExceptionBlock value
!
-findFirst:aOneArgBlock
+findFirst:anOneArgBlock
"find the first child, for which evaluation of the argument, aOneArgBlock
returns true; return its index or 0 if none detected.
"
- self keysAndValuesDo:[:anIndex :aChild|
- (aOneArgBlock value:aChild) ifTrue:[^ anIndex]
- ].
- ^ 0
+ self keysAndValuesDo:[:i :el| (anOneArgBlock value:el) ifTrue:[^ i] ].
+ ^ 0
!
-findLast:aOneArgBlock
+findLast:anOneArgBlock
"find the last child, for which evaluation of the argument, aOneArgBlock
returns true; return its index or 0 if none detected.
"
- self keysAndValuesReverseDo:[:anIndex :aChild|
- (aOneArgBlock value:aChild) ifTrue:[^ anIndex]
- ].
- ^ 0
+ self keysAndValuesReverseDo:[:i :el| (anOneArgBlock value:el) ifTrue:[^ i] ].
+ ^ 0
!
identityIndexOf:aChild
@@ -1525,14 +1554,13 @@
"
|index|
- index := 0.
+ index := startIndex.
- self children size ~~ 0 ifTrue:[
- self criticalDo:[
- index := children identityIndexOf:aChild startingAt:startIndex
- ]
+ self from:startIndex do:[:el|
+ el == aChild ifTrue:[^ index ].
+ index := index + 1.
].
- ^ index
+ ^ 0
!
recursiveDetect:aOneArgBlock
@@ -1704,5 +1732,5 @@
!HierarchicalItem class methodsFor:'documentation'!
version
- ^ '$Header: /cvs/stx/stx/libwidg2/HierarchicalItem.st,v 1.36 2001-10-15 07:21:10 martin Exp $'
+ ^ '$Header: /cvs/stx/stx/libwidg2/HierarchicalItem.st,v 1.37 2002-02-15 12:01:52 ca Exp $'
! !