diff options
Diffstat (limited to 'generic/ttk/ttkLayout.c')
-rw-r--r-- | generic/ttk/ttkLayout.c | 124 |
1 files changed, 80 insertions, 44 deletions
diff --git a/generic/ttk/ttkLayout.c b/generic/ttk/ttkLayout.c index bfa10c4..a5046ed 100644 --- a/generic/ttk/ttkLayout.c +++ b/generic/ttk/ttkLayout.c @@ -5,7 +5,7 @@ * * Copyright (c) 2003 Joe English. Freely redistributable. * - * $Id: ttkLayout.c,v 1.11 2007/12/13 15:26:26 dgp Exp $ + * $Id: ttkLayout.c,v 1.11.2.1 2010/08/26 02:06:09 hobbs Exp $ */ #include <string.h> @@ -47,8 +47,6 @@ Ttk_NewBoxObj(Ttk_Box box) return Tcl_NewListObj(4, result); } - - /* * packTop, packBottom, packLeft, packRight -- * Carve out a parcel of the specified height (resp width) @@ -514,24 +512,27 @@ Tcl_Obj *Ttk_NewStickyObj(Ttk_Sticky sticky) /*------------------------------------------------------------------------ * +++ Layout nodes. */ + +typedef struct Ttk_LayoutNode_ Ttk_LayoutNode; struct Ttk_LayoutNode_ { unsigned flags; /* Packing and sticky flags */ - Ttk_ElementImpl element; /* Element implementation */ + Ttk_ElementClass *eclass; /* Class record */ Ttk_State state; /* Current state */ Ttk_Box parcel; /* allocated parcel */ Ttk_LayoutNode *next, *child; }; -static Ttk_LayoutNode *Ttk_NewLayoutNode(unsigned flags, Ttk_ElementImpl element) +static Ttk_LayoutNode *Ttk_NewLayoutNode( + unsigned flags, Ttk_ElementClass *elementClass) { - Ttk_LayoutNode *node = (Ttk_LayoutNode*)ckalloc(sizeof(Ttk_LayoutNode)); + Ttk_LayoutNode *node = (Ttk_LayoutNode*)ckalloc(sizeof(*node)); node->flags = flags; - node->element = element; + node->eclass = elementClass; node->state = 0u; node->next = node->child = 0; - /* parcel uninitialized */ + node->parcel = Ttk_MakeBox(0,0,0,0); return node; } @@ -582,8 +583,8 @@ void Ttk_FreeLayoutTemplate(Ttk_LayoutTemplate op) static Ttk_LayoutNode * Ttk_InstantiateLayout(Ttk_Theme theme, Ttk_TemplateNode *op) { - Ttk_ElementImpl elementImpl = Ttk_GetElement(theme, op->name); - Ttk_LayoutNode *node = Ttk_NewLayoutNode(op->flags, elementImpl); + Ttk_ElementClass *elementClass = Ttk_GetElement(theme, op->name); + Ttk_LayoutNode *node = Ttk_NewLayoutNode(op->flags, elementClass); if (op->next) { node->next = Ttk_InstantiateLayout(theme,op->next); @@ -611,7 +612,7 @@ Ttk_LayoutTemplate Ttk_ParseLayoutTemplate(Tcl_Interp *interp, Tcl_Obj *objPtr) { enum { OP_SIDE, OP_STICKY, OP_EXPAND, OP_BORDER, OP_UNIT, OP_CHILDREN }; static const char *optStrings[] = { - "-side", "-sticky", "-expand", "-border", "-unit", "-children", 0 }; + "-side", "-sticky", "-expand", "-border", "-unit", "-children", 0 }; int i = 0, objc; Tcl_Obj **objv; @@ -621,7 +622,7 @@ Ttk_LayoutTemplate Ttk_ParseLayoutTemplate(Tcl_Interp *interp, Tcl_Obj *objPtr) return 0; while (i < objc) { - char *elementName = Tcl_GetString(objv[i]); + const char *elementName = Tcl_GetString(objv[i]); unsigned flags = 0x0, sticky = TTK_FILL_BOTH; Tcl_Obj *childSpec = 0; @@ -735,7 +736,7 @@ Ttk_LayoutTemplate Ttk_BuildLayoutTemplate(Ttk_LayoutSpec spec) last = node; } - if (spec->opcode & _TTK_CHILDREN) { + if (spec->opcode & _TTK_CHILDREN && last) { int depth = 1; last->child = Ttk_BuildLayoutTemplate(spec+1); @@ -768,7 +769,7 @@ void Ttk_RegisterLayouts(Ttk_Theme theme, Ttk_LayoutSpec spec) } } -Tcl_Obj *Ttk_UnparseLayoutTemplate(Ttk_TemplateNode *node) +Tcl_Obj *Ttk_UnparseLayoutTemplate(Ttk_TemplateNode *node) { Tcl_Obj *result = Tcl_NewListObj(0,0); @@ -785,14 +786,14 @@ Tcl_Obj *Ttk_UnparseLayoutTemplate(Ttk_TemplateNode *node) */ if (flags & TTK_EXPAND) { APPENDSTR("-expand"); - APPENDSTR("1"); + APPENDSTR("1"); } else { if (flags & _TTK_MASK_PACK) { int side = 0; unsigned sideFlags = flags & _TTK_MASK_PACK; while ((sideFlags & TTK_PACK_LEFT) == 0) { - ++side; + ++side; sideFlags >>= 1; } APPENDSTR("-side"); @@ -872,7 +873,7 @@ Ttk_Layout Ttk_CreateLayout( Ttk_Style style = Ttk_GetStyle(themePtr, styleName); Ttk_LayoutTemplate layoutTemplate = Ttk_FindLayoutTemplate(themePtr,styleName); - Ttk_ElementImpl bgelement = Ttk_GetElement(themePtr, "background"); + Ttk_ElementClass *bgelement = Ttk_GetElement(themePtr, "background"); Ttk_LayoutNode *bgnode; if (!layoutTemplate) { @@ -891,7 +892,7 @@ Ttk_Layout Ttk_CreateLayout( * Creates a new sublayout. * * Sublayouts are used to draw subparts of a compound widget. - * They use the same Tk_Window, but a different option table + * They use the same Tk_Window, but a different option table * and data record. */ Ttk_Layout @@ -924,7 +925,7 @@ Ttk_CreateSublayout( Tcl_DStringFree(&buf); return TTKNewLayout( - style, 0, optionTable, parentLayout->tkwin, + style, 0, optionTable, parentLayout->tkwin, Ttk_InstantiateLayout(themePtr, layoutTemplate)); } @@ -947,6 +948,15 @@ Tcl_Obj *Ttk_QueryOption( layout->style,layout->recordPtr,layout->optionTable,optionName,state); } +/* + * Ttk_LayoutStyle -- + * Extract Ttk_Style from Ttk_Layout. + */ +Ttk_Style Ttk_LayoutStyle(Ttk_Layout layout) +{ + return layout->style; +} + /*------------------------------------------------------------------------ * +++ Size computation. */ @@ -961,7 +971,7 @@ static void Ttk_NodeSize( int elementWidth, elementHeight, subWidth, subHeight; Ttk_Padding elementPadding; - Ttk_ElementSize(node->element, + Ttk_ElementSize(node->eclass, layout->style, layout->recordPtr,layout->optionTable, layout->tkwin, state|node->state, &elementWidth, &elementHeight, &elementPadding); @@ -1011,7 +1021,7 @@ Ttk_Padding Ttk_LayoutNodeInternalPadding( { int unused; Ttk_Padding padding; - Ttk_ElementSize(node->element, + Ttk_ElementSize(node->eclass, layout->style, layout->recordPtr, layout->optionTable, layout->tkwin, 0/*state*/, &unused, &unused, &padding); return padding; @@ -1105,7 +1115,7 @@ static void Ttk_DrawNodeList( Ttk_DrawNodeList(layout, substate, node->child, d); Ttk_DrawElement( - node->element, + node->eclass, layout->style,layout->recordPtr,layout->optionTable,layout->tkwin, d, node->parcel, state | node->state); @@ -1124,20 +1134,18 @@ void Ttk_DrawLayout(Ttk_Layout layout, Ttk_State state, Drawable d) */ /* - * Ttk_LayoutIdentify -- - * Find the layout node at the specified x,y coordinate. + * Ttk_IdentifyElement -- + * Find the element at the specified x,y coordinate. */ -static Ttk_LayoutNode * -Ttk_LayoutNodeIdentify(Ttk_LayoutNode *node, int x, int y) +static Ttk_Element IdentifyNode(Ttk_Element node, int x, int y) { - Ttk_LayoutNode *closest = NULL; + Ttk_Element closest = NULL; for (; node; node = node->next) { if (Ttk_BoxContains(node->parcel, x, y)) { closest = node; if (node->child && !(node->flags & TTK_UNIT)) { - Ttk_LayoutNode *childNode = - Ttk_LayoutNodeIdentify(node->child, x,y); + Ttk_Element childNode = IdentifyNode(node->child, x,y); if (childNode) { closest = childNode; } @@ -1147,9 +1155,9 @@ Ttk_LayoutNodeIdentify(Ttk_LayoutNode *node, int x, int y) return closest; } -Ttk_LayoutNode *Ttk_LayoutIdentify(Ttk_Layout layout, int x, int y) +Ttk_Element Ttk_IdentifyElement(Ttk_Layout layout, int x, int y) { - return Ttk_LayoutNodeIdentify(layout->root, x, y); + return IdentifyNode(layout->root, x, y); } /* @@ -1166,19 +1174,18 @@ static const char *tail(const char *elementName) } /* - * Ttk_LayoutFindNode -- - * Look up a layout node by name. + * Ttk_FindElement -- + * Look up an element by name */ -static Ttk_LayoutNode * -Ttk_LayoutNodeFind(Ttk_LayoutNode *node, const char *nodeName) +static Ttk_Element +FindNode(Ttk_Element node, const char *nodeName) { for (; node ; node = node->next) { - if (!strcmp(tail(Ttk_LayoutNodeName(node)), nodeName)) + if (!strcmp(tail(Ttk_ElementName(node)), nodeName)) return node; if (node->child) { - Ttk_LayoutNode *childNode = - Ttk_LayoutNodeFind(node->child, nodeName); + Ttk_Element childNode = FindNode(node->child, nodeName); if (childNode) return childNode; } @@ -1186,22 +1193,48 @@ Ttk_LayoutNodeFind(Ttk_LayoutNode *node, const char *nodeName) return 0; } -Ttk_LayoutNode *Ttk_LayoutFindNode(Ttk_Layout layout, const char *nodeName) +Ttk_Element Ttk_FindElement(Ttk_Layout layout, const char *nodeName) { - return Ttk_LayoutNodeFind(layout->root, nodeName); + return FindNode(layout->root, nodeName); } -const char *Ttk_LayoutNodeName(Ttk_LayoutNode *node) +/* + * Ttk_ClientRegion -- + * Find the internal parcel of a named element within a given layout. + * If the element is not present, use the entire window. + */ +Ttk_Box Ttk_ClientRegion(Ttk_Layout layout, const char *elementName) { - return Ttk_ElementName(node->element); + Ttk_Element element = Ttk_FindElement(layout, elementName); + return element + ? Ttk_LayoutNodeInternalParcel(layout, element) + : Ttk_WinBox(layout->tkwin) + ; } -Ttk_Box Ttk_LayoutNodeParcel(Ttk_LayoutNode *node) +/* + * Ttk_ElementName -- + * Return the name (class name) of the element. + */ +const char *Ttk_ElementName(Ttk_Element node) +{ + return Ttk_ElementClassName(node->eclass); +} + +/* + * Ttk_ElementParcel -- + * Return the element's current parcel. + */ +Ttk_Box Ttk_ElementParcel(Ttk_Element node) { return node->parcel; } -void Ttk_PlaceLayoutNode(Ttk_Layout layout, Ttk_LayoutNode *node, Ttk_Box b) +/* + * Ttk_PlaceElement -- + * Explicitly specify an element's parcel. + */ +void Ttk_PlaceElement(Ttk_Layout layout, Ttk_Element node, Ttk_Box b) { node->parcel = b; if (node->child) { @@ -1210,6 +1243,9 @@ void Ttk_PlaceLayoutNode(Ttk_Layout layout, Ttk_LayoutNode *node, Ttk_Box b) } } +/* + * Ttk_ChangeElementState -- + */ void Ttk_ChangeElementState(Ttk_LayoutNode *node,unsigned set,unsigned clr) { node->state = (node->state | set) & ~clr; |