diff options
Diffstat (limited to 'generic/ttk/ttkNotebook.c')
-rw-r--r-- | generic/ttk/ttkNotebook.c | 181 |
1 files changed, 107 insertions, 74 deletions
diff --git a/generic/ttk/ttkNotebook.c b/generic/ttk/ttkNotebook.c index 8bcee74..6958180 100644 --- a/generic/ttk/ttkNotebook.c +++ b/generic/ttk/ttkNotebook.c @@ -1,4 +1,4 @@ -/* $Id: ttkNotebook.c,v 1.13.2.1 2009/12/16 20:40:29 jenglish Exp $ +/* $Id: ttkNotebook.c,v 1.13.2.2 2010/08/26 02:06:09 hobbs Exp $ * Copyright (c) 2004, Joe English */ @@ -20,7 +20,7 @@ #define DEFAULT_MIN_TAB_WIDTH 24 -static const char *TabStateStrings[] = { "normal", "disabled", "hidden", 0 }; +static const char *const TabStateStrings[] = { "normal", "disabled", "hidden", 0 }; typedef enum { TAB_STATE_NORMAL, TAB_STATE_DISABLED, TAB_STATE_HIDDEN } TAB_STATE; @@ -73,7 +73,7 @@ static Tk_OptionSpec TabOptionSpecs[] = 0,(ClientData)ttkCompoundStrings,GEOMETRY_CHANGED }, {TK_OPTION_INT, "-underline", "underline", "Underline", "-1", Tk_Offset(Tab,underlineObj), -1, 0,0,GEOMETRY_CHANGED }, - {TK_OPTION_END} + {TK_OPTION_END, NULL, NULL, NULL, NULL, 0, 0, 0, 0, 0 } }; static Tk_OptionSpec PaneOptionSpecs[] = @@ -149,20 +149,27 @@ static void NotebookStyleOptions(Notebook *nb, NotebookStyle *nbstyle) TtkGetLabelAnchorFromObj(NULL, objPtr, &nbstyle->tabPosition); } - /* compute tabPlacement and tabOrient as function of tabPosition: + /* Guess default tabPlacement as function of tabPosition: */ if (nbstyle->tabPosition & TTK_PACK_LEFT) { nbstyle->tabPlacement = TTK_PACK_TOP | TTK_STICK_E; - nbstyle->tabOrient = TTK_ORIENT_VERTICAL; } else if (nbstyle->tabPosition & TTK_PACK_RIGHT) { nbstyle->tabPlacement = TTK_PACK_TOP | TTK_STICK_W; - nbstyle->tabOrient = TTK_ORIENT_VERTICAL; } else if (nbstyle->tabPosition & TTK_PACK_BOTTOM) { nbstyle->tabPlacement = TTK_PACK_LEFT | TTK_STICK_N; - nbstyle->tabOrient = TTK_ORIENT_HORIZONTAL; } else { /* Assume TTK_PACK_TOP */ nbstyle->tabPlacement = TTK_PACK_LEFT | TTK_STICK_S; + } + if ((objPtr = Ttk_QueryOption(nb->core.layout, "-tabplacement", 0)) != 0) { + TtkGetLabelAnchorFromObj(NULL, objPtr, &nbstyle->tabPlacement); + } + + /* Compute tabOrient as function of tabPlacement: + */ + if (nbstyle->tabPlacement & (TTK_PACK_LEFT|TTK_PACK_RIGHT)) { nbstyle->tabOrient = TTK_ORIENT_HORIZONTAL; + } else { + nbstyle->tabOrient = TTK_ORIENT_VERTICAL; } nbstyle->tabMargins = Ttk_UniformPadding(0); @@ -208,7 +215,7 @@ static void DestroyTab(Notebook *nb, Tab *tab) static int ConfigureTab( Tcl_Interp *interp, Notebook *nb, Tab *tab, Tk_Window slaveWindow, - int objc, Tcl_Obj *CONST objv[]) + int objc, Tcl_Obj *const objv[]) { Ttk_Sticky sticky = tab->sticky; Ttk_Padding padding = tab->padding; @@ -367,7 +374,7 @@ static int NotebookSize(void *clientData, int *widthPtr, int *heightPtr) Notebook *nb = clientData; NotebookStyle nbstyle; Ttk_Padding padding; - Ttk_LayoutNode *clientNode = Ttk_LayoutFindNode(nb->core.layout, "client"); + Ttk_Element clientNode = Ttk_FindElement(nb->core.layout, "client"); int clientWidth = 0, clientHeight = 0, reqWidth = 0, reqHeight = 0, tabrowWidth = 0, tabrowHeight = 0; @@ -413,8 +420,13 @@ static int NotebookSize(void *clientData, int *widthPtr, int *heightPtr) padding = Ttk_AddPadding(padding, ipad); } - *widthPtr = MAX(tabrowWidth, clientWidth) + Ttk_PaddingWidth(padding); - *heightPtr = tabrowHeight + clientHeight + Ttk_PaddingHeight(padding); + if (nbstyle.tabPosition & (TTK_PACK_TOP|TTK_PACK_BOTTOM)) { + *widthPtr = MAX(tabrowWidth, clientWidth) + Ttk_PaddingWidth(padding); + *heightPtr = tabrowHeight + clientHeight + Ttk_PaddingHeight(padding); + } else { + *widthPtr = tabrowWidth + clientWidth + Ttk_PaddingWidth(padding); + *heightPtr = MAX(tabrowHeight,clientHeight) + Ttk_PaddingHeight(padding); + } return 1; } @@ -424,12 +436,12 @@ static int NotebookSize(void *clientData, int *widthPtr, int *heightPtr) */ /* SqueezeTabs -- - * If the notebook is not wide enough to display all tabs, - * attempt to decrease tab widths to fit. + * Squeeze or stretch tabs to fit within the tab area parcel. * - * All tabs are shrunk by an equal amount, but will not be made + * All tabs are adjusted by an equal amount, but will not be made * smaller than the minimum width. (If all the tabs still do - * not fit in the available space, the rightmost tabs are truncated). + * not fit in the available space, the rightmost ones will + * be further squozen by PlaceTabs()). * * The algorithm does not always yield an optimal layout, but does * have the important property that decreasing the available width @@ -438,23 +450,35 @@ static int NotebookSize(void *clientData, int *widthPtr, int *heightPtr) * and grows. * * @@@ <<NOTE-TABPOSITION>> bug: only works for horizontal orientations + * @@@ <<NOTE-SQUEEZE-HIDDEN>> does not account for hidden tabs. */ static void SqueezeTabs( - Notebook *nb, int desiredWidth, int availableWidth, int minTabWidth) + Notebook *nb, int needed, int available, int minTabWidth) { int nTabs = Ttk_NumberSlaves(nb->notebook.mgr); - int shrinkage = desiredWidth - availableWidth; - int extra = 0; - int i; - for (i = 0; i < nTabs; ++i) { - Tab *tab = Ttk_SlaveData(nb->notebook.mgr,i); - int shrink = (shrinkage/nTabs) + (i < (shrinkage%nTabs)) + extra; - int shrinkability = MAX(0, tab->width - minTabWidth); - int delta = MIN(shrinkability, shrink); - tab->width -= delta; - extra = shrink - delta; + if (nTabs > 0) { + int difference = available - needed, + delta = difference / nTabs, + remainder = difference % nTabs, + slack = 0; + int i; + + if (remainder < 0) { remainder += nTabs; --delta; } + + for (i = 0; i < nTabs; ++i) { + Tab *tab = Ttk_SlaveData(nb->notebook.mgr,i); + int adj = delta + (i < remainder) + slack; + + if (tab->width + adj >= minTabWidth) { + tab->width += adj; + slack = 0; + } else { + slack = adj - (minTabWidth - tab->width); + tab->width = minTabWidth; + } + } } } @@ -501,7 +525,7 @@ static void NotebookDoLayout(void *recordPtr) Tk_Window nbwin = nb->core.tkwin; Ttk_Box cavity = Ttk_WinBox(nbwin); int tabrowWidth = 0, tabrowHeight = 0; - Ttk_LayoutNode *clientNode = Ttk_LayoutFindNode(nb->core.layout, "client"); + Ttk_Element clientNode = Ttk_FindElement(nb->core.layout, "client"); Ttk_Box tabrowBox; NotebookStyle nbstyle; @@ -525,15 +549,13 @@ static void NotebookDoLayout(void *recordPtr) nbstyle.tabPosition), nbstyle.tabMargins); - if (tabrowWidth > tabrowBox.width) { - SqueezeTabs(nb, tabrowWidth, tabrowBox.width, nbstyle.minTabWidth); - } + SqueezeTabs(nb, tabrowWidth, tabrowBox.width, nbstyle.minTabWidth); PlaceTabs(nb, tabrowBox, nbstyle.tabPlacement); /* Layout for client area frame: */ if (clientNode) { - Ttk_PlaceLayoutNode(nb->core.layout, clientNode, cavity); + Ttk_PlaceElement(nb->core.layout, clientNode, cavity); cavity = Ttk_LayoutNodeInternalParcel(nb->core.layout, clientNode); } @@ -854,7 +876,7 @@ static int GetTabIndex( /* $nb add window ?options ... ? */ static int NotebookAddCommand( - Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[], void *recordPtr) + void *recordPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]) { Notebook *nb = recordPtr; int index = Ttk_NumberSlaves(nb->notebook.mgr); @@ -863,7 +885,7 @@ static int NotebookAddCommand( Tab *tab; if (objc <= 2 || objc % 2 != 1) { - Tcl_WrongNumArgs(interp, 2, objv, "window ?options...?"); + Tcl_WrongNumArgs(interp, 2, objv, "window ?-option value ...?"); return TCL_ERROR; } @@ -890,11 +912,11 @@ static int NotebookAddCommand( return TCL_OK; } -/* $nb insert $index $tab ?options...? +/* $nb insert $index $tab ?-option value ...? * Insert new tab, or move existing one. */ static int NotebookInsertCommand( - Tcl_Interp *interp, int objc, Tcl_Obj *const objv[], void *recordPtr) + void *recordPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]) { Notebook *nb = recordPtr; int current = nb->notebook.currentIndex; @@ -902,7 +924,7 @@ static int NotebookInsertCommand( int srcIndex, destIndex; if (objc < 4) { - Tcl_WrongNumArgs(interp, 2,objv, "index slave ?options...?"); + Tcl_WrongNumArgs(interp, 2,objv, "index slave ?-option value ...?"); return TCL_ERROR; } @@ -968,7 +990,7 @@ static int NotebookInsertCommand( * Removes the specified tab. */ static int NotebookForgetCommand( - Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[], void *recordPtr) + void *recordPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]) { Notebook *nb = recordPtr; int index; @@ -992,7 +1014,7 @@ static int NotebookForgetCommand( * Hides the specified tab. */ static int NotebookHideCommand( - Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[], void *recordPtr) + void *recordPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]) { Notebook *nb = recordPtr; int index; @@ -1022,20 +1044,26 @@ static int NotebookHideCommand( * Returns name of tab element at $x,$y; empty string if none. */ static int NotebookIdentifyCommand( - Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[], void *recordPtr) + void *recordPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]) { + static const char *whatTable[] = { "element", "tab", NULL }; + enum { IDENTIFY_ELEMENT, IDENTIFY_TAB }; + int what = IDENTIFY_ELEMENT; Notebook *nb = recordPtr; - Ttk_LayoutNode *node = NULL; + Ttk_Element element = NULL; int x, y, tabIndex; - if (objc != 4) { - Tcl_WrongNumArgs(interp, 2, objv, "x y"); + if (objc < 4 || objc > 5) { + Tcl_WrongNumArgs(interp, 2,objv, "?what? x y"); return TCL_ERROR; } - if ( Tcl_GetIntFromObj(interp, objv[2], &x) != TCL_OK - || Tcl_GetIntFromObj(interp, objv[3], &y) != TCL_OK) - { + if ( Tcl_GetIntFromObj(interp, objv[objc-2], &x) != TCL_OK + || Tcl_GetIntFromObj(interp, objv[objc-1], &y) != TCL_OK + || (objc == 5 && + Tcl_GetIndexFromObj(interp, objv[2], whatTable, "option", 0, &what) + != TCL_OK) + ) { return TCL_ERROR; } @@ -1048,14 +1076,22 @@ static int NotebookIdentifyCommand( Ttk_RebindSublayout(tabLayout, tab); Ttk_PlaceLayout(tabLayout, state, tab->parcel); - node = Ttk_LayoutIdentify(tabLayout, x, y); + element = Ttk_IdentifyElement(tabLayout, x, y); } - if (node) { - const char *elementName = Ttk_LayoutNodeName(node); - Tcl_SetObjResult(interp,Tcl_NewStringObj(elementName,-1)); + switch (what) { + case IDENTIFY_ELEMENT: + if (element) { + const char *elementName = Ttk_ElementName(element); + Tcl_SetObjResult(interp,Tcl_NewStringObj(elementName,-1)); + } + break; + case IDENTIFY_TAB: + if (tabIndex >= 0) { + Tcl_SetObjResult(interp, Tcl_NewIntObj(tabIndex)); + } + break; } - return TCL_OK; } @@ -1065,7 +1101,7 @@ static int NotebookIdentifyCommand( * See above for valid item formats. */ static int NotebookIndexCommand( - Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[], void *recordPtr) + void *recordPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]) { Notebook *nb = recordPtr; int index, status; @@ -1097,7 +1133,7 @@ static int NotebookIndexCommand( * the currently-selected pane. */ static int NotebookSelectCommand( - Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[], void *recordPtr) + void *recordPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]) { Notebook *nb = recordPtr; @@ -1123,7 +1159,7 @@ static int NotebookSelectCommand( * Return list of tabs. */ static int NotebookTabsCommand( - Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[], void *recordPtr) + void *recordPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]) { Notebook *nb = recordPtr; Ttk_Manager *mgr = nb->notebook.mgr; @@ -1148,7 +1184,7 @@ static int NotebookTabsCommand( /* $nb tab $tab ?-option ?value -option value...?? */ static int NotebookTabCommand( - Tcl_Interp *interp, int objc, Tcl_Obj * CONST objv[], void *recordPtr) + void *recordPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]) { Notebook *nb = recordPtr; Ttk_Manager *mgr = nb->notebook.mgr; @@ -1192,29 +1228,28 @@ static int NotebookTabCommand( /* Subcommand table: */ -static WidgetCommandSpec NotebookCommands[] = -{ - { "add", NotebookAddCommand }, - { "configure", TtkWidgetConfigureCommand }, - { "cget", TtkWidgetCgetCommand }, - { "forget", NotebookForgetCommand }, - { "hide", NotebookHideCommand }, - { "identify", NotebookIdentifyCommand }, - { "index", NotebookIndexCommand }, - { "insert", NotebookInsertCommand }, - { "instate", TtkWidgetInstateCommand }, - { "select", NotebookSelectCommand }, - { "state", TtkWidgetStateCommand }, - { "tab", NotebookTabCommand }, - { "tabs", NotebookTabsCommand }, - { 0,0 } +static const Ttk_Ensemble NotebookCommands[] = { + { "add", NotebookAddCommand,0 }, + { "configure", TtkWidgetConfigureCommand,0 }, + { "cget", TtkWidgetCgetCommand,0 }, + { "forget", NotebookForgetCommand,0 }, + { "hide", NotebookHideCommand,0 }, + { "identify", NotebookIdentifyCommand,0 }, + { "index", NotebookIndexCommand,0 }, + { "insert", NotebookInsertCommand,0 }, + { "instate", TtkWidgetInstateCommand,0 }, + { "select", NotebookSelectCommand,0 }, + { "state", TtkWidgetStateCommand,0 }, + { "tab", NotebookTabCommand,0 }, + { "tabs", NotebookTabsCommand,0 }, + { 0,0,0 } }; /*------------------------------------------------------------------------ * +++ Widget class hooks. */ -static int NotebookInitialize(Tcl_Interp *interp, void *recordPtr) +static void NotebookInitialize(Tcl_Interp *interp, void *recordPtr) { Notebook *nb = recordPtr; @@ -1232,8 +1267,6 @@ static int NotebookInitialize(Tcl_Interp *interp, void *recordPtr) Tk_CreateEventHandler( nb->core.tkwin, NotebookEventMask, NotebookEventHandler, recordPtr); - - return TCL_OK; } static void NotebookCleanup(void *recordPtr) @@ -1367,7 +1400,7 @@ TTK_END_LAYOUT * +++ Initialization. */ -MODULE_SCOPE +MODULE_SCOPE void TtkNotebook_Init(Tcl_Interp *interp) { Ttk_Theme themePtr = Ttk_GetDefaultTheme(interp); |