--- a/NoteBookView.st Fri May 28 20:07:15 1999 +0200
+++ b/NoteBookView.st Mon Jun 07 14:45:09 1999 +0200
@@ -1,6 +1,39 @@
"
COPYRIGHT (c) 1997 by eXept Software AG
- All Rights Reserved
+ All Rights Reserved
+
+ This software is furnished under a license and may be used
+ only in accordance with the terms of that license and with the
+ inclusion of the above copyright notice. This software may not
+ be provided or otherwise made available to, or used by, any
+ other person. No title to or ownership of the software is
+ hereby transferred.
+"
+
+
+View subclass:#NoteBookView
+ instanceVariableNames:'list listHolder foregroundColor selection enabled action useIndex
+ direction numberOfLines selectConditionBlock expandSelection
+ canvas canvasInset canvasHolder halfLightColor halfShadowColor
+ fitLastRow tabModus'
+ classVariableNames:''
+ poolDictionaries:''
+ category:'Views-Layout'
+!
+
+Object subclass:#Tab
+ instanceVariableNames:'label model printableLabel disabledLabel lineNr layout extent'
+ classVariableNames:''
+ poolDictionaries:''
+ privateIn:NoteBookView
+!
+
+!NoteBookView class methodsFor:'documentation'!
+
+copyright
+"
+ COPYRIGHT (c) 1997 by eXept Software AG
+ All Rights Reserved
This software is furnished under a license and may be used
only in accordance with the terms of that license and with the
@@ -10,301 +43,1557 @@
hereby transferred.
"
-SimpleView subclass:#NoteBookView
- instanceVariableNames:'tabRaw canvas canvasHolder'
- classVariableNames:''
- poolDictionaries:''
- category:'Views-Layout'
-!
-
-!NoteBookView class methodsFor:'documentation'!
-
-copyright
-"
- COPYRIGHT (c) 1997 by eXept Software AG
- All Rights Reserved
-
- This software is furnished under a license and may be used
- only in accordance with the terms of that license and with the
- inclusion of the above copyright notice. This software may not
- be provided or otherwise made available to, or used by, any
- other person. No title to or ownership of the software is
- hereby transferred.
-"
!
documentation
"
- this is not yet finished - for now it implements a Notebook
+ implements the noteBook.
+ May also be used on its own (without a surrounding noteBook).
+
+ [author:]
+ Claus Atzkern
[see also:]
TabView
"
+
!
examples
"
tabs at top ( default )
[exBegin]
- |top tab view inset|
+ |top tab|
- top := StandardSystemView new label:'test'; extent:250@100.
- view := NoteBookView origin:0.0 @ 0.0 corner:1.0 @ 1.0 in:top.
- view list:#( 'Foo' 'Bar' 'Baz' ).
- view action:[:aName| Transcript showCR:aName].
-
+ top := StandardSystemView extent:250@100.
+ tab := NoteBook origin:0.0 @ 0.0 corner:1.0 @ 1.0 in:top.
+ tab list:#( 'Foo' 'Bar' 'Baz' ).
+ tab action:[:aName| Transcript showCR:aName].
top open.
[exEnd]
tabs at bottom
[exBegin]
- |top tab view inset|
+ |top tab|
- top := StandardSystemView new label:'test'; extent:250@100.
- view := NoteBookView origin:0.0 @ 0.0 corner:1.0 @ 1.0 in:top.
- view direction:#bottom.
- view list:#( 'Foo' 'Bar' 'Baz' ).
- view action:[:aName| Transcript showCR:aName].
-
+ top := StandardSystemView extent:250@100.
+ tab := NoteBook origin:0.0 @ 0.0 corner:1.0 @ 1.0 in:top.
+ tab direction:#bottom.
+ tab list:#( 'Foo' 'Bar' 'Baz' ).
+ tab action:[:aName| Transcript showCR:aName].
top open.
[exEnd]
tabs at left
[exBegin]
- |top tab view inset|
+ |top tab|
- top := StandardSystemView new label:'test'; extent:100@200.
- view := NoteBookView origin:0.0 @ 0.0 corner:1.0 @ 1.0 in:top.
- view direction:#left.
- view list:#( 'Foo' 'Bar' 'Baz' ).
- view action:[:aName| Transcript showCR:aName].
-
+ top := StandardSystemView extent:100@200.
+ tab := NoteBook origin:0.0 @ 0.0 corner:1.0 @ 1.0 in:top.
+ tab direction:#left.
+ tab list:#( 'Foo' 'Bar' 'Baz' ).
+ tab action:[:aName| Transcript showCR:aName].
top open.
[exEnd]
tabs at right
[exBegin]
- |top tab view inset|
+ |top tab|
- top := StandardSystemView new label:'test'; extent:100@200.
- view := NoteBookView origin:0.0 @ 0.0 corner:1.0 @ 1.0 in:top.
- view direction:#right.
- view list:#( 'Foo' 'Bar' 'Baz' ).
- view action:[:aName| Transcript showCR:aName].
-
+ top := StandardSystemView extent:100@200.
+ tab := NoteBook origin:0.0 @ 0.0 corner:1.0 @ 1.0 in:top.
+ tab direction:#right.
+ tab list:#( 'Foo' 'Bar' 'Baz' ).
+ tab action:[:aName| Transcript showCR:aName].
top open.
[exEnd]
"
+
+! !
+
+!NoteBookView class methodsFor:'claus'!
+
+test2:aDirection
+ |top tab|
+
+ top := StandardSystemView extent:300@300.
+ tab := NoteBookView origin:0.1 @ 0.1 corner:0.9 @ 0.9 in:top.
+ tab direction:aDirection.
+ tab tabModus:true.
+ tab list:#( 'Tab 1' 'Tab 2' 'Tab 3' 'XgQTab 4' ).
+ tab action:[:aLabel| Transcript showCR:aLabel].
+ top open.
+
+
+!
+
+test:aDirection
+ |top tab|
+
+ top := StandardSystemView extent:300@300.
+ tab := NoteBookView origin:0.1 @ 0.1 corner:0.9 @ 0.9 in:top.
+ tab direction:aDirection.
+ tab list:#( 'Tab 1' 'Tab 2' 'Tab 3' 'XgQTab 4' ).
+ tab canvas:(ClockView new).
+ tab action:[:aLabel| Transcript showCR:aLabel].
+ top open.
+
+
+! !
+
+!NoteBookView class methodsFor:'defaults'!
+
+defaultFont
+ ^ MenuView defaultFont
! !
!NoteBookView methodsFor:'accessing'!
+action:oneArgBlock
+ "set the action block to be performed on select; the argument to
+ the block is the selected index or nil in case of no selection.
+ "
+ action := oneArgBlock.
+
+!
+
canvas
- "returns canvas; the container view
- "
^ canvas
!
canvas:aCanvas
"change canvas; the containter view
"
- |origin corner|
+ aCanvas == canvas ifFalse:[
+ canvas notNil ifTrue:[
+ canvas destroy.
+ ].
+ (canvas := aCanvas) notNil ifTrue:[
+ tabModus := false.
+ self addSubView:canvas.
+
+ (shown and:[numberOfLines notNil]) ifTrue:[
+ canvas layout:(self computeCanvasLayout)
+ ]
+ ]
+ ].
+!
+
+list
+ "return the list of Tabs or Labels
+ "
+ ^ list collect:[:aTab| aTab label ]
+
+!
- aCanvas == canvas ifFalse:[
- canvas destroy.
+list:aList
+ "set the list
+ "
+ |size|
+
+ list do:[:aTab| aTab removeDependent:self].
+
+ aList notNil ifTrue:[
+ list := aList collect:[:el| Tab label:el on:self].
+ list do:[:aTab| aTab addDependent:self].
+ ] ifFalse:[
+ list := #()
+ ].
+ preferredExtent := nil.
+ numberOfLines := nil.
+
+ selection notNil ifTrue:[
+ selection > list size ifTrue:[
+ selection := nil.
+ self selectionChanged.
+ ]
+ ].
+ shown ifTrue:[
+ self invalidate
+ ].
+
+!
- (canvas := aCanvas) isNil ifTrue:[
- canvas := View in:self
- ] ifFalse:[
- self addSubView:canvas.
- ].
- canvas viewBackground:viewBackground.
- canvas allSubViewsDo:[:s|s viewBackground:viewBackground].
- canvas origin:0.0@0.0 corner:1.0@1.0.
+listIndexOf:something
+ "convert something to an index into list or nil.
+ "
+ |index|
+
+ something isNil ifTrue:[^ nil ].
+
+ something isNumber ifTrue:[
+ index := something
+ ] ifFalse:[
+ index := list findFirst:[:aTab|aTab label = something].
+ index == 0 ifTrue:[
+ index := list findFirst:[:aTab|aTab printableLabel = something]
+ ]
+ ].
+ ^ (index between:1 and:list size) ifTrue:[index] ifFalse:[nil]
+
+
+!
+
+useIndex
+ "use index instead of name
+ "
+ ^ useIndex
+
+
+!
+
+useIndex:aBoolean
+ "set/clear the useIndex flag. If set, both actionBlock and change-messages
+ are passed the index(indices) of the selection as argument.
+ If clear, the value(s) (i.e. the selected string) is passed.
+ Default is false."
+
+ useIndex := aBoolean
+
+
+! !
+
+!NoteBookView methodsFor:'accessing behavior'!
+
+enabled
+ "returns true if tabs are enabled
+ "
+ ^ enabled
+!
+
+enabled:aState
+ "set enabled state
+ "
+ |state|
+
+ state := aState ? true.
+
+ enabled ~~ state ifTrue:[
+ enabled := state.
+ self invalidate.
]
!
-labels
- ^ tabRaw list
+selectConditionBlock
+ "get the conditionBlock; this block is evaluated before a selection
+ change is performed; the change will not be done, if the evaluation
+ returns false. The argument to the block is the selection index
+ "
+ ^ selectConditionBlock
!
-labels:aListOfLabels
- tabRaw list:aListOfLabels
+selectConditionBlock:aOneArgBlock
+ "get the conditionBlock; this block is evaluated before a selection
+ change is performed; the change will not be done, if the evaluation
+ returns false. The argument to the block is the selection index
+ "
+ selectConditionBlock := aOneArgBlock
! !
-!NoteBookView methodsFor:'accessing holders'!
+!NoteBookView methodsFor:'accessing channels/holders'!
canvasHolder
+ "get the model, which keeps the canvas, a kind of SimpleView
+ "
^ canvasHolder
!
canvasHolder:aValueHolder
- canvasHolder notNil ifTrue:[
- canvasHolder removeDependent:self.
+ "set the model, which keeps the canvas, a kind of SimpleView
+ "
+ canvasHolder removeDependent:self.
+
+ (canvasHolder := aValueHolder) notNil ifTrue:[
+ canvasHolder addDependent:self.
+ self canvas:(canvasHolder value)
+ ]
+
+
+!
+
+listHolder
+ "get the model, which keeps the list of Tabs or Labels
+ "
+ ^ listHolder
+!
+
+listHolder:aValueHolder
+ "set the model, which keeps the list of Tabs or Labels
+ "
+ listHolder removeDependent:self.
+
+ (listHolder := aValueHolder) notNil ifTrue:[
+ listHolder addDependent:self.
+ self list:listHolder value.
].
- canvasHolder := aValueHolder .
- self canvas:(canvasHolder value).
!
-labelsHolder
- ^ tabRaw listHolder
+model:aValueHolder
+ "set the model, which keeps the selection
+ "
+ super model:aValueHolder.
+
+ model notNil ifTrue:[
+ self selection:(model value)
+ ]
+! !
+
+!NoteBookView methodsFor:'accessing dimension'!
+
+maxTabHeight
+ |e y|
+
+ e := self preferredExtent.
+ y := self isHorizontal ifTrue:[e y] ifFalse:[e x].
+ ^ y - (expandSelection y)
!
-labelsHolder:aHolder
- tabRaw listHolder:aHolder
+preferredExtent
+ "compute max extent x/y based on one line
+ "
+ |x "{ Class:SmallInteger }"
+ y "{ Class:SmallInteger }"
+ |
+ preferredExtent isNil ifTrue:[
+ y := 0.
+ x := 0.
+
+ list notEmpty ifTrue:[
+ list do:[:aTab|
+ x := x + aTab preferredExtentX.
+ y := y max:(aTab preferredExtentY).
+ ]
+ ].
+ y := y + (expandSelection y).
+ x := x + (expandSelection x).
+ preferredExtent := self isHorizontal ifTrue:[x @ y] ifFalse:[y @ x]
+ ].
+ ^ preferredExtent
+!
+
+preferredSizeXorY
+ "returns preferred size dependant on the current view layout and
+ the direction of the tabs
+ "
+ |e y|
+
+ list isEmpty ifTrue:[^ 0].
+
+ y := self maxTabHeight.
+ e := expandSelection y.
+
+ numberOfLines isNil ifTrue:[
+ self shown ifFalse:[^ y + e ].
+ self recomputeList.
+ ].
+ ^ numberOfLines * y + e
! !
!NoteBookView methodsFor:'accessing look'!
-backgroundColor:aColor
- "change viewBackground
+backgroundColor
+ "get backgroundColor of the notebook view
"
- self viewBackground:aColor
+ ^ viewBackground
!
-font:aFont
- "set a font
+foregroundColor
+ "get the color to be used for drawing text
"
- super font:aFont.
- tabRaw font:aFont.
+ ^ foregroundColor
+!
+
+foregroundColor:aColor
+ "set the color to be used for drawing text
+ "
+ aColor ~= foregroundColor ifTrue:[
+ foregroundColor := aColor.
+
+ shown ifTrue:[
+ self invalidate
+ ]
+ ]
!
-viewBackground:aColor
- "viewBackground changed
+halfLightColor
+ "get the color to be used for drawing text
"
- viewBackground ~~ aColor ifTrue:[
- super viewBackground:aColor.
- tabRaw viewBackground:viewBackground.
- canvas allSubViewsDo:[:s| s viewBackground:viewBackground].
- ]
+ ^ halfLightColor
+!
+
+halfShadowColor
+ ^ halfShadowColor
+!
+
+lightColor
+ "get the color to be used for lighted edges
+ "
+ ^ lightColor
+!
+
+shadowColor
+ "get the color to be used for shadowed edges
+ "
+ ^ shadowColor
! !
-!NoteBookView methodsFor:'actions'!
+!NoteBookView methodsFor:'accessing style'!
+
+direction
+ "returns the direction of tabs as symbol. On default the value is
+ set to #top. Valid symbols are:
+ #top arrange tabs to be on top of a view
+ #bottom arrange tabs to be on bottom of a view
+ #left arrange tabs to be on left of a view
+ #right arrange tabs to be on right of a view
+ "
+ ^ direction
+
+!
+
+direction:aDirection
+ "change the direction of tabs. On default the value is set to #top.
+ Valid symbols are:
+ #top arrange tabs to be on top of a view
+ #bottom arrange tabs to be on bottom of a view
+ #left arrange tabs to be on left of a view
+ #right arrange tabs to be on right of a view
+ "
+ direction ~~ aDirection ifTrue:[
+ direction := aDirection.
+ preferredExtent := nil.
+ numberOfLines := nil.
+ self invalidate.
+ ].
+!
-clearCanvas
- "destroy all subviews in canvas
+fitLastRow
+ "in case of true, the last row is expanded to the view size like all
+ other raws. In case of false all the tabs in the last raw keep their
+ preferred extent (x or y) dependant on the direction.
+ "
+ ^ fitLastRow
+!
+
+fitLastRow:aBool
+ "in case of true, the last row is expanded to the view size like all
+ other raws. In case of false all the tabs in the last raw keep their
+ preferred extent (x or y) dependant on the direction.
"
- canvas destroySubViews
+ fitLastRow := aBool
+!
+
+tabModus
+ ^ tabModus
+!
+tabModus:aBoolean
+
+ tabModus ~~ aBoolean ifTrue:[
+ (aBoolean and:[canvas notNil]) ifFalse:[
+ tabModus := aBoolean.
+ numberOfLines := nil.
+ shown ifTrue:[self invalidate]
+ ]
+ ]
! !
!NoteBookView methodsFor:'change & update'!
-recomputeSizes
- "recompute sizes dependent on list
+update:something with:aParameter from:changedObject
+ "one of my models changed its value
+ "
+ |idx tab|
+
+ changedObject == model ifTrue:[^ self selection:model value].
+ changedObject == listHolder ifTrue:[^ self list:(listHolder value)].
+ changedObject == enableChannel ifTrue:[^ self enabled:enableChannel value].
+
+ (idx := list findFirst:[:aTab| aTab label == changedObject]) ~~ 0 ifTrue:[
+ tab := list at:idx.
+
+ idx == selection ifTrue:[
+ tab isEnabled ifFalse:[
+ ^ self selection:nil
+ ]
+ ].
+ tab label:(tab label) on:self.
+ self invalidateTab:tab
+ ]
+! !
+
+!NoteBookView methodsFor:'drawing'!
+
+invalidateTab:aTab
+ "invalidate a tab
+ "
+ shown ifTrue:[
+ self invalidate:(self computeLayoutForTab:aTab)
+ ]
+!
+
+redrawX:x y:y width:w height:h
+ "a region must be redrawn
"
- |y x tabExt maxExt|
+ |savClip selTab damage lyt savLyt|
+
+ self shown ifFalse:[
+ ^ self
+ ].
+ numberOfLines isNil ifTrue:[
+ self recomputeList.
+ ^ self invalidate
+ ].
+ selTab := selection notNil ifTrue:[list at:selection] ifFalse:[nil].
+
+ (selTab notNil and:[selTab lineNr ~~ 1]) ifTrue:[
+ self makeToBaseLine:(selTab lineNr).
+ ^ self invalidate
+ ].
+
+ self paint:(self viewBackground).
+ self fillRectangleX:x y:y width:w height:h.
+
+ savClip := clipRect.
+ damage := Rectangle left:x top:y width:w height:h.
+ self clippingRectangle:damage.
+
+ list notEmpty ifTrue:[
+ numberOfLines to:1 by:-1 do:[:aLnNr|
+ list reverseDo:[:aTab|
+ ( aTab lineNr == aLnNr
+ and:[aTab ~~ selTab
+ and:[aTab intersects:damage]]
+ ) ifTrue:[
+ aTab redrawAt:direction selected:false on:self
+ ]
+ ]
+ ]
+ ] ifFalse:[
+ selTab := nil
+ ].
+
+ tabModus ifFalse:[
+ lyt := self computeBorderLayout.
- maxExt := self extent - (margin * 2).
- tabExt := tabRaw preferredExtent.
+ self drawEdgesForX:lyt left
+ y:lyt top
+ width:lyt width
+ height:lyt height
+ level:2
+ shadow:shadowColor
+ light:lightColor
+ halfShadow:halfShadowColor
+ halfLight:halfLightColor
+ style:#softWin95.
+ ].
+
+
+ selTab notNil ifTrue:[
+ lyt := self computeLayoutForTab:selTab.
+
+ (lyt intersects:damage) ifTrue:[
+ savLyt := selTab layout.
+ selTab layout:lyt.
+ selTab redrawAt:direction selected:true on:self.
+ selTab layout:savLyt.
+ ]
+ ].
+ self clippingRectangle:savClip
+! !
+
+!NoteBookView methodsFor:'event handling'!
+
+buttonPress:button x:x y:y
+ "a button is pressed; find tab under point and set the selection
+ "
+ |idx|
+
+ (enabled and:[list notEmpty]) ifTrue:[
+ idx := list findFirst:[:aTab| aTab containsPointX:x y:y ].
- x := tabExt x.
- y := tabExt y.
+ (idx ~~ 0 and:[(list at:idx) isEnabled]) ifTrue:[
+ self selection:idx
+ ]
+ ]
+!
+
+keyPress:aKey x:x y:y
+ "selection might change; look for corresponding list entry
+ "
+ |size index n|
+
+ (enabled and:[(size := list size) > 1]) ifFalse:[
+ ^ self
+ ].
+
+ (aKey == #CursorRight or:[aKey == #CursorDown]) ifTrue:[
+ n := selection ? 0.
+
+ (size - 1) timesRepeat:[
+ (n := n + 1) > size ifTrue:[n := 1].
+
+ (self isSelectable:n) ifTrue:[
+ ^ self selection:n
+ ]
+ ].
+ ^ self
+ ].
+
+ (aKey == #CursorLeft or:[aKey == #CursorUp]) ifTrue:[
+ n := selection ? size.
+
+ (size - 1) timesRepeat:[
+ (n := n - 1) < 1 ifTrue:[n := size].
+
+ (self isSelectable:n) ifTrue:[
+ ^ self selection:n
+ ]
+ ].
+ ^ self
+ ].
+
+ aKey isCharacter ifTrue:[
+ (selection isNil or:[selection == size]) ifTrue:[index := 1]
+ ifFalse:[index := selection + 1].
- canvas viewBackground:(tabRaw styleAt:#selectedColor).
- tabRaw isHorizontalDirection ifTrue:[
- x > (maxExt x) ifTrue:[y := tabRaw preferredSizeXorY].
+ n := index - 1.
+ [
+ n := self findTabStartingWithKey:aKey startingAt:n + 1.
+
+ (n ~~ 0 and:[self isSelectable:n]) ifTrue:[
+ ^ self selection:n
+ ].
+ n ~~ 0
+
+ ] whileTrue.
+
+ index ~~ 1 ifTrue:[
+ (n := self findTabStartingWithKey:aKey startingAt:1) ~~ 0 ifTrue:[
+ ^ self selection:n
+ ]
+ ]
+ ].
+
+ super keyPress:aKey x:x y:y
+!
+
+sizeChanged:how
+ "size of view changed
+ "
+ super sizeChanged:how.
+
+ list notEmpty ifTrue:[
+ numberOfLines := nil.
+ shown ifTrue:[self invalidate]
+ ]
+! !
+
+!NoteBookView methodsFor:'initialize / release'!
+
+destroy
+ "remove dependencies
+ "
+ list removeDependent:self.
+
+ listHolder removeDependent:self.
+ enableChannel removeDependent:self.
+ canvasHolder removeDependent:self.
+
+ super destroy.
+!
+
+initStyle
+ "setup style attributes
+ "
+
+ super initStyle.
+ self font:self class defaultFont.
+ foregroundColor := Color black on:device.
+ shadowColor := foregroundColor.
+ halfLightColor := Color white on:device.
+ halfShadowColor := Color gray on:device.
+ tabModus := false.
+!
+
+initialize
+ "setup default attributes
+ "
+ super initialize.
+
+ self cursor:Cursor hand.
+
+ list := #().
+ useIndex := false.
+ direction := #top.
+ fitLastRow := true.
+ enabled := true.
+ expandSelection := 6@4.
+ canvasInset := 8.
+
+ self lineWidth:0.
+
+ canvas notNil ifTrue:[
+ canvas := canvas in:self.
+ ].
- tabRaw direction == #top ifTrue:[
- tabRaw origin:0.0@0.0 corner:1.0@(y+margin).
- canvas origin:0.0@(y+margin) corner:1.0@1.0.
+! !
+
+!NoteBookView methodsFor:'layout'!
+
+computeBorderLayout
+ |xL yT xR yB tab|
+
+ self paint:lightColor.
+ tab := list detect:[:aTab| aTab lineNr == 1] ifNone:nil.
+ xL := 0.
+ yT := 0.
+ xR := width.
+ yB := height.
+
+ tab notNil ifTrue:[
+ direction == #top ifTrue:[yT := tab layout bottom]
+ ifFalse:[direction == #bottom ifTrue:[yB := tab layout top]
+ ifFalse:[direction == #left ifTrue:[xL := tab layout right]
+ ifFalse:[xR := tab layout left]]]
+ ].
+ ^ Rectangle left:xL top:yT right:xR bottom:yB
+
+!
+
+computeCanvasLayout
+
+ ^ self computeBorderLayout expandBy:(canvasInset negated).
+
+!
+
+computeLayoutForTab:aTab
+ "calculate extent of a tab
+ "
+ |layout x y w h level|
+
+ layout := aTab layout.
+ level := 2.
+
+ self selectedTab == aTab ifTrue:[
+ layout := layout copy.
+ w := expandSelection x.
+ h := expandSelection y.
+ x := w // 2.
+ y := h // 2.
+
+ self isHorizontal ifTrue:[
+ layout setLeft:(layout left - x).
+ layout width:(layout width + w).
+ layout setTop:(layout top - y).
+ layout height:(layout height + y + level).
] ifFalse:[
- y := maxExt y - y.
- canvas origin:0.0@0.0 corner:1.0@(y+margin).
- tabRaw origin:0.0@(y+margin) corner:1.0@1.0.
+ layout setLeft:(layout left - level).
+ layout width:(layout width + y + level).
+ layout setTop:(layout top - x).
+ layout height:(layout height + w).
+ ]
+ ].
+ ^ layout
+!
+
+makeToBaseLine:aLnNr
+ |layout1 layoutN topN top1 leftN left1
+ nr "{ Class:SmallInteger }"
+ |
+ nr := list findFirst:[:aTab| aTab lineNr == 1].
+ layout1 := (list at:nr) layout.
+
+ nr := list findFirst:[:aTab| aTab lineNr == aLnNr].
+ layoutN := (list at:nr) layout.
+
+ self isHorizontal ifTrue:[
+ top1 := layout1 top.
+ topN := layoutN top.
+
+ list do:[:el|
+ (nr := el lineNr) == 1 ifTrue:[
+ el layout setTop:topN. el lineNr:aLnNr
+ ] ifFalse:[
+ nr == aLnNr ifTrue:[
+ el layout setTop:top1. el lineNr:1
+ ]
+ ]
]
] ifFalse:[
- y > (maxExt y) ifTrue:[x := tabRaw preferredSizeXorY].
+ left1 := layout1 left.
+ leftN := layoutN left.
+
+ list do:[:el|
+ (nr := el lineNr) == 1 ifTrue:[
+ el layout setLeft:leftN. el lineNr:aLnNr
+ ] ifFalse:[
+ nr == aLnNr ifTrue:[
+ el layout setLeft:left1. el lineNr:1
+ ]
+ ]
+ ]
+ ]
+
+!
+
+recomputeList
+ "recompute list
+ "
+ numberOfLines := 1.
+
+ list notEmpty ifTrue:[
+ self isHorizontal ifTrue:[
+ self recomputeListHorizontal
+ ] ifFalse:[
+ self recomputeListVertical
+ ]
+ ].
+ canvas notNil ifTrue:[
+ canvas layout:(self computeCanvasLayout)
+ ]
+!
+
+recomputeListHorizontal
+ "recompute list
+ "
+ |layout lastLyt checkDir
+ xLeft "{ Class:SmallInteger }"
+ yTop "{ Class:SmallInteger }"
+ tabWidth "{ Class:SmallInteger }"
+ tabHeight "{ Class:SmallInteger }"
+ lineWidth "{ Class:SmallInteger }"
+ startX "{ Class:SmallInteger }"
+ delta "{ Class:SmallInteger }"
+ first "{ Class:SmallInteger }"
+ last "{ Class:SmallInteger }"
+ |
+ startX := expandSelection x // 2.
+ lineWidth := self width - startX.
+ tabHeight := self maxTabHeight.
+ xLeft := startX.
+ yTop := expandSelection y.
+
+ checkDir := canvas isNil ifTrue:[#top] ifFalse:[#bottom].
+
+ direction == #bottom ifTrue:[
+ yTop := self height - tabHeight - yTop
+ ].
+
+ list do:[:aTab|
+ tabWidth := aTab preferredExtentX.
+
+ (xLeft + tabWidth > lineWidth and:[xLeft ~~ startX]) ifTrue:[
+ numberOfLines := numberOfLines + 1.
+ xLeft := startX.
+ ].
+ aTab lineNr:numberOfLines.
+ aTab layout:(Rectangle left:xLeft top:yTop width:tabWidth height:tabHeight).
+ xLeft := xLeft + tabWidth
+ ].
+
+ numberOfLines ~~ 1 ifTrue:[
+ last := numberOfLines.
+ delta := direction == #bottom ifFalse:[tabHeight]
+ ifTrue:[tabHeight negated].
+
+ list reverseDo:[:aTab|
+ aTab lineNr ~~ last ifTrue:[
+ last := aTab lineNr.
+ yTop := yTop + delta
+ ].
+ aTab layout setTop:yTop
+ ]
+ ].
+ tabModus ifTrue:[
+ layout := (list at:1) layout.
+ delta := direction == #top ifTrue:[self height - layout bottom]
+ ifFalse:[layout top negated].
+
+ list do:[:aTab| aTab layout setTop:(aTab layout top + delta)].
+ ].
+
+ "/ FIT LINES
+ (numberOfLines ~~ 1 or:[fitLastRow]) ifFalse:[
+ ^ self
+ ].
+
+ first := 1.
+
+ 1 to:numberOfLines do:[:aLnNr|
+ last := list findLast:[:t|t lineNr == aLnNr].
+ lastLyt := (list at:last) layout.
+
+ (delta := lineWidth - lastLyt right) ~~ 0 ifTrue:[
+ xLeft := startX.
+ delta := delta // (last - first + 1).
+
+ delta ~~ 0 ifTrue:[
+ list from:first to:last do:[:aTab|
+ layout := aTab layout.
+ tabWidth := layout width + delta.
+ layout setLeft:xLeft.
+ layout width:tabWidth.
+ xLeft := xLeft + tabWidth.
+ ]
+ ].
+ lastLyt width:(lineWidth - lastLyt left)
+ ].
+ first := last + 1.
+ ]
+
+!
+
+recomputeListVertical
+ "recompute list
+ "
+ |layout lastLyt
+ xTop "{ Class:SmallInteger }"
+ yTop "{ Class:SmallInteger }"
+ tabWidth "{ Class:SmallInteger }"
+ tabHeight "{ Class:SmallInteger }"
+ lineHeight "{ Class:SmallInteger }"
+ startY "{ Class:SmallInteger }"
+ delta "{ Class:SmallInteger }"
+ first "{ Class:SmallInteger }"
+ last "{ Class:SmallInteger }"
+ |
+ startY := expandSelection x // 2.
+ lineHeight := self height - startY.
+ tabHeight := self maxTabHeight.
+ yTop := startY.
+ xTop := expandSelection y.
+
+ direction == #right ifTrue:[
+ xTop := self width - tabHeight - xTop
+ ].
+
+ list do:[:aTab|
+ tabWidth := aTab preferredExtentX.
+
+ (yTop + tabWidth > lineHeight and:[yTop ~~ startY])ifTrue:[
+ numberOfLines := numberOfLines + 1.
+ yTop := startY.
+ ].
+ aTab lineNr:numberOfLines.
+ aTab layout:(Rectangle left:xTop top:yTop width:tabHeight height:tabWidth).
+ yTop := yTop + tabWidth
+ ].
+ numberOfLines ~~ 1 ifTrue:[
+ last := numberOfLines.
+ delta := direction == #left ifTrue:[tabHeight] ifFalse:[tabHeight negated].
+
+ list reverseDo:[:aTab|
+ aTab lineNr ~~ last ifTrue:[
+ last := aTab lineNr.
+ xTop := xTop + delta
+ ].
+ aTab layout setLeft:xTop
+ ]
+ ].
+ tabModus ifTrue:[
+ layout := (list at:1) layout.
+ delta := direction == #left ifTrue:[self width - layout right]
+ ifFalse:[layout left negated].
+
+ list do:[:aTab| aTab layout setLeft:(aTab layout left + delta)].
+ ].
+
+ "/ FIT LINES
+ (numberOfLines ~~ 1 or:[fitLastRow]) ifFalse:[
+ ^ self
+ ].
+
+ first := 1.
+
+ 1 to:numberOfLines do:[:aLnNr|
+ last := list findLast:[:t|t lineNr == aLnNr].
+ lastLyt := (list at:last) layout.
+
+ (delta := lineHeight - lastLyt bottom) ~~ 0 ifTrue:[
+ yTop := startY.
+ delta := delta // (last - first + 1).
+
+ delta ~~ 0 ifTrue:[
+ list from:first to:last do:[:aTab|
+ layout := aTab layout.
+ tabWidth := layout height + delta.
+ layout setTop:yTop.
+ layout height:tabWidth.
+ yTop := yTop + tabWidth.
+ ]
+ ].
+ lastLyt height:(lineHeight - lastLyt top)
+ ].
+ first := last + 1.
+ ]
+! !
+
+!NoteBookView methodsFor:'obsolete'!
+
+labels
+ "return the list of labels
+ "
+ ^ self list
+!
+
+labels:aListOfLabels
+ "set the list of labels
+ "
+ ^ self list:aListOfLabels
+!
+
+labelsHolder
+ "get the model, which keeps the list of Tabs or Labels
+ "
+ ^ self listHolder
+!
+
+labelsHolder:aValueHolder
+ "set the model, which keeps the list of Tabs or Labels
+ "
+ self listHolder:aValueHolder.
+!
+
+moveSelectedRow
+ ^ true
+!
+
+moveSelectedRow:something
+!
+
+oneTabPerLine
+ ^ false
+!
+
+oneTabPerLine:something
+!
+
+tabWidget
+ ^ nil
+!
+
+tabWidget:something
+! !
+
+!NoteBookView methodsFor:'private'!
+
+findTabStartingWithKey:aKey startingAt:anIndex
+ "get index of tab starting its printableLabel with a key or 0
+ "
+ |upper lower string char|
+
+ (aKey isCharacter and:[anIndex <= list size]) ifFalse:[ ^ 0 ].
+
+ upper := aKey asUppercase.
+ lower := aKey asLowercase.
+
+ ^ list findFirst:[:aTab|
+ ( (string := aTab string) size ~~ 0
+ and:[((char := string first) == lower or:[char == upper])]
+ )
+ ] startingAt:anIndex
+! !
+
+!NoteBookView methodsFor:'queries'!
+
+isEnabled
+ "returns enabled state
+ "
+ ^ enabled
+!
+
+isFirstTabInLine:aTab
+ |idx tab|
+
+ idx := list identityIndexOf:aTab.
+ tab := list at:(idx - 1) ifAbsent:nil.
+ ^ (tab isNil or:[tab lineNr ~~ aTab lineNr])
+!
+
+isHorizontal
+ "returns true in case of direction is #top or #bottom
+ "
+ ^ (direction == #top or:[direction == #bottom])
+
+!
+
+isLastTabInLine:aTab
+ |index tab|
+
+ index := list identityIndexOf:aTab.
+ tab := list at:(index + 1) ifAbsent:nil.
+ ^ (tab isNil or:[tab lineNr ~~ aTab lineNr])
+! !
+
+!NoteBookView methodsFor:'selection'!
- tabRaw direction == #left ifTrue:[
- tabRaw origin:0.0@0.0 corner:(x+margin)@1.0.
- canvas origin:(x+margin)@0.0 corner:1.0@1.0.
- ] ifFalse:[
- x := maxExt x - x.
- canvas origin:0.0@0.0 corner:(x+margin)@1.0.
- tabRaw origin:(x+margin)@0.0 corner:1.0@1.0.
+isSelectable:anIndex
+ "returns true if tab at an index is selectable
+ "
+ (anIndex notNil and:[anIndex between:1 and:list size]) ifTrue:[
+ (list at:anIndex) isEnabled ifTrue:[
+ ^ selectConditionBlock isNil ifTrue:[true]
+ ifFalse:[selectConditionBlock value:anIndex]
+ ]
+ ].
+ ^ false
+!
+
+selectedTab
+ "returns the selected tab ot nil
+ "
+ ^ selection notNil ifTrue:[list at:selection] ifFalse:[nil]
+!
+
+selection
+ "return the selection or nil
+ "
+ selection isNil ifTrue:[
+ ^ useIndex ifTrue:[0] ifFalse:[nil]
+ ].
+ ^ useIndex ifTrue:[selection] ifFalse:[(list at:selection) label]
+!
+
+selection:anIndexOrNil
+ "change the selection to index or nil. The model and/or actionBlock is notified
+ "
+ |oldSel|
+
+ oldSel := selection.
+ self setSelection:anIndexOrNil.
+ oldSel ~~ selection ifTrue:[self selectionChanged].
+!
+
+selectionChanged
+ "selection has changed; raise notification
+ "
+ |sel|
+
+ sel := self selection.
+
+ model notNil ifTrue:[model value:sel].
+ action notNil ifTrue:[action value:sel]
+
+!
+
+setSelection:anIndexOrNil
+ "change the selection to index or nil. No notifications are raised
+ "
+ |newSel lnNr|
+
+ newSel := self listIndexOf:anIndexOrNil.
+
+ (newSel notNil and:[(self isSelectable:newSel) not]) ifTrue:[
+ newSel := nil
+ ].
+ selection == newSel ifTrue:[^ self].
+
+ (shown and:[numberOfLines notNil]) ifFalse:[
+ selection := newSel.
+ self invalidate
+ ] ifTrue:[
+ selection notNil ifTrue:[self invalidateTab:(list at:selection)].
+ selection := newSel.
+ selection notNil ifTrue:[self invalidateTab:(list at:selection)].
+ ]
+! !
+
+!NoteBookView::Tab class methodsFor:'instance creation'!
+
+label:aLabel on:aGC
+ ^ self basicNew label:aLabel on:aGC
+
+
+! !
+
+!NoteBookView::Tab methodsFor:'accessing'!
+
+label
+ "returns my original label
+ "
+ ^ label
+
+
+!
+
+label:aLabel on:aGC
+ "initialize attributes
+ "
+ label := aLabel.
+ model := (aLabel isKindOf:TabItem) ifTrue:[aLabel] ifFalse:[nil].
+
+ printableLabel := model notNil ifTrue:[model rawLabel]
+ ifFalse:[aLabel].
+
+ printableLabel notNil ifTrue:[
+ printableLabel isImageOrForm ifTrue:[
+ printableLabel := printableLabel onDevice:(aGC device)
]
+ ] ifFalse:[
+ printableLabel := ''
+ ].
+ extent := (printableLabel widthOn:aGC) @ (printableLabel heightOn:aGC).
+
+!
+
+lineNr
+ "get the line number
+ "
+ ^ lineNr
+
+!
+
+lineNr:aLineNr
+ "set the line number
+ "
+ lineNr := aLineNr
+
+!
+
+printableLabel
+ "get my printable label
+ "
+ ^ printableLabel
+
+!
+
+string
+ "access the printable string used for steping through a list
+ searching for an entry starting with a character.
+ "
+ ^ printableLabel perform:#string ifNotUnderstood:nil
+
+! !
+
+!NoteBookView::Tab methodsFor:'accessing dimensions'!
+
+extent
+ "returns the extent of the label
+ "
+ ^ extent
+
+
+!
+
+layout
+ "get the tab's layout
+ "
+ ^ layout
+
+
+!
+
+layout:aLayout
+ "set the tab's layout
+ "
+ layout := aLayout
+
+
+!
+
+preferredExtentX
+ "returns my preferred extent x
+ "
+ ^ 4 + extent x
+
+
+!
+
+preferredExtentY
+ "returns my preferred extent y
+ "
+ ^ 4 + extent y
+
+
+! !
+
+!NoteBookView::Tab methodsFor:'accessing mvc'!
+
+addDependent:aGC
+ "make the noteBook be a dependent of the tab model
+ "
+ model notNil ifTrue:[model addDependent:aGC]
+
+
+!
+
+removeDependent:aGC
+ "make the noteBook be independent of the tab model
+ "
+ model notNil ifTrue:[model removeDependent:aGC]
+
+
+! !
+
+!NoteBookView::Tab methodsFor:'drawing'!
+
+drawAtBottomOn:aGC selected:isSelected
+ "redraw tab at bottom of view
+ "
+ |yT "{ Class:SmallInteger }"
+ xL "{ Class:SmallInteger }"
+ xR "{ Class:SmallInteger }"
+ yB "{ Class:SmallInteger }"
+ |
+ xL := layout left.
+ yT := layout top.
+ xR := layout right - 1.
+ yB := layout bottom - 1.
+
+ aGC paint:(aGC halfLightColor).
+ aGC displayLineFromX:xL+1 y:yB toX:xL+1 y:yT.
+
+ aGC paint:(aGC lightColor).
+ aGC displayLineFromX:xL y:yB-1 toX:xL y:yT.
+
+ aGC paint:(aGC shadowColor).
+ aGC displayLineFromX:xL+1 y:yB toX:xR-2 y:yB.
+ aGC displayLineFromX:xR y:yT toX:xR y:yB-2.
+ aGC displayPointX:xR-1 y:yB-1.
+
+ aGC paint:(aGC halfShadowColor).
+ aGC displayLineFromX:xR-1 y:yT-1 toX:xR-1 y:yB-2.
+ aGC displayLineFromX:xL+2 y:yB-1 toX:xR-2 y:yB-1.
+ aGC displayPointX:xR-2 y:yB-2.
+
+ isSelected ifTrue:[
+ (aGC isLastTabInLine:self) ifFalse:[aGC displayPointX:xR y:yT].
+ (aGC isFirstTabInLine:self) ifFalse:[aGC displayPointX:xL y:yT].
+ ]
+
+
+
+
+
+
+
+!
+
+drawAtLeftOn:aGC selected:isSelected
+ "redraw tab at left of view
+ "
+ |yT "{ Class:SmallInteger }"
+ xL "{ Class:SmallInteger }"
+ xR "{ Class:SmallInteger }"
+ yB "{ Class:SmallInteger }"
+ |
+ xL := layout left.
+ yT := layout top.
+ xR := layout right - 1.
+ yB := layout bottom - 1.
+
+ aGC paint:(aGC shadowColor).
+ aGC displayLineFromX:xR y:yB toX:xL+2 y:yB.
+
+ aGC paint:(aGC halfShadowColor).
+ aGC displayLineFromX:xR y:yB-1 toX:xL+1 y:yB-1.
+
+ aGC paint:(aGC lightColor).
+ aGC displayLineFromX:xL+2 y:yT toX:xR y:yT.
+
+ aGC paint:(aGC halfLightColor).
+ aGC displayLineFromX:xL y:yT+2 toX:xL y:yB-3.
+ aGC displayLineFromX:xL+1 y:yT+2 toX:xL+1 y:yB-2.
+ aGC displayLineFromX:xL+1 y:yT+1 toX:xR y:yT+1.
+
+
+ (aGC isLastTabInLine:self) ifFalse:[aGC displayPointX:xR y:yB].
+ (aGC isFirstTabInLine:self) ifFalse:[aGC displayPointX:xR y:yT].
+
+
+
+!
+
+drawAtRightOn:aGC selected:isSelected
+ "redraw tab at right of view
+ "
+ |yT "{ Class:SmallInteger }"
+ xL "{ Class:SmallInteger }"
+ xR "{ Class:SmallInteger }"
+ yB "{ Class:SmallInteger }"
+ |
+ xL := layout left.
+ yT := layout top.
+ xR := layout right - 1.
+ yB := layout bottom - 1.
+
+ aGC paint:(aGC lightColor).
+ aGC displayLineFromX:xL y:yT toX:xR-2 y:yT.
+
+ aGC paint:(aGC halfLightColor).
+ aGC displayLineFromX:xL y:yT+1 toX:xR-2 y:yT+1.
+
+ aGC paint:(aGC shadowColor).
+ aGC displayLineFromX:xR-2 y:yB toX:xL y:yB.
+ aGC displayLineFromX:xR y:yT+2 toX:xR y:yB-2.
+ aGC displayPointX:xR-1 y:yB-1.
+
+ aGC paint:(aGC halfShadowColor).
+ aGC displayLineFromX:xR-2 y:yB-1 toX:xL y:yB-1.
+ aGC displayLineFromX:xR-1 y:yT+1 toX:xR-1 y:yB-2.
+
+ isSelected ifFalse:[^ self].
+
+ (aGC isLastTabInLine:self) ifFalse:[aGC displayPointX:xL y:yB].
+
+ (aGC isFirstTabInLine:self) ifFalse:[
+ aGC displayPointX:xL y:yT+1.
+ aGC displayPointX:xL y:yT
].
!
-update:something with:aParameter from:changedObject
- "tabs changed
+drawAtTopOn:aGC selected:isSelected
+ "redraw tab at top of view
"
- changedObject == tabRaw ifTrue:[
- something == #preferredExtent ifFalse:[
- something == #direction ifFalse:[
- ^ self
- ].
- tabRaw isHorizontalDirection ifTrue:[
- tabRaw origin:0.0@0.0 corner:1.0@0.0
- ] ifFalse:[
- tabRaw origin:0.0@0.0 corner:0.0@1.0
+ |yT "{ Class:SmallInteger }"
+ xL "{ Class:SmallInteger }"
+ xR "{ Class:SmallInteger }"
+ yB "{ Class:SmallInteger }"
+ |
+ xL := layout left.
+ yT := layout top.
+ xR := layout right - 1.
+ yB := layout bottom - 1.
+
+ aGC paint:(aGC shadowColor).
+ aGC displayLineFromX:xR y:yB toX:xR y:yT+2.
+
+ aGC paint:(aGC halfShadowColor).
+ aGC displayLineFromX:xR-1 y:yB toX:xR-1 y:yT+1.
+
+ aGC paint:(aGC lightColor).
+ aGC displayLineFromX:xL+2 y:yT toX:xR-2 y:yT.
+ aGC displayLineFromX:xL y:yB toX:xL y:yT+2.
+
+ aGC paint:(aGC halfLightColor).
+ aGC displayLineFromX:xL+2 y:yT+1 toX:xR-2 y:yT+1.
+ aGC displayLineFromX:xL+1 y:yB toX:xL+1 y:yT+1.
+
+ isSelected ifFalse:[^ self].
+ (aGC isLastTabInLine:self) ifFalse:[aGC displayPointX:xR y:yB].
+ (aGC isFirstTabInLine:self) ifFalse:[aGC displayPointX:xL y:yB].
+
+
+
+
+!
+
+redrawAt:aDirection selected:isSelected on:aGC
+ "redraw tab
+ "
+ |dispObj fgColor
+ y "{ Class:SmallInteger }"
+ x "{ Class:SmallInteger }"
+ dI "{ Class:SmallInteger }"
+ |
+
+ isSelected ifTrue:[
+ aGC paint:(aGC backgroundColor).
+ layout displayFilledOn:aGC.
+ ].
+ aDirection == #top ifTrue:[self drawAtTopOn:aGC selected:isSelected]
+ ifFalse:[aDirection == #bottom ifTrue:[self drawAtBottomOn:aGC selected:isSelected]
+ ifFalse:[aDirection == #right ifTrue:[self drawAtRightOn:aGC selected:isSelected]
+ ifFalse:[aDirection == #left ifTrue:[self drawAtLeftOn:aGC selected:isSelected]
+ ifFalse:[^ self]]]].
+
+ "/ REDRAW LABEL
+ (aGC isEnabled and:[self isEnabled]) ifTrue:[
+ dispObj := printableLabel.
+ fgColor := aGC foregroundColor.
+
+ model notNil ifTrue:[
+ fgColor := model foregroundColor ? fgColor
+ ]
+ ] ifFalse:[
+ fgColor := aGC lightColor.
+
+ (dispObj := disabledLabel) isNil ifTrue:[
+ (dispObj := printableLabel) isImageOrForm ifTrue:[
+ disabledLabel := printableLabel lightened onDevice:(aGC device)
]
+ ]
+ ].
+ aGC paint:fgColor.
+ dI := 4.
+ (aDirection == #top or:[aDirection == #bottom]) ifTrue:[
+ x := (layout left) + (layout width - extent x // 2).
+
+ y := aDirection == #top ifTrue:[layout top + dI]
+ ifFalse:[layout bottom - extent y - dI].
+
+ dispObj isImageOrForm ifFalse:[
+ y := y + aGC font ascent
].
- self recomputeSizes
- ]
-! !
+ ] ifFalse:[
+ y := (layout top) + (layout height - extent x // 2).
+
+ x := aDirection == #left ifTrue:[layout left + dI]
+ ifFalse:[layout right - extent y - dI].
-!NoteBookView methodsFor:'event handling'!
+ dispObj isImageOrForm ifFalse:[
+ x := x + aGC font descent.
+ "/ workaround for a bug in display-with-angle,
+ "/ iff displayed string is a labelAndIcon.
+ "/ (In this case, display is always opaque, and the current
+ "/ backgroundPaint color is used to fill the underlying rectangle)
+ "/
+ aGC backgroundPaint:(aGC paint:fgColor).
+ ^ aGC displayString:dispObj x:x y:y angle:90.
+ ]
+ ].
+ dispObj displayOn:aGC x:x y:y
-doesNotUnderstand:aMessage
- (tabRaw respondsTo:(aMessage selector)) ifTrue:[
- ^ aMessage sendTo:tabRaw
- ].
- ^ super doesNotUnderstand:aMessage
+
+
+
+
+""
! !
-!NoteBookView methodsFor:'initialize / release'!
+!NoteBookView::Tab methodsFor:'testing'!
-destroy
- "remove dependancies
+containsPointX:x y:y
+ "return true, if the point defined by x@y is contained in the tab.
"
- canvasHolder notNil ifTrue:[
- canvasHolder removeDependent:self.
- ].
- tabRaw removeDependent:self.
- self delegate:self.
- super destroy
+ ^ layout notNil ifTrue:[layout containsPointX:x y:y]
+ ifFalse:[false].
+
+
!
-initialize
- "initialize tabs and canvas
+intersects:aRectangle
+ "return true, if the intersection between the argument, aRectangle
+ and the tab is not empty
"
- super initialize.
+ ^ layout notNil ifTrue:[layout intersects:aRectangle]
+ ifFalse:[false].
- tabRaw := TabView origin:0.0@0.0 corner:1.0@0.0 in:self.
- "/ class for canvas could be set by a subclass
- canvas isNil ifTrue:[
- canvas := View
- ].
- canvas := canvas origin:0.0@0.0 corner:1.0@1.0 in:self.
+!
- tabRaw addDependent:self.
- self delegate:(KeyboardForwarder toView:tabRaw
- condition:nil
- filter:[:key | key size > 6 and:[key startsWith:#Cursor]]).
+isEnabled
+ "returne true if no model exists or the model is enabled
+ "
+ ^ (model isNil or:[model isEnabled])
-! !
-!NoteBookView methodsFor:'selection'!
-
-setSelection:something
- tabRaw setSelection:something
! !
!NoteBookView class methodsFor:'documentation'!
version
- ^ '$Header: /cvs/stx/stx/libwidg2/NoteBookView.st,v 1.12 1999-05-21 18:03:42 cg Exp $'
+ ^ '$Header: /cvs/stx/stx/libwidg2/NoteBookView.st,v 1.13 1999-06-07 12:44:58 cg Exp $'
+
! !
--- a/TabView.st Fri May 28 20:07:15 1999 +0200
+++ b/TabView.st Mon Jun 07 14:45:09 1999 +0200
@@ -11,11 +11,8 @@
"
-View subclass:#TabView
- instanceVariableNames:'list listHolder selection enabled action tabStyle useIndex
- maxRawNr direction fitLastRow moveSelectedRow
- selectConditionBlock oldExtent oneTabPerLine fontAscent
- fontDescent'
+NoteBookView subclass:#TabView
+ instanceVariableNames:''
classVariableNames:''
poolDictionaries:''
category:'Views-Interactors'
@@ -222,1149 +219,20 @@
"
! !
-!TabView class methodsFor:'defaults'!
-
-defaultTabWidget
- ^ #Window
-! !
-
-!TabView methodsFor:'accessing'!
-
-action:oneArgBlock
- "set the action block to be performed on select; the argument to
- the block is the selected index or nil in case of no selection.
- "
- action := oneArgBlock.
-
-!
-
-backgroundColor
- ^ viewBackground
-!
-
-fontAscent
- fontAscent isNil ifTrue:[
- fontAscent := self font ascent
- ].
- ^ fontAscent
-!
-
-fontDescent
- fontDescent isNil ifTrue:[
- fontDescent := self font descent
- ].
- ^ fontDescent
-!
-
-list
- "return the list
- "
- ^ list
-!
-
-list:aList
- "set the list
- "
- |hasChanged newSel model|
-
- aList size == list size ifTrue:[
- list notNil ifTrue:[
- list keysAndValuesDo:[:aKey :aTab|
- (aTab label) = (aList at:aKey) ifFalse:[
- hasChanged := true
- ]
- ]
- ].
- hasChanged == true ifFalse:[^ self ].
- ].
-
- self removeListDependencies.
-
- aList size ~~ 0 ifTrue:[
- (newSel := self tabAt:selection) notNil ifTrue:[
- newSel := newSel printableLabel
- ].
- list := (tabStyle at:#widget) labels:aList for:self.
-
- list do:[:aTab|
- (model := aTab model) notNil ifTrue:[
- model addDependent:self
- ]
- ].
-
- newSel notNil ifTrue:[
- (newSel := list findFirst:[:aTab| aTab printableLabel = newSel]) == 0 ifTrue:[
- newSel := nil
- ]
- ].
- ] ifFalse:[
- list := nil.
- ].
- selection := newSel.
-
- self shown ifTrue:[
- self recomputeList.
- self invalidateRepairNow:true
- ].
- self changed:#preferredExtent
-!
-
-oneTabPerLine
- ^ oneTabPerLine
-!
-
-oneTabPerLine:aBool
- oneTabPerLine := aBool.
-!
-
-useIndex
- "use index instead of name
- "
- ^ useIndex
-
-
-!
-
-useIndex:aBoolean
- "set/clear the useIndex flag. If set, both actionBlock and change-messages
- are passed the index(indices) of the selection as argument.
- If clear, the value(s) (i.e. the selected string) is passed.
- Default is false."
-
- useIndex := aBoolean
-
-
-!
-
-viewBackground:aColor
- "update colors
- "
- super viewBackground:aColor.
- TabWidget computeColorsOn:self style:tabStyle.
- shown ifTrue:[
- self invalidate.
- ]
-
- "Modified: / 6.6.1998 / 19:55:59 / cg"
-! !
-
-!TabView methodsFor:'accessing behavior'!
-
-enabled
- "returns true if tabs are enabled
- "
- ^ enabled
-!
-
-enabled:aState
- "set enabled state
- "
- |state|
-
- state := aState ? true.
-
- enabled ~~ state ifTrue:[
- enabled := state.
- self redrawLabels.
- ]
-!
-
-selectConditionBlock
- "get the conditionBlock; this block is evaluated before a selection
- change is performed; the change will not be done, if the evaluation
- returns false. The argument to the block is the selection index
- "
- ^ selectConditionBlock
-!
-
-selectConditionBlock:aOneArgBlock
- "get the conditionBlock; this block is evaluated before a selection
- change is performed; the change will not be done, if the evaluation
- returns false. The argument to the block is the selection index
- "
- selectConditionBlock := aOneArgBlock
-! !
-
-!TabView methodsFor:'accessing channels/holders'!
-
-listHolder
- "returns the list holder
- "
- ^ listHolder
-!
-
-listHolder:aValueHolder
- "change the list holder
- "
- listHolder notNil ifTrue:[
- listHolder removeDependent:self.
- ].
-
- listHolder := aValueHolder.
- listHolder notNil ifTrue:[
- listHolder addDependent:self.
- self list:listHolder value.
- self selection:model value.
- ].
-!
-
-model:aValueHolder
- super model:aValueHolder.
-
- model notNil ifTrue:[
- self selection:(model value)
- ]
-! !
-
-!TabView methodsFor:'accessing dimension'!
-
-preferredExtent
- "compute max extent x/y based on one line
- "
- |x y ovl size maxY|
-
- (size := list size) == 0 ifTrue:[^ 0 @ 0 ].
-
- maxY := tabStyle at:#maxY.
- y := maxY + self viewSpacing.
-
- oneTabPerLine ifTrue:[
- y := y + ((size - 1) * maxY).
-
- (self isHorizontalDirection) ifTrue:[x := super extent x]
- ifFalse:[x := super extent y]
- ] ifFalse:[
- x := ovl := tabStyle at:#rightCovered.
- list do:[:aTab|x := x - ovl + aTab preferredExtentX]
- ].
-
- (self isHorizontalDirection) ifTrue:[^ x @ y]
- ifFalse:[^ y @ x]
-!
-
-preferredSizeXorY
- "returns preferred size dependant on the current view layout and
- the direction of the tabs
- "
- list size == 0 ifFalse:[
- maxRawNr isNil ifTrue:[self recomputeList].
-
- oneTabPerLine ifTrue:[
- self isHorizontalDirection ifTrue:[^ super extent y]
- ifFalse:[^ super extent x]
- ].
- ^ ((maxRawNr * (tabStyle at:#maxY)) + self viewSpacing).
- ].
- ^ 0
-!
-
-viewSpacing
- "returns my view spacing
- "
- ^ ((tabStyle at:#expandSelection) y) + (self class viewSpacing)
-! !
-
-!TabView methodsFor:'accessing style'!
-
-direction
- "returns the direction of tabs as symbol. On default the value is
- set to #top. Valid symbols are:
- #top arrange tabs to be on top of a view
- #bottom arrange tabs to be on bottom of a view
- #left arrange tabs to be on left of a view
- #right arrange tabs to be on right of a view
- "
- ^ direction
-
-!
-
-direction:aDirection
- "change the direction of tabs. On default the value is set to #top.
- Valid symbols are:
- #top arrange tabs to be on top of a view
- #bottom arrange tabs to be on bottom of a view
- #left arrange tabs to be on left of a view
- #right arrange tabs to be on right of a view
- "
- direction ~~ aDirection ifTrue:[
- direction := aDirection.
- self changed:#direction
- ].
-!
-
-fitLastRow
- "in case of true, the last row is expanded to the view size like all
- other raws. In case of false all the tabs in the last raw keep their
- preferred extent (x or y) dependant on the direction.
- "
- ^ fitLastRow
-!
-
-fitLastRow:aBool
- "in case of true, the last row is expanded to the view size like all
- other raws. In case of false all the tabs in the last raw keep their
- preferred extent (x or y) dependant on the direction.
- "
- fitLastRow := aBool
-!
-
-font:aFont
- (aFont ~= font) ifTrue:[
- super font:aFont.
- fontAscent := fontDescent := nil
- ]
-
-!
-
-moveSelectedRow
- "in case of true, the raw assigned to the tab will be moved
- to the first line (to the view). Otherwise the position of
- the view will be kept.
- "
- ^ moveSelectedRow
-!
-
-moveSelectedRow:aBool
- "in case of true, the raw assigned to the tab will be moved
- to the first line (to the view). Otherwise the position of
- the view will be kept.
- "
- moveSelectedRow := aBool
-!
-
-style
- "returns the style sheet derived from the current widget class
- "
- ^ tabStyle
-!
-
-styleAt:anIdentifier
- "returns a specific entry into the widget description. For more information
- see the specific widget class ( TabWidget ... ).
- "
- ^ tabStyle at:anIdentifier
-!
-
-styleAt:anIdentifier put:something
- "change a specific entry from the widget description. For more information
- see the specific widget class ( TabWidget ... ).
- "
- tabStyle at:anIdentifier put:something.
-!
-
-tabWidget
- "returns the current widget class as symbol
- "
- |widget|
-
- widget := tabStyle at:#widget.
- widget := widget nameWithoutPrefix asSymbol.
- ^ widget
-!
-
-tabWidget:aWidget
- "change the current widget class. An existing list will be
- recomputed and redrawn
- "
- |widget labels|
-
- (self tabWidget) ~~ aWidget ifTrue:[
- widget := TabWidget widgetClass:aWidget.
-
- widget notNil ifTrue:[
- tabStyle := widget tabStyleOn:self.
-
- list notNil ifTrue:[
- labels := list collect:[:aTab| aTab label].
- list := widget labels:labels for:self.
-
- self shown ifTrue:[
- self recomputeList.
- self invalidate.
- ]
- ]
- ]
- ]
-
- "Modified: / 6.6.1998 / 19:56:26 / cg"
-! !
-
-!TabView methodsFor:'accessing tabs'!
-
-tabAt:anIndex
- "get tab at an index or nil
- "
- ^ anIndex notNil ifTrue:[list at:anIndex ifAbsent:nil] ifFalse:[nil]
-! !
-
-!TabView methodsFor:'change & update'!
-
-update:something with:aParameter from:changedObject
- "one of my models changed its value
- "
- |idx tab|
-
- changedObject == model ifTrue:[^ self selection:model value].
- changedObject == listHolder ifTrue:[^ self list:(listHolder value)].
- changedObject == enableChannel ifTrue:[^ self enabled:enableChannel value].
-
- ( list isNil
- or:[(idx := list findFirst:[:aTab| aTab model == changedObject]) == 0]
- ) ifTrue:[
- ^ self
- ].
-
- self shown ifTrue:[
- tab := list at:idx.
-
- something == #foregroundColor ifTrue:[
- ^ self redrawLabelOfTab:tab
- ].
-
- something == #enabled ifTrue:[
- idx == selection ifTrue:[
- ^ self selection:nil
- ].
- ^ self redrawLabelOfTab:tab
- ].
- tab labelChanged.
- self recomputeList.
- self invalidate.
- self changed:#preferredExtent
- ]
-
- "Modified: / 30.3.1999 / 14:28:43 / stefan"
- "Modified: / 28.4.1999 / 19:54:20 / cg"
-! !
-
-!TabView methodsFor:'drawing'!
-
-paintColor:aColorSymbol
- "set the paint color derived from the symbol used as key into the current
- style sheet to access the color
- "
- self paint:(tabStyle at:aColorSymbol)
-!
-
-redraw
- "redraw"
-
- self redrawX:0 y:0 width:width height:height.
-
-!
-
-redrawLabelOfTab:aTab
- "redraw only the label of the tab
- "
- shown ifTrue:[
- aTab == (self tabAt:selection) ifTrue:[
- self selectedTab:aTab redrawBlock:[aTab redrawLabel]
- ] ifFalse:[
- aTab redrawLabel
- ]
- ].
-!
-
-redrawLabels
- "redraw all the labels
- "
- |selectedTab|
-
- (shown and:[list size ~~ 0]) ifTrue:[
- selectedTab := self tabAt:selection.
-
- list reverseDo:[:aTab|
- aTab ~~ selectedTab ifTrue:[
- aTab redrawLabel
- ] ifFalse:[
- self selectedTab:aTab redrawBlock:[aTab redrawLabel]
- ]
- ]
- ].
-!
-
-redrawRawAt:aRawNr
- "redraw raw at a number; all contained tabs are drawn unselected
- "
- list reverseDo:[:aTab|aTab lineNr == aRawNr ifTrue:[aTab redraw:false]].
-!
-
-redrawRawAt:aRawNr in:aRectangle
- "redraw raw at a number; all contained tabs are drawn unselected
- "
- list reverseDo:[:aTab|
- aTab lineNr == aRawNr ifTrue:[
- (aTab intersects:aRectangle) ifTrue:[
- aTab redraw:false
- ]
- ]
- ].
-!
-
-redrawSelection
- "redraw current selection
- "
- |tab idx|
-
- (selection notNil and:[self shown and:[list size ~~ 0]]) ifTrue:[
- tab := list at:selection.
- idx := tab lineNr.
- self selectedTab:tab redrawBlock:[tab redraw:true].
- [(idx := idx - 1) ~~ 0] whileTrue:[self redrawRawAt:idx].
- ].
-!
-
-redrawX:x y:y width:w height:h
- "a region must be redrawn
- "
- |rectangle oldSelect prevClipArea|
-
- self shown ifFalse:[
- ^ self
- ].
-
- self paint:(self viewBackground).
- self clearRectangleX:x y:y width:w height:h.
-
- list size == 0 ifTrue:[^ self].
-
- prevClipArea := clipRect.
- clipRect := nil.
- device setClipX:x y:y width:w height:h in:drawableId gc:gcId.
- rectangle := Rectangle left:x top:y width:w height:h.
-
- maxRawNr isNil ifTrue:[
- self recomputeList.
- ].
- maxRawNr to:1 by:-1 do:[:i| self redrawRawAt:i in:rectangle].
-
- selection notNil ifTrue:[
- oldSelect := selection.
- selection := nil.
- self setSelection:oldSelect.
- ].
-
- prevClipArea isNil ifTrue:[device noClipIn:drawableId gc:gcId]
- ifFalse:[self clippingRectangle:prevClipArea].
-
- "Modified: / 20.5.1999 / 19:16:51 / cg"
-!
-
-selectedTab:aTab redrawBlock:aRedrawBlock
- "calculate extent of selection and evaluate the block which will
- perform a redraw action
- "
- |tab oldAnc newAnc oldExt newExt expSel expDlt x y|
-
- tab := list at:selection.
- oldAnc := tab anchor.
- oldExt := tab extent.
- expSel := tabStyle at:#expandSelection.
- expDlt := expSel x.
-
- (self isHorizontalDirection) ifTrue:[
- newExt := oldExt + ( expDlt @ 0 ).
- newAnc := oldAnc - ((expDlt//2) @ ((expSel y) negated)).
-
- (x := newAnc x) < 0 ifTrue:[
- newExt x:(newExt x + x).
- newAnc x:0.
- x := 0.
- ].
- (x + newExt x) > width ifTrue:[newExt x:(width - x)].
- ] ifFalse:[
- newExt := oldExt + ( 0 @ expDlt ).
- newAnc := oldAnc - (((expSel y) negated) @ (expDlt//2)).
-
- (y := newAnc y) < 0 ifTrue:[
- newExt y:(newExt y + y).
- newAnc y:0.
- y := 0.
- ].
- (y + newExt y) > height ifTrue:[newExt y:(height - y)].
- ].
-
- tab anchor:newAnc extent:newExt.
- aRedrawBlock value.
- tab anchor:oldAnc extent:oldExt.
-
- "Modified: / 4.5.1999 / 02:01:19 / cg"
-! !
-
-!TabView methodsFor:'event handling'!
-
-buttonPress:button x:x y:y
- "a button is pressed; find tab under point and set the selection
- "
- |idx|
-
- ( self isEnabled
- and:[list notNil
- and:[(idx := list findFirst:[:aTab|aTab containsPoint:(x@y)]) ~~ 0]]
- ) ifTrue:[
- self selection:idx
- ].
-!
-
-keyPress:aKey x:x y:y
- "selection might change; look for corresponding list entry
- "
- |size index n|
-
- (self isEnabled and:[(size := list size) > 1]) ifFalse:[
- ^ self
- ].
-
- (aKey == #CursorRight or:[aKey == #CursorDown]) ifTrue:[
- n := selection ? 0.
-
- (size - 1) timesRepeat:[
- (n := n + 1) > size ifTrue:[n := 1].
-
- (self canSelectTabAtIndex:n) ifTrue:[
- ^ self selection:n
- ]
- ].
- ^ self
- ].
-
- (aKey == #CursorLeft or:[aKey == #CursorUp]) ifTrue:[
- n := selection ? size.
-
- (size - 1) timesRepeat:[
- (n := n - 1) < 1 ifTrue:[n := size].
-
- (self canSelectTabAtIndex:n) ifTrue:[
- ^ self selection:n
- ]
- ].
- ^ self
- ].
-
- aKey isCharacter ifTrue:[
- (selection isNil or:[selection == size]) ifTrue:[index := 1]
- ifFalse:[index := selection + 1].
-
- n := index - 1.
- [
- n := self findTabStartingWithKey:aKey startingAt:n + 1.
-
- (n ~~ 0 and:[self canSelectTabAtIndex:n]) ifTrue:[
- ^ self selection:n
- ].
- n ~~ 0
-
- ] whileTrue.
-
- index ~~ 1 ifTrue:[
- (n := self findTabStartingWithKey:aKey startingAt:1) ~~ 0 ifTrue:[
- ^ self selection:n
- ]
- ]
- ].
-
- super keyPress:aKey x:x y:y
-!
-
-sizeChanged:how
- "size of view changed
- "
- |extent delta dX dY|
-
- super sizeChanged:how.
-
- list size ~~ 0 ifTrue:[
- shown ifTrue:[
- self invalidate
- ].
-
- extent := super extent.
- delta := oldExtent - extent.
-
- ((dX := delta x) > 1 or:[dX < -1
- or:[(dY := delta y) > 1 or:[dY < -1]]]) ifTrue:[
- oldExtent := extent.
- self recomputeList.
- self changed:#preferredExtent.
- ].
- ].
-
- "Modified: / 22.4.1998 / 14:20:31 / cg"
-! !
-
-!TabView methodsFor:'initialize / release'!
-
-destroy
- listHolder notNil ifTrue:[
- listHolder removeDependent:self.
- ].
- enableChannel notNil ifTrue:[
- enableChannel removeDependent:self.
- ].
- self removeListDependencies.
- super destroy.
-!
+!TabView methodsFor:'initialization'!
initStyle
"setup style attributes
"
super initStyle.
- self font:(MenuView defaultFont on:device).
-
- "Created: / 5.9.1998 / 17:36:37 / cg"
- "Modified: / 5.9.1998 / 17:37:38 / cg"
-!
-
-initialize
- "setup default attributes
- "
- |widget|
-
- super initialize.
-
- self cursor:Cursor hand.
-
- widget := TabWidget widgetClass:(self class defaultTabWidget).
- tabStyle := widget tabStyleOn:self.
-
- styleSheet name == #win95 ifTrue:[
-"/ tabStyle at:#unselectedColor put:(tabStyle at:#selectedColor).
-"/ tabStyle at:#expandSelection put:(4@2).
-"/ tabStyle at:#lightColorUnselected put:(Color white).
-"/ tabStyle at:#lightColorSelected put:(Color white).
- tabStyle at:#labelTopInset put:0.
- tabStyle at:#labelBottomInset put:0.
- ].
-
- useIndex := false.
- oneTabPerLine := false.
- direction := #top.
- fitLastRow := true.
- moveSelectedRow := true.
- enabled := true.
- oldExtent := 0@0.
-
- "Modified: / 4.5.1999 / 02:26:28 / cg"
-! !
-
-!TabView methodsFor:'layout'!
-
-changeRaw:aRawA with:aRawB
- "exchange positions of two raws
- "
- |tabB tabA ancA ancB hrz|
-
- tabA := list at:(list findFirst:[:aTab|aTab lineNr == aRawA]).
- tabB := list at:(list findFirst:[:aTab|aTab lineNr == aRawB]).
- hrz := (self isHorizontalDirection).
-
- hrz ifTrue:[
- ancA := tabA anchor y.
- ancB := tabB anchor y.
- ] ifFalse:[
- ancA := tabA anchor x.
- ancB := tabB anchor x.
- ].
-
- list do:[:aTab||ln|
- (ln := aTab lineNr) == aRawB ifTrue:[
- aTab lineNr:aRawA.
- hrz ifTrue:[aTab anchor y:ancA]
- ifFalse:[aTab anchor x:ancA]
- ] ifFalse:[
- ln == aRawA ifTrue:[
- aTab lineNr:aRawB.
- hrz ifTrue:[aTab anchor y:ancB]
- ifFalse:[aTab anchor x:ancB]
- ]
- ]
- ].
-
- oneTabPerLine ifFalse:[
- aRawB == maxRawNr ifTrue:[
- self fitRawAt:aRawA.
- self unfitLastRaw.
- ] ifFalse:[
- aRawA == maxRawNr ifTrue:[
- self fitRawAt:aRawB.
- self unfitLastRaw.
- ]
- ]
- ]
-!
-
-fitRawAt:aRawNr
- "fit raw to view's size
- "
- |last first tab ext org max size|
-
- (aRawNr ~~ maxRawNr or:[fitLastRow]) ifFalse:[
- ^ self
- ].
-
- last := list findLast:[:aTab| aTab lineNr == aRawNr ].
- first := list findFirst:[:aTab| aTab lineNr == aRawNr ].
- tab := list at:last.
- size := last - first + 1.
- org := 0.
-
- (self isHorizontalDirection) ifTrue:[
- max := super extent x.
- ext := (max - ((tab anchor x) + (tab extent x))) // size.
-
- ext > 1 ifTrue:[
- first to:last do:[:i|
- tab := list at:i.
- tab extent x:((tab extent x) + ext).
- tab anchor x:((tab anchor x) + org).
- org := org + ext.
- ].
- tab := list at:last.
- ].
- tab extent x:(max - tab anchor x).
- ] ifFalse:[
- max := super extent y.
- ext := (max - ((tab anchor y) + (tab extent y))) // size.
-
- ext > 1 ifTrue:[
- first to:last do:[:i|
- tab := list at:i.
- tab extent y:((tab extent y) + ext).
- tab anchor y:((tab anchor y) + org).
- org := org + ext.
- ].
- tab := list at:last.
- ].
- tab extent y:(max - tab anchor y).
- ]
-!
-
-recomputeList
- "recompute list
- "
- |maxY x y maxSz ovl|
-
- list size == 0 ifTrue:[
- ^ self
- ].
-
- maxY := tabStyle at:#maxY.
- ovl := tabStyle at:#rightCovered.
- maxRawNr := 1.
-
- (self isHorizontalDirection) ifTrue:[
- maxSz := super extent x.
- x := 0.
- y := maxY.
-
- oneTabPerLine ifTrue:[
- list do:[:aTab|
- aTab lineNr:maxRawNr.
- aTab anchor:x@y extent:(maxSz @ maxY).
- maxRawNr := maxRawNr + 1.
- y := y + maxY.
- ].
- ^ self
- ].
- list do:[:aTab||eX n|
- eX := aTab preferredExtentX.
- n := eX + x - ovl.
-
- (n > maxSz and:[x ~~ 0]) ifTrue:[
- maxRawNr := maxRawNr + 1.
- x := 0.
- y := y + maxY.
- n := eX - ovl.
- ].
- aTab lineNr:maxRawNr.
- aTab anchor:x@y extent:(eX @ maxY).
- x := n.
- ]
- ] ifFalse:[
- maxSz := super extent y.
- x := maxY.
- y := 0.
-
- oneTabPerLine ifTrue:[
- list do:[:aTab|
- aTab lineNr:maxRawNr.
- aTab anchor:x@y extent:(maxY @ maxSz).
- maxRawNr := maxRawNr + 1.
- x := x + maxY.
- ].
- ^ self
- ].
- list do:[:aTab||eY n|
- eY := aTab preferredExtentX.
- n := eY + y - ovl.
-
- (n > maxSz and:[y ~~ 0]) ifTrue:[
- maxRawNr := maxRawNr + 1.
- y := 0.
- x := x + maxY.
- n := eY - ovl.
- ].
- aTab lineNr:maxRawNr.
- aTab anchor:x@y extent:(maxY @ eY).
- y := n.
- ]
- ].
- "/ fit raws to view
- 1 to:maxRawNr do:[:aLnNr|self fitRawAt:aLnNr].
-!
-
-unfitLastRaw
- "use the preferred extent for all tabs in the last raw
- "
- |last first tab ovl anchor extent pos offset hrz|
-
- fitLastRow ifTrue:[
- ^ self
- ].
- last := list findLast:[:aTab| aTab lineNr == maxRawNr ].
- first := list findFirst:[:aTab| aTab lineNr == maxRawNr ].
- ovl := tabStyle at:#rightCovered.
- pos := 0.
- hrz := (self isHorizontalDirection).
-
- first to:last do:[:i|
- tab := list at:i.
- anchor := tab anchor.
- extent := tab extent.
- offset := tab preferredExtentX.
+ tabModus := true.
- hrz ifTrue:[
- extent x:offset.
- anchor x:pos
- ] ifFalse:[
- extent y:offset.
- anchor y:pos.
- ].
- tab anchor:anchor extent:extent.
- pos := pos + offset - ovl.
- ].
-! !
-!TabView methodsFor:'private'!
-
-findTabStartingWithKey:aKey startingAt:anIndex
- "get index of tab starting its printableLabel with a key or 0
- "
- |upper lower|
-
- (aKey isCharacter and:[anIndex <= list size]) ifFalse:[ ^ 0 ].
-
- upper := aKey asUppercase.
- lower := aKey asLowercase.
-
- ^ list findFirst:[:aTab||l c|
- ( (l := aTab printableLabel) isString
- and:[((c := l first) == lower or:[c == upper])]
- )
- ] startingAt:anIndex
-!
-
-listIndexOf:something
- "convert something to an index into list or nil.
- "
- |index|
-
- something isNil ifTrue:[^ nil ].
-
- something isNumber ifTrue:[
- index := something
- ] ifFalse:[
- index := list findFirst:[:aTab|aTab label = something].
-
- index == 0 ifTrue:[
- index := list findFirst:[:aTab|aTab printableLabel = something].
- ]
- ].
- ^ index ~~ 0 ifTrue:[index] ifFalse:[nil]
-!
-
-removeListDependencies
- |model|
-
- list notNil ifTrue:[
- list do:[:aTab|
- (model := aTab model) notNil ifTrue:[
- model removeDependent:self
- ]
- ]
- ]
-! !
-
-!TabView methodsFor:'queries'!
-
-canSelectTabAtIndex:anIndex
- "returns true if tab at an index is selectable
- "
- (list at:anIndex) isEnabled ifTrue:[
- ^ selectConditionBlock isNil ifTrue:[true]
- ifFalse:[selectConditionBlock value:anIndex]
- ].
- ^ false
-!
-
-getBackgroundPaintForTab:aTab
- "returns background color of the tab
- "
- |key|
-
- key := aTab == (self tabAt:selection) ifFalse:[#unselectedColor]
- ifTrue:[#selectedColor].
-
- ^ tabStyle at:key
-!
-
-isEnabled
- "returns enabled state
- "
- ^ enabled
-!
-
-isHorizontalDirection
- "returns true in case of direction is #top or #bottom
- "
- ^ (direction == #top or:[direction == #bottom])
-
-!
-
-isVerticalDirection
- "returns true in case of direction is #left or #right
- "
- ^ (direction == #left or:[direction == #right])
-
-! !
-
-!TabView methodsFor:'selection'!
-
-isTabSelected:aTab
- "returns true if tab is selected
- "
- ^ aTab == (self tabAt:selection)
-!
-
-selection
- "return the selection index or nil
- "
- |tab|
-
- useIndex ifTrue:[
- ^ selection ? 0
- ].
- tab := self tabAt:selection.
- ^ tab notNil ifTrue:[tab label] ifFalse:[nil]
-!
-
-selection:anIndexOrNil
- "change the selection to index or nil. The model and/or actionBlock is notified
- "
- |oldSel|
-
- oldSel := selection.
- self setSelection:anIndexOrNil.
- oldSel ~~ selection ifTrue:[self selectionHasChanged].
-!
-
-selectionHasChanged
- "selection might change; raise notification
- "
- |sel|
-
- sel := self selection.
-
- model notNil ifTrue:[model value:sel].
- action notNil ifTrue:[action value:sel]
-
-!
-
-setSelection:something
- "change the selection to index or nil. No notifications are raised
- "
- |newSel lnNr tab last first exp x y w h|
-
- list size == 0 ifTrue:[^ self].
- newSel := self listIndexOf:something.
- selection == newSel ifTrue:[^ self].
-
- newSel notNil ifTrue:[
- (self tabAt:newSel) isNil ifTrue:[
- newSel := nil
- ] ifFalse:[
- (self canSelectTabAtIndex:newSel) ifFalse:[^ self ].
- ]
- ].
-
- self shown ifFalse:[
- selection := newSel.
- ^ self
- ].
-
- maxRawNr isNil ifTrue:[
- selection := newSel.
- self recomputeList.
- self invalidate.
- ^ self.
- ].
-
- (newSel notNil
- and:[moveSelectedRow
- and:[(lnNr := (list at:newSel) lineNr) > 1]]
- ) ifTrue:[
- self changeRaw:1 with:lnNr.
- selection := 1. "/ force a redraw
- ].
-
- selection notNil ifTrue:[
- maxRawNr > 1 ifTrue:[
- self paint:(self viewBackground). "/ total redraw
- self clear.
- selection := nil.
- maxRawNr to:1 by:-1 do:[:i| self redrawRawAt:i ].
- ] ifFalse:[
- first := 1.
-
- (selection ~~ 1 and:[(tabStyle at:#rightCovered) == 0]) ifTrue:[
- first := selection - 1
- ].
-
- (last := selection + 1) > list size ifTrue:[
- last := selection
- ].
- exp := (tabStyle at:#expandSelection) x.
- tab := list at:selection.
-
- self isHorizontalDirection ifTrue:[
- (x := tab anchor x - (exp // 2)) < 0 ifTrue:[x := 0].
- w := tab extent x + exp.
- h := super extent y.
- y := 0.
- ] ifFalse:[
- (y := tab anchor y - (exp // 2)) < 0 ifTrue:[y := 0].
- h := tab extent y + exp.
- w := super extent x.
- x := 0.
- ].
- self paint:(self viewBackground).
- self clearRectangleX:x y:y width:w height:h.
-
- last to:first by:-1 do:[:i|
- tab := list at:i.
- tab redraw:false
- ]
- ]
- ].
- selection := newSel.
- self redrawSelection.
-
- "Modified: / 6.6.1998 / 19:56:45 / cg"
! !
!TabView class methodsFor:'documentation'!
version
- ^ '$Header: /cvs/stx/stx/libwidg2/TabView.st,v 1.45 1999-05-21 18:01:23 cg Exp $'
+ ^ '$Header: /cvs/stx/stx/libwidg2/TabView.st,v 1.46 1999-06-07 12:45:09 cg Exp $'
! !