CompactHierarchicalItem.st
changeset 4736 7efebff3d62b
child 4744 8ec2fbbfce9e
equal deleted inserted replaced
4735:783272ebf6e1 4736:7efebff3d62b
       
     1 "{ Encoding: utf8 }"
       
     2 
       
     3 "
       
     4  COPYRIGHT (c) 1999 by eXept Software AG
       
     5               All Rights Reserved
       
     6 
       
     7  This software is furnished under a license and may be used
       
     8  only in accordance with the terms of that license and with the
       
     9  inclusion of the above copyright notice.   This software may not
       
    10  be provided or otherwise made available to, or used by, any
       
    11  other person.  No title to or ownership of the software is
       
    12  hereby transferred.
       
    13 "
       
    14 "{ Package: 'stx:libwidg2' }"
       
    15 
       
    16 "{ NameSpace: Smalltalk }"
       
    17 
       
    18 AbstractHierarchicalItem subclass:#CompactHierarchicalItem
       
    19 	instanceVariableNames:'widthAndHeight model'
       
    20 	classVariableNames:'MaskHeight MaskWidth ShiftHeight ShiftWidth'
       
    21 	poolDictionaries:''
       
    22 	category:'Views-Support'
       
    23 !
       
    24 
       
    25 CompactHierarchicalItem subclass:#CompactHierarchicalItemExpanded
       
    26 	instanceVariableNames:''
       
    27 	classVariableNames:''
       
    28 	poolDictionaries:''
       
    29 	privateIn:CompactHierarchicalItem
       
    30 !
       
    31 
       
    32 Object subclass:#Geometry
       
    33 	instanceVariableNames:'width height'
       
    34 	classVariableNames:''
       
    35 	poolDictionaries:''
       
    36 	privateIn:CompactHierarchicalItem
       
    37 !
       
    38 
       
    39 !CompactHierarchicalItem class methodsFor:'documentation'!
       
    40 
       
    41 copyright
       
    42 "
       
    43  COPYRIGHT (c) 1999 by eXept Software AG
       
    44               All Rights Reserved
       
    45 
       
    46  This software is furnished under a license and may be used
       
    47  only in accordance with the terms of that license and with the
       
    48  inclusion of the above copyright notice.   This software may not
       
    49  be provided or otherwise made available to, or used by, any
       
    50  other person.  No title to or ownership of the software is
       
    51  hereby transferred.
       
    52 "
       
    53 
       
    54 !
       
    55 
       
    56 documentation
       
    57 "
       
    58     Compact Hierarchical Items are a new, tuned and optimized version of the original
       
    59     hierarchical item, which suffers various problems:
       
    60         1) the old item did not store the model, which in many situations leads to very
       
    61            poor performance (it walks along the super-item hierarchy to find the model,
       
    62            which makes many algorithms O(n^2) instead of O(n)
       
    63         2) it keeps individual width/height information, where this could be shared if
       
    64            many items have the same extent.
       
    65         3) it uses separate width/height instvars, where this information can be stored more compact
       
    66            in single integer (using bit-masks)
       
    67         4) it uses a separate boolean for the isExpanded, which can be encoded as a single bit
       
    68 
       
    69     This class solves those issues:
       
    70         - it uses a compact width/height representation (bit masks in an integer), for
       
    71           items within a reasonable size (up to 64k pixels wide, up to 16k pixels high).
       
    72         - falls back to a separate width/height holding object, if ever exceeded (which is unlikely)
       
    73 
       
    74         - it encodes the expanded state in the class itself (changing as appropriate)
       
    75 
       
    76         - it uses the saved slot to allow for the model to be kept locally
       
    77 
       
    78     [author:]
       
    79         Claus Gittinger
       
    80 
       
    81     [see also:]
       
    82         HierarchicalItem
       
    83 "
       
    84 ! !
       
    85 
       
    86 !CompactHierarchicalItem class methodsFor:'class initialization'!
       
    87 
       
    88 initialize
       
    89     ShiftWidth  := 0.
       
    90     MaskWidth  := 16rFFFF.
       
    91     ShiftHeight := MaskWidth highBit.
       
    92     MaskHeight := 16r1FFF.
       
    93     "/ self assert:(ShiftHeight + (MaskHeight highBit)) < 31.
       
    94 ! !
       
    95 
       
    96 !CompactHierarchicalItem methodsFor:'accessing-mvc'!
       
    97 
       
    98 fetchModel
       
    99     "returns the hierachicalList model or nil.
       
   100      This is a stupid implementation here, in that the top-item's parent is assumed to
       
   101      be the model of the tree, and that is returned.
       
   102      This saves a slot in every node, but makes some algorithms O(n*log n) or even O(n^2).
       
   103      So be aware of the performance penalty"
       
   104 
       
   105     |item next|
       
   106 
       
   107     item := self. 
       
   108     [ (next := item parentOrModel) notNil ] whileTrue:[
       
   109         item := next.
       
   110     ].
       
   111 
       
   112     item isHierarchicalItem ifFalse:[^ item].
       
   113     ^ nil
       
   114 !
       
   115 
       
   116 model
       
   117     "returns the hierachicalList model or nil.
       
   118      This fixes the stupid implementation of the old HierarchicalItem, 
       
   119      by caching the fetched model (behaving the same, if there is no model)"
       
   120 
       
   121     model isNil ifTrue:[
       
   122         model := self fetchModel.
       
   123         model isNil ifTrue:[
       
   124             model := #nilModel.
       
   125             ^ nil
       
   126         ].
       
   127     ].
       
   128     model == #nilModel ifTrue:[
       
   129         ^ nil
       
   130     ].
       
   131     ^ model
       
   132 ! !
       
   133 
       
   134 !CompactHierarchicalItem methodsFor:'private'!
       
   135 
       
   136 classToUseWhenCollapsed
       
   137     "must be redefined when subclassed"
       
   138 
       
   139     self class == CompactHierarchicalItemExpanded ifFalse:[
       
   140         self subclassResponsibility:'this method must be redefined when subclassed'
       
   141     ].
       
   142     ^ CompactHierarchicalItem
       
   143 !
       
   144 
       
   145 classToUseWhenExpanded
       
   146     "must be redefined when subclassed"
       
   147 
       
   148     self class == CompactHierarchicalItem ifFalse:[
       
   149         self subclassResponsibility:'this method must be redefined when subclassed'
       
   150     ].
       
   151     ^ CompactHierarchicalItemExpanded
       
   152 !
       
   153 
       
   154 heightIsUnknown
       
   155     ^ widthAndHeight isNil
       
   156     or:[ widthAndHeight isInteger not
       
   157          and:[ widthAndHeight height isNil ]]
       
   158 !
       
   159 
       
   160 makeWidthAndHeightUnknown
       
   161     "invalidate any cached with/height information"
       
   162 
       
   163     "see comments in widthOn/heightOn"
       
   164     widthAndHeight := nil
       
   165 !
       
   166 
       
   167 setExpanded:aBoolean
       
   168     "set expanded flag without any computation or notification"
       
   169 
       
   170     |newClass|
       
   171 
       
   172     self isExpanded ~~ aBoolean ifTrue:[
       
   173         newClass := aBoolean 
       
   174                         ifTrue:[self classToUseWhenExpanded] 
       
   175                         ifFalse:[self classToUseWhenCollapsed].
       
   176         self changeClassTo:newClass
       
   177     ]
       
   178 !
       
   179 
       
   180 widthIsUnknown
       
   181     ^ widthAndHeight isNil
       
   182     or:[ widthAndHeight isInteger not
       
   183          and:[ widthAndHeight width isNil ]]
       
   184 ! !
       
   185 
       
   186 !CompactHierarchicalItem methodsFor:'protocol-displaying'!
       
   187 
       
   188 getWidthAndHeightOn:aGC
       
   189     "fetch the width and height from my label, if it is to be displayed on aGC"
       
   190 
       
   191     |lbl|
       
   192 
       
   193     lbl := self label.
       
   194     self width:(self widthOf:lbl on:aGC) height:(self heightOf:lbl on:aGC)
       
   195 !
       
   196 
       
   197 heightOn:aGC
       
   198     "return the width of the receiver, if it is to be displayed on aGC"
       
   199 
       
   200     widthAndHeight isNil ifTrue:[
       
   201         self getWidthAndHeightOn:aGC.
       
   202     ].
       
   203     widthAndHeight isInteger ifTrue:[
       
   204         ^ (widthAndHeight rightShift:ShiftHeight) bitAnd:MaskHeight
       
   205     ].
       
   206     ^ widthAndHeight height
       
   207 !
       
   208 
       
   209 width:w height:h
       
   210     ((w between:0 and:MaskWidth)
       
   211     and:[ (h between:0 and:MaskHeight) ]) ifTrue:[
       
   212         widthAndHeight := (w bitShift:ShiftWidth) bitOr:(h bitShift:ShiftHeight)
       
   213     ] ifFalse:[
       
   214         widthAndHeight := Geometry new width:w height:h
       
   215     ].
       
   216 !
       
   217 
       
   218 widthOn:aGC
       
   219     "return the width of the receiver, if it is to be displayed on aGC"
       
   220 
       
   221     widthAndHeight isNil ifTrue:[
       
   222         self getWidthAndHeightOn:aGC.
       
   223     ].
       
   224     widthAndHeight isInteger ifTrue:[
       
   225         ^ (widthAndHeight rightShift:ShiftWidth) bitAnd:MaskWidth
       
   226     ].
       
   227     ^ widthAndHeight width
       
   228 ! !
       
   229 
       
   230 !CompactHierarchicalItem methodsFor:'queries'!
       
   231 
       
   232 isExpanded
       
   233     "returns true if the item is expanded"
       
   234 
       
   235     "see my ghost-class CompactHierarchicalItemExpanded for the other case"
       
   236     ^ false 
       
   237 ! !
       
   238 
       
   239 !CompactHierarchicalItem::CompactHierarchicalItemExpanded methodsFor:'queries'!
       
   240 
       
   241 isExpanded
       
   242     "returns true if the item is expanded"
       
   243 
       
   244     ^ true 
       
   245 ! !
       
   246 
       
   247 !CompactHierarchicalItem::Geometry class methodsFor:'documentation'!
       
   248 
       
   249 documentation
       
   250 "
       
   251     instances are only used if any of width/height is too large to fit into the
       
   252     compact integer bitmasked representation
       
   253 "
       
   254 ! !
       
   255 
       
   256 !CompactHierarchicalItem::Geometry methodsFor:'accessing'!
       
   257 
       
   258 height
       
   259     ^ height
       
   260 !
       
   261 
       
   262 height:something
       
   263     height := something.
       
   264 !
       
   265 
       
   266 width
       
   267     ^ width
       
   268 !
       
   269 
       
   270 width:something
       
   271     width := something.
       
   272 !
       
   273 
       
   274 width:widthArg height:heightArg 
       
   275     width := widthArg.
       
   276     height := heightArg.
       
   277 ! !
       
   278 
       
   279 !CompactHierarchicalItem class methodsFor:'documentation'!
       
   280 
       
   281 version
       
   282     ^ '$Header: /cvs/stx/stx/libwidg2/CompactHierarchicalItem.st,v 1.1 2015-05-01 14:40:04 cg Exp $'
       
   283 !
       
   284 
       
   285 version_CVS
       
   286     ^ '$Header: /cvs/stx/stx/libwidg2/CompactHierarchicalItem.st,v 1.1 2015-05-01 14:40:04 cg Exp $'
       
   287 ! !
       
   288 
       
   289 
       
   290 CompactHierarchicalItem initialize!