summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ChangeLog20
-rw-r--r--doc/ttk_panedwindow.n7
-rw-r--r--generic/ttk/ttkFrame.c77
-rw-r--r--generic/ttk/ttkManager.c179
-rw-r--r--generic/ttk/ttkManager.h52
-rw-r--r--generic/ttk/ttkNotebook.c177
-rw-r--r--generic/ttk/ttkPanedwindow.c240
-rw-r--r--library/ttk/panedwindow.tcl6
-rw-r--r--tests/ttk/notebook.test45
-rw-r--r--tests/ttk/panedwindow.test7
10 files changed, 460 insertions, 350 deletions
diff --git a/ChangeLog b/ChangeLog
index 0b9c768..f256389 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,23 @@
+2007-06-09 Joe English <jenglish@users.sourceforge.net>
+
+ * generic/ttk/ttkManager.h, generic/ttk/ttkManager.c,
+ generic/ttk/ttkNotebook.c, generic/ttk/ttkPanedwindow.c,
+ generic/ttk/ttkFrame.c: Ttk_Manager API overhaul:
+ + Ttk_Manager no longer responsible for managing slave records
+ + Ttk_Manager structure now opaque
+ + Ttk_Slave structure now private
+ + Pass Ttk_Manager * to Tk_GeomMgr hooks instead of Ttk_Slave *
+
+ * generic/ttk/ttkFrame.c: Simplified -labelwidget management.
+
+ * doc/ttk_panedwindow.n, library/ttk/panedwindow.tcl:
+ Changed documentation of ttk::panedwindow 'identify' command
+ to match implementation.
+
+ * generic/ttk/ttkNotebook.c, tests/ttk/notebook.test:
+ BUGFIX: ttk::noteboook 'insert' command didn't correctly
+ maintain current tab.
+
2007-06-09 Daniel Steffen <das@users.sourceforge.net>
* macosx/tkMacOSXColor.c: fix issues with TK_{IF,ELSE,ENDIF} macros;
diff --git a/doc/ttk_panedwindow.n b/doc/ttk_panedwindow.n
index d823473..4928b15 100644
--- a/doc/ttk_panedwindow.n
+++ b/doc/ttk_panedwindow.n
@@ -4,7 +4,7 @@
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
-'\" RCS: @(#) $Id: ttk_panedwindow.n,v 1.4 2007/05/03 23:55:30 dkf Exp $
+'\" RCS: @(#) $Id: ttk_panedwindow.n,v 1.5 2007/06/09 21:45:44 jenglish Exp $
'\"
.so man.macros
.TH ttk_panedwindow n 8.5 Tk "Tk Themed Widget"
@@ -82,9 +82,8 @@ If \fInewpos\fR is specified, sets the sash position
Returns the position of sash number \fIindex\fR.
.TP
\fIpathname\fR \fBidentify\fR \fIx y\fR
-Returns a list consisting of the sash index at point \fIx,y\fR
-and the name of the sash subelement at that point.
-Returns the empty list if \fIx,y\fR is not over a sash.
+Returns the index of the sash at point \fIx,y\fR,
+or the empty string if \fIx,y\fR is not over a sash.
.SH "SEE ALSO"
ttk_widget(n), ttk_notebook(n), panedwindow(n)
diff --git a/generic/ttk/ttkFrame.c b/generic/ttk/ttkFrame.c
index ee5259f..08f1f7f 100644
--- a/generic/ttk/ttkFrame.c
+++ b/generic/ttk/ttkFrame.c
@@ -1,4 +1,4 @@
-/* $Id: ttkFrame.c,v 1.5 2007/01/11 14:49:47 jenglish Exp $
+/* $Id: ttkFrame.c,v 1.6 2007/06/09 21:45:44 jenglish Exp $
* Copyright (c) 2004, Joe English
*
* ttk::frame and ttk::labelframe widgets.
@@ -234,10 +234,9 @@ typedef struct {
Tcl_Obj *labelAnchorObj;
Tcl_Obj *textObj;
Tcl_Obj *underlineObj;
- Tcl_Obj *labelWidgetObj;
+ Tk_Window labelWidget;
Ttk_Manager *mgr;
- Tk_Window labelWidget; /* Set in configureProc */
Ttk_Box labelParcel; /* Set in layoutProc */
} LabelframePart;
@@ -262,7 +261,7 @@ static Tk_OptionSpec LabelframeOptionSpecs[] =
"-1", Tk_Offset(Labelframe,label.underlineObj), -1,
0,0,0 },
{TK_OPTION_WINDOW, "-labelwidget", "labelWidget", "LabelWidget", NULL,
- Tk_Offset(Labelframe,label.labelWidgetObj), -1,
+ -1, Tk_Offset(Labelframe,label.labelWidget),
TK_OPTION_NULL_OK,0,LABELWIDGET_CHANGED|GEOMETRY_CHANGED },
WIDGET_INHERIT_OPTIONS(FrameOptionSpecs)
@@ -454,47 +453,26 @@ static void LabelframePlaceSlaves(void *recordPtr)
/* Labelframe geometry manager:
*/
-static void LabelAdded(Ttk_Manager *mgr, int slaveIndex) { /* no-op */ }
-static void LabelRemoved(Ttk_Manager *mgr, int slaveIndex) { /* no-op */ }
-static int LabelConfigured(
- Tcl_Interp *interp, Ttk_Manager *mgr, Ttk_Slave *slave, unsigned mask)
- { return TCL_OK; }
-
-/* LabelframeLostSlave --
- * Called when the labelWidget slave is involuntarily lost;
- * unset the -labelwidget option.
- * Notes:
- * Do this here instead of in the SlaveRemoved hook,
- * since the latter is also called when the widget voluntarily
- * forgets the slave. The latter happens in the ConfigureProc
- * at a time when the widget is in an inconsistent state.
+
+/* LabelRemoved --
+ * Unset the -labelwidget option.
+ *
+ * <<NOTE-LABELREMOVED>>:
+ * This routine is also called when the widget voluntarily forgets
+ * the slave in LabelframeConfigure.
*/
-static void LabelframeLostSlave(ClientData clientData, Tk_Window slaveWindow)
+static void LabelRemoved(Ttk_Manager *mgr, int slaveIndex)
{
- Ttk_Slave *slave = clientData;
- Labelframe *lframePtr = slave->manager->managerData;
-
- Tcl_DecrRefCount(lframePtr->label.labelWidgetObj);
- lframePtr->label.labelWidgetObj = 0;
- lframePtr->label.labelWidget = 0;
- Ttk_LostSlaveProc(clientData, slaveWindow);
+ Labelframe *lframe = Ttk_ManagerData(mgr);
+ lframe->label.labelWidget = 0;
}
-static Tk_OptionSpec LabelOptionSpecs[] = {
- {TK_OPTION_END, 0,0,0, NULL, -1,-1, 0, 0,0}
-};
-
static Ttk_ManagerSpec LabelframeManagerSpec =
{
- { "labelframe", Ttk_GeometryRequestProc, LabelframeLostSlave },
- LabelOptionSpecs, 0,
-
+ { "labelframe", Ttk_GeometryRequestProc, Ttk_LostSlaveProc },
LabelframeSize,
LabelframePlaceSlaves,
-
- LabelAdded,
- LabelRemoved,
- LabelConfigured
+ LabelRemoved
};
/* LabelframeInitialize --
@@ -546,22 +524,14 @@ static void RaiseLabelWidget(Labelframe *lframe)
static int LabelframeConfigure(Tcl_Interp *interp,void *recordPtr,int mask)
{
Labelframe *lframePtr = recordPtr;
- Tk_Window labelWidget = NULL;
+ Tk_Window labelWidget = lframePtr->label.labelWidget;
Ttk_PositionSpec unused;
- /* Validate -labelwidget option:
+ /* Validate options:
*/
- if (lframePtr->label.labelWidgetObj) {
- const char *pathName = Tcl_GetString(lframePtr->label.labelWidgetObj);
- if (pathName && *pathName) {
- labelWidget =
- Tk_NameToWindow(interp, pathName, lframePtr->core.tkwin);
- if (!labelWidget) {
- return TCL_ERROR;
- }
- if (!Ttk_Maintainable(interp, labelWidget, lframePtr->core.tkwin)) {
- return TCL_ERROR;
- }
+ if (mask & LABELWIDGET_CHANGED && labelWidget != NULL) {
+ if (!Ttk_Maintainable(interp, labelWidget, lframePtr->core.tkwin)) {
+ return TCL_ERROR;
}
}
@@ -582,12 +552,13 @@ static int LabelframeConfigure(Tcl_Interp *interp,void *recordPtr,int mask)
if (mask & LABELWIDGET_CHANGED) {
if (Ttk_NumberSlaves(lframePtr->label.mgr) == 1) {
Ttk_ForgetSlave(lframePtr->label.mgr, 0);
+ /* Restore labelWidget field (see <<NOTE-LABELREMOVED>>)
+ */
+ lframePtr->label.labelWidget = labelWidget;
}
- lframePtr->label.labelWidget = labelWidget;
-
if (labelWidget) {
- Ttk_AddSlave(interp, lframePtr->label.mgr, labelWidget, 0, 0,0);
+ Ttk_InsertSlave(lframePtr->label.mgr, 0, labelWidget, NULL);
RaiseLabelWidget(lframePtr);
}
}
diff --git a/generic/ttk/ttkManager.c b/generic/ttk/ttkManager.c
index 319e465..3c9d51c 100644
--- a/generic/ttk/ttkManager.c
+++ b/generic/ttk/ttkManager.c
@@ -1,8 +1,8 @@
-/* $Id: ttkManager.c,v 1.3 2007/01/11 19:59:26 jenglish Exp $
+/* $Id: ttkManager.c,v 1.4 2007/06/09 21:45:44 jenglish Exp $
*
* Copyright 2005, Joe English. Freely redistributable.
*
- * Ttk widget set: support routines for geometry managers.
+ * Support routines for geometry managers.
*/
#include <string.h>
@@ -41,19 +41,38 @@
* in this case Tk does _not_ call the LostSlaveProc (documented behavior).
* Tk doesn't handle case (3) either; to account for that we
* register an event handler on the slave widget to track <Destroy> events.
- *
*/
-/* ++ manager->flags bits:
+/* ++ Data structures.
*/
-#define MGR_UPDATE_PENDING 0x1
-#define MGR_RESIZE_REQUIRED 0x2
-#define MGR_RELAYOUT_REQUIRED 0x4
+typedef struct
+{
+ Tk_Window slaveWindow;
+ Ttk_Manager *manager;
+ void *slaveData;
+ unsigned flags;
+} Ttk_Slave;
-/* ++ slave->flags bits:
+/* slave->flags bits:
*/
#define SLAVE_MAPPED 0x1 /* slave to be mapped when master is */
+struct TtkManager_
+{
+ Ttk_ManagerSpec *managerSpec;
+ void *managerData;
+ Tk_Window masterWindow;
+ unsigned flags;
+ int nSlaves;
+ Ttk_Slave **slaves;
+};
+
+/* manager->flags bits:
+ */
+#define MGR_UPDATE_PENDING 0x1
+#define MGR_RESIZE_REQUIRED 0x2
+#define MGR_RELAYOUT_REQUIRED 0x4
+
static void ManagerIdleProc(void *); /* forward */
/* ++ ScheduleUpdate --
@@ -103,7 +122,7 @@ static void ManagerIdleProc(ClientData clientData)
if (mgr->flags & MGR_RESIZE_REQUIRED) {
RecomputeSize(mgr);
- }
+ }
if (mgr->flags & MGR_RELAYOUT_REQUIRED) {
if (mgr->flags & MGR_UPDATE_PENDING) {
/* RecomputeSize has scheduled another update; relayout later */
@@ -127,7 +146,7 @@ static void ManagerEventHandler(ClientData clientData, XEvent *eventPtr)
Ttk_Manager *mgr = clientData;
int i;
- switch (eventPtr->type)
+ switch (eventPtr->type)
{
case ConfigureNotify:
RecomputeLayout(mgr);
@@ -159,7 +178,7 @@ static void SlaveEventHandler(ClientData clientData, XEvent *eventPtr)
Ttk_Slave *slave = clientData;
if (eventPtr->type == DestroyNotify) {
slave->manager->managerSpec->tkGeomMgr.lostSlaveProc(
- clientData, slave->slaveWindow);
+ slave->manager, slave->slaveWindow);
}
}
@@ -167,40 +186,21 @@ static void SlaveEventHandler(ClientData clientData, XEvent *eventPtr)
* +++ Slave initialization and cleanup.
*/
-static Ttk_Slave *CreateSlave(
- Tcl_Interp *interp, Ttk_Manager *mgr, Tk_Window slaveWindow)
+static Ttk_Slave *NewSlave(
+ Ttk_Manager *mgr, Tk_Window slaveWindow, void *slaveData)
{
Ttk_Slave *slave = (Ttk_Slave*)ckalloc(sizeof(*slave));
- int status;
slave->slaveWindow = slaveWindow;
slave->manager = mgr;
slave->flags = 0;
- slave->slaveData = ckalloc(mgr->managerSpec->slaveSize);
- memset(slave->slaveData, 0, mgr->managerSpec->slaveSize);
-
- if (!mgr->slaveOptionTable) {
- mgr->slaveOptionTable =
- Tk_CreateOptionTable(interp, mgr->managerSpec->slaveOptionSpecs);
- }
-
- status = Tk_InitOptions(
- interp, slave->slaveData, mgr->slaveOptionTable, slaveWindow);
-
- if (status != TCL_OK) {
- ckfree((ClientData)slave->slaveData);
- ckfree((ClientData)slave);
- return NULL;
- }
+ slave->slaveData = slaveData;
return slave;
}
static void DeleteSlave(Ttk_Slave *slave)
{
- Tk_FreeConfigOptions(
- slave->slaveData, slave->manager->slaveOptionTable, slave->slaveWindow);
- ckfree((ClientData)slave->slaveData);
ckfree((ClientData)slave);
}
@@ -216,7 +216,6 @@ Ttk_Manager *Ttk_CreateManager(
mgr->managerSpec = managerSpec;
mgr->managerData = managerData;
mgr->masterWindow = masterWindow;
- mgr->slaveOptionTable= 0;
mgr->nSlaves = 0;
mgr->slaves = NULL;
mgr->flags = 0;
@@ -238,9 +237,6 @@ void Ttk_DeleteManager(Ttk_Manager *mgr)
if (mgr->slaves) {
ckfree((ClientData)mgr->slaves);
}
- if (mgr->slaveOptionTable) {
- Tk_DeleteOptionTable(mgr->slaveOptionTable);
- }
Tk_CancelIdleCall(ManagerIdleProc, mgr);
@@ -268,7 +264,7 @@ static void InsertSlave(Ttk_Manager *mgr, Ttk_Slave *slave, int index)
mgr->slaves[index] = slave;
Tk_ManageGeometry(slave->slaveWindow,
- &mgr->managerSpec->tkGeomMgr, (ClientData)slave);
+ &mgr->managerSpec->tkGeomMgr, (ClientData)mgr);
Tk_CreateEventHandler(slave->slaveWindow,
SlaveEventMask, SlaveEventHandler, (ClientData)slave);
@@ -281,7 +277,7 @@ static void InsertSlave(Ttk_Manager *mgr, Ttk_Slave *slave, int index)
*
* NOTES/ASSUMPTIONS:
*
- * [1] It's safe to call Tk_UnmapWindow / Tk_UnmaintainGeometry even if this
+ * [1] It's safe to call Tk_UnmapWindow / Tk_UnmaintainGeometry even if this
* routine is called from the slave's DestroyNotify event handler.
*/
static void RemoveSlave(Ttk_Manager *mgr, int index)
@@ -320,85 +316,31 @@ static void RemoveSlave(Ttk_Manager *mgr, int index)
void Ttk_GeometryRequestProc(ClientData clientData, Tk_Window slaveWindow)
{
- Ttk_Slave *slave = clientData;
- ScheduleUpdate(slave->manager, MGR_RESIZE_REQUIRED);
+ Ttk_Manager *mgr = clientData;
+ ScheduleUpdate(mgr, MGR_RESIZE_REQUIRED);
}
void Ttk_LostSlaveProc(ClientData clientData, Tk_Window slaveWindow)
{
- Ttk_Slave *slave = clientData;
- int index = Ttk_SlaveIndex(slave->manager, slave->slaveWindow);
+ Ttk_Manager *mgr = clientData;
+ int index = Ttk_SlaveIndex(mgr, slaveWindow);
/* ASSERT: index >= 0 */
- RemoveSlave(slave->manager, index);
+ RemoveSlave(mgr, index);
}
/*------------------------------------------------------------------------
* +++ Public API.
*/
-/* ++ Ttk_AddSlave --
- * Create and configure new slave window, insert at specified index.
- *
- * Returns:
- * TCL_OK or TCL_ERROR; in the case of TCL_ERROR, the slave
- * is not added and an error message is left in interp.
+/* ++ Ttk_InsertSlave --
+ * Add a new slave window at the specified index.
*/
-int Ttk_AddSlave(
- Tcl_Interp *interp, Ttk_Manager *mgr, Tk_Window slaveWindow,
- int index, int objc, Tcl_Obj *CONST objv[])
+void Ttk_InsertSlave(
+ Ttk_Manager *mgr, int index, Tk_Window tkwin, void *slaveData)
{
- Ttk_Slave *slave;
-
- /* Sanity-checks:
- */
- if (!Ttk_Maintainable(interp, slaveWindow, mgr->masterWindow)) {
- return TCL_ERROR;
- }
- if (Ttk_SlaveIndex(mgr, slaveWindow) >= 0) {
- Tcl_AppendResult(interp,
- Tk_PathName(slaveWindow), " already added",
- NULL);
- return TCL_ERROR;
- }
-
- /* Create, configure, and insert slave:
- */
- slave = CreateSlave(interp, mgr, slaveWindow);
- if (Ttk_ConfigureSlave(interp, mgr, slave, objc, objv) != TCL_OK) {
- DeleteSlave(slave);
- return TCL_ERROR;
- }
+ Ttk_Slave *slave = NewSlave(mgr, tkwin, slaveData);
InsertSlave(mgr, slave, index);
- mgr->managerSpec->SlaveAdded(mgr, index);
- return TCL_OK;
-}
-
-/* ++ Ttk_ConfigureSlave --
- */
-int Ttk_ConfigureSlave(
- Tcl_Interp *interp, Ttk_Manager *mgr, Ttk_Slave *slave,
- int objc, Tcl_Obj *CONST objv[])
-{
- Tk_SavedOptions savedOptions;
- int mask = 0;
-
- /* ASSERT: mgr->slaveOptionTable != NULL */
-
- if (Tk_SetOptions(interp, slave->slaveData, mgr->slaveOptionTable,
- objc, objv, slave->slaveWindow, &savedOptions, &mask) != TCL_OK)
- {
- return TCL_ERROR;
- }
-
- if (mgr->managerSpec->SlaveConfigured(interp,mgr,slave,mask) != TCL_OK) {
- Tk_RestoreSavedOptions(&savedOptions);
- return TCL_ERROR;
- }
-
- Tk_FreeSavedOptions(&savedOptions);
- ScheduleUpdate(mgr, MGR_RELAYOUT_REQUIRED);
- return TCL_OK;
}
/* ++ Ttk_ForgetSlave --
@@ -437,7 +379,7 @@ void Ttk_UnmapSlave(Ttk_Manager *mgr, int slaveIndex)
Ttk_Slave *slave = mgr->slaves[slaveIndex];
Tk_UnmaintainGeometry(slave->slaveWindow, mgr->masterWindow);
slave->flags &= ~SLAVE_MAPPED;
- /* Contrary to documentation, Tk_UnmaintainGeometry doesn't always
+ /* Contrary to documentation, Tk_UnmaintainGeometry doesn't always
* unmap the slave:
*/
Tk_UnmapWindow(slave->slaveWindow);
@@ -458,9 +400,13 @@ void Ttk_ManagerSizeChanged(Ttk_Manager *mgr)
/* +++ Accessors.
*/
-int Ttk_NumberSlaves(Ttk_Manager *mgr)
+int Ttk_NumberSlaves(Ttk_Manager *mgr)
{
- return mgr->nSlaves;
+ return mgr->nSlaves;
+}
+void *Ttk_ManagerData(Ttk_Manager *mgr)
+{
+ return mgr->managerData;
}
void *Ttk_SlaveData(Ttk_Manager *mgr, int slaveIndex)
{
@@ -487,17 +433,16 @@ int Ttk_SlaveIndex(Ttk_Manager *mgr, Tk_Window slaveWindow)
return -1;
}
-/* ++ Ttk_GetSlaveFromObj(interp, mgr, objPtr, indexPtr) --
+/* ++ Ttk_GetSlaveIndexFromObj(interp, mgr, objPtr, indexPtr) --
* Return the index of the slave specified by objPtr.
* Slaves may be specified as an integer index or
* as the name of the managed window.
*
* Returns:
- * Pointer to slave; stores slave index in *indexPtr.
- * On error, returns NULL and leaves an error message in interp.
+ * Standard Tcl completion code. Leaves an error message in case of error.
*/
-Ttk_Slave *Ttk_GetSlaveFromObj(
+int Ttk_GetSlaveIndexFromObj(
Tcl_Interp *interp, Ttk_Manager *mgr, Tcl_Obj *objPtr, int *indexPtr)
{
const char *string = Tcl_GetString(objPtr);
@@ -512,10 +457,10 @@ Ttk_Slave *Ttk_GetSlaveFromObj(
Tcl_AppendResult(interp,
"Slave index ", Tcl_GetString(objPtr), " out of bounds",
NULL);
- return NULL;
+ return TCL_ERROR;
}
*indexPtr = slaveIndex;
- return mgr->slaves[slaveIndex];
+ return TCL_OK;
}
/* Try interpreting as a slave window name;
@@ -529,15 +474,15 @@ Ttk_Slave *Ttk_GetSlaveFromObj(
Tcl_AppendResult(interp,
string, " is not managed by ", Tk_PathName(mgr->masterWindow),
NULL);
- return NULL;
+ return TCL_ERROR;
}
*indexPtr = slaveIndex;
- return mgr->slaves[slaveIndex];
+ return TCL_OK;
}
Tcl_ResetResult(interp);
Tcl_AppendResult(interp, "Invalid slave specification ", string, NULL);
- return NULL;
+ return TCL_ERROR;
}
/* ++ Ttk_ReorderSlave(mgr, fromIndex, toIndex) --
@@ -569,7 +514,7 @@ void Ttk_ReorderSlave(Ttk_Manager *mgr, int fromIndex, int toIndex)
/* ++ Ttk_Maintainable(interp, slave, master) --
* Utility routine. Verifies that 'master' may be used to maintain
* the geometry of 'slave' via Tk_MaintainGeometry:
- *
+ *
* + 'master' is either 'slave's parent -OR-
* + 'master is a descendant of 'slave's parent.
* + 'slave' is not a toplevel window
@@ -596,7 +541,7 @@ int Ttk_Maintainable(Tcl_Interp *interp, Tk_Window slave, Tk_Window master)
return 1;
badWindow:
- Tcl_AppendResult(interp,
+ Tcl_AppendResult(interp,
"can't add ", Tk_PathName(slave),
" as slave of ", Tk_PathName(master),
NULL);
diff --git a/generic/ttk/ttkManager.h b/generic/ttk/ttkManager.h
index c03c3da..550fe62 100644
--- a/generic/ttk/ttkManager.h
+++ b/generic/ttk/ttkManager.h
@@ -1,10 +1,8 @@
-/* $Id: ttkManager.h,v 1.5 2007/01/11 14:49:47 jenglish Exp $
+/* $Id: ttkManager.h,v 1.6 2007/06/09 21:45:44 jenglish Exp $
*
* Copyright (c) 2005, Joe English. Freely redistributable.
*
- * Ttk widget set: Geometry management utilities.
- *
- * TODO: opacify data structures.
+ * Geometry manager utilities.
*/
#ifndef _TTKMANAGER
@@ -12,8 +10,7 @@
#include "ttkTheme.h"
-typedef struct TtkManager_ Ttk_Manager; /* forward */
-typedef struct TtkSlave_ Ttk_Slave; /* forward */
+typedef struct TtkManager_ Ttk_Manager;
/*
* Geometry manager specification record:
@@ -23,24 +20,16 @@ typedef struct TtkSlave_ Ttk_Slave; /* forward */
* PlaceSlaves sets the position and size of all managed slaves
* by calling Ttk_PlaceSlave().
*
- * SlaveAdded() is called after a new slave has been added.
- *
* SlaveRemoved() is called immediately before a slave is removed.
* NB: the associated slave window may have been destroyed when this
* routine is called.
*/
typedef struct { /* Manager hooks */
Tk_GeomMgr tkGeomMgr; /* "real" Tk Geometry Manager */
- Tk_OptionSpec *slaveOptionSpecs; /* slave record options */
- size_t slaveSize; /* size of slave record */
int (*RequestedSize)(void *managerData, int *widthPtr, int *heightPtr);
void (*PlaceSlaves)(void *managerData);
-
- void (*SlaveAdded)(Ttk_Manager *, int slaveIndex);
void (*SlaveRemoved)(Ttk_Manager *, int slaveIndex);
- int (*SlaveConfigured)(
- Tcl_Interp *, Ttk_Manager *, Ttk_Slave *, unsigned mask);
} Ttk_ManagerSpec;
/*
@@ -49,25 +38,6 @@ typedef struct { /* Manager hooks */
MODULE_SCOPE void Ttk_GeometryRequestProc(ClientData, Tk_Window slave);
MODULE_SCOPE void Ttk_LostSlaveProc(ClientData, Tk_Window slave);
-struct TtkSlave_
-{
- Tk_Window slaveWindow;
- Ttk_Manager *manager;
- void *slaveData;
- unsigned flags; /* private; see manager.c */
-};
-
-struct TtkManager_
-{
- Ttk_ManagerSpec *managerSpec;
- void *managerData;
- Tk_Window masterWindow;
- Tk_OptionTable slaveOptionTable;
- unsigned flags; /* private; see manager.c */
- int nSlaves;
- Ttk_Slave **slaves;
-};
-
/*
* Public API:
*/
@@ -75,16 +45,11 @@ MODULE_SCOPE Ttk_Manager *Ttk_CreateManager(
Ttk_ManagerSpec *, void *managerData, Tk_Window masterWindow);
MODULE_SCOPE void Ttk_DeleteManager(Ttk_Manager *);
-MODULE_SCOPE int Ttk_AddSlave(
- Tcl_Interp *, Ttk_Manager *, Tk_Window, int position,
- int objc, Tcl_Obj *CONST objv[]);
+MODULE_SCOPE void Ttk_InsertSlave(
+ Ttk_Manager *, int position, Tk_Window, void *slaveData);
MODULE_SCOPE void Ttk_ForgetSlave(Ttk_Manager *, int slaveIndex);
-MODULE_SCOPE int Ttk_ConfigureSlave(
- Tcl_Interp *interp, Ttk_Manager *, Ttk_Slave *,
- int objc, Tcl_Obj *CONST objv[]);
-
MODULE_SCOPE void Ttk_ReorderSlave(Ttk_Manager *, int fromIndex, int toIndex);
/* Rearrange slave positions */
@@ -104,7 +69,7 @@ MODULE_SCOPE void Ttk_ManagerLayoutChanged(Ttk_Manager *);
MODULE_SCOPE int Ttk_SlaveIndex(Ttk_Manager *, Tk_Window);
/* Returns: index in slave array of specified window, -1 if not found */
-MODULE_SCOPE Ttk_Slave *Ttk_GetSlaveFromObj(
+MODULE_SCOPE int Ttk_GetSlaveIndexFromObj(
Tcl_Interp *, Ttk_Manager *, Tcl_Obj *, int *indexPtr);
/* Accessor functions:
@@ -112,8 +77,11 @@ MODULE_SCOPE Ttk_Slave *Ttk_GetSlaveFromObj(
MODULE_SCOPE int Ttk_NumberSlaves(Ttk_Manager *);
/* Returns: number of managed slaves */
+MODULE_SCOPE void *Ttk_ManagerData(Ttk_Manager *);
+ /* Returns: client data associated with master */
+
MODULE_SCOPE void *Ttk_SlaveData(Ttk_Manager *, int slaveIndex);
- /* Returns: private data associated with slave */
+ /* Returns: client data associated with slave */
MODULE_SCOPE Tk_Window Ttk_SlaveWindow(Ttk_Manager *, int slaveIndex);
/* Returns: slave window */
diff --git a/generic/ttk/ttkNotebook.c b/generic/ttk/ttkNotebook.c
index a9596b9..a90f465 100644
--- a/generic/ttk/ttkNotebook.c
+++ b/generic/ttk/ttkNotebook.c
@@ -1,4 +1,4 @@
-/* $Id: ttkNotebook.c,v 1.8 2007/01/11 19:59:26 jenglish Exp $
+/* $Id: ttkNotebook.c,v 1.9 2007/06/09 21:45:44 jenglish Exp $
* Copyright (c) 2004, Joe English
*
* NOTE-ACTIVE: activeTabIndex is not always correct (it's
@@ -188,6 +188,67 @@ static void NotebookStyleOptions(Notebook *nb, NotebookStyle *nbstyle)
* +++ Tab management.
*/
+static Tab *CreateTab(Tcl_Interp *interp, Notebook *nb, Tk_Window slaveWindow)
+{
+ Tk_OptionTable optionTable = nb->notebook.paneOptionTable;
+ void *record = ckalloc(sizeof(Tab));
+ memset(record, 0, sizeof(Tab));
+
+ if (Tk_InitOptions(interp, record, optionTable, slaveWindow) != TCL_OK) {
+ ckfree(record);
+ return NULL;
+ }
+
+ return record;
+}
+
+static void DestroyTab(Notebook *nb, Tab *tab)
+{
+ void *record = tab;
+ Tk_FreeConfigOptions(record, nb->notebook.paneOptionTable, nb->core.tkwin);
+ ckfree(record);
+}
+
+static int ConfigureTab(
+ Tcl_Interp *interp, Notebook *nb, Tab *tab, Tk_Window slaveWindow,
+ int objc, Tcl_Obj *CONST objv[])
+{
+ Ttk_Sticky sticky = tab->sticky;
+ Ttk_Padding padding = tab->padding;
+ Tk_SavedOptions savedOptions;
+ int mask = 0;
+
+ if (Tk_SetOptions(interp, (ClientData)tab, nb->notebook.paneOptionTable,
+ objc, objv, slaveWindow, &savedOptions, &mask) != TCL_OK)
+ {
+ return TCL_ERROR;
+ }
+
+ /* Check options:
+ * @@@ TODO: validate -image option.
+ */
+ if (Ttk_GetStickyFromObj(interp, tab->stickyObj, &sticky) != TCL_OK)
+ {
+ goto error;
+ }
+ if (Ttk_GetPaddingFromObj(interp, slaveWindow, tab->paddingObj, &padding)
+ != TCL_OK)
+ {
+ goto error;
+ }
+
+ tab->sticky = sticky;
+ tab->padding = padding;
+
+ Tk_FreeSavedOptions(&savedOptions);
+ Ttk_ManagerSizeChanged(nb->notebook.mgr);
+
+ return TCL_OK;
+error:
+ Tk_RestoreSavedOptions(&savedOptions);
+ return TCL_ERROR;
+}
+
/*
* IdentifyTab --
* Return the index of the tab at point x,y,
@@ -605,17 +666,14 @@ static void SelectNearestTab(Notebook *nb)
}
}
-/* TabAdded -- GM SlaveAdded hook.
- */
-static void TabAdded(Ttk_Manager *mgr, int slaveIndex) { /* No-op */ }
-
/* TabRemoved -- GM SlaveRemoved hook.
* Select the next tab if the current one is being removed.
- * Adjust currentIndex to account for removed slave if needed.
+ * Adjust currentIndex to account for removed slave.
*/
static void TabRemoved(Ttk_Manager *mgr, int index)
{
- Notebook *nb = mgr->managerData;
+ Notebook *nb = Ttk_ManagerData(mgr);
+ Tab *tab = Ttk_SlaveData(mgr, index);
if (index == nb->notebook.currentIndex) {
SelectNearestTab(nb);
@@ -625,44 +683,49 @@ static void TabRemoved(Ttk_Manager *mgr, int index)
--nb->notebook.currentIndex;
}
+ DestroyTab(nb, tab);
+
TtkRedisplayWidget(&nb->core);
}
-/* TabConfigured -- GM slaveConfigured hook.
- */
-static int TabConfigured(
- Tcl_Interp *interp, Ttk_Manager *mgr, Ttk_Slave *slave, unsigned mask)
+
+static int AddTab(
+ Tcl_Interp *interp, Notebook *nb,
+ int destIndex, Tk_Window slaveWindow,
+ int objc, Tcl_Obj *const objv[])
{
- Tab *tab = slave->slaveData;
- Ttk_Sticky sticky = tab->sticky;
- Tk_Window tkwin = mgr->masterWindow;
+ Tab *tab;
+ if (!Ttk_Maintainable(interp, slaveWindow, nb->core.tkwin)) {
+ return TCL_ERROR;
+ }
+ if (Ttk_SlaveIndex(nb->notebook.mgr, slaveWindow) >= 0) {
+ Tcl_AppendResult(interp,
+ Tk_PathName(slaveWindow), " already added",
+ NULL);
+ return TCL_ERROR;
+ }
- /* Check options:
- * @@@ TODO: validate -image option.
+ /* Create and insert tab.
*/
- if (Ttk_GetStickyFromObj(interp, tab->stickyObj, &sticky) != TCL_OK) {
+ tab = CreateTab(interp, nb, slaveWindow);
+ if (!tab) {
return TCL_ERROR;
}
- if (Ttk_GetPaddingFromObj(interp,tkwin,tab->paddingObj,&tab->padding)
- != TCL_OK)
- {
+ if (ConfigureTab(interp, nb, tab, slaveWindow, objc, objv) != TCL_OK) {
+ DestroyTab(nb, tab);
return TCL_ERROR;
}
- tab->sticky = sticky;
+ Ttk_InsertSlave(nb->notebook.mgr, destIndex, slaveWindow, tab);
return TCL_OK;
}
static Ttk_ManagerSpec NotebookManagerSpec =
{
{ "notebook", Ttk_GeometryRequestProc, Ttk_LostSlaveProc },
- PaneOptionSpecs, sizeof(Tab),
-
NotebookSize,
NotebookPlaceSlaves,
- TabAdded,
TabRemoved,
- TabConfigured
};
/*------------------------------------------------------------------------
@@ -736,13 +799,13 @@ static int FindTabIndex(
/* ... or integer index or slave window name:
*/
- if (Ttk_GetSlaveFromObj(
- interp, nb->notebook.mgr, objPtr, index_rtn) != NULL)
+ if (Ttk_GetSlaveIndexFromObj(
+ interp, nb->notebook.mgr, objPtr, index_rtn) == TCL_OK)
{
return TCL_OK;
}
- /* Nothing matched; Ttk_GetSlaveFromObj will have left error message.
+ /* Nothing matched; Ttk_GetSlaveIndexFromObj will have left error message.
*/
return TCL_ERROR;
}
@@ -777,7 +840,7 @@ static int NotebookAddCommand(
Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[], void *recordPtr)
{
Notebook *nb = recordPtr;
- int index = nb->notebook.mgr->nSlaves;
+ int index = Ttk_NumberSlaves(nb->notebook.mgr);
Tk_Window slaveWindow;
if (objc <= 2 || objc % 2 != 1) {
@@ -792,10 +855,8 @@ static int NotebookAddCommand(
/* Create and initialize new tab:
*/
- if (TCL_OK != Ttk_AddSlave(
- interp, nb->notebook.mgr, slaveWindow, index, objc-3,objv+3) )
- {
- return TCL_ERROR;
+ if (AddTab(interp, nb, index, slaveWindow, objc-3,objv+3) != TCL_OK) {
+ return TCL_ERROR;
}
/* If no tab is currently selected (or if this is the first tab),
@@ -818,6 +879,7 @@ static int NotebookInsertCommand(
{
Notebook *nb = recordPtr;
int current = nb->notebook.currentIndex;
+ int nSlaves = Ttk_NumberSlaves(nb->notebook.mgr);
int srcIndex, destIndex;
int status = TCL_OK;
@@ -828,26 +890,28 @@ static int NotebookInsertCommand(
if (!strcmp(Tcl_GetString(objv[2]), "end")) {
destIndex = Ttk_NumberSlaves(nb->notebook.mgr);
- } else if (!Ttk_GetSlaveFromObj(
+ } else if (TCL_OK != Ttk_GetSlaveIndexFromObj(
interp, nb->notebook.mgr, objv[2], &destIndex)) {
return TCL_ERROR;
}
- if (!Ttk_GetSlaveFromObj(interp, nb->notebook.mgr, objv[3], &srcIndex)) {
+ if (TCL_OK != Ttk_GetSlaveIndexFromObj(
+ interp, nb->notebook.mgr, objv[3], &srcIndex))
+ {
/* Try adding new slave:
*/
Tk_Window slaveWindow =
Tk_NameToWindow(interp,Tcl_GetString(objv[3]),nb->core.tkwin);
+
+ /* Check validity.
+ */
if (!slaveWindow) {
return TCL_ERROR;
}
-
- if (Ttk_AddSlave(interp, nb->notebook.mgr, slaveWindow,
- destIndex, objc - 4, objv + 4) != TCL_OK)
- {
+ if (TCL_OK != AddTab(interp,nb,destIndex,slaveWindow,objc-4,objv+4)) {
return TCL_ERROR;
}
- if (nb->notebook.currentIndex <= destIndex) {
+ if (nb->notebook.currentIndex >= destIndex) {
++nb->notebook.currentIndex;
}
return TCL_OK;
@@ -855,8 +919,8 @@ static int NotebookInsertCommand(
/* else - move existing slave: */
- if (destIndex >= nb->notebook.mgr->nSlaves) {
- destIndex = nb->notebook.mgr->nSlaves - 1;
+ if (destIndex >= nSlaves) {
+ destIndex = nSlaves - 1;
}
Ttk_ReorderSlave(nb->notebook.mgr, srcIndex, destIndex);
@@ -872,8 +936,10 @@ static int NotebookInsertCommand(
}
if (objc > 4) {
- status = Ttk_ConfigureSlave(interp, nb->notebook.mgr,
- nb->notebook.mgr->slaves[destIndex], objc-4,objv+4);
+ status = ConfigureTab(interp, nb,
+ Ttk_SlaveData(nb->notebook.mgr,destIndex),
+ Ttk_SlaveWindow(nb->notebook.mgr,destIndex),
+ objc-4,objv+4);
}
TtkRedisplayWidget(&nb->core);
@@ -934,7 +1000,7 @@ static int NotebookIdentifyCommand(
Ttk_RebindSublayout(tabLayout, tab);
Ttk_PlaceLayout(tabLayout, state, tab->parcel);
- node = Ttk_LayoutIdentify(tabLayout, x, y);
+ node = Ttk_LayoutIdentify(tabLayout, x, y);
}
if (node) {
@@ -965,7 +1031,8 @@ static int NotebookIndexCommand(
* Special-case for "end":
*/
if (!strcmp("end", Tcl_GetString(objv[2]))) {
- Tcl_SetObjResult(interp, Tcl_NewIntObj(nb->notebook.mgr->nSlaves));
+ int nSlaves = Ttk_NumberSlaves(nb->notebook.mgr);
+ Tcl_SetObjResult(interp, Tcl_NewIntObj(nSlaves));
return TCL_OK;
}
@@ -1021,7 +1088,7 @@ static int NotebookTabsCommand(
}
result = Tcl_NewListObj(0, NULL);
- for (i = 0; i < mgr->nSlaves; ++i) {
+ for (i = 0; i < Ttk_NumberSlaves(mgr); ++i) {
const char *pathName = Tk_PathName(Ttk_SlaveWindow(mgr,i));
Tcl_ListObjAppendElement(interp, result, Tcl_NewStringObj(pathName,-1));
}
@@ -1038,7 +1105,7 @@ static int NotebookTabCommand(
Notebook *nb = recordPtr;
Ttk_Manager *mgr = nb->notebook.mgr;
int index;
- Ttk_Slave *slave;
+ Tk_Window slaveWindow;
Tab *tab;
if (objc < 3) {
@@ -1050,18 +1117,18 @@ static int NotebookTabCommand(
return TCL_ERROR;
}
- slave = mgr->slaves[index];
tab = Ttk_SlaveData(mgr, index);
+ slaveWindow = Ttk_SlaveWindow(mgr, index);
if (objc == 3) {
return TtkEnumerateOptions(interp, tab,
- PaneOptionSpecs, nb->notebook.paneOptionTable, nb->core.tkwin);
+ PaneOptionSpecs, nb->notebook.paneOptionTable, slaveWindow);
} else if (objc == 4) {
return TtkGetOptionValue(interp, tab, objv[3],
- nb->notebook.paneOptionTable, nb->core.tkwin);
+ nb->notebook.paneOptionTable, slaveWindow);
} /* else */
- if (Ttk_ConfigureSlave(interp, mgr, slave, objc - 3,objv + 3) != TCL_OK) {
+ if (ConfigureTab(interp, nb, tab, slaveWindow, objc-3,objv+3) != TCL_OK) {
return TCL_ERROR;
}
@@ -1180,7 +1247,8 @@ static Ttk_Layout NotebookGetLayout(
return notebookLayout;
}
-/* +++ Display routines.
+/*------------------------------------------------------------------------
+ * +++ Display routines.
*/
static void DisplayTab(Notebook *nb, int index, Drawable d)
@@ -1199,6 +1267,7 @@ static void DisplayTab(Notebook *nb, int index, Drawable d)
static void NotebookDisplay(void *clientData, Drawable d)
{
Notebook *nb = clientData;
+ int nSlaves = Ttk_NumberSlaves(nb->notebook.mgr);
int index;
/* Draw notebook background (base layout):
@@ -1208,7 +1277,7 @@ static void NotebookDisplay(void *clientData, Drawable d)
/* Draw tabs from left to right, but draw the current tab last
* so it will overwrite its neighbors.
*/
- for (index = 0; index < nb->notebook.mgr->nSlaves; ++index) {
+ for (index = 0; index < nSlaves; ++index) {
if (index != nb->notebook.currentIndex) {
DisplayTab(nb, index, d);
}
diff --git a/generic/ttk/ttkPanedwindow.c b/generic/ttk/ttkPanedwindow.c
index ccc376d..7de701c 100644
--- a/generic/ttk/ttkPanedwindow.c
+++ b/generic/ttk/ttkPanedwindow.c
@@ -1,4 +1,4 @@
-/* $Id: ttkPanedwindow.c,v 1.9 2007/01/11 14:49:47 jenglish Exp $
+/* $Id: ttkPanedwindow.c,v 1.10 2007/06/09 21:45:45 jenglish Exp $
*
* Copyright (c) 2005, Joe English. Freely redistributable.
*
@@ -64,6 +64,7 @@ typedef struct {
Tcl_Obj *orientObj;
int orient;
Ttk_Manager *mgr;
+ Tk_OptionTable paneOptionTable;
Ttk_Layout sashLayout;
int sashThickness;
} PanedPart;
@@ -98,6 +99,74 @@ static Tk_OptionSpec PaneOptionSpecs[] = {
{TK_OPTION_END, 0,0,0, NULL, -1,-1, 0,0,0}
};
+/* CreatePane --
+ * Create a new pane record.
+ */
+static Pane *CreatePane(Tcl_Interp *interp, Paned *pw, Tk_Window slaveWindow)
+{
+ Tk_OptionTable optionTable = pw->paned.paneOptionTable;
+ void *record = ckalloc(sizeof(Pane));
+ Pane *pane = record;
+
+ memset(record, 0, sizeof(Pane));
+ if (Tk_InitOptions(interp, record, optionTable, slaveWindow) != TCL_OK) {
+ ckfree(record);
+ return NULL;
+ }
+
+ pane->reqSize
+ = pw->paned.orient == TTK_ORIENT_HORIZONTAL
+ ? Tk_ReqWidth(slaveWindow) : Tk_ReqHeight(slaveWindow);
+
+ return pane;
+}
+
+/* DestroyPane --
+ * Free pane record.
+ */
+static void DestroyPane(Paned *pw, Pane *pane)
+{
+ void *record = pane;
+ Tk_FreeConfigOptions(record, pw->paned.paneOptionTable, pw->core.tkwin);
+ ckfree(record);
+}
+
+/* ConfigurePane --
+ * Set pane options.
+ */
+static int ConfigurePane(
+ Tcl_Interp *interp, Paned *pw, Pane *pane, Tk_Window slaveWindow,
+ int objc, Tcl_Obj *CONST objv[])
+{
+ Ttk_Manager *mgr = pw->paned.mgr;
+ Tk_SavedOptions savedOptions;
+ int mask = 0;
+
+ if (Tk_SetOptions(interp, (void*)pane, pw->paned.paneOptionTable,
+ objc, objv, slaveWindow, &savedOptions, &mask) != TCL_OK)
+ {
+ return TCL_ERROR;
+ }
+
+ /* Sanity-check:
+ */
+ if (pane->weight < 0) {
+ Tcl_AppendResult(interp, "-weight must be nonnegative", NULL);
+ goto error;
+ }
+
+ /* Done.
+ */
+ Tk_FreeSavedOptions(&savedOptions);
+ Ttk_ManagerSizeChanged(mgr);
+ return TCL_OK;
+
+error:
+ Tk_RestoreSavedOptions(&savedOptions);
+ return TCL_ERROR;
+}
+
+
/*------------------------------------------------------------------------
* +++ Layout algorithm.
*/
@@ -135,7 +204,7 @@ static int ShoveDown(Paned *pw, int i, int pos)
Pane *pane = Ttk_SlaveData(pw->paned.mgr,i);
int sashThickness = pw->paned.sashThickness;
- if (i == pw->paned.mgr->nSlaves - 1) {
+ if (i == Ttk_NumberSlaves(pw->paned.mgr) - 1) {
pos = pane->sashPos; /* Sentinel value == master window size */
} else {
Pane *nextPane = Ttk_SlaveData(pw->paned.mgr,i+1);
@@ -146,8 +215,10 @@ static int ShoveDown(Paned *pw, int i, int pos)
}
/* PanedSize --
- * Compute the requested size of the paned widget.
- * Used as both the WidgetSpec sizeProc and the ManagerSpec sizeProc.
+ * Compute the requested size of the paned widget
+ * from the individual pane request sizes.
+ *
+ * Used as the WidgetSpec sizeProc and the ManagerSpec sizeProc.
*/
static int PanedSize(void *recordPtr, int *widthPtr, int *heightPtr)
{
@@ -326,29 +397,39 @@ static void PanedPlaceSlaves(void *managerData)
PlacePanes(pw);
}
-static void PaneAdded(Ttk_Manager *mgr, int index)
+static void PaneRemoved(Ttk_Manager *mgr, int index)
{
+ Paned *pw = Ttk_ManagerData(mgr);
Pane *pane = Ttk_SlaveData(mgr, index);
- Tk_Window slaveWindow = Ttk_SlaveWindow(mgr, index);
- Paned *pw = mgr->managerData;
-
- /* See also: PanedGeometryRequestProc */
- pane->reqSize
- = pw->paned.orient == TTK_ORIENT_HORIZONTAL
- ? Tk_ReqWidth(slaveWindow) : Tk_ReqHeight(slaveWindow);
+ DestroyPane(pw, pane);
}
-static void PaneRemoved(Ttk_Manager *mgr, int i) { /*no-op*/ }
-
-static int PaneConfigured(
- Tcl_Interp *interp, Ttk_Manager *mgr, Ttk_Slave *slave, unsigned mask)
+static int AddPane(
+ Tcl_Interp *interp, Paned *pw,
+ int destIndex, Tk_Window slaveWindow,
+ int objc, Tcl_Obj *const objv[])
{
- Pane *pane = slave->slaveData;
- if (pane->weight < 0) {
- Tcl_AppendResult(interp, "-weight must be nonnegative", NULL);
- pane->weight = 0;
+ Pane *pane;
+ if (!Ttk_Maintainable(interp, slaveWindow, pw->core.tkwin)) {
+ return TCL_ERROR;
+ }
+ if (Ttk_SlaveIndex(pw->paned.mgr, slaveWindow) >= 0) {
+ Tcl_AppendResult(interp,
+ Tk_PathName(slaveWindow), " already added",
+ NULL);
+ return TCL_ERROR;
+ }
+
+ pane = CreatePane(interp, pw, slaveWindow);
+ if (!pane) {
+ return TCL_ERROR;
+ }
+ if (ConfigurePane(interp, pw, pane, slaveWindow, objc, objv) != TCL_OK) {
+ DestroyPane(pw, pane);
return TCL_ERROR;
}
+
+ Ttk_InsertSlave(pw->paned.mgr, destIndex, slaveWindow, pane);
return TCL_OK;
}
@@ -358,15 +439,15 @@ static int PaneConfigured(
* in order to avoid unexpected pane resizes (esp. while the
* user is dragging a sash [#1325286]).
*/
-
static void PanedGeometryRequestProc(
ClientData clientData, Tk_Window slaveWindow)
{
- Ttk_Slave *slave = clientData;
- Pane *pane = slave->slaveData;
- Paned *pw = slave->manager->managerData;
+ Ttk_Manager *mgr = clientData;
+ Paned *pw = Ttk_ManagerData(mgr);
if (!Tk_IsMapped(slaveWindow)) {
+ int slaveIndex = Ttk_SlaveIndex(mgr, slaveWindow); /* ASSERT: != -1 */
+ Pane *pane = Ttk_SlaveData(mgr, slaveIndex);
pane->reqSize
= pw->paned.orient == TTK_ORIENT_HORIZONTAL
? Tk_ReqWidth(slaveWindow) : Tk_ReqHeight(slaveWindow);
@@ -379,12 +460,9 @@ static void PanedGeometryRequestProc(
static Ttk_ManagerSpec PanedManagerSpec = {
{ "panedwindow", PanedGeometryRequestProc, Ttk_LostSlaveProc },
- PaneOptionSpecs, sizeof(Pane),
PanedSize,
PanedPlaceSlaves,
- PaneAdded,
- PaneRemoved,
- PaneConfigured,
+ PaneRemoved
};
/*------------------------------------------------------------------------
@@ -422,6 +500,7 @@ static int PanedInitialize(Tcl_Interp *interp, void *recordPtr)
Tk_CreateEventHandler(pw->core.tkwin,
PanedEventMask, PanedEventProc, recordPtr);
pw->paned.mgr = Ttk_CreateManager(&PanedManagerSpec, pw, pw->core.tkwin);
+ pw->paned.paneOptionTable = Tk_CreateOptionTable(interp,PaneOptionSpecs);
pw->paned.sashLayout = 0;
pw->paned.sashThickness = 1;
@@ -450,7 +529,7 @@ static Ttk_Layout PanedGetLayout(
if (panedLayout) {
int horizontal = pw->paned.orient == TTK_ORIENT_HORIZONTAL;
- const char *layoutName =
+ const char *layoutName =
horizontal ? ".Vertical.Sash" : ".Horizontal.Sash";
Ttk_Layout sashLayout = Ttk_CreateSublayout(
interp, themePtr, panedLayout, layoutName, pw->core.optionTable);
@@ -478,35 +557,39 @@ static Ttk_Layout PanedGetLayout(
return panedLayout;
}
-static void PanedDisplay(void *recordPtr, Drawable d)
+/*------------------------------------------------------------------------
+ * +++ Drawing routines.
+ */
+
+static void DrawSash(Paned *pw, Drawable d, Ttk_Box b)
{
- Paned *pw = recordPtr;
- int horizontal = pw->paned.orient == TTK_ORIENT_HORIZONTAL;
Ttk_Layout sashLayout = pw->paned.sashLayout;
- int sashThickness = pw->paned.sashThickness;
Ttk_State state = pw->core.state;
- int nPanes = Ttk_NumberSlaves(pw->paned.mgr);
+
+ Ttk_PlaceLayout(sashLayout, state, b);
+ Ttk_DrawLayout(sashLayout, state, d);
+}
+
+static void PanedDisplay(void *recordPtr, Drawable d)
+{
+ Paned *pw = recordPtr;
+ int nPanes = Ttk_NumberSlaves(pw->paned.mgr),
+ horizontal = pw->paned.orient == TTK_ORIENT_HORIZONTAL,
+ thickness = pw->paned.sashThickness,
+ height = Tk_Height(pw->core.tkwin),
+ width = Tk_Width(pw->core.tkwin);
int i;
TtkWidgetDisplay(recordPtr, d);
/* Draw sashes:
*/
- if (horizontal) {
- int height = Tk_Height(pw->core.tkwin);
- for (i = 0; i < nPanes; ++i) {
- Pane *pane = Ttk_SlaveData(pw->paned.mgr, i);
- Ttk_PlaceLayout(sashLayout, state,
- Ttk_MakeBox(pane->sashPos, 0, sashThickness, height));
- Ttk_DrawLayout(sashLayout, state, d);
- }
- } else {
- int width = Tk_Width(pw->core.tkwin);
- for (i = 0; i < nPanes; ++i) {
- Pane *pane = Ttk_SlaveData(pw->paned.mgr, i);
- Ttk_PlaceLayout(sashLayout, state,
- Ttk_MakeBox(0, pane->sashPos, width, sashThickness));
- Ttk_DrawLayout(sashLayout, state, d);
+ for (i = 0; i < nPanes; ++i) {
+ Pane *pane = Ttk_SlaveData(pw->paned.mgr, i);
+ if (horizontal) {
+ DrawSash(pw, d, Ttk_MakeBox(pane->sashPos, 0, thickness, height));
+ } else {
+ DrawSash(pw, d, Ttk_MakeBox(0, pane->sashPos, width, thickness));
}
}
}
@@ -535,8 +618,8 @@ static int PanedAddCommand(
return TCL_ERROR;
}
- return Ttk_AddSlave(interp, pw->paned.mgr, slaveWindow,
- Ttk_NumberSlaves(pw->paned.mgr), objc - 3, objv + 3);
+ return AddPane(interp, pw, Ttk_NumberSlaves(pw->paned.mgr), slaveWindow,
+ objc - 3, objv + 3);
}
/* $pw insert $index $slave ?options...?
@@ -546,6 +629,7 @@ static int PanedInsertCommand(
Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[], void *recordPtr)
{
Paned *pw = recordPtr;
+ int nSlaves = Ttk_NumberSlaves(pw->paned.mgr);
int srcIndex, destIndex;
Tk_Window slaveWindow;
@@ -562,23 +646,26 @@ static int PanedInsertCommand(
if (!strcmp(Tcl_GetString(objv[2]), "end")) {
destIndex = Ttk_NumberSlaves(pw->paned.mgr);
- } else if (!Ttk_GetSlaveFromObj(interp,pw->paned.mgr,objv[2],&destIndex)) {
+ } else if (TCL_OK != Ttk_GetSlaveIndexFromObj(
+ interp,pw->paned.mgr,objv[2],&destIndex))
+ {
return TCL_ERROR;
}
srcIndex = Ttk_SlaveIndex(pw->paned.mgr, slaveWindow);
if (srcIndex < 0) { /* New slave: */
- return Ttk_AddSlave(interp, pw->paned.mgr, slaveWindow,
- destIndex, objc - 4, objv + 4);
+ return AddPane(interp, pw, destIndex, slaveWindow, objc-4, objv+4);
} /* else -- move existing slave: */
- if (destIndex >= pw->paned.mgr->nSlaves)
- destIndex = pw->paned.mgr->nSlaves - 1;
+ if (destIndex >= nSlaves)
+ destIndex = nSlaves - 1;
Ttk_ReorderSlave(pw->paned.mgr, srcIndex, destIndex);
return objc == 4 ? TCL_OK :
- Ttk_ConfigureSlave(interp, pw->paned.mgr,
- pw->paned.mgr->slaves[destIndex], objc-4,objv+4);
+ ConfigurePane(interp, pw,
+ Ttk_SlaveData(pw->paned.mgr, destIndex),
+ Ttk_SlaveWindow(pw->paned.mgr, destIndex),
+ objc-4,objv+4);
}
/* $pw forget $pane
@@ -594,7 +681,9 @@ static int PanedForgetCommand(
return TCL_ERROR;
}
- if (!Ttk_GetSlaveFromObj(interp, pw->paned.mgr, objv[2], &paneIndex)) {
+ if (TCL_OK != Ttk_GetSlaveIndexFromObj(
+ interp, pw->paned.mgr, objv[2], &paneIndex))
+ {
return TCL_ERROR;
}
Ttk_ForgetSlave(pw->paned.mgr, paneIndex);
@@ -602,14 +691,15 @@ static int PanedForgetCommand(
return TCL_OK;
}
-/* $pw identify $x $y
- * @@@ TODO: implement as documented, or change documentation.
+/* $pw identify $x $y --
+ * Return index of sash at $x,$y
*/
static int PanedIdentifyCommand(
Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[], void *recordPtr)
{
Paned *pw = recordPtr;
int sashThickness = pw->paned.sashThickness;
+ int nSashes = Ttk_NumberSlaves(pw->paned.mgr) - 1;
int x, y, pos;
int index;
@@ -624,7 +714,7 @@ static int PanedIdentifyCommand(
}
pos = pw->paned.orient == TTK_ORIENT_HORIZONTAL ? x : y;
- for (index = 0; index < pw->paned.mgr->nSlaves - 1; ++index) {
+ for (index = 0; index < nSashes; ++index) {
Pane *pane = Ttk_SlaveData(pw->paned.mgr, index);
if (pane->sashPos <= pos && pos <= pane->sashPos + sashThickness) {
Tcl_SetObjResult(interp, Tcl_NewIntObj(index));
@@ -632,7 +722,7 @@ static int PanedIdentifyCommand(
}
}
- return TCL_OK; /* empty list */
+ return TCL_OK; /* return empty string */
}
/* $pw pane $pane ?-option ?value -option value ...??
@@ -643,28 +733,32 @@ static int PanedPaneCommand(
{
Paned *pw = recordPtr;
int paneIndex;
- Ttk_Slave *slave;
+ Tk_Window slaveWindow;
+ Pane *pane;
if (objc < 3) {
Tcl_WrongNumArgs(interp, 2,objv, "pane ?-option value...?");
return TCL_ERROR;
}
- slave = Ttk_GetSlaveFromObj(interp,pw->paned.mgr,objv[2],&paneIndex);
- if (!slave) {
+ if (TCL_OK != Ttk_GetSlaveIndexFromObj(
+ interp,pw->paned.mgr,objv[2],&paneIndex))
+ {
return TCL_ERROR;
}
+ pane = Ttk_SlaveData(pw->paned.mgr, paneIndex);
+ slaveWindow = Ttk_SlaveWindow(pw->paned.mgr, paneIndex);
+
switch (objc) {
case 3:
- return TtkEnumerateOptions(interp, slave->slaveData, PaneOptionSpecs,
- pw->paned.mgr->slaveOptionTable, slave->slaveWindow);
+ return TtkEnumerateOptions(interp, pane, PaneOptionSpecs,
+ pw->paned.paneOptionTable, slaveWindow);
case 4:
- return TtkGetOptionValue(interp, slave->slaveData,objv[3],
- pw->paned.mgr->slaveOptionTable, slave->slaveWindow);
+ return TtkGetOptionValue(interp, pane, objv[3],
+ pw->paned.paneOptionTable, slaveWindow);
default:
- return Ttk_ConfigureSlave(
- interp, pw->paned.mgr, slave, objc-3,objv+3);
+ return ConfigurePane(interp, pw, pane, slaveWindow, objc-3,objv+3);
}
}
@@ -745,7 +839,7 @@ static WidgetSpec PanedWidgetSpec =
PanedInitialize, /* initializeProc */
PanedCleanup, /* cleanupProc */
TtkCoreConfigure, /* configureProc */
- TtkNullPostConfigure, /* postConfigureProc */
+ TtkNullPostConfigure, /* postConfigureProc */
PanedGetLayout, /* getLayoutProc */
PanedSize, /* sizeProc */
TtkWidgetDoLayout, /* layoutProc */
diff --git a/library/ttk/panedwindow.tcl b/library/ttk/panedwindow.tcl
index 15ec4f8..9cb046d 100644
--- a/library/ttk/panedwindow.tcl
+++ b/library/ttk/panedwindow.tcl
@@ -1,5 +1,5 @@
#
-# $Id: panedwindow.tcl,v 1.3 2007/04/13 00:21:47 hobbs Exp $
+# $Id: panedwindow.tcl,v 1.4 2007/06/09 21:45:45 jenglish Exp $
#
# Bindings for ttk::panedwindow widget.
#
@@ -33,8 +33,8 @@ bind TPanedwindow <<EnteredChild>> { ttk::panedwindow::ResetCursor %W }
proc ttk::panedwindow::Press {w x y} {
variable State
- lassign [$w identify $x $y] sash element
- if {![info exists sash] || $sash eq ""} {
+ set sash [$w identify $x $y]
+ if {$sash eq ""} {
set State(pressed) 0
return
}
diff --git a/tests/ttk/notebook.test b/tests/ttk/notebook.test
index ecb614a..d4c5e4c 100644
--- a/tests/ttk/notebook.test
+++ b/tests/ttk/notebook.test
@@ -1,5 +1,5 @@
#
-# $Id: notebook.test,v 1.1 2006/10/31 01:42:27 hobbs Exp $
+# $Id: notebook.test,v 1.2 2007/06/09 21:45:45 jenglish Exp $
#
package require Tk 8.5
@@ -380,6 +380,49 @@ test notebook-7.7d "insert - current tab undisturbed" -body {
.nb index current
} -result 4
+test notebook-7.8a "move tabs - current tab undisturbed - exhaustive" -body {
+ .nb select .nb.f0
+ foreach i {0 1 2 3 4} {
+ .nb insert $i .nb.f$i
+ }
+
+ foreach i {0 1 2 3 4} {
+ .nb select .nb.f$i
+ foreach j {0 1 2 3 4} {
+ foreach k {0 1 2 3 4} {
+ .nb insert $j $k
+ set current [lindex [.nb tabs] [.nb index current]]
+ if {$current != ".nb.f$i"} {
+ error "($i,$j,$k) current = $current"
+ }
+ .nb insert $k $j
+ if {[.nb tabs] ne [list .nb.f0 .nb.f1 .nb.f2 .nb.f3 .nb.f4]} {
+ error "swap $j $k; swap $k $j => [.nb tabs]"
+ }
+ }
+ }
+ }
+ .nb tabs
+} -result [list .nb.f0 .nb.f1 .nb.f2 .nb.f3 .nb.f4]
+
+test notebook-7.8b "insert new - current tab undisturbed - exhaustive" -body {
+ foreach i {0 1 2 3 4} {
+ .nb select .nb.f$i
+ foreach j {0 1 2 3 4} {
+.nb select .nb.f$i
+ .nb insert $j [frame .nb.newf]
+ set current [lindex [.nb tabs] [.nb index current]]
+ if {$current != ".nb.f$i"} {
+ puts stderr "new tab at $j, current = $current, expect .nb.f$i"
+ }
+ destroy .nb.newf
+ if {[.nb tabs] ne [list .nb.f0 .nb.f1 .nb.f2 .nb.f3 .nb.f4]} {
+ error "tabs disturbed"
+ }
+ }
+ }
+}
+
test notebook-7.end "insert - cleanup" -body {
destroy .nb
}
diff --git a/tests/ttk/panedwindow.test b/tests/ttk/panedwindow.test
index 190e6b5..47764a2 100644
--- a/tests/ttk/panedwindow.test
+++ b/tests/ttk/panedwindow.test
@@ -1,5 +1,5 @@
#
-# $Id: panedwindow.test,v 1.2 2006/11/07 03:45:28 jenglish Exp $
+# $Id: panedwindow.test,v 1.3 2007/06/09 21:45:45 jenglish Exp $
#
package require Tk 8.5
@@ -156,10 +156,11 @@ test panedwindow-4.2 "forget forgotten" -body {
#
proc checkorder {winlist} {
set pos -1
+ set positions [list]
foreach win $winlist {
- set nextpos [winfo y $win]
+ lappend positions [set nextpos [winfo y $win]]
if {$nextpos <= $pos} {
- error "window $win out of order"
+ error "window $win out of order ($positions)"
}
set pos $nextpos
}