GraphColumnView.st
changeset 741 1d91a0437471
child 749 18179e2bfff4
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/GraphColumnView.st	Sat Feb 07 16:16:52 1998 +0100
@@ -0,0 +1,657 @@
+View subclass:#GraphColumnView
+	instanceVariableNames:'listHolder zoomYHolder columns oldMenuMessage windowSizeHolder
+		windowSize gridColor showGrid fgColor bgColor vLinesColor zoomY'
+	classVariableNames:'DefaultBackgroundColor DefaultGridColor DefaultForegroundColor
+		DefaultVLinesColor'
+	poolDictionaries:''
+	category:'Views-Graphs'
+!
+
+
+!GraphColumnView class methodsFor:'defaults'!
+
+defaultMenu
+    "redefined by subclass: should return the default middle button menu
+    "
+    ^ nil
+!
+
+updateStyleCache
+    "extract values from the styleSheet and cache them in class variables
+    "
+    DefaultForegroundColor := Color black.
+    DefaultBackgroundColor := Color veryLightGray.
+    DefaultGridColor       := Color lightGray.
+    DefaultVLinesColor     := DefaultForegroundColor
+"
+ self updateStyleCache
+"
+
+
+! !
+
+!GraphColumnView methodsFor:'accessing'!
+
+columns
+    "returns list of column descriptions
+    "
+    ^ columns
+
+
+!
+
+columns:aList
+    "set list of columns
+    "
+    columns notNil ifTrue:[
+        columns do:[:aCol| aCol removeDependent:self ]
+    ].
+
+    aList size ~~ 0 ifTrue:[
+        columns := OrderedCollection new.
+
+        aList do:[:aColumn| 
+            aColumn addDependent:self.
+            columns add:aColumn
+        ]
+    ] ifFalse:[
+        columns := nil
+    ].
+    self recomputeWholeGraph
+!
+
+showDefaultMenu
+    "enable or disable my default menu
+    "
+    ^ self menuMessage == #defaultMenu
+!
+
+showDefaultMenu:aBool
+    "enable or disable my default menu
+    "
+    |currMsg|
+
+    currMsg := self menuMessage.
+
+    aBool ifTrue:[
+        oldMenuMessage := currMsg.
+        self menuMessage:#defaultMenu
+    ] ifFalse:[
+        currMsg == #defaultMenu ifTrue:[
+            self menuMessage:oldMenuMessage
+        ]
+    ].
+
+
+! !
+
+!GraphColumnView methodsFor:'accessing dimensions'!
+
+windowSize
+    "get number of horizontal steps ( X )
+    "
+    ^ windowSize
+
+
+!
+
+windowSize:aValue
+    "set number of horizontal steps ( X )
+    "
+    |sz|
+
+    sz := (self unsignedIntegerFrom:aValue onError:[101]) max:5.
+
+    sz ~~ windowSize ifTrue:[
+        windowSize := sz.
+        self recomputeWholeGraph
+    ]
+
+!
+
+zoomY
+    "returns current y-zoom factor
+    "
+    ^ zoomY
+
+
+!
+
+zoomY:aValue
+    "set current y-zoom factor; if the argument is nil,
+     the y-zoom is set to 1 ( no zoom ).
+    "
+    |zY|
+
+    (zY := self floatFrom:aValue onError:[1]) <= 0 ifTrue:[
+        zY := 1
+    ].
+
+    zY = zoomY ifFalse:[
+        zoomY := zY.
+        self invalidateGraph
+    ]
+
+
+! !
+
+!GraphColumnView methodsFor:'accessing look'!
+
+backgroundColor
+    "get the background color
+    "
+    ^ bgColor
+
+
+!
+
+backgroundColor:aColor
+    "set the background color
+    "
+    (aColor isColor and:[bgColor ~= aColor]) ifTrue:[
+        shown ifTrue:[
+            bgColor := aColor on:device.
+            self colorChanged:#background.
+        ] ifFalse:[
+            bgColor := aColor
+        ]
+    ]
+!
+
+foregroundColor
+    "get the default foreground color; used in case that no color for
+     a column is specified
+    "
+    ^ fgColor
+
+!
+
+foregroundColor:aColor
+    "set the default foreground color; used in case that no color for
+     a column is specified
+    "
+    (aColor isColor and:[fgColor ~= aColor]) ifTrue:[
+        shown ifTrue:[
+            fgColor := aColor on:device.
+            self colorChanged:#foreground
+        ] ifFalse:[
+            fgColor := aColor
+        ]
+    ]
+
+!
+
+gridColor
+    "get the foreground color of the grid
+    "
+    ^ gridColor
+
+!
+
+gridColor:aColor
+    "set the foreground color of the grid
+    "
+    (aColor isColor and:[gridColor ~= aColor]) ifTrue:[
+        shown ifTrue:[
+            gridColor := aColor on:device.
+
+            showGrid ifTrue:[
+                self colorChanged:#grid
+            ]
+        ] ifFalse:[
+            gridColor := aColor
+        ]
+    ]
+
+!
+
+showGrid
+    ^ showGrid
+
+!
+
+showGrid:aBool
+    |hasGrid|
+
+    showGrid ~~ aBool ifTrue:[
+        showGrid := aBool.
+
+        shown ifTrue:[
+            self invalidateGraph
+        ]
+    ]
+
+!
+
+vLinesColor
+    "get the foreground color of the vertical lines
+    "
+    ^ vLinesColor
+
+
+!
+
+vLinesColor:aColor
+    "set the foreground color of the vertical lines
+    "
+    (aColor isColor and:[vLinesColor ~= aColor]) ifTrue:[
+        shown ifTrue:[
+            vLinesColor := aColor on:device.
+            self colorChanged:#vLines
+        ] ifFalse:[
+            vLinesColor := aColor
+        ]
+    ]
+
+! !
+
+!GraphColumnView methodsFor:'accessing mvc'!
+
+listHolder
+    "get the valueHolder which holds the list of column descriptons
+    "
+    ^ listHolder
+
+
+!
+
+listHolder:aHolder
+    "set the valueHolder which holds the list of column descriptons
+    "
+    listHolder == aHolder ifFalse:[
+        listHolder notNil ifTrue:[
+            listHolder removeDependent:self
+        ].
+        (listHolder := aHolder) notNil ifTrue:[
+            listHolder addDependent:self
+        ].
+    ].
+    self columns:(listHolder value)
+
+!
+
+model:aModel
+    "set the valueHolder which holds the selection and maybe the list of columnms
+    "
+    (model respondsTo:#list) ifTrue:[
+        (model list == listHolder) ifTrue:[
+            self listHolder:nil
+        ]
+    ].
+    super model:aModel.
+
+    aModel notNil ifTrue:[
+        (aModel respondsTo:#list) ifTrue:[
+            self listHolder:model list
+        ]
+    ]
+
+!
+
+windowSizeHolder
+    "get the valueHolder which holds the size of the window; X
+    "
+    ^ windowSizeHolder
+
+!
+
+windowSizeHolder:aHolder
+    "set the valueHolder which holds the size of the window; X
+    "
+    windowSizeHolder == aHolder ifFalse:[
+        windowSizeHolder notNil ifTrue:[
+            windowSizeHolder removeDependent:self
+        ].
+        (windowSizeHolder := aHolder) notNil ifTrue:[
+            windowSizeHolder addDependent:self
+        ].
+    ].
+    self windowSize:(windowSizeHolder value)
+
+!
+
+zoomYHolder
+    "get the valueHolder which holds the y zoom factor
+    "
+    ^ zoomYHolder
+
+!
+
+zoomYHolder:aHolder
+    "set the valueHolder which holds the y zoom factor
+    "
+    zoomYHolder == aHolder ifFalse:[
+        zoomYHolder notNil ifTrue:[
+            zoomYHolder removeDependent:self
+        ].
+        (zoomYHolder := aHolder) notNil ifTrue:[
+            zoomYHolder addDependent:self
+        ]
+    ].
+    self zoomY:(zoomYHolder value).
+
+! !
+
+!GraphColumnView methodsFor:'adding & removing'!
+
+add:aColumn
+    "insert a column at end; returns the inserted column
+    "
+    ^ self add:aColumn beforeIndex:(1 + columns size)
+
+!
+
+add:aColumn afterIndex:anIndex
+    "add a new column after an index; returns the inserted column
+    "
+    ^ self add:aColumn beforeIndex:(anIndex + 1)
+
+!
+
+add:aColumn beforeIndex:anIndex
+    "add a column before an index; returns the inserted column
+    "
+    aColumn isNil ifTrue:[^ nil].
+
+    columns isNil ifTrue:[
+        self columns:(Array with:aColumn).
+        ^ aColumn.
+    ].
+    columns add:aColumn beforeIndex:anIndex.
+    aColumn addDependent:self.
+
+    aColumn shown ifTrue:[
+        self listSizeChanged:#insert: from:aColumn.
+    ].
+
+!
+
+addAll:aCollection beforeIndex:anIndex
+    "add a collection of columns before an index
+    "
+    aCollection size ~~ 0 ifTrue:[
+        columns size == 0 ifTrue:[
+            self columns:aCollection
+        ] ifFalse:[
+            columns addAll:aCollection beforeIndex:anIndex.
+            self recomputeWholeGraph.
+        ]
+    ]
+
+!
+
+addFirst:aColumn
+    "insert a column at start; returns the inserted column
+    "
+    ^ self add:aColumn beforeIndex:1
+
+!
+
+removeAll
+    "remove all columns
+    "
+    self columns:nil
+
+!
+
+removeFirst
+    "remove first column; returns the removed column
+    "
+    ^ self removeIndex:1
+
+
+!
+
+removeIndex:anIndex
+    "remove column at an index; returns the removed column
+    "
+    |col|
+
+    col := columns removeAtIndex:anIndex.
+    col removeDependent:self.
+
+    columns size == 0 ifTrue:[
+        columns := nil
+    ].
+    col shown ifTrue:[
+        self listSizeChanged:#remove: from:col
+    ].
+  ^ col
+
+
+!
+
+removeLast
+    "remove last column; the removed column is returned
+    "
+    ^ self removeIndex:(columns size)
+
+! !
+
+!GraphColumnView methodsFor:'change & update'!
+
+update:what with:aPara from:chgObj
+    "catch and handle a change notification of any object
+    "
+    |list start size stop|
+
+    chgObj == windowSizeHolder ifTrue:[
+        ^ self windowSize:(windowSizeHolder value)
+    ].
+
+    chgObj == zoomYHolder ifTrue:[
+        ^ self zoomY:(zoomYHolder value)
+    ].
+
+    chgObj == model ifTrue:[
+        (what == #selectionIndex or:[what == #selection]) ifTrue:[
+            ^ self
+        ].
+        what == #list ifTrue:[
+            ^ self listHolder:model list
+        ].
+        model == listHolder ifFalse:[
+            ^ self
+        ].
+    ].
+
+    chgObj == listHolder ifTrue:[
+        list := listHolder value.
+
+        (what == #insert:) ifTrue:[
+            self add:(list at:aPara) beforeIndex:aPara
+        ] ifFalse:[
+            (what == #remove:) ifTrue:[
+                self removeIndex:aPara
+            ] ifFalse:[
+                (what == #insertCollection:) ifTrue:[
+                    start := aPara first.
+                    size  := aPara last.
+
+                    size ~~ 0 ifTrue:[
+                        size == 1 ifTrue:[
+                            self add:(list at:start) beforeIndex:start
+                        ] ifFalse:[
+                            stop := start + size - 1.
+                            self addAll:(list copyFrom:start to:stop) beforeIndex:start
+                        ]
+                    ]
+                ] ifFalse:[
+                    self listHolder:chgObj
+                ]
+            ]
+        ].
+        ^ self
+    ].
+
+    columns notNil ifTrue:[
+        (columns includesIdentical:chgObj) ifTrue:[
+            ^ self columnChanged:what with:aPara from:chgObj
+        ]
+    ].
+
+    super update:what with:aPara from:chgObj
+
+! !
+
+!GraphColumnView methodsFor:'conversion'!
+
+floatFrom:aValue onError:aBlock
+    "converts something to a float, on error the result of the
+     block is returned
+    "
+    ^ aValue isNumber ifTrue:[aValue asFloat] ifFalse:[aBlock value]
+!
+
+unsignedIntegerFrom:aValue onError:aBlock
+    "converts something to an unsigned integer, on error the result of the
+     block is returned
+    "
+    |v|
+
+    aValue isNumber ifTrue:[
+        v := aValue isInteger ifTrue:[aValue] ifFalse:[(aValue asFloat) rounded].       "/ no fractions
+
+        v >= 0 ifTrue:[ ^ v ]
+    ].
+    ^ aBlock value
+! !
+
+!GraphColumnView methodsFor:'initialization'!
+
+create
+    "set color on device
+    "
+    super create.
+
+    fgColor     := (fgColor     ? DefaultForegroundColor) on:device.
+    bgColor     := (bgColor     ? DefaultBackgroundColor) on:device.
+    gridColor   := (gridColor   ? DefaultGridColor)       on:device.
+    vLinesColor := (vLinesColor ? DefaultVLinesColor)     on:device.
+
+!
+
+destroy
+    "remove dependencies
+    "
+    super destroy.
+
+    listHolder removeDependent:self.
+    listHolder := nil.
+
+    windowSizeHolder removeDependent:self.
+    windowSizeHolder := nil.
+
+    zoomYHolder removeDependent:self.
+    zoomYHolder := nil.
+
+    columns notNil ifTrue:[
+        columns do:[:aCol| aCol removeDependent:self ]
+    ].
+
+!
+
+initialize
+    "setup default values
+    "
+    super initialize.
+
+    DefaultGridColor isNil ifTrue:[
+        self class updateStyleCache
+    ].
+
+    windowSize := 101.
+    showGrid   := false.
+    zoomY      := 1.
+
+! !
+
+!GraphColumnView methodsFor:'menu & submenus'!
+
+defaultMenu
+    "returns the default middle button menu
+    "
+    |menu|
+
+    menu := self class defaultMenu decodeAsLiteralArray.
+    menu notNil ifTrue:[
+        menu receiver:self
+    ].
+  ^ menu
+
+
+!
+
+doZoomY:aValue
+    |old|
+
+    old := self zoomY.
+    self zoomY:aValue.
+
+    self zoomYHolder notNil ifTrue:[
+        zoomYHolder value:(self zoomY)
+    ]
+!
+
+subMenuZoomY
+    "returns a submenu to configure the y-zoom value
+    "
+    ^ GraphColumn zoomMenuSelector:#doZoomY:
+
+
+! !
+
+!GraphColumnView methodsFor:'protocol'!
+
+colorChanged:what
+    "called if a color changed, #foreground, #background, #grid or #vLines
+    "
+    self recomputeWholeGraph
+!
+
+columnChanged:what with:aPara from:aColumn
+    "a column changed
+    "
+    self recomputeWholeGraph
+
+
+!
+
+invalidateGraph
+    "called to redraw the graph
+    "
+    self recomputeWholeGraph
+!
+
+listSizeChanged:what from:aColumn
+    "called if a column is inserted (#insert:) or removed from list
+    "
+    self recomputeWholeGraph
+!
+
+recomputeWholeGraph
+    "called if the whole graph should be recomputed
+    "
+    self subclassResponsibility
+! !
+
+!GraphColumnView methodsFor:'queries'!
+
+numberOfVisibleColumns
+    "returns number of visible Columns
+    "
+    |no|
+
+    no := 0.
+
+    columns notNil ifTrue:[
+        columns do:[:aCol| aCol shown ifTrue:[no := no + 1]]
+    ].
+    ^ no
+! !
+
+!GraphColumnView class methodsFor:'documentation'!
+
+version
+    ^ '$Header: /cvs/stx/stx/libwidg2/GraphColumnView.st,v 1.1 1998-02-07 15:15:50 ca Exp $'
+! !