summaryrefslogtreecommitdiffstats
path: root/generic/ttk/ttkNotebook.c
diff options
context:
space:
mode:
Diffstat (limited to 'generic/ttk/ttkNotebook.c')
-rw-r--r--generic/ttk/ttkNotebook.c181
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);