TabView.st
author Claus Gittinger <cg@exept.de>
Fri, 28 Jun 2019 09:21:50 +0200
changeset 6078 08c9e2a47dc5
parent 6045 c1e2a95ac169
permissions -rw-r--r--
#OTHER by cg self class name -> self className

"{ Encoding: utf8 }"

"
 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.
"
"{ Package: 'stx:libwidg2' }"

"{ NameSpace: Smalltalk }"

NoteBookView subclass:#TabView
	instanceVariableNames:''
	classVariableNames:''
	poolDictionaries:''
	category:'Views-Interactors'
!

!TabView 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
"
    implements the tabs-view component of a noteBook.
    May also be used on its own (without a surrounding noteBook).

    The functionality is basically the same as provided by a
    PopUpList or SelectionInListView, in that a valueHolder
    gets a value assigned corresponding to the selected tab
    from a list of possible tabs.

    [author:]
	Claus Atzkern

    [see also:]
	NoteBookView
	SelectionInListView PopUpList ValueHolder TabWidget
"

!

examples
"
    tabs at top of a view
                                                                                [exBegin]
    |top tab|

    top := StandardSystemView new label:'tabs at bottom'; extent:250@100.
    tab := TabView origin:(0.0 @ 0.0) corner:(1.0 @ 0.0)in:top.
    tab direction:#top.
    tab list:#( 'Foo' 'Bar' 'Baz' ).
    tab action:[:anIndex| Transcript showCR:anIndex ].
    tab bottomInset:(tab preferredExtent y negated).
    top open.
                                                                                [exEnd]

    tabs at bottom a view
                                                                                [exBegin]                                      
    |top tab|

    top := StandardSystemView new label:'tabs at bottom'; extent:250@100.
    tab := TabView origin:(0.0 @ 1.0) corner:(1.0 @ 1.0)in:top.
    tab direction:#bottom.
    tab list:#( 'Foo' 'Bar' 'Baz' ).
    tab action:[:anIndex| Transcript showCR:anIndex ].
    tab topInset:(tab preferredExtent y negated).
    top open.
                                                                                [exEnd]

    tabs at right of a view
                                                                                [exBegin]                                      
    |top tab|

    top := StandardSystemView new label:'tabs at right'; extent:100@250.
    tab := TabView origin:1.0 @ 0.0 corner:1.0 @ 1.0 in:top.

    tab direction:#right.
    tab list:#( 'Foo' 'Bar' 'Baz' ).
    tab action:[:aName|Transcript showCR:aName].
    tab leftInset:(tab preferredExtent x negated).
    top open.
                                                                                [exEnd]

    tabs at left of a view
                                                                                [exBegin]                                      
    |top tab view inset|

    top := StandardSystemView new label:'tabs at left'; extent:100@250.
    tab := TabView origin:0.0 @ 0.0 corner:0.0 @ 1.0 in:top.

    tab direction:#left.
    tab list:#( 'Foo' 'Bar' 'Baz' ).
    tab action:[:aName|Transcript showCR:aName].
    tab rightInset:(tab preferredExtent x negated).
    top open.
                                                                                [exEnd]

    using icons and text
                                                                                [exBegin]
    |top tab view list|

    top := StandardSystemView new label:'using icons, text, ..'; extent:300@100.
    tab := TabView origin:0.0 @ 0.0 corner:1.0 @ 0.0 in:top.
    list := OrderedCollection new.
    list add:( LabelAndIcon icon:(ToolbarIconLibrary workspace24x24Icon2) string:'Workspace' ).
    list add:( ToolbarIconLibrary workspace24x24Icon2 ).
    list add:( 'Workspace' ).
    list add:( 'Workspace' allBold ).

    tab list:list.
    tab hasScrollButtons:true.
    tab action:[:indexOrNil| Transcript showCR:indexOrNil ].
    tab bottomInset:(tab preferredExtent y negated).
    top open.
                                                                                [exEnd]
"
! !

!TabView methodsFor:'accessing'!

recomputeListHorizontal
    "compute layouts for all tabs"

    | borderLevel xLeft xRight yTop tabWidth tabHeight delta tabLvlAbs minLeft maxRight leftMargin rightMargin |

    maxRight := self width  // list size.
    maxRight < 7 ifTrue:[
        selectionInsetX := 0.
        maxRight > 5 ifTrue:[ selectionInsetX := 1 ].
    ] ifFalse:[
        selectionInsetX := 2.
        maxRight > 8 ifTrue:[ selectionInsetX := 3 ].
    ].
    tabLabelInset x: 0.

    tabLvlAbs   := tabLevel abs.
    borderLevel := tabLvlAbs * 2.
    tabHeight   := 0.
    leftMargin  := self tabLeftMargin.
    rightMargin := self tabRightMargin.
    minLeft     := leftMargin + selectionInsetX.
    maxRight    := self width - rightMargin - selectionInsetX.
    xLeft       := minLeft.

    addTabAction notNil
        ifTrue:[ maxRight := maxRight - self horizontalMarginForAddTabButton ].

    list do:[:aTab| |tabExtent|
        tabExtent := self preferredExtentForTab:aTab.
        tabWidth  := tabExtent x + borderLevel.
        tabHeight := tabExtent y max:tabHeight.
        xRight    := xLeft + tabWidth.

        aTab destroyTabButtonShown ifTrue:[
            xRight := xRight + self destroyButtonUsedWidth
        ].

        aTab lineNr: 1.
        aTab unselectedLayout:(Rectangle left:xLeft top:0 width:tabWidth height:tabHeight).
        xLeft := xRight.
    ].
    tabHeight := tabHeight + tabLvlAbs.
    yTop      := selectionInsetY + tabTopMargin.
    delta     := tabHeight.

    direction == #bottom ifTrue:[
        yTop  := self height - tabHeight - yTop.
        delta := tabHeight negated.
    ].

    list reverseDo:[:aTab|
        aTab unselectedLayout setTop:yTop.
        aTab unselectedLayout height:tabHeight.
    ].

    tabModus ifTrue:[
        |firstTabLayout|

        firstTabLayout := list first unselectedLayout.
        delta  := direction == #top 
                        ifTrue:[self height - firstTabLayout bottom]
                        ifFalse:[firstTabLayout top negated].

        list do:[:aTab | |l|
                l := aTab unselectedLayout.
                l setTop:(l top + delta).
        ].
    ].

    list isEmpty ifTrue:[ ^ self ].
    
    delta := maxRight - list last unselectedLayout right.
    [ delta < 0 ] whileTrue:[ |tab wdt|
        tab := nil.
        wdt := 2.

        list do:[: each |
            each unselectedLayout width > wdt ifTrue:[
                tab := each.
                wdt := each unselectedLayout width.
            ].
        ].
        tab isNil
             ifTrue:[ delta := 0 ]
            ifFalse:[ delta := delta + 1. tab unselectedLayout width: (tab unselectedLayout width - 1) ].
    ].

    [ delta > 0 ] whileTrue:[ |tab wdt|
        tab := list first.
        wdt := tab unselectedLayout width - tab extent x.

        list from:2 to: list size do:[: each | |new|
            new :=  each unselectedLayout width - each extent x.
            wdt > new ifTrue:[ wdt := new. tab := each. ].
        ].
        tab unselectedLayout width: (tab unselectedLayout width + 1).
        delta := delta - 1.
    ].

    2 to: list size do:[: i |
        (list at: i) unselectedLayout setLeft: ((list at: i -1) unselectedLayout right).
    ].

    list do:[:eachTab | eachTab layout:eachTab unselectedLayout; selectedLayout:nil ].
! !

!TabView methodsFor:'initialization'!

initStyle
    "setup style attributes
    "

    super initStyle.
    tabModus := true.


! !

!TabView class methodsFor:'documentation'!

version
    ^ '$Header$'
!

version_CVS
    ^ '$Header$'
! !