From b29adcfbfc2e03e058536524f1aa3378b948e7ed Mon Sep 17 00:00:00 2001 From: hobbs Date: Thu, 26 Aug 2010 02:06:08 +0000 Subject: Major backport of 8.6 Ttk for 8.5.9. Most changes were only being committed to head (8.6), although they could apply for 8.5 as well. This re-sync makes future work easier to maintain and adds some useful work for 8.5 users. Notable changes: - Lots of code cleanup - Some bug fixes never backported - Addition of ttk::spinbox - minor color changes - Improved Vista/7 styling - Move to tile version 0.8.6 (pseudo-package) - ABI and API compatible (even $w identify) - minor new features (extended $w identify) --- ChangeLog | 53 +++ doc/ttk_Geometry.3 | 45 +- doc/ttk_Theme.3 | 4 +- doc/ttk_button.n | 8 +- doc/ttk_checkbutton.n | 11 +- doc/ttk_combobox.n | 62 +-- doc/ttk_entry.n | 117 +++--- doc/ttk_frame.n | 8 +- doc/ttk_image.n | 9 +- doc/ttk_intro.n | 49 ++- doc/ttk_label.n | 7 +- doc/ttk_labelframe.n | 7 +- doc/ttk_menubutton.n | 11 +- doc/ttk_notebook.n | 26 +- doc/ttk_panedwindow.n | 68 +-- doc/ttk_progressbar.n | 7 +- doc/ttk_radiobutton.n | 12 +- doc/ttk_scale.n | 5 +- doc/ttk_scrollbar.n | 11 +- doc/ttk_separator.n | 7 +- doc/ttk_sizegrip.n | 9 +- doc/ttk_spinbox.n | 88 ++++ doc/ttk_style.n | 15 +- doc/ttk_treeview.n | 106 +++-- doc/ttk_vsapi.n | 11 +- doc/ttk_widget.n | 79 ++-- generic/ttk/ttk.decls | 4 +- generic/ttk/ttkButton.c | 143 ++++--- generic/ttk/ttkCache.c | 39 +- generic/ttk/ttkClamTheme.c | 16 +- generic/ttk/ttkClassicTheme.c | 10 +- generic/ttk/ttkDecls.h | 74 +--- generic/ttk/ttkDefaultTheme.c | 193 ++++----- generic/ttk/ttkElements.c | 30 +- generic/ttk/ttkEntry.c | 309 +++++++++----- generic/ttk/ttkFrame.c | 20 +- generic/ttk/ttkGenStubs.tcl | 51 +-- generic/ttk/ttkImage.c | 4 +- generic/ttk/ttkInit.c | 8 +- generic/ttk/ttkLabel.c | 9 +- generic/ttk/ttkLayout.c | 124 ++++-- generic/ttk/ttkNotebook.c | 181 ++++---- generic/ttk/ttkPanedwindow.c | 148 ++++--- generic/ttk/ttkProgress.c | 61 ++- generic/ttk/ttkScale.c | 55 +-- generic/ttk/ttkScroll.c | 2 +- generic/ttk/ttkScrollbar.c | 45 +- generic/ttk/ttkSeparator.c | 32 +- generic/ttk/ttkSquare.c | 29 +- generic/ttk/ttkState.c | 8 +- generic/ttk/ttkStubInit.c | 6 +- generic/ttk/ttkStubLib.c | 10 +- generic/ttk/ttkTagSet.c | 260 +++++++++--- generic/ttk/ttkTheme.c | 408 +++++++++--------- generic/ttk/ttkTheme.h | 56 ++- generic/ttk/ttkThemeInt.h | 11 +- generic/ttk/ttkTrace.c | 6 +- generic/ttk/ttkTrack.c | 75 ++-- generic/ttk/ttkTreeview.c | 931 ++++++++++++++++++++++++++---------------- generic/ttk/ttkWidget.c | 295 ++++++------- generic/ttk/ttkWidget.h | 66 +-- library/ttk/altTheme.tcl | 22 +- library/ttk/aquaTheme.tcl | 19 +- library/ttk/button.tcl | 4 +- library/ttk/clamTheme.tcl | 20 +- library/ttk/classicTheme.tcl | 16 +- library/ttk/combobox.tcl | 56 ++- library/ttk/cursors.tcl | 2 +- library/ttk/defaults.tcl | 31 +- library/ttk/entry.tcl | 35 +- library/ttk/notebook.tcl | 33 +- library/ttk/panedwindow.tcl | 17 +- library/ttk/scale.tcl | 2 +- library/ttk/sizegrip.tcl | 34 +- library/ttk/spinbox.tcl | 175 ++++++++ library/ttk/treeview.tcl | 64 ++- library/ttk/ttk.tcl | 12 +- library/ttk/utils.tcl | 104 +++-- library/ttk/vistaTheme.tcl | 14 +- library/ttk/winTheme.tcl | 19 +- library/ttk/xpTheme.tcl | 21 +- macosx/ttkMacOSXTheme.c | 85 +++- tests/ttk/checkbutton.test | 49 +++ tests/ttk/combobox.test | 4 +- tests/ttk/radiobutton.test | 49 +++ tests/ttk/spinbox.test | 280 +++++++++++++ tests/ttk/treetags.test | 190 ++++++++- tests/ttk/treeview.test | 135 +++++- tests/ttk/ttk.test | 199 ++++----- tests/ttk/vsapi.test | 2 +- win/ttkWinMonitor.c | 6 +- win/ttkWinTheme.c | 34 +- win/ttkWinXPTheme.c | 50 ++- 93 files changed, 4106 insertions(+), 2231 deletions(-) create mode 100644 doc/ttk_spinbox.n create mode 100644 library/ttk/spinbox.tcl create mode 100644 tests/ttk/checkbutton.test create mode 100644 tests/ttk/radiobutton.test create mode 100644 tests/ttk/spinbox.test diff --git a/ChangeLog b/ChangeLog index 0137741..3296b91 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,56 @@ +2010-08-25 Jeff Hobbs + + * doc/ttk_spinbox.n (new), doc/ttk_*.3, doc/ttk_*.n: + * generic/ttk/ttkGenStubs.tcl: + * generic/ttk/ttk.decls, generic/ttk/ttkDecls.h: + * generic/ttk/ttkButton.c, generic/ttk/ttkCache.c: + * generic/ttk/ttkClamTheme.c, generic/ttk/ttkClassicTheme.c: + * generic/ttk/ttkDefaultTheme.c, generic/ttk/ttkElements.c: + * generic/ttk/ttkEntry.c, generic/ttk/ttkFrame.c: + * generic/ttk/ttkImage.c, generic/ttk/ttkInit.c: + * generic/ttk/ttkLabel.c, generic/ttk/ttkLayout.c: + * generic/ttk/ttkNotebook.c, generic/ttk/ttkPanedwindow.c: + * generic/ttk/ttkProgress.c, generic/ttk/ttkScale.c: + * generic/ttk/ttkScroll.c, generic/ttk/ttkScrollbar.c: + * generic/ttk/ttkSeparator.c, generic/ttk/ttkSquare.c: + * generic/ttk/ttkState.c, generic/ttk/ttkStubInit.c: + * generic/ttk/ttkStubLib.c, generic/ttk/ttkTagSet.c: + * generic/ttk/ttkTheme.c, generic/ttk/ttkTheme.h: + * generic/ttk/ttkThemeInt.h, generic/ttk/ttkTrace.c: + * generic/ttk/ttkTrack.c, generic/ttk/ttkTreeview.c: + * generic/ttk/ttkWidget.c, generic/ttk/ttkWidget.h: + * library/ttk/spinbox.tcl (new): + * library/ttk/altTheme.tcl, library/ttk/aquaTheme.tcl: + * library/ttk/button.tcl, library/ttk/clamTheme.tcl: + * library/ttk/classicTheme.tcl, library/ttk/combobox.tcl: + * library/ttk/cursors.tcl, library/ttk/defaults.tcl: + * library/ttk/entry.tcl, library/ttk/notebook.tcl: + * library/ttk/panedwindow.tcl, library/ttk/scale.tcl: + * library/ttk/sizegrip.tcl, library/ttk/treeview.tcl: + * library/ttk/ttk.tcl, library/ttk/utils.tcl: + * library/ttk/vistaTheme.tcl, library/ttk/winTheme.tcl: + * library/ttk/xpTheme.tcl: + * macosx/ttkMacOSXTheme.c: used 8.6/carbon variant + * tests/ttk/combobox.test, tests/ttk/treetags.test: + * tests/ttk/treeview.test, tests/ttk/ttk.test: + * tests/ttk/vsapi.test: + * tests/ttk/checkbutton.test (new): + * tests/ttk/radiobutton.test (new): + * tests/ttk/spinbox.test (new): + * win/ttkWinMonitor.c, win/ttkWinTheme.c, win/ttkWinXPTheme.c: + Major backport of 8.6 Ttk for 8.5.9. Most changes were only being + committed to head (8.6), although they could apply for 8.5 as well. + This re-sync makes future work easier to maintain and adds some + useful work for 8.5 users. Notable changes: + - Lots of code cleanup + - Some bug fixes never backported + - Addition of ttk::spinbox + - minor color changes + - Improved Vista/7 styling + - Move to tile version 0.8.6 (pseudo-package) + - ABI and API compatible (even $w identify) + - minor new features (extended $w identify) + 2010-08-03 Don Porter * changes: Updated for 8.5.9 release. diff --git a/doc/ttk_Geometry.3 b/doc/ttk_Geometry.3 index 74e44f4..042caf0 100644 --- a/doc/ttk_Geometry.3 +++ b/doc/ttk_Geometry.3 @@ -1,7 +1,7 @@ '\" '\" Copyright (c) 2004 Joe English '\" -'\" RCS: @(#) $Id: ttk_Geometry.3,v 1.4 2007/12/13 15:23:44 dgp Exp $ +'\" RCS: @(#) $Id: ttk_Geometry.3,v 1.4.2.1 2010/08/26 02:06:09 hobbs Exp $ '\" .so man.macros .TH Geometry 3 8.5 Tk "Tk Themed Widget" @@ -42,7 +42,7 @@ Ttk_Padding Ttk_Padding \fBTtk_AddPadding\fR(Ttk_Padding \fIpadding1\fR, Ttk_Padding \fIpadding2\fR; -Ttk_Padding +Ttk_Padding \fBTtk_RelievePadding\fR(Ttk_Padding \fIpadding\fR, int \fIrelief\fR); int @@ -57,7 +57,6 @@ int int \fBTtk_GetStickyFromObj\fR(Tcl_Interp *\fIinterp\fR, Tcl_Obj *\fIobjPtr\fR, int *\fIsticky_rtn\fR); .fi - .SH ARGUMENTS .AP Tk_Anchor anchor in One of the symbolic constants \fBTK_ANCHOR_N\fR, \fBTK_ANCHOR_NE\fR, @@ -118,16 +117,16 @@ X coordinate of upper-left corner of region. .AP int y in Y coordinate of upper-left corner of region. .BE - .SH "BOXES" -The \fBTtk_Box\fR structure represents a rectangular region of a window: +.PP +The \fBTtk_Box\fR structure represents a rectangular region of a window: .CS -typedef struct { - int x; - int y; - int width; - int height; -} Ttk_Box; +typedef struct { + int \fIx\fR; + int \fIy\fR; + int \fIwidth\fR; + int \fIheight\fR; +} \fBTtk_Box\fR; .CE All coordinates are relative to the window. .PP @@ -136,12 +135,12 @@ a \fBTtk_Box\fR structure representing a region \fIwidth\fR pixels wide, \fIheight\fR pixels tall, at the specified \fIx, y\fR coordinates. .PP \fBTtk_PadBox\fR returns a new box located inside the specified \fIparcel\fR, -shrunken according to the left, top, right, and bottom margins +shrunken according to the left, top, right, and bottom margins specified by \fIpadding\fR. .PP \fBTtk_ExpandBox\fR is the inverse of \fBTtk_PadBox\fR: it returns a new box surrounding the specified \fIparcel\fR, -expanded according to the left, top, right, and bottom margins +expanded according to the left, top, right, and bottom margins specified by \fIpadding\fR. .PP \fBTtk_PackBox\fR allocates a parcel \fIwidth\fR by \fIheight\fR @@ -149,7 +148,7 @@ pixels wide on the specified \fIside\fR of the \fIcavity\fR, and shrinks the \fIcavity\fR accordingly. .PP \fBTtk_StickBox\fR places a box with the requested \fIwidth\fR -and \fIheight\fR inside the \fIparcel\fR according to the +and \fIheight\fR inside the \fIparcel\fR according to the \fIsticky\fR bits. .PP \fBTtk_PlaceBox\fR combines \fBTtk_PackBox\fR and \fBTtk_StickBox\fR: @@ -164,20 +163,21 @@ specified \fIanchor\fR option. \fBTtk_BoxContains\fR tests if the specified \fIx, y\fR coordinate lies within the rectangular region \fIbox\fR. .SH "PADDDING" -The \fBTtk_Padding\fR structure is used to represent +.PP +The \fBTtk_Padding\fR structure is used to represent borders, internal padding, and external margins: .CS typedef struct { - short left; - short top; - short right; - short bottom; -} Ttk_Padding; + short \fIleft\fR; + short \fItop\fR; + short \fIright\fR; + short \fIbottom\fR; +} \fBTtk_Padding\fR; .CE -.PP +.PP \fBTtk_MakePadding\fR is a convenience routine that contsructs a \fBTtk_Padding\fR structure with the specified left, top, right, and bottom -components. +components. .PP \fBTtk_UniformPadding\fR constructs a \fBTtk_Padding\fR structure with all components equal to the specified \fIborder\fR. @@ -200,6 +200,7 @@ This is typically used in element geometry procedures to simulate a .QW pressed-in look for pushbuttons. .SH "CONVERSION ROUTINES" +.PP \fBTtk_GetPaddingFromObj\fR converts the string in \fIobjPtr\fR to a \fBTtk_Padding\fR structure. The string representation is a list of diff --git a/doc/ttk_Theme.3 b/doc/ttk_Theme.3 index fb16978..86b84da 100644 --- a/doc/ttk_Theme.3 +++ b/doc/ttk_Theme.3 @@ -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_Theme.3,v 1.1 2006/10/31 01:42:25 hobbs Exp $ +'\" RCS: @(#) $Id: ttk_Theme.3,v 1.1.4.1 2010/08/26 02:06:09 hobbs Exp $ '\" .so man.macros .TH Ttk_CreateTheme 3 8.5 Tk "Tk Themed Widget" @@ -28,7 +28,7 @@ inherit elements and layouts. The name of the theme. .BE .SH DESCRIPTION - +.\" TODO - Document these functions better! .SH "SEE ALSO" Ttk_RegisterLayout, Ttk_BuildLayout .\" .SH KEYWORDS diff --git a/doc/ttk_button.n b/doc/ttk_button.n index a3b7c89..c6807bf 100644 --- a/doc/ttk_button.n +++ b/doc/ttk_button.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_button.n,v 1.11.2.2 2009/04/30 13:52:55 dkf Exp $ +'\" RCS: @(#) $Id: ttk_button.n,v 1.11.2.3 2010/08/26 02:06:09 hobbs Exp $ '\" .so man.macros .TH ttk::button n 8.5 Tk "Tk Themed Widget" @@ -56,12 +56,17 @@ in the style. .\" .OP \-padding padding Padding .\" .OP \-relief relief Relief .SH "WIDGET COMMAND" +.PP In addition to the standard \fBcget\fR, \fBconfigure\fR, \fBidentify\fR, \fBinstate\fR, and \fBstate\fR commands, buttons support the following additional widget commands: .TP \fIpathName \fBinvoke\fR Invokes the command associated with the button. +.SH "STANDARD STYLES" +.PP +\fBTtk::button\fR widgets support the \fBToolbutton\fR style in all standard +themes, which is useful for creating widgets for toolbars. .SH "COMPATIBILITY OPTIONS" .OP \-state state State May be set to \fBnormal\fR or \fBdisabled\fR to control the @@ -75,5 +80,4 @@ ttk::widget(n), button(n) widget, button, default, command '\" Local Variables: '\" mode: nroff -'\" fill-column: 78 '\" End: diff --git a/doc/ttk_checkbutton.n b/doc/ttk_checkbutton.n index 241022e..9edfa35 100644 --- a/doc/ttk_checkbutton.n +++ b/doc/ttk_checkbutton.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_checkbutton.n,v 1.12.2.1 2008/05/11 00:31:01 patthoyts Exp $ +'\" RCS: @(#) $Id: ttk_checkbutton.n,v 1.12.2.2 2010/08/26 02:06:09 hobbs Exp $ '\" .so man.macros .TH ttk::checkbutton n 8.5 Tk "Tk Themed Widget" @@ -37,6 +37,7 @@ when the widget is selected. Defaults to \fB1\fR. The name of a global variable whose value is linked to the widget. Defaults to the widget pathname if not specified. .SH "WIDGET COMMAND" +.PP In addition to the standard \fBcget\fR, \fBconfigure\fR, \fBidentify\fR, \fBinstate\fR, and \fBstate\fR commands, checkbuttons support the following additional @@ -53,6 +54,7 @@ Returns the result of the \fB\-command\fR. .\" Are these useful? They don't invoke the -command .\" Missing: flash. This is definitely not useful. .SH "WIDGET STATES" +.PP The widget does not respond to user input if the \fBdisabled\fR state is set. The widget sets the \fBselected\fR state whenever the linked \fB\-variable\fR is set to the widget's \fB\-onvalue\fR, @@ -64,7 +66,14 @@ linked \fB\-variable\fR is unset. or .QW indeterminate selection.) +.SH "STANDARD STYLES" +.PP +\fBTtk::checkbutton\fR widgets support the \fBToolbutton\fR style in all +standard themes, which is useful for creating widgets for toolbars. .SH "SEE ALSO" ttk::widget(n), ttk::radiobutton(n), checkbutton(n) .SH "KEYWORDS" widget, button, toggle, check, option +'\" Local Variables: +'\" mode: nroff +'\" End: diff --git a/doc/ttk_combobox.n b/doc/ttk_combobox.n index de025d0..d8603e1 100644 --- a/doc/ttk_combobox.n +++ b/doc/ttk_combobox.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_combobox.n,v 1.15.2.1 2008/05/11 00:31:01 patthoyts Exp $ +'\" RCS: @(#) $Id: ttk_combobox.n,v 1.15.2.2 2010/08/26 02:06:09 hobbs Exp $ '\" .so man.macros .TH ttk::combobox n 8.5 Tk "Tk Themed Widget" @@ -15,6 +15,7 @@ ttk::combobox \- text field with popdown selection list \fBttk::combobox\fR \fIpathName \fR?\fIoptions\fR? .BE .SH DESCRIPTION +.PP A \fBttk::combobox\fR combines a text field with a pop-down list of values; the user may select the value of the text field from among the values in the list. @@ -29,7 +30,7 @@ Boolean value. If set, the widget selection is linked to the X selection. .OP \-justify justify Justify Specifies how the text is aligned within the widget. -One of \fBleft\fR, \fBcenter\fR, or \fBright\fR. +Must be one of \fBleft\fR, \fBcenter\fR, or \fBright\fR. .OP \-height height Height Specifies the height of the pop-down listbox, in rows. .OP \-postcommand postCommand PostCommand @@ -55,14 +56,16 @@ Specifies the list of values to display in the drop-down listbox. Specifies an integer value indicating the desired width of the entry window, in average-size characters of the widget's font. .SH "WIDGET COMMAND" -.TP -\fIpathName \fBcget\fR \fIoption\fR -Returns the current value of the specified \fIoption\fR. -See \fIttk::widget(n)\fR. -.TP -\fIpathName \fBconfigure\fR ?\fIoption\fR? ?\fIvalue option value ...\fR? -Modify or query widget options. -See \fIttk::widget(n)\fR. +.PP +The following subcommands are possible for combobox widgets: +'\".TP +'\"\fIpathName \fBcget\fR \fIoption\fR +'\"Returns the current value of the specified \fIoption\fR. +'\"See \fIttk::widget(n)\fR. +'\".TP +'\"\fIpathName \fBconfigure\fR ?\fIoption\fR? ?\fIvalue option value ...\fR? +'\"Modify or query widget options. +'\"See \fIttk::widget(n)\fR. .TP \fIpathName \fBcurrent\fR ?\fInewIndex\fR? If \fInewIndex\fR is supplied, sets the combobox value @@ -72,31 +75,39 @@ Otherwise, returns the index of the current value in the list of .TP \fIpathName \fBget\fR Returns the current value of the combobox. -.TP -\fIpathName \fBidentify \fIx y\fR -Returns the name of the element at position \fIx\fR, \fIy\fR. -See \fIttk::widget(n)\fR. -.TP -\fIpathName \fBinstate \fIstateSpec\fR ?\fIscript\fR? -Test the widget state. -See \fIttk::widget(n)\fR. +'\".TP +'\"\fIpathName \fBidentify \fIx y\fR +'\"Returns the name of the element at position \fIx\fR, \fIy\fR. +'\"See \fIttk::widget(n)\fR. +'\".TP +'\"\fIpathName \fBinstate \fIstateSpec\fR ?\fIscript\fR? +'\"Test the widget state. +'\"See \fIttk::widget(n)\fR. .TP \fIpathName \fBset\fR \fIvalue\fR Sets the value of the combobox to \fIvalue\fR. -.TP -\fIpathName \fBstate\fR ?\fIstateSpec\fR? -Modify or query the widget state. -See \fIttk::widget(n)\fR. +'\".TP +'\"\fIpathName \fBstate\fR ?\fIstateSpec\fR? +'\"Modify or query the widget state. +'\"See \fIttk::widget(n)\fR. .PP -The combobox widget also supports the following \fIttk::entry\fR -widget commands (see \fIttk::entry(n)\fR for details): +The combobox widget also supports the following \fBttk::entry\fR +widget subcommands (see \fIttk::entry(n)\fR for details): .DS .ta 5.5c 11c \fBbbox\fR \fBdelete\fR \fBicursor\fR \fBindex\fR \fBinsert\fR \fBselection\fR \fBxview\fR .DE +The combobox widget also supports the following generic \fBttk::widget\fR +widget subcommands (see \fIttk::widget(n)\fR for details): +.DS +.ta 5.5c 11c +\fBcget\fR \fBconfigure\fR \fBidentify\fR +\fBinstate\fR \fBstate\fR +.DE .SH "VIRTUAL EVENTS" +.PP The combobox widget generates a \fB<>\fR virtual event when the user selects an element from the list of values. If the selection action unposts the listbox, @@ -105,3 +116,6 @@ this event is delivered after the listbox is unposted. ttk::widget(n), ttk::entry(n) .SH KEYWORDS choice, entry, list box, text box, widget +'\" Local Variables: +'\" mode: nroff +'\" End: diff --git a/doc/ttk_entry.n b/doc/ttk_entry.n index 2be5714..6184fa6 100644 --- a/doc/ttk_entry.n +++ b/doc/ttk_entry.n @@ -7,7 +7,7 @@ '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES. '\" '\" SOURCE: entry.n, r1.12 -'\" RCS: @(#) $Id: ttk_entry.n,v 1.11 2008/01/29 15:38:00 dkf Exp $ +'\" RCS: @(#) $Id: ttk_entry.n,v 1.11.2.1 2010/08/26 02:06:09 hobbs Exp $ '\" .so man.macros .TH ttk::entry n 8.5 Tk "Tk Themed Widget" @@ -88,6 +88,7 @@ in average-size characters of the widget's font. .\" Not in ttk: If the value is less than or equal to zero, the widget picks a .\" Not in ttk: size just large enough to hold its current text. .SH NOTES +.PP A portion of the entry may be selected as described below. If an entry is exporting its selection (see the \fBexportSelection\fR option), then it will observe the standard X11 protocols for handling the @@ -105,6 +106,7 @@ the standard \fBxScrollCommand\fR mechanism for interacting with scrollbars (see the description of the \fBxScrollCommand\fR option for details). .SH "INDICES" +.PP Many of the \fBentry\fR widget commands take one or more indices as arguments. An index specifies a particular character in the entry's string, in any of the following ways: @@ -132,15 +134,15 @@ Indicates the character just after the last one in the selection. It is an error to use this form if the selection is not in the entry window. .LP -Abbreviations may be used for any of the forms above, e.g. +Abbreviations may be used for any of the forms above, e.g.\| .QW \fBe\fR or -.QW \fBsel.f\fR . +.QW \fBsel.l\fR . In general, out-of-range indices are automatically rounded to the nearest legal value. .SH "WIDGET COMMAND" .PP -The following commands are possible for entry widgets: +The following subcommands are possible for entry widgets: .TP \fIpathName \fBbbox \fIindex\fR Returns a list of four numbers describing the bounding box of the @@ -151,14 +153,14 @@ the upper-left corner of the screen area covered by the character the width and height of the character, in pixels. The bounding box may refer to a region outside the visible area of the window. -.TP -\fIpathName \fBcget\fR \fIoption\fR -Returns the current value of the specified \fIoption\fR. -See \fIttk::widget(n)\fR. -.TP -\fIpathName \fBconfigure\fR ?\fIoption\fR? ?\fIvalue option value ...\fR? -Modify or query widget options. -See \fIttk::widget(n)\fR. +'\".TP +'\"\fIpathName \fBcget\fR \fIoption\fR +'\"Returns the current value of the specified \fIoption\fR. +'\"See \fIttk::widget(n)\fR. +'\".TP +'\"\fIpathName \fBconfigure\fR ?\fIoption\fR? ?\fIvalue option value ...\fR? +'\"Modify or query widget options. +'\"See \fIttk::widget(n)\fR. .TP \fIpathName \fBdelete \fIfirst \fR?\fIlast\fR? Delete one or more elements of the entry. @@ -175,10 +177,10 @@ Returns the entry's string. \fIpathName \fBicursor \fIindex\fR Arrange for the insert cursor to be displayed just before the character given by \fIindex\fR. Returns the empty string. -.TP -\fIpathName \fBidentify \fIx y\fR -Returns the name of the element at position \fIx\fR, \fIy\fR, -or the empty string if the coordinates are outside the window. +'\".TP +'\"\fIpathName \fBidentify \fIx y\fR +'\"Returns the name of the element at position \fIx\fR, \fIy\fR, +'\"or the empty string if the coordinates are outside the window. .TP \fIpathName \fBindex\fI index\fR Returns the numerical index corresponding to \fIindex\fR. @@ -186,10 +188,10 @@ Returns the numerical index corresponding to \fIindex\fR. \fIpathName \fBinsert \fIindex string\fR Insert \fIstring\fR just before the character indicated by \fIindex\fR. Returns the empty string. -.TP -\fIpathName \fBinstate \fIstatespec\fR ?\fIscript\fR? -Test the widget state. -See \fIttk::widget(n)\fR. +'\".TP +'\"\fIpathName \fBinstate \fIstatespec\fR ?\fIscript\fR? +'\"Test the widget state. +'\"See \fIttk::widget(n)\fR. .TP \fIpathName \fBselection \fIoption arg\fR This command is used to adjust the selection within an entry. It @@ -212,16 +214,17 @@ before \fIend\fR. If \fIend\fR refers to the same character as \fIstart\fR or an earlier one, then the entry's selection is cleared. .RE -.TP -\fIpathName \fBstate\fR ?\fIstateSpec\fR? -Modify or query the widget state. -See \fIttk::widget(n)\fR. +'\".TP +'\"\fIpathName \fBstate\fR ?\fIstateSpec\fR? +'\"Modify or query the widget state. +'\"See \fIttk::widget(n)\fR. .TP \fIpathName \fBvalidate\fR Force revalidation, independent of the conditions specified by the \fB\-validate\fR option. Returns 0 if validation fails, 1 if it succeeds. Sets or clears the \fBinvalid\fR state accordingly. +See \fBVALIDATION\fR below for more details. .TP \fIpathName \fBxview \fIargs\fR This command is used to query and change the horizontal position of the @@ -261,10 +264,20 @@ If \fInumber\fR is negative then characters farther to the left become visible; if it is positive then characters farther to the right become visible. .RE +.PP +The entry widget also supports the following generic \fBttk::widget\fR +widget subcommands (see \fIttk::widget(n)\fR for details): +.DS +.ta 5.5c 11c +\fBcget\fR \fBconfigure\fR \fBidentify\fR +\fBinstate\fR \fBstate\fR +.DE .SH VALIDATION +.PP The \fB\-validate\fR, \fB\-validatecommand\fR, and \fB\-invalidcommand\fR options are used to enable entry widget validation. .SS "VALIDATION MODES" +.PP There are two main validation modes: \fIprevalidation\fR, in which the \fB\-validatecommand\fR is evaluated prior to each edit and the return value is used to determine whether to accept @@ -274,6 +287,7 @@ evaluated to determine whether the current value is valid. .PP The \fB\-validate\fR option determines when validation occurs; it may be set to any of the following values: +.RS .IP \fBnone\fR Default. This means validation will only occur when specifically requested by the \fBvalidate\fR widget command. @@ -290,6 +304,7 @@ The entry is revalidated when the entry receives focus. The entry is revalidated when the entry loses focus. .IP \fBall\fR Validation is performed for all above conditions. +.RE .PP The \fB\-invalidcommand\fR is evaluated whenever the \fB\-validatecommand\fR returns a false value. @@ -305,10 +320,12 @@ regardless of the value returned by the \fB\-validatecommand\fR. If \fB\-validatecommand\fR is empty (the default), validation always succeeds. .SS "VALIDATION SCRIPT SUBSTITUTIONS" +.PP It is possible to perform percent substitutions on the -\fB\-validatecommand\fR and \fBinvalidCommand\fR, +\fB\-validatecommand\fR and \fB\-invalidcommand\fR, just as in a \fBbind\fR script. The following substitutions are recognized: +.RS .IP \fB%d\fR Type of action: 1 for \fBinsert\fR prevalidation, 0 for \fBdelete\fR prevalidation, @@ -329,8 +346,9 @@ The validation condition that triggered the callback (\fBkey\fR, \fBfocusin\fR, \fBfocusout\fR, or \fBforced\fR). .IP \fB%W\fR The name of the entry widget. +.RE .SS "DIFFERENCES FROM TK ENTRY WIDGET VALIDATION" -.IP \(bu +.PP The standard Tk entry widget automatically disables validation (by setting \fB\-validate\fR to \fBnone\fR) if the \fB\-validatecommand\fR or \fB\-invalidcommand\fR modifies @@ -338,53 +356,54 @@ the entry's value. The Tk themed entry widget only disables validation if one of the validation scripts raises an error, or if \fB\-validatecommand\fR does not return a valid boolean value. -(Thus, it is not necessary to reenable validation after +(Thus, it is not necessary to re-enable validation after modifying the entry value in a validation script). -.IP \(bu -The standard entry widget invokes validation whenever the linked +.PP +In addition, the standard entry widget invokes validation whenever the linked \fB\-textvariable\fR is modified; the Tk themed entry widget does not. .SH "DEFAULT BINDINGS" +.PP The entry widget's default bindings enable the following behavior. In the descriptions below, .QW word refers to a contiguous group of letters, digits, or .QW _ characters, or any single character other than these. -.IP \(bu +.IP \0\(bu 4 Clicking mouse button 1 positions the insert cursor just before the character underneath the mouse cursor, sets the input focus to this widget, and clears any selection in the widget. Dragging with mouse button 1 down strokes out a selection between the insert cursor and the character under the mouse. -.IP \(bu +.IP \0\(bu 4 Double-clicking with mouse button 1 selects the word under the mouse and positions the insert cursor at the end of the word. Dragging after a double click strokes out a selection consisting of whole words. -.IP \(bu +.IP \0\(bu 4 Triple-clicking with mouse button 1 selects all of the text in the entry and positions the insert cursor at the end of the line. -.IP \(bu +.IP \0\(bu 4 The ends of the selection can be adjusted by dragging with mouse button 1 while the Shift key is down. If the button is double-clicked before dragging then the selection will be adjusted in units of whole words. -.IP \(bu +.IP \0\(bu 4 Clicking mouse button 1 with the Control key down will position the insert cursor in the entry without affecting the selection. -.IP \(bu +.IP \0\(bu 4 If any normal printing characters are typed in an entry, they are inserted at the point of the insert cursor. -.IP \(bu +.IP \0\(bu 4 The view in the entry can be adjusted by dragging with mouse button 2. If mouse button 2 is clicked without moving the mouse, the selection is copied into the entry at the position of the mouse cursor. -.IP \(bu +.IP \0\(bu 4 If the mouse is dragged out of the entry on the left or right sides while button 1 is pressed, the entry will automatically scroll to make more text visible (if there is more text off-screen on the side where the mouse left the window). -.IP \(bu +.IP \0\(bu 4 The Left and Right keys move the insert cursor one character to the left or right; they also clear any selection in the entry. If Left or Right is typed with the Shift key down, then the insertion @@ -393,38 +412,39 @@ Control-Left and Control-Right move the insert cursor by words, and Control-Shift-Left and Control-Shift-Right move the insert cursor by words and also extend the selection. Control-b and Control-f behave the same as Left and Right, respectively. -.IP \(bu +.IP \0\(bu 4 The Home key and Control-a move the insert cursor to the beginning of the entry and clear any selection in the entry. Shift-Home moves the insert cursor to the beginning of the entry and extends the selection to that point. -.IP \(bu +.IP \0\(bu 4 The End key and Control-e move the insert cursor to the end of the entry and clear any selection in the entry. Shift-End moves the cursor to the end and extends the selection to that point. -.IP \(bu +.IP \0\(bu 4 Control-/ selects all the text in the entry. -.IP \(bu +.IP \0\(bu 4 Control-\e clears any selection in the entry. -.IP \(bu +.IP \0\(bu 4 The standard Tk <>, <>, <>, and <> virtual events operate on the selection in the expected manner. -.IP \(bu +.IP \0\(bu 4 The Delete key deletes the selection, if there is one in the entry. If there is no selection, it deletes the character to the right of the insert cursor. -.IP \(bu +.IP \0\(bu 4 The BackSpace key and Control-h delete the selection, if there is one in the entry. If there is no selection, it deletes the character to the left of the insert cursor. -.IP \(bu +.IP \0\(bu 4 Control-d deletes the character to the right of the insert cursor. -.IP \(bu +.IP \0\(bu 4 Control-k deletes all the characters to the right of the insertion cursor. .SH "WIDGET STATES" +.PP In the \fBdisabled\fR state, the entry cannot be edited and the text cannot be selected. In the \fBreadonly\fR state, @@ -448,3 +468,6 @@ and clears it whenever validation succeeds. ttk::widget(n), entry(n) .SH KEYWORDS entry, widget, text field +'\" Local Variables: +'\" mode: nroff +'\" End: diff --git a/doc/ttk_frame.n b/doc/ttk_frame.n index f9acc02..c40edd1 100644 --- a/doc/ttk_frame.n +++ b/doc/ttk_frame.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_frame.n,v 1.9.2.1 2008/05/11 00:31:01 patthoyts Exp $ +'\" RCS: @(#) $Id: ttk_frame.n,v 1.9.2.2 2010/08/26 02:06:09 hobbs Exp $ '\" .so man.macros .TH ttk::frame n 8.5 Tk "Tk Themed Widget" @@ -15,6 +15,7 @@ ttk::frame \- Simple container widget \fBttk::frame\fR \fIpathName \fR?\fIoptions\fR? .BE .SH DESCRIPTION +.PP A \fBttk::frame\fR widget is a container, used to group other widgets together. .SO ttk_widget @@ -36,10 +37,12 @@ If specified, the widget's requested width in pixels. .OP \-height height Height If specified, the widget's requested height in pixels. .SH "WIDGET COMMAND" +.PP Supports the standard widget commands \fBconfigure\fR, \fBcget\fR, \fBidentify\fR, \fBinstate\fR, and \fBstate\fR; see \fIttk::widget(n)\fR. .SH "NOTES" +.PP Note that if the \fBpack\fR, \fBgrid\fR, or other geometry managers are used to manage the children of the \fBframe\fR, by the GM's requested size will normally take precedence @@ -50,3 +53,6 @@ to change this. ttk::widget(n), ttk::labelframe(n), frame(n) .SH "KEYWORDS" widget, frame, container +'\" Local Variables: +'\" mode: nroff +'\" End: diff --git a/doc/ttk_image.n b/doc/ttk_image.n index 0c38e94..0d8ea69 100644 --- a/doc/ttk_image.n +++ b/doc/ttk_image.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_image.n,v 1.12.2.1 2009/05/14 00:53:04 patthoyts Exp $ +'\" RCS: @(#) $Id: ttk_image.n,v 1.12.2.2 2010/08/26 02:06:09 hobbs Exp $ '\" .so man.macros .TH ttk_image n 8.5 Tk "Tk Themed Widget" @@ -15,6 +15,7 @@ ttk_image \- Define an element based on an image \fBttk::style element create \fIname\fR \fBimage\fR \fIimageSpec\fR ?\fIoptions\fR? .BE .SH DESCRIPTION +.PP The \fIimage\fR element factory creates a new element in the current theme whose visual appearance is determined by Tk images. @@ -24,6 +25,7 @@ The rest of the list is a sequence of \fIstatespec / value\fR pairs specifying other images to use when the element is in a particular state or combination of states. .SH OPTIONS +.PP Valid \fIoptions\fR are: .TP \fB\-border\fR \fIpadding\fR @@ -52,6 +54,7 @@ or Specifies a minimum width for the element. If less than zero, the base image's width is used as a default. .SH "IMAGE STRETCHING" +.PP If the element's allocated parcel is larger than the image, the image will be placed in the parcel based on the \fB\-sticky\fR option. If the image needs to stretch horizontally (i.e., \fB\-sticky ew\fR) @@ -63,6 +66,7 @@ four fixed corners, top and left edges (which may be tiled horizontally), left and right edges (which may be tiled vertically), and the central area (which may be tiled in both directions). .SH "EXAMPLE" +.PP .CS set img1 [image create photo \-file button.png] set img2 [image create photo \-file button-pressed.png] @@ -75,3 +79,6 @@ style element create Button.button image \e ttk::intro(n), ttk::style(n), ttk_vsapi(n), image(n), photo(n) .SH KEYWORDS style, theme, appearance, pixmap theme, image +'\" Local Variables: +'\" mode: nroff +'\" End: diff --git a/doc/ttk_intro.n b/doc/ttk_intro.n index 912a5c0..81a1c7b 100644 --- a/doc/ttk_intro.n +++ b/doc/ttk_intro.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_intro.n,v 1.10.2.1 2010/03/09 04:20:56 hobbs Exp $ +'\" RCS: @(#) $Id: ttk_intro.n,v 1.10.2.2 2010/08/26 02:06:09 hobbs Exp $ '\" .so man.macros .TH ttk::intro n 8.5 Tk "Tk Themed Widget" @@ -13,6 +13,7 @@ ttk::intro \- Introduction to the Tk theme engine .BE .SH "OVERVIEW" +.PP The Tk themed widget set is based on a revised and enhanced version of TIP #48 (http://tip.tcl.tk/48) specified style engine. The main concepts are described below. @@ -24,22 +25,24 @@ maintaining the widget state and invoking callbacks; all aspects of the widget's appearance are controlled by the style of the widget (i.e. the style of the elements of the widget). .SH "THEMES" +.PP A \fItheme\fR is a collection of elements and styles that determine the look and feel of the widget set. Themes can be used to: .IP \(bu -Isolate platform differences (X11 vs. classic Windows vs. XP vs. Aqua ...) +isolate platform differences (X11 vs. classic Windows vs. XP vs. Aqua ...) .IP \(bu -Adapt to display limitations (low-color, grayscale, monochrome, tiny screens) +adapt to display limitations (low-color, grayscale, monochrome, tiny screens) .IP \(bu -Accessibility (high contrast, large type) +accessibility (high contrast, large type) .IP \(bu -Application suite branding +application suite branding .IP \(bu -Blend in with the rest of the desktop (Gnome, KDE, Java) +blend in with the rest of the desktop (Gnome, KDE, Java) .IP \(bu -And, of course: eye candy. +and, of course: eye candy. .SH "ELEMENTS" +.PP An \fIelement\fR displays an individual part of a widget. For example, a vertical scrollbar widget contains \fBuparrow\fR, \fBdownarrow\fR, \fBtrough\fR and \fBslider\fR elements. @@ -61,14 +64,15 @@ For example, the \fBtext\fR element \fB\-underline\fR, and \fB\-width\fR options. The value of an element option is taken from: .IP \(bu -An option of the same name and type in the widget containing the element; +an option of the same name and type in the widget containing the element; .IP \(bu -A dynamic setting specified by \fBstyle map\fR and the current state; +a dynamic setting specified by \fBstyle map\fR and the current state; .IP \(bu -The default setting specified by \fBstyle configure\fR; or +the default setting specified by \fBstyle configure\fR; or .IP \(bu -The element's built-in default value for the option. +the element's built-in default value for the option. .SH "LAYOUTS" +.PP A \fIlayout\fR specifies which elements make up a widget and how they are arranged. The layout engine uses a simplified version of the \fBpack\fR @@ -77,9 +81,10 @@ of the widget, elements are allocated a parcel within the cavity along the side specified by the \fB\-side\fR option, and placed within the parcel according to the \fB\-sticky\fR option. -For example, the layout for a horizontal scrollbar +For example, the layout for a horizontal scrollbar is: +.PP .CS -ttk::style layout Horizontal.TScrollbar { +ttk::\fBstyle layout\fR Horizontal.TScrollbar { Scrollbar.trough \-children { Scrollbar.leftarrow \-side left \-sticky w Scrollbar.rightarrow \-side right \-sticky e @@ -87,10 +92,12 @@ ttk::style layout Horizontal.TScrollbar { } } .CE +.PP By default, the layout for a widget is the same as its class name. Some widgets may override this (for example, the \fBttk::scrollbar\fR widget chooses different layouts based on the \fB\-orient\fR option). .SH "STATES" +.PP In standard Tk, many widgets have a \fB\-state\fR option which (in most cases) is either \fBnormal\fR or \fBdisabled\fR. Some widgets support additional states, such @@ -112,6 +119,7 @@ exclamation point indicating that the bit is cleared instead. .PP For example, the class bindings for the \fBttk::button\fR widget are: +.PP .CS bind TButton { %W state active } bind TButton { %W state !active } @@ -121,6 +129,7 @@ bind TButton { %W state pressed } bind TButton \e { %W instate {pressed} { %W state !pressed ; %W invoke } } .CE +.PP This specifies that the widget becomes \fBactive\fR when the pointer enters the widget, and inactive when it leaves. Similarly it becomes \fBpressed\fR when the mouse button is pressed, @@ -133,28 +142,31 @@ Finally, when the mouse button is released, the widget's in the \fBpressed\fR state. (The actual bindings are a little more complicated than the above, but not by much). -.PP -\fINote to self: rewrite that paragraph. It's horrible.\fR +'\" Note to self: rewrite that paragraph. It's horrible. .SH "STYLES" +.PP Each widget is associated with a \fIstyle\fR, which specifies values for element options. Style names use a recursive dotted notation like layouts and elements; by default, widgets use the class name to look up a style in the current theme. For example: +.PP .CS -ttk::style configure TButton \e +ttk::\fBstyle configure\fR TButton \e \-background #d9d9d9 \e \-foreground black \e \-relief raised \e ; .CE +.PP Many elements are displayed differently depending on the widget state. For example, buttons have a different background when they are active, a different foreground when disabled, and a different relief when pressed. The \fBstyle map\fR command specifies dynamic option settings for a particular style: +.PP .CS -ttk::style map TButton \e +ttk::\fBstyle map\fR TButton \e \-background [list disabled #d9d9d9 active #ececec] \e \-foreground [list disabled #a3a3a3] \e \-relief [list {pressed !disabled} sunken] \e @@ -162,3 +174,6 @@ ttk::style map TButton \e .CE .SH "SEE ALSO" ttk::widget(n), ttk::style(n) +'\" Local Variables: +'\" mode: nroff +'\" End: diff --git a/doc/ttk_label.n b/doc/ttk_label.n index 6592c08..3987585 100644 --- a/doc/ttk_label.n +++ b/doc/ttk_label.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_label.n,v 1.9.2.1 2008/05/11 00:31:01 patthoyts Exp $ +'\" RCS: @(#) $Id: ttk_label.n,v 1.9.2.2 2010/08/26 02:06:09 hobbs Exp $ '\" .so man.macros .TH ttk::label n 8.5 Tk "Tk Themed Widget" @@ -15,6 +15,7 @@ ttk::label \- Display a text string and/or image \fBttk::label\fR \fIpathName \fR?\fIoptions\fR? .BE .SH DESCRIPTION +.PP A \fBttk::label\fR widget displays a textual label and/or image. The label may be linked to a Tcl variable to automatically change the displayed text. @@ -68,8 +69,12 @@ then automatic wrapping is not performed; otherwise the text is split into lines such that no line is longer than the specified value. .SH "WIDGET COMMAND" +.PP Supports the standard widget commands \fBconfigure\fR, \fBcget\fR, \fBidentify\fR, \fBinstate\fR, and \fBstate\fR; see \fIttk::widget(n)\fR. .SH "SEE ALSO" ttk::widget(n), label(n) +'\" Local Variables: +'\" mode: nroff +'\" End: diff --git a/doc/ttk_labelframe.n b/doc/ttk_labelframe.n index 11681d6..44f2d4b 100644 --- a/doc/ttk_labelframe.n +++ b/doc/ttk_labelframe.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_labelframe.n,v 1.9.2.1 2008/05/11 00:31:03 patthoyts Exp $ +'\" RCS: @(#) $Id: ttk_labelframe.n,v 1.9.2.2 2010/08/26 02:06:09 hobbs Exp $ '\" .so man.macros .TH ttk::labelframe n 8.5 Tk "Tk Themed Widget" @@ -15,6 +15,7 @@ ttk::labelframe \- Container widget with optional label \fBttk::labelframe\fR \fIpathName \fR?\fIoptions\fR? .BE .SH DESCRIPTION +.PP A \fBttk::labelframe\fR widget is a container used to group other widgets together. It has an optional label, which may be a plain text string or another widget. @@ -64,6 +65,7 @@ If specified, the widget's requested height in pixels. (See \fIttk::frame(n)\fR for further notes on \fB\-width\fR and \fB\-height\fR). .SH "WIDGET COMMAND" +.PP Supports the standard widget commands \fBconfigure\fR, \fBcget\fR, \fBidentify\fR, \fBinstate\fR, and \fBstate\fR; see \fIttk::widget(n)\fR. @@ -71,3 +73,6 @@ see \fIttk::widget(n)\fR. ttk::widget(n), ttk::frame(n), labelframe(n) .SH "KEYWORDS" widget, frame, container, label, groupbox +'\" Local Variables: +'\" mode: nroff +'\" End: diff --git a/doc/ttk_menubutton.n b/doc/ttk_menubutton.n index a9baf7d..8552c6d 100644 --- a/doc/ttk_menubutton.n +++ b/doc/ttk_menubutton.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_menubutton.n,v 1.9.2.1 2008/05/11 00:31:03 patthoyts Exp $ +'\" RCS: @(#) $Id: ttk_menubutton.n,v 1.9.2.2 2010/08/26 02:06:09 hobbs Exp $ '\" .so man.macros .TH ttk::menubutton n 8.5 Tk "Tk Themed Widget" @@ -15,6 +15,7 @@ ttk::menubutton \- Widget that pops down a menu when pressed \fBttk::menubutton\fR \fIpathName \fR?\fIoptions\fR? .BE .SH DESCRIPTION +.PP A \fBttk::menubutton\fR widget displays a textual label and/or image, and displays a menu when pressed. .SO ttk_widget @@ -38,10 +39,18 @@ menubutton. .\" .OP \-anchor anchor Anchor .\" .OP \-padding padding Pad .SH "WIDGET COMMAND" +.PP Menubutton widgets support the standard \fBcget\fR, \fBconfigure\fR, \fBidentify\fR, \fBinstate\fR, and \fBstate\fR methods. No other widget methods are used. +.SH "STANDARD STYLES" +.PP +\fBTtk::menubutton\fR widgets support the \fBToolbutton\fR style in all +standard themes, which is useful for creating widgets for toolbars. .SH "SEE ALSO" ttk::widget(n), menu(n), menubutton(n) .SH "KEYWORDS" widget, button, menu +'\" Local Variables: +'\" mode: nroff +'\" End: diff --git a/doc/ttk_notebook.n b/doc/ttk_notebook.n index e8f8dbe..69c124a 100644 --- a/doc/ttk_notebook.n +++ b/doc/ttk_notebook.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_notebook.n,v 1.12.2.1 2008/05/11 00:31:03 patthoyts Exp $ +'\" RCS: @(#) $Id: ttk_notebook.n,v 1.12.2.2 2010/08/26 02:06:09 hobbs Exp $ '\" .so man.macros .TH ttk::notebook n 8.5 Tk "Tk Themed Widget" @@ -13,10 +13,10 @@ ttk::notebook \- Multi-paned container widget .SH SYNOPSIS .nf -\fBttk::notebook\fR \fIpathName \fR?\fIoptions...\fR? +\fBttk::notebook\fR \fIpathname \fR?\fIoptions...\fR? .br -\fIpathName \fBadd\fR \fIwindow\fR ?\fIoptions...\fR? -\fIpathName \fBinsert\fR \fIindex\fR \fIwindow\fR ?\fIoptions...\fR? +\fIpathname \fBadd\fR \fIwindow\fR ?\fIoptions...\fR? +\fIpathname \fBinsert\fR \fIindex\fR \fIwindow\fR ?\fIoptions...\fR? .fi .BE .SH DESCRIPTION @@ -124,9 +124,18 @@ The tab will not be displayed, but the associated window remains managed by the notebook and its configuration remembered. Hidden tabs may be restored with the \fBadd\fR command. .TP -\fIpathName \fBidentify\fR \fIx y\fR -Returns the name of the element at position \fIx\fR, \fIy\fR. -See \fIttk::widget(n)\fR. +\fIpathname \fBidentify\fR \fIcomponent\fR \fIx\fR \fIy\fR +Returns the name of the element under the point given by \fIx\fR and \fIy\fR, +or the empty string if no component is present at that location. +The following subcommands are supported: +.RS +.TP +\fIpathname \fBidentify\fR \fBelement\fR \fIx\fR \fIy\fR +Returns the name of the element at the specified location. +.TP +\fIpathname \fBidentify\fR \fBtab\fR \fIx\fR \fIy\fR +Returns the index of the tab at the specified location. +.RE .TP \fIpathname \fBindex\fR \fItabid\fR Returns the numeric index of the tab specified by \fItabid\fR, @@ -201,3 +210,6 @@ ttk::notebook::enableTraversal .nb ttk::widget(n), grid(n) .SH "KEYWORDS" pane, tab +'\" Local Variables: +'\" mode: nroff +'\" End: diff --git a/doc/ttk_panedwindow.n b/doc/ttk_panedwindow.n index 5955f56..89708ad 100644 --- a/doc/ttk_panedwindow.n +++ b/doc/ttk_panedwindow.n @@ -3,26 +3,27 @@ '\" '\" 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.15.2.1 2008/05/11 00:31:03 patthoyts Exp $ -'\" +'\" +'\" RCS: @(#) $Id: ttk_panedwindow.n,v 1.15.2.2 2010/08/26 02:06:09 hobbs Exp $ +'\" .so man.macros -.TH ttk::panedwindow n 8.5 Tk "Tk Themed Widget" +.TH ttk::panedwindow n 8.5.9 Tk "Tk Themed Widget" .BS .SH NAME ttk::panedwindow \- Multi-pane container window .SH SYNOPSIS .nf -\fBttk::panedwindow\fR \fIpathName \fR?\fIoptions\fR? +\fBttk::panedwindow\fR \fIpathname \fR?\fIoptions\fR? .br -\fIpathName \fBadd\fR \fIwindow\fR ?\fIoptions...\fR? -\fIpathName \fBinsert\fR \fIindex\fR \fIwindow\fR ?\fIoptions...\fR? +\fIpathname \fBadd\fR \fIwindow\fR ?\fIoptions...\fR? +\fIpathname \fBinsert\fR \fIindex\fR \fIwindow\fR ?\fIoptions...\fR? .fi .BE .SH DESCRIPTION -A \fBttk::panedwindow\fR widget displays a number of subwindows, stacked -either vertically or horizontally. The user may adjust the relative sizes -of the subwindows by dragging the sash between panes. +A \fBttk::panedwindow\fR widget displays a number of subwindows, +stacked either vertically or horizontally. +The user may adjust the relative sizes of the subwindows +by dragging the sash between panes. .SO ttk_widget \-class \-cursor \-takefocus \-style @@ -33,12 +34,12 @@ Specifies the orientation of the window. If \fBvertical\fR, subpanes are stacked top-to-bottom; if \fBhorizontal\fR, subpanes are stacked left-to-right. .OP \-width width Width -If present and greater than zero, +If present and greater than zero, specifies the desired width of the widget in pixels. Otherwise, the requested width is determined by the width of the managed windows. .OP \-height height Height -If present and greater than zero, +If present and greater than zero, specifies the desired height of the widget in pixels. Otherwise, the requested height is determined by the height of the managed windows. @@ -49,45 +50,57 @@ An integer specifying the relative stretchability of the pane. When the paned window is resized, the extra space is added or subtracted to each pane proportionally to its \fB\-weight\fR. .SH "WIDGET COMMAND" -Supports the standard \fBconfigure\fR, \fBcget\fR, \fBstate\fR, +Supports the standard \fBconfigure\fR, \fBcget\fR, \fBstate\fR, and \fBinstate\fR commands; see \fIttk::widget(n)\fR for details. Additional commands: .TP -\fIpathname \fBadd\fR \fIsubwindow\fR \fIoptions...\fR +\fIpathname\fR \fBadd\fR \fIsubwindow\fR \fIoptions...\fR Adds a new pane to the window. -\fIsubwindow\fR must be a direct child of the paned window \fIpathname\fR. See \fBPANE OPTIONS\fR for the list of available options. .TP -\fIpathname \fBforget\fR \fIpane\fR +\fIpathname\fR \fBforget\fR \fIpane\fR Removes the specified subpane from the widget. \fIpane\fR is either an integer index or the name of a managed subwindow. .TP -\fIpathname\fR \fBidentify\fR \fIx y\fR -Returns the index of the sash at point \fIx,y\fR, -or the empty string if \fIx,y\fR is not over a sash. +\fIpathname\fR \fBidentify\fR \fIcomponent\fR \fIx\fR \fIy\fR +Returns the name of the element under the point given by \fIx\fR and \fIy\fR, +or the empty string if no component is present at that location. +If \fIcomponent\fR is omitted, it defaults to \fBsash\fR. +The following subcommands are supported: +.RS +.TP +\fIpathname\fR \fBidentify\fR \fBelement\fR \fIx\fR \fIy\fR +Returns the name of the element at the specified location. .TP -\fIpathname \fBinsert\fR \fIpos\fR \fIsubwindow\fR \fIoptions...\fR +\fIpathname\fR \fBidentify\fR \fBsash\fR \fIx\fR \fIy\fR +Returns the index of the sash at the specified location. +.RE +.TP +\fIpathname\fR \fBinsert\fR \fIpos\fR \fIsubwindow\fR \fIoptions...\fR Inserts a pane at the specified position. -\fIpos\fR is either the string \fBend\fR, an integer index, +\fIpos\fR is either the string \fBend\fR, an integer index, or the name of a managed subwindow. -If \fIsubwindow\fR is already managed by the paned window, +If \fIsubwindow\fR is already managed by the paned window, moves it to the specified position. See \fBPANE OPTIONS\fR for the list of available options. .TP -\fIpathname \fBpane\fR \fIpane \-option \fR?\fIvalue \fR?\fI\-option value...\fR +\fIpathname\fR \fBpane\fR \fIpane \-option \fR?\fIvalue \fR?\fI\-option value...\fR Query or modify the options of the specified \fIpane\fR, where \fIpane\fR is either an integer index or the name of a managed subwindow. -If no \fI\-option\fR is specified, returns a dictionary of the pane +If no \fI\-option\fR is specified, returns a dictionary of the pane option values. If one \fI\-option\fR is specified, returns the value of that \fIoption\fR. Otherwise, sets the \fI\-option\fRs to the corresponding \fIvalue\fRs. .TP +\fIpathname\fR \fBpanes\fR +Returns the list of all windows managed by the widget. +.TP \fIpathname\fR \fBsashpos\fR \fIindex\fR ?\fInewpos\fR? -If \fInewpos\fR is specified, sets the position +If \fInewpos\fR is specified, sets the position of sash number \fIindex\fR. May adjust the positions of adjacent sashes to ensure that positions are monotonically increasing. -Sash positions are further constrained to be between 0 +Sash positions are further constrained to be between 0 and the total size of the widget. .\" Full story: "total size" is either the -height (resp -width), .\" or the actual window height (resp actual window width), @@ -96,3 +109,6 @@ Returns the new position of sash number \fIindex\fR. .\" Full story: new position may be different than the requested position. .SH "SEE ALSO" ttk::widget(n), ttk::notebook(n), panedwindow(n) +'\" Local Variables: +'\" mode: nroff +'\" End: diff --git a/doc/ttk_progressbar.n b/doc/ttk_progressbar.n index 0b97176..af3e312 100644 --- a/doc/ttk_progressbar.n +++ b/doc/ttk_progressbar.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_progressbar.n,v 1.10.2.1 2008/05/11 00:31:03 patthoyts Exp $ +'\" RCS: @(#) $Id: ttk_progressbar.n,v 1.10.2.2 2010/08/26 02:06:09 hobbs Exp $ '\" .so man.macros .TH ttk::progressbar n 8.5 Tk "Tk Themed Widget" @@ -15,6 +15,7 @@ ttk::progressbar \- Provide progress feedback \fBttk::progressbar\fR \fIpathName \fR?\fIoptions\fR? .BE .SH DESCRIPTION +.PP A \fBttk::progressbar\fR widget shows the status of a long-running operation. They can operate in two modes: \fIdeterminate\fR mode shows the amount completed relative to the total amount of work to be done, and @@ -56,6 +57,7 @@ in \fIdeterminate\fR mode, less than \fB\-maximum\fR. This option may be used by the current theme to provide additional animation effects. .SH "WIDGET COMMAND" +.PP .TP \fIpathName \fBcget\fR \fIoption\fR Returns the current value of the specified \fIoption\fR; see \fIttk::widget(n)\fR. @@ -88,3 +90,6 @@ Stop autoincrement mode: cancels any recurring timer event initiated by \fIpathName \fBstart\fR. .SH "SEE ALSO" ttk::widget(n) +'\" Local Variables: +'\" mode: nroff +'\" End: diff --git a/doc/ttk_radiobutton.n b/doc/ttk_radiobutton.n index 0880a39..8cb341a 100644 --- a/doc/ttk_radiobutton.n +++ b/doc/ttk_radiobutton.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_radiobutton.n,v 1.11.2.1 2008/05/11 00:31:03 patthoyts Exp $ +'\" RCS: @(#) $Id: ttk_radiobutton.n,v 1.11.2.2 2010/08/26 02:06:09 hobbs Exp $ '\" .so man.macros .TH ttk::radiobutton n 8.5 Tk "Tk Themed Widget" @@ -15,6 +15,7 @@ ttk::radiobutton \- Mutually exclusive option widget \fBttk::radiobutton\fR \fIpathName \fR?\fIoptions\fR? .BE .SH DESCRIPTION +.PP \fBttk::radiobutton\fR widgets are used in groups to show or change a set of mutually-exclusive options. Radiobuttons are linked to a Tcl variable, @@ -36,6 +37,7 @@ when the widget is selected. The name of a global variable whose value is linked to the widget. Default value is \fB::selectedButton\fR. .SH "WIDGET COMMAND" +.PP In addition to the standard \fBcget\fR, \fBconfigure\fR, \fBidentify\fR, \fBinstate\fR, and \fBstate\fR commands, radiobuttons support the following additional @@ -49,6 +51,7 @@ string if no \fB\-command\fR is specified. .\" Missing: select, deselect. Useful? .\" Missing: flash. This is definitely not useful. .SH "WIDGET STATES" +.PP The widget does not respond to user input if the \fBdisabled\fR state is set. The widget sets the \fBselected\fR state whenever the linked \fB\-variable\fR is set to the widget's \fB\-value\fR, @@ -60,7 +63,14 @@ linked \fB\-variable\fR is unset. or .QW indeterminate selection.) +.SH "STANDARD STYLES" +.PP +\fBTtk::radiobutton\fR widgets support the \fBToolbutton\fR style in all +standard themes, which is useful for creating widgets for toolbars. .SH "SEE ALSO" ttk::widget(n), ttk::checkbutton(n), radiobutton(n) .SH "KEYWORDS" widget, button, option +'\" Local Variables: +'\" mode: nroff +'\" End: diff --git a/doc/ttk_scale.n b/doc/ttk_scale.n index e9c8743..2358ddd 100644 --- a/doc/ttk_scale.n +++ b/doc/ttk_scale.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. .\" -.\" CVS: @(#) $Id: ttk_scale.n,v 1.1.4.1 2008/05/11 00:31:03 patthoyts Exp $ +.\" CVS: @(#) $Id: ttk_scale.n,v 1.1.4.2 2010/08/26 02:06:09 hobbs Exp $ .\" .so man.macros .TH ttk::scale n 8.5 Tk "Tk Themed Widget" @@ -15,6 +15,7 @@ ttk::scale \- Create and manipulate a scale widget \fBttk::scale \fIpathName \fR?\fIoptions...\fR? .BE .SH DESCRIPTION +.PP A \fBttk::scale\fR widget is typically used to control the numeric value of a linked variable that varies uniformly over some range. A scale displays a \fIslider\fR that can be moved along over a \fItrough\fR, with the relative @@ -49,6 +50,7 @@ value of the variable changes, the scale will update to reflect this value. Whenever the scale is manipulated interactively, the variable will be modified to reflect the scale's new value. .SH "WIDGET COMMAND" +.PP .TP \fIpathName \fBcget \fIoption\fR . @@ -84,6 +86,7 @@ named in the \fB\-variable\fR option) does not cause such clipping. . Modify or query the widget state; see \fIttk::widget(n)\fR. .SH "INTERNAL COMMANDS" +.PP .TP \fIpathName \fBcoords \fR?\fIvalue\fR? . diff --git a/doc/ttk_scrollbar.n b/doc/ttk_scrollbar.n index b42b160..eec877a 100644 --- a/doc/ttk_scrollbar.n +++ b/doc/ttk_scrollbar.n @@ -6,7 +6,7 @@ '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES. '\" '\" SOURCE: tk/doc/scrollbar.n, r1.4 -'\" RCS: @(#) $Id: ttk_scrollbar.n,v 1.12.2.1 2008/05/11 00:31:03 patthoyts Exp $ +'\" RCS: @(#) $Id: ttk_scrollbar.n,v 1.12.2.2 2010/08/26 02:06:09 hobbs Exp $ '\" .so man.macros .TH ttk::scrollbar n 8.5 Tk "Tk Themed Widget" @@ -17,6 +17,7 @@ ttk::scrollbar \- Control the viewport of a scrollable widget \fBttk::scrollbar\fR \fIpathName \fR?\fIoptions...\fR? .BE .SH DESCRIPTION +.PP \fBttk::scrollbar\fR widgets are typically linked to an associated window that displays a document of some sort, such as a file being edited or a drawing. @@ -48,6 +49,7 @@ or \fByview\fR (for vertical scrollbars). One of \fBhorizontal\fR or \fBvertical\fR. Specifies the orientation of the scrollbar. .SH "WIDGET COMMAND" +.PP .TP \fIpathName \fBcget\fR \fIoption\fR Returns the current value of the specified \fIoption\fR; see \fIttk::widget(n)\fR. @@ -75,6 +77,7 @@ Specifies the visible range to be displayed. \fIpathName \fBstate\fR ?\fIstateSpec\fR? Modify or query the widget state; see \fIttk::widget(n)\fR. .SH "INTERNAL COMMANDS" +.PP The following widget commands are used internally by the TScrollbar widget class bindings. .TP @@ -99,6 +102,7 @@ widget. If \fIx\fR and \fIy\fR refer to a point outside the trough, the closest point in the trough is used. .SH "SCROLLING COMMANDS" +.PP When the user interacts with the scrollbar, for example by dragging the thumb, the scrollbar notifies the associated widget that it must change its view. @@ -134,12 +138,14 @@ is a slight overlap between the old and new views. become visible, or \-1, which means that the previous page should become visible. .SH "WIDGET STATES" +.PP The scrollbar automatically sets the \fBdisabled\fR state bit. when the entire range is visible (range is 0.0 to 1.0), and clears it otherwise. It also sets the \fBactive\fR and \fBpressed\fR state flags of individual elements, based on the position and state of the mouse pointer. .SH EXAMPLE +.PP .CS set f [frame .f] ttk::scrollbar $f.hsb \-orient horizontal \-command [list $f.t xview] @@ -155,3 +161,6 @@ grid rowconfigure $f 0 \-weight 1 ttk::widget(n), scrollbar(n) .SH KEYWORDS scrollbar, widget +'\" Local Variables: +'\" mode: nroff +'\" End: diff --git a/doc/ttk_separator.n b/doc/ttk_separator.n index 9598b54..8aa91ea 100644 --- a/doc/ttk_separator.n +++ b/doc/ttk_separator.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_separator.n,v 1.8.2.1 2008/05/11 00:31:03 patthoyts Exp $ +'\" RCS: @(#) $Id: ttk_separator.n,v 1.8.2.2 2010/08/26 02:06:09 hobbs Exp $ '\" .so man.macros .TH ttk::separator n 8.5 Tk "Tk Themed Widget" @@ -15,6 +15,7 @@ ttk::separator \- Separator bar \fBttk::separator\fR \fIpathName \fR?\fIoptions\fR? .BE .SH DESCRIPTION +.PP A \fBttk::separator\fR widget displays a horizontal or vertical separator bar. .SO ttk_widget @@ -26,6 +27,7 @@ bar. One of \fBhorizontal\fR or \fBvertical\fR. Specifies the orientation of the separator. .SH "WIDGET COMMAND" +.PP Separator widgets support the standard \fBcget\fR, \fBconfigure\fR, \fBidentify\fR, \fBinstate\fR, and \fBstate\fR methods. No other widget methods are used. @@ -33,3 +35,6 @@ methods. No other widget methods are used. ttk::widget(n) .SH "KEYWORDS" widget, separator +'\" Local Variables: +'\" mode: nroff +'\" End: diff --git a/doc/ttk_sizegrip.n b/doc/ttk_sizegrip.n index 698f14d..304a56a 100644 --- a/doc/ttk_sizegrip.n +++ b/doc/ttk_sizegrip.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_sizegrip.n,v 1.15.2.1 2008/05/11 00:31:03 patthoyts Exp $ +'\" RCS: @(#) $Id: ttk_sizegrip.n,v 1.15.2.2 2010/08/26 02:06:09 hobbs Exp $ '\" .so man.macros .TH ttk::sizegrip n 8.5 Tk "Tk Themed Widget" @@ -15,6 +15,7 @@ ttk::sizegrip \- Bottom-right corner resize widget \fBttk::sizegrip\fR \fIpathName \fR?\fIoptions\fR? .BE .SH DESCRIPTION +.PP A \fBttk::sizegrip\fR widget (also known as a \fIgrow box\fR) allows the user to resize the containing toplevel window by pressing and dragging the grip. @@ -23,10 +24,12 @@ by pressing and dragging the grip. \-style \-takefocus .SE .SH "WIDGET COMMAND" +.PP Sizegrip widgets support the standard \fBcget\fR, \fBconfigure\fR, \fBidentify\fR, \fBinstate\fR, and \fBstate\fR methods. No other widget methods are used. .SH "PLATFORM-SPECIFIC NOTES" +.PP On Mac OSX, toplevel windows automatically include a built-in size grip by default. Adding a \fBttk::sizegrip\fR there is harmless, since @@ -47,6 +50,7 @@ grid [\fBttk::sizegrip\fR $top.statusbar.grip] \e # ... optional: add horizontal scrollbar in $lastRow .CE .SH "BUGS" +.PP If the containing toplevel's position was specified relative to the right or bottom of the screen (e.g., @@ -62,3 +66,6 @@ resizing. ttk::widget(n) .SH "KEYWORDS" widget, sizegrip, grow box +'\" Local Variables: +'\" mode: nroff +'\" End: diff --git a/doc/ttk_spinbox.n b/doc/ttk_spinbox.n new file mode 100644 index 0000000..854c2d1 --- /dev/null +++ b/doc/ttk_spinbox.n @@ -0,0 +1,88 @@ +'\" +'\" Copyright (c) 2008 Pat Thoyts +'\" +'\" See the file "license.terms" for information on usage and redistribution +'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES. +'\" +'\" RCS: @(#) $Id: ttk_spinbox.n,v 1.2.2.2 2010/08/26 02:06:09 hobbs Exp $ +'\" +.so man.macros +.TH ttk::spinbox n 8.5.9 Tk "Tk Themed Widget" +.BS +.SH NAME +ttk::spinbox \- Selecting text field widget +.SH SYNOPSIS +\fBttk::spinbox\fR \fIpathName \fR?\fIoptions\fR? +.BE +.SH DESCRIPTION +.PP +A \fBttk::spinbox\fR widget is a \fBttk::entry\fR widget with built-in +up and down buttons that are used to either modify a numeric value or +to select among a set of values. The widget implements all the features +of the \fBttk::entry\fR widget including support of the +\fB\-textvariable\fR option to link the value displayed by the widget +to a Tcl variable. +.SO ttk_widget +\-class \-cursor \-style +\-takefocus \-xscrollcommand +.SE +.SO ttk_entry +\-validate \-validatecommand +.SE +.SH "WIDGET-SPECIFIC OPTIONS" +.OP \-from from From +A floating\-point value specifying the lowest value for the spinbox. This is +used in conjunction with \fI\-to\fR and \fI\-increment\fR to set a numerical +range. +.OP \-to to To +A floating\-point value specifying the highest permissible value for the +widget. See also \fI\-from\fR and \fI\-increment\fR. +range. +.OP \-increment increment Increment +A floating\-point value specifying the change in value to be applied each +time one of the widget spin buttons is pressed. The up button applies a +positive increment, the down button applies a negative increment. +.OP \-values values Values +This must be a Tcl list of values. If this option is set then this will +override any range set using the \fI\-from\fR, \fI\-to\fR and +\fI\-increment\fR options. The widget will instead use the values +specified beginning with the first value. +.OP \-wrap wrap Wrap +Must be a proper boolean value. If on, the spinbox will wrap around the +values of data in the widget. +.OP \-format format Format +Specifies an alternate format to use when setting the string value +when using the \fB\-from\fR and \fB\-to\fR range. +This must be a format specifier of the form \fB%.f\fR, +as it will format a floating-point number. +.OP \-command command Command +Specifies a Tcl command to be invoked whenever a spinbutton is invoked. +.SH "INDICES" +.PP +See the \fBttk::entry\fR manual for information about indexing characters. +.SH "VALIDATION" +.PP +See the \fBttk::entry\fR manual for information about using the +\fI\-validate\fR and \fI\-validatecommand\fR options. +.SH "WIDGET COMMAND" +.PP +The following subcommands are possible for spinbox widgets in addition to +the commands described for the \fBttk::entry\fR widget: +.TP +\fIpathName \fBcurrent \fIindex\fR +.TP +\fIpathName \fBget\fR +Returns the spinbox's current value. +.TP +\fIpathName \fBset \fIvalue\fR +Set the spinbox string to \fIvalue\fR. If a \fI\-format\fR option has +been configured then this format will be applied. If formatting fails +or is not set or the \fI\-values\fR option has been used then the value +is set directly. +.SH "SEE ALSO" +ttk::widget(n), ttk::entry(n), spinbox(n) +.SH KEYWORDS +entry, spinbox, widget, text field +'\" Local Variables: +'\" mode: nroff +'\" End: diff --git a/doc/ttk_style.n b/doc/ttk_style.n index b5d4121..a459e9a 100644 --- a/doc/ttk_style.n +++ b/doc/ttk_style.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_style.n,v 1.13.2.1 2009/05/14 00:53:04 patthoyts Exp $ +'\" RCS: @(#) $Id: ttk_style.n,v 1.13.2.2 2010/08/26 02:06:09 hobbs Exp $ '\" .so man.macros .TH ttk::style n 8.5 Tk "Tk Themed Widget" @@ -15,9 +15,11 @@ ttk::style \- Manipulate style database \fBttk::style\fR \fIoption\fR ?\fIargs\fR? .BE .SH NOTES +.PP See also the Tcl'2004 conference presentation, available at http://tktable.sourceforge.net/tile/tile-tcl2004.pdf .SH DEFINITIONS +.PP Each widget is assigned a \fIstyle\fR, which specifies the set of elements making up the widget and how they are arranged, along with dynamic and default @@ -28,6 +30,7 @@ this may be overridden by the \fB\-style\fR option. A \fItheme\fR is a collection of elements and styles which controls the overall look and feel of an application. .SH DESCRIPTION +.PP The \fBttk::style\fR command takes the following arguments: .TP \fBttk::style configure \fIstyle\fR ?\fI\-option\fR ?\fIvalue option value...\fR? ? @@ -86,9 +89,12 @@ though arbitrary Tcl code may appear. \fBttk::style theme names\fR Returns a list of all known themes. .TP -\fBttk::style theme use\fR \fIthemeName\fR -Sets the current theme to \fIthemeName\fR, and refreshes all widgets. +\fBttk::style theme use\fR ?\fIthemeName\fR? +Without an argument the result is the name of the current theme. +Otherwise this command sets the current theme to \fIthemeName\fR, +and refreshes all widgets. .SH LAYOUTS +.PP A \fIlayout\fR specifies a list of elements, each followed by one or more options specifying how to arrange the element. The layout mechanism uses a simplified version of the \fBpack\fR @@ -122,3 +128,6 @@ ttk::style layout Horizontal.TScrollbar { ttk::intro(n), ttk::widget(n), photo(n), ttk_image(n) .SH KEYWORDS style, theme, appearance +'\" Local Variables: +'\" mode: nroff +'\" End: diff --git a/doc/ttk_treeview.n b/doc/ttk_treeview.n index fbe84b1..50bd38c 100644 --- a/doc/ttk_treeview.n +++ b/doc/ttk_treeview.n @@ -4,17 +4,18 @@ '\" See the file "license.terms" for information on usage and redistribution '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES. '\" -'\" RCS: @(#) $Id: ttk_treeview.n,v 1.17 2008/01/29 15:38:00 dkf Exp $ +'\" RCS: @(#) $Id: ttk_treeview.n,v 1.17.2.1 2010/08/26 02:06:09 hobbs Exp $ '\" .so man.macros -.TH ttk::treeview n 8.5 Tk "Tk Themed Widget" +.TH ttk::treeview n 8.5.9 Tk "Tk Themed Widget" .BS .SH NAME ttk::treeview \- hierarchical multicolumn data display widget .SH SYNOPSIS -\fBttk::treeview\fR \fIpathname \fR?\fIoptions\fR? +\fBttk::treeview \fIpathname \fR?\fIoptions\fR? .BE .SH DESCRIPTION +.PP The \fBttk::treeview\fR widget displays a hierarchical collection of items. Each item has a textual label, an optional image, and an optional list of data values. @@ -58,11 +59,8 @@ A list of column identifiers specifying which data columns are displayed and the order in which they appear, or the string \fB#all\fP. -.RS -.PP -If set to \fB#all\fP (the default), all columns are shown in the order -given. -.RE +If set to \fB#all\fP (the default), +all columns are shown in the order given. .OP \-height height Height Specifies the number of rows which should be visible. Note: @@ -98,20 +96,21 @@ The default is \fBtree headings\fR, i.e., show all elements. even if \fB\-show tree\fR is not specified. .RE .SH "WIDGET COMMAND" +.PP .TP -\fIpathname \fBbbox\fR \fIitem\fR ?\fIcolumn\fR? +\fIpathname \fBbbox \fIitem\fR ?\fIcolumn\fR? Returns the bounding box (relative to the treeview widget's window) of the specified \fIitem\fR in the form \fIx y width height\fR. If \fIcolumn\fR is specified, returns the bounding box of that cell. -If the \fIitem\fR is not visible +If the \fIitem\fR is not visible (i.e., if it is a descendant of a closed item or is scrolled offscreen), returns the empty list. .TP -\fIpathname \fBcget\fR \fIoption\fR +\fIpathname \fBcget \fIoption\fR Returns the current value of the specified \fIoption\fR; see \fIttk::widget(n)\fR. .TP -\fIpathname \fBchildren\fR \fIitem\fR ?\fInewchildren\fR? +\fIpathname \fBchildren \fIitem\fR ?\fInewchildren\fR? If \fInewchildren\fR is not specified, returns the list of children belonging to \fIitem\fR. .RS @@ -124,7 +123,7 @@ None of the items in \fInewchildren\fR may be an ancestor of \fIitem\fR. .RE .TP -\fIpathname \fBcolumn\fR \fIcolumn\fR ?\fI\-option \fR?\fIvalue \-option value...\fR? +\fIpathname \fBcolumn \fIcolumn\fR ?\fI\-option \fR?\fIvalue \-option value...\fR? Query or modify the options for the specified \fIcolumn\fR. If no \fI\-option\fR is specified, returns a dictionary of option/value pairs. @@ -165,16 +164,17 @@ Use \fIpathname column #0\fR to configure the tree column. \fIpathname \fBconfigure\fR ?\fIoption\fR? ?\fIvalue option value ...\fR? Modify or query widget options; see \fIttk::widget(n)\fR. .TP -\fIpathname \fBdelete\fR \fIitemList\fR +\fIpathname \fBdelete \fIitemList\fR Deletes each of the items in \fIitemList\fR and all of their descendants. The root item may not be deleted. See also: \fBdetach\fR. .TP -\fIpathname \fBdetach\fR \fIitemList\fR +\fIpathname \fBdetach \fIitemList\fR Unlinks all of the specified items in \fIitemList\fR from the tree. The items and all of their descendants are still present and may be reinserted at another point in the tree -but will not be displayed. +with the \fBmove\fR operation, +but will not be displayed until that is done. The root item may not be detached. See also: \fBdelete\fR. .TP @@ -187,7 +187,7 @@ If \fIitem\fR is specified, sets the focus item to \fIitem\fR. Otherwise, returns the current focus item, or \fB{}\fR if there is none. .\" Need: way to clear the focus item. {} works for this... .TP -\fIpathname \fBheading\fR \fIcolumn\fR ?\fI\-option \fR?\fIvalue \-option value...\fR? +\fIpathname \fBheading \fIcolumn\fR ?\fI\-option \fR?\fIvalue \-option value...\fR? Query or modify the heading options for the specified \fIcolumn\fR. Valid options are: .RS @@ -215,12 +215,35 @@ or the empty string if no such \fIcomponent\fR is present at that position. The following subcommands are supported: .RS .TP -\fIpathname \fBidentify row\fR \fIx y\fR +\fIpathname \fBidentify region \fIx y\fR +.RS +Returns one of: +.IP heading +Tree heading area; +use [\fBpathname identify column \fIx y\fR] +to determine the heading number. +.IP separator +Space between two column headings; +[\fBpathname identify column \fIx y\fR] +will return the display column identifier +of the heading to left of the separator. +.IP tree +The tree area. +.IP cell +A data cell. +.RE +\fIpathname \fBidentify item \fIx y\fR Returns the item ID of the item at position \fIy\fR. .TP -\fIpathname \fBidentify column\fR \fIx y\fR +\fIpathname \fBidentify column \fIx y\fR Returns the data column identifier of the cell at position \fIx\fR. The tree column has ID \fB#0\fR. +.TP +\fIpathname \fBidentify element \fIx y\fR +The element at position \fIx,y\fR. +.TP +\fIpathname \fBidentify row \fIx y\fR +Obsolescent synonym for \fIpathname \fBidentify item\fR. .PP See \fBCOLUMN IDENTIFIERS\fR for a discussion of display columns and data columns. @@ -229,7 +252,7 @@ and data columns. \fIpathname \fBindex \fIitem\fR Returns the integer index of \fIitem\fR within its parent's list of children. .TP -\fIpathname \fBinsert\fR \fIparent\fR \fIindex\fR ?\fB\-id \fIid\fR? \fIoptions...\fR +\fIpathname \fBinsert \fIparent index\fR ?\fB\-id \fIid\fR? \fIoptions...\fR Creates a new item. \fIparent\fR is the item ID of the parent item, or the empty string \fB{}\fR @@ -253,7 +276,7 @@ See \fBITEM OPTIONS\fR for the list of available options. \fIpathname \fBinstate \fIstatespec\fR ?\fIscript\fR? Test the widget state; see \fIttk::widget(n)\fR. .TP -\fIpathname \fBitem\fR \fIitem\fR ?\fI\-option \fR?\fIvalue \-option value...\fR? +\fIpathname \fBitem \fIitem\fR ?\fI\-option \fR?\fIvalue \-option value...\fR? Query or modify the options for the specified \fIitem\fR. If no \fI\-option\fR is specified, returns a dictionary of option/value pairs. @@ -284,13 +307,13 @@ or \fB{}\fR if \fIitem\fR is at the top level of the hierarchy. Returns the identifier of \fIitem\fR's previous sibling, or \fB{}\fR if \fIitem\fR is the first child of its parent. .TP -\fIpathname \fBsee\fR \fIitem\fR +\fIpathname \fBsee \fIitem\fR Ensure that \fIitem\fR is visible: sets all of \fIitem\fR's ancestors to \fB\-open true\fR, and scrolls the widget if necessary so that \fIitem\fR is within the visible portion of the tree. .TP -\fIpathname \fBselection\fR ?\fIselop\fR \fIitemList\fR? +\fIpathname \fBselection\fR ?\fIselop itemList\fR? If \fIselop\fR is not specified, returns the list of selected items. Otherwise, \fIselop\fR is one of the following: .RS @@ -308,9 +331,9 @@ Remove \fIitemList\fR from the selection Toggle the selection state of each item in \fIitemList\fR. .RE .TP -\fIpathname \fBset\fR \fIitem\fR ?\fIcolumn\fR? ?\fIvalue\fR? +\fIpathname \fBset \fIitem\fR ?\fIcolumn\fR? ?\fIvalue\fR? With one argument, returns a dictionary of column/value pairs -for the specified \fIitem\fR. +for the specified \fIitem\fR. With two arguments, returns the current value of the specified \fIcolumn\fR. With three arguments, sets the value of column \fIcolumn\fR in item \fIitem\fR to the specified \fIvalue\fR. @@ -339,7 +362,7 @@ The binding \fIscript\fR undergoes \fB%\fR-substitutions before evaluation; see \fBbind(n)\fR for details. .RE .TP -\fIpathName \fBtag configure\fR \fItagName\fR ?\fIoption\fR? ?\fIvalue option value...\fR? +\fIpathName \fBtag configure \fItagName\fR ?\fIoption\fR? ?\fIvalue option value...\fR? Query or modify the options for the specified \fItagName\fR. If one or more \fIoption/value\fR pairs are specified, sets the value of those options for the specified tag. @@ -349,6 +372,26 @@ returns the value of that option With no additional arguments, returns a dictionary of the option settings for \fItagName\fR. See \fBTAG OPTIONS\fR for the list of available options. +.TP +\fIpathName \fBtag has \fItagName\fR ?\fIitem\fR? +If \fIitem\fR is specified, returns 1 or 0 +depending on whether the specified item has the named tag. +Otherwise, returns a list of all items which have +the specified tag. +.TP +\fIpathName \fBtag names\fR +Returns a list of all tags used by the widget. +.TP +\fIpathName \fBtag add\fR \fItag\fR \fIitems\fR +Adds the specified \fItag\fR to each of the listed \fIitems\fR. +If \fItag\fR is already present for a particular item, +then the \fB-tags\fR for that item are unchanged. +.TP +\fIpathName \fBtag remove\fR \fItag\fR ?\fIitems\fR? +Removes the specified \fItag\fR from each of the listed \fIitems\fR. +If \fIitems\fR is omitted, removes \fItag\fR from each item in the tree. +If \fItag\fR is not present for a particular item, +then the \fB-tags\fR for that item are unchanged. .RE .TP \fIpathName \fBxview \fIargs\fR @@ -357,6 +400,7 @@ Standard command for horizontal scrolling; see \fIwidget(n)\fR. \fIpathName \fByview \fIargs\fR Standard command for vertical scrolling; see \fIttk::widget(n)\fR. .SH "ITEM OPTIONS" +.PP The following item options may be specified for items in the \fBinsert\fR and \fBitem\fR widget commands. .OP \-text text Text @@ -380,6 +424,7 @@ should be displayed (\fB\-open true\fR) or hidden (\fB\-open false\fR). .OP \-tags tags Tags A list of tags associated with this item. .SH "TAG OPTIONS" +.PP The following options may be specified on tags: .IP \fB\-foreground\fR Specifies the text foreground color. @@ -392,9 +437,10 @@ Specifies the font to use when drawing text. .\" ??? Maybe: .IP \-text .IP \fB\-image\fR Specifies the item image, in case the item's \fB\-image\fR option is empty. -.PP -\fI(@@@ TODO: sort out order of precedence for options)\fR +.\" .PP +.\" \fI(@@@ TODO: sort out order of precedence for options)\fR .SH "COLUMN IDENTIFIERS" +.PP Column identifiers take any of the following forms: .IP \(bu A symbolic name from the list of \fB\-columns\fR. @@ -419,6 +465,7 @@ If \fB\-displaycolumns\fR is not set, then data column \fIn\fR is displayed in display column \fB#\fIn+1\fR. Again, \fBcolumn #0 always refers to the tree column\fR. .SH "VIRTUAL EVENTS" +.PP The treeview widget generates the following virtual events. .IP <> Generated whenever the selection changes. @@ -434,3 +481,6 @@ to determine the affected item or items. '\" of the virtual event. .SH "SEE ALSO" ttk::widget(n), listbox(n), image(n), bind(n) +'\" Local Variables: +'\" mode: nroff +'\" End: diff --git a/doc/ttk_vsapi.n b/doc/ttk_vsapi.n index ef510dc..15f18fd 100644 --- a/doc/ttk_vsapi.n +++ b/doc/ttk_vsapi.n @@ -1,10 +1,10 @@ -'\" -*- nroff -*- +'\" '\" Copyright (c) 2008 Pat Thoyts '\" '\" See the file "license.terms" for information on usage and redistribution '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES. '\" -'\" RCS: @(#) $Id: ttk_vsapi.n,v 1.4.2.2 2009/05/14 00:53:04 patthoyts Exp $ +'\" RCS: @(#) $Id: ttk_vsapi.n,v 1.4.2.3 2010/08/26 02:06:09 hobbs Exp $ '\" .so man.macros .TH ttk_vsapi n 8.5 Tk "Tk Themed Widget" @@ -15,6 +15,7 @@ ttk_vsapi \- Define a Microsoft Visual Styles element \fBttk::style element create \fIname\fR \fBvsapi\fR \fIclassName\fR \fIpartId\fR ?\fIstateMap\fR? ?\fIoptions\fR? .BE .SH DESCRIPTION +.PP The \fIvsapi\fR element factory creates a new element in the current theme whose visual appearance is drawn using the Microsoft Visual Styles API which is reponsible for the themed styles @@ -27,6 +28,7 @@ the Visual Styles class and part as given in the Microsoft documentation. The \fIstateMap\fR may be provided to map ttk states to Visual Styles API states (see \fBSTATE MAP\fR). .SH "OPTIONS" +.PP Valid \fIoptions\fR are: .TP \fB\-padding\fR \fIpadding\fR @@ -51,6 +53,7 @@ be mixed with the \fI-padding\fR or \fI-margins\fR options. \fB\-height\fR \fIheight\fR Specifies the height of the element. See the comments for \fI-width\fR. .SH "STATE MAP" +.PP The \fIstateMap\fR parameter is a list of ttk states and the corresponding Visual Styles API state value. This permits the element appearence to respond to changes in the @@ -66,6 +69,7 @@ versions of the Windows Development Kit this is \fIvssym32.h\fR. If no \fIstateMap\fR parameter is given there is an implicit default map of {{} 1} .SH "EXAMPLE" +.PP Create a correctly themed close button by changing the layout of a \fBttk::button\fR(n). This uses the WINDOW part WP_SMALLCLOSEBUTTON and as documented the states CBS_DISABLED, CBS_HOT, CBS_NORMAL and @@ -95,3 +99,6 @@ pack [ttk::checkbutton .pin -style Explorer.Pin] ttk::intro(n), ttk::widget(n), ttk::style(n), ttk_image(n) .SH "KEYWORDS" style, theme, appearance, windows +'\" Local Variables: +'\" mode: nroff +'\" End: diff --git a/doc/ttk_widget.n b/doc/ttk_widget.n index 8b19f62..7c0ba88 100644 --- a/doc/ttk_widget.n +++ b/doc/ttk_widget.n @@ -1,13 +1,13 @@ '\" '\" Copyright (c) 2004 Joe English -'\" +'\" '\" See the file "license.terms" for information on usage and redistribution '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES. -'\" -'\" RCS: @(#) $Id: ttk_widget.n,v 1.13.2.2 2009/05/14 00:53:04 patthoyts Exp $ -'\" +'\" +'\" RCS: @(#) $Id: ttk_widget.n,v 1.13.2.3 2010/08/26 02:06:09 hobbs Exp $ +'\" .so man.macros -.TH ttk::widget n 8.5 Tk "Tk Themed Widget" +.TH ttk::widget n 8.5.9 Tk "Tk Themed Widget" .BS .SH NAME ttk::widget \- Standard options and commands supported by Tk themed widgets @@ -18,11 +18,11 @@ This manual describes common widget options and commands. The following options are supported by all Tk themed widgets: .OP \-class undefined undefined Specifies the window class. -The class is used when querying the option database +The class is used when querying the option database for the window's other options, to determine the default bindtags for the window, and to select the widget's default layout and style. -This is a read-only option: +This is a read-only option: it may only be specified when the window is created, and may not be changed with the \fBconfigure\fR widget command. .OP \-cursor cursor Cursor @@ -32,16 +32,16 @@ for the legal values. If set to the empty string (the default), the cursor is inherited from the parent widget. .OP \-takefocus takeFocus TakeFocus -Determines whether the window accepts the focus during keyboard traversal. +Determines whether the window accepts the focus during keyboard traversal. Either \fB0\fR, \fB1\fR, a command prefix (to which the widget path -is appended, and which should return \fB0\fR or \fB1\fR), +is appended, and which should return \fB0\fR or \fB1\fR), or the empty string. See \fIoptions(n)\fR in the Tk reference manual for the full description. .OP \-style style Style May be used to specify a custom widget style. .SH "SCROLLABLE WIDGET OPTIONS" The following options are supported by widgets that -are controllable by a scrollbar. +are controllable by a scrollbar. See \fIscrollbar(n)\fR for more information .OP \-xscrollcommand xScrollCommand ScrollCommand A command prefix, used to communicate with horizontal scrollbars. @@ -56,12 +56,12 @@ The first fraction indicates the first information in the widget that is visible in the window, and the second fraction indicates the information just after the last portion that is visible. .PP -Typically the \fBxScrollCommand\fR option consists of the path name +Typically the \fBxScrollCommand\fR option consists of the path name of a \fBscrollbar\fR widget followed by .QW set , e.g. .QW ".x.scrollbar set" . -This will cause the scrollbar to be updated whenever the view in the +This will cause the scrollbar to be updated whenever the view in the window changes. .PP If this option is set to the empty string (the default), @@ -80,7 +80,7 @@ Specifies a text string to be displayed inside the widget Specifies the name of variable whose value will be used in place of the \fB\-text\fR resource. .OP \-underline underline Underline -If set, specifies the integer index (0-based) of a character to underline +If set, specifies the integer index (0-based) of a character to underline in the text string. The underlined character is used for mnemonic activation. .OP \-image image Image @@ -94,7 +94,7 @@ All images in the list should have the same size. .OP \-compound compound Compound Specifies how to display the image relative to the text, in the case both \fB\-text\fR and \fB\-image\fR are present. -Valid values are: +Valid values are: .RS .IP text Display text only. @@ -111,8 +111,8 @@ Display image above, below, left of, or right of the text, respectively. The default; display the image if present, otherwise the text. .RE .OP \-width width Width -If greater than zero, specifies how much space, in character widths, -to allocate for the text label. +If greater than zero, specifies how much space, in character widths, +to allocate for the text label. If less than zero, specifies a minimum width. If zero or unspecified, the natural width of the text label is used. .SH "COMPATIBILITY OPTIONS" @@ -120,10 +120,9 @@ If zero or unspecified, the natural width of the text label is used. May be set to \fBnormal\fR or \fBdisabled\fR to control the \fBdisabled\fR state bit. This is a write-only option: -setting it changes the widget state, -but the \fBstate\fR widget command +setting it changes the widget state, +but the \fBstate\fR widget command does not affect the \fB\-state\fR option. - .SH COMMANDS .TP \fIpathName \fBcget\fR \fIoption\fR @@ -133,36 +132,37 @@ by \fIoption\fR. \fIpathName \fBconfigure\fR ?\fIoption\fR? ?\fIvalue option value ...\fR? Query or modify the configuration options of the widget. If one or more \fIoption\-value\fR pairs are specified, -then the command modifies the given widget option(s) -to have the given value(s); +then the command modifies the given widget option(s) +to have the given value(s); in this case the command returns an empty string. -If \fIoption\fR is specified with no \fIvalue\fR, +If \fIoption\fR is specified with no \fIvalue\fR, then the command returns a list describing the named option: -the elements of the list are the -option name, database name, database class, default value, +the elements of the list are the +option name, database name, database class, default value, and current value. .\" Note: Ttk widgets don't use TK_OPTION_SYNONYM. If no \fIoption\fR is specified, returns a list describing all of the available options for \fIpathName\fR. .TP -\fIpathName \fBidentify\fR \fIx y\fR -Returns the name of the element under the point given +\fIpathName \fBidentify\fR \fBelement\fR \fIx y\fR +Returns the name of the element under the point given by \fIx\fR and \fIy\fR, or an empty string if the point does not lie within any element. \fIx\fR and \fIy\fR are pixel coordinates relative to the widget. -.TP +Some widgets accept other \fBidentify\fR subcommands. +.TP \fIpathName \fBinstate\fR \fIstatespec\fR ?\fIscript\fR? Test the widget's state. -If \fIscript\fR is not specified, returns 1 if +If \fIscript\fR is not specified, returns 1 if the widget state matches \fIstatespec\fR and 0 otherwise. If \fIscript\fR is specified, equivalent to .CS if {[\fIpathName\fR instate \fIstateSpec\fR]} \fIscript\fR .CE -.TP +.TP \fIpathName \fBstate\fR ?\fIstateSpec\fR? Modify or inquire widget state. -If \fIstateSpec\fR is present, sets the widget state: +If \fIstateSpec\fR is present, sets the widget state: for each flag in \fIstateSpec\fR, sets the corresponding flag or clears it if prefixed by an exclamation point. .RS @@ -172,7 +172,7 @@ set changes [\fIpathName \fRstate \fIspec\fR] \fIpathName \fRstate $changes .CE will restore \fIpathName\fR to the original state. -If \fIstateSpec\fR is not specified, +If \fIstateSpec\fR is not specified, returns a list of the currently-enabled state flags. .RE .SH "WIDGET STATES" @@ -180,7 +180,7 @@ The widget state is a bitmap of independent state flags. Widget state flags include: .TP \fBactive\fR -The mouse cursor is over the widget +The mouse cursor is over the widget and pressing a mouse button will cause some action to occur. (aka .QW prelight (Gnome), @@ -191,22 +191,22 @@ and pressing a mouse button will cause some action to occur. (aka \fBdisabled\fR Widget is disabled under program control (aka .QW unavailable , -.QW inactive ) +.QW inactive ) .TP \fBfocus\fR -Widget has keyboard focus +Widget has keyboard focus .TP \fBpressed\fR Widget is being pressed (aka .QW armed -in Motif). +in Motif). .TP \fBselected\fR .QW On , .QW true , or .QW current -for things like checkbuttons and radiobuttons. +for things like checkbuttons and radiobuttons. .TP \fBbackground\fR Windows and the Mac have a notion of an @@ -228,7 +228,7 @@ state, and for buttons with \fB\-default active\fR. .TP \fBinvalid\fR The widget's value is invalid. -(Potential uses: scale widget value out of bounds, +(Potential uses: scale widget value out of bounds, entry widget value failed validation.) .TP \fBhover\fR @@ -256,6 +256,9 @@ $b instate {pressed !disabled} { .b invoke } $b state !disabled .CE .SH "SEE ALSO" -ttk::intro(n), style(n) +ttk::intro(n), ttk::style(n) .SH KEYWORDS state, configure, option +'\" Local Variables: +'\" mode: nroff +'\" End: diff --git a/generic/ttk/ttk.decls b/generic/ttk/ttk.decls index 889a130..66a0191 100644 --- a/generic/ttk/ttk.decls +++ b/generic/ttk/ttk.decls @@ -1,5 +1,5 @@ # -# $Id: ttk.decls,v 1.2.4.1 2010/02/07 23:24:13 nijtmans Exp $ +# $Id: ttk.decls,v 1.2.4.2 2010/08/26 02:06:09 hobbs Exp $ # library ttk @@ -34,7 +34,7 @@ declare 5 current { } declare 6 current { - Ttk_ElementImpl Ttk_RegisterElement( + Ttk_ElementClass *Ttk_RegisterElement( Tcl_Interp *interp, Ttk_Theme theme, const char *elementName, diff --git a/generic/ttk/ttkButton.c b/generic/ttk/ttkButton.c index bae3e6a..64c5d7e 100644 --- a/generic/ttk/ttkButton.c +++ b/generic/ttk/ttkButton.c @@ -1,4 +1,4 @@ -/* $Id: ttkButton.c,v 1.8 2007/12/13 15:26:24 dgp Exp $ +/* $Id: ttkButton.c,v 1.8.2.1 2010/08/26 02:06:09 hobbs Exp $ * Copyright (c) 2003, Joe English * * label, button, checkbutton, radiobutton, and menubutton widgets. @@ -57,24 +57,24 @@ typedef struct static Tk_OptionSpec BaseOptionSpecs[] = { {TK_OPTION_STRING, "-text", "text", "Text", "", - Tk_Offset(Base,base.textObj), -1, + Tk_Offset(Base,base.textObj), -1, 0,0,GEOMETRY_CHANGED }, {TK_OPTION_STRING, "-textvariable", "textVariable", "Variable", "", - Tk_Offset(Base,base.textVariableObj), -1, + Tk_Offset(Base,base.textVariableObj), -1, TK_OPTION_NULL_OK,0,GEOMETRY_CHANGED }, {TK_OPTION_INT, "-underline", "underline", "Underline", - "-1", Tk_Offset(Base,base.underlineObj), -1, + "-1", Tk_Offset(Base,base.underlineObj), -1, 0,0,0 }, /* SB: OPTION_INT, see <> */ {TK_OPTION_STRING, "-width", "width", "Width", - NULL, Tk_Offset(Base,base.widthObj), -1, + NULL, Tk_Offset(Base,base.widthObj), -1, TK_OPTION_NULL_OK,0,GEOMETRY_CHANGED }, /* * Image options */ {TK_OPTION_STRING, "-image", "image", "Image", NULL/*default*/, - Tk_Offset(Base,base.imageObj), -1, + Tk_Offset(Base,base.imageObj), -1, TK_OPTION_NULL_OK,0,GEOMETRY_CHANGED }, /* @@ -118,13 +118,12 @@ static void TextVariableChanged(void *clientData, const char *value) TtkResizeWidget(&basePtr->core); } -static int +static void BaseInitialize(Tcl_Interp *interp, void *recordPtr) { Base *basePtr = recordPtr; basePtr->base.textVariableTrace = 0; basePtr->base.imageSpec = NULL; - return TCL_OK; } static void @@ -133,7 +132,7 @@ BaseCleanup(void *recordPtr) Base *basePtr = recordPtr; if (basePtr->base.textVariableTrace) Ttk_UntraceVariable(basePtr->base.textVariableTrace); - if (basePtr->base.imageSpec) + if (basePtr->base.imageSpec) TtkFreeImageSpec(basePtr->base.imageSpec); } @@ -220,23 +219,23 @@ typedef struct static Tk_OptionSpec LabelOptionSpecs[] = { - {TK_OPTION_BORDER, "-background", "frameColor", "FrameColor", + {TK_OPTION_BORDER, "-background", "frameColor", "FrameColor", NULL, Tk_Offset(Label,label.backgroundObj), -1, TK_OPTION_NULL_OK,0,0 }, - {TK_OPTION_COLOR, "-foreground", "textColor", "TextColor", + {TK_OPTION_COLOR, "-foreground", "textColor", "TextColor", NULL, Tk_Offset(Label,label.foregroundObj), -1, TK_OPTION_NULL_OK,0,0 }, {TK_OPTION_FONT, "-font", "font", "Font", NULL, Tk_Offset(Label,label.fontObj), -1, TK_OPTION_NULL_OK,0,GEOMETRY_CHANGED }, - {TK_OPTION_PIXELS, "-borderwidth", "borderWidth", "BorderWidth", + {TK_OPTION_PIXELS, "-borderwidth", "borderWidth", "BorderWidth", NULL, Tk_Offset(Label,label.borderWidthObj), -1, TK_OPTION_NULL_OK,0,GEOMETRY_CHANGED }, {TK_OPTION_RELIEF, "-relief", "relief", "Relief", NULL, Tk_Offset(Label,label.reliefObj), -1, TK_OPTION_NULL_OK,0,GEOMETRY_CHANGED }, {TK_OPTION_ANCHOR, "-anchor", "anchor", "Anchor", - NULL, Tk_Offset(Label,label.anchorObj), -1, + NULL, Tk_Offset(Label,label.anchorObj), -1, TK_OPTION_NULL_OK, 0, GEOMETRY_CHANGED}, {TK_OPTION_JUSTIFY, "-justify", "justify", "Justify", NULL, Tk_Offset(Label, label.justifyObj), -1, @@ -248,14 +247,13 @@ static Tk_OptionSpec LabelOptionSpecs[] = WIDGET_INHERIT_OPTIONS(BaseOptionSpecs) }; -static WidgetCommandSpec LabelCommands[] = -{ - { "configure", TtkWidgetConfigureCommand }, - { "cget", TtkWidgetCgetCommand }, - { "instate", TtkWidgetInstateCommand }, - { "state", TtkWidgetStateCommand }, - { "identify", TtkWidgetIdentifyCommand }, - { NULL, NULL } +static const Ttk_Ensemble LabelCommands[] = { + { "configure", TtkWidgetConfigureCommand,0 }, + { "cget", TtkWidgetCgetCommand,0 }, + { "instate", TtkWidgetInstateCommand,0 }, + { "state", TtkWidgetStateCommand,0 }, + { "identify", TtkWidgetIdentifyCommand,0 }, + { 0,0,0 } }; static WidgetSpec LabelWidgetSpec = @@ -342,7 +340,7 @@ static int ButtonConfigure(Tcl_Interp *interp, void *recordPtr, int mask) */ static int ButtonInvokeCommand( - Tcl_Interp *interp, int objc, Tcl_Obj *const objv[], void *recordPtr) + void *recordPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]) { Button *buttonPtr = recordPtr; if (objc > 2) { @@ -355,15 +353,14 @@ ButtonInvokeCommand( return Tcl_EvalObjEx(interp, buttonPtr->button.commandObj, TCL_EVAL_GLOBAL); } -static WidgetCommandSpec ButtonCommands[] = -{ - { "configure", TtkWidgetConfigureCommand }, - { "cget", TtkWidgetCgetCommand }, - { "invoke", ButtonInvokeCommand }, - { "instate", TtkWidgetInstateCommand }, - { "state", TtkWidgetStateCommand }, - { "identify", TtkWidgetIdentifyCommand }, - { NULL, NULL } +static const Ttk_Ensemble ButtonCommands[] = { + { "configure", TtkWidgetConfigureCommand,0 }, + { "cget", TtkWidgetCgetCommand,0 }, + { "invoke", ButtonInvokeCommand,0 }, + { "instate", TtkWidgetInstateCommand,0 }, + { "state", TtkWidgetStateCommand,0 }, + { "identify", TtkWidgetIdentifyCommand,0 }, + { 0,0,0 } }; static WidgetSpec ButtonWidgetSpec = @@ -418,13 +415,17 @@ static Tk_OptionSpec CheckbuttonOptionSpecs[] = WIDGET_TAKES_FOCUS, {TK_OPTION_STRING, "-variable", "variable", "Variable", - "", Tk_Offset(Checkbutton, checkbutton.variableObj), -1, 0,0,0}, + "", Tk_Offset(Checkbutton, checkbutton.variableObj), -1, + TK_OPTION_DONT_SET_DEFAULT,0,0}, {TK_OPTION_STRING, "-onvalue", "onValue", "OnValue", - "1", Tk_Offset(Checkbutton, checkbutton.onValueObj), -1, 0,0,0}, + "1", Tk_Offset(Checkbutton, checkbutton.onValueObj), -1, + 0,0,0}, {TK_OPTION_STRING, "-offvalue", "offValue", "OffValue", - "0", Tk_Offset(Checkbutton, checkbutton.offValueObj), -1, 0,0,0}, + "0", Tk_Offset(Checkbutton, checkbutton.offValueObj), -1, + 0,0,0}, {TK_OPTION_STRING, "-command", "command", "Command", - "", Tk_Offset(Checkbutton, checkbutton.commandObj), -1, 0,0,0}, + "", Tk_Offset(Checkbutton, checkbutton.commandObj), -1, + 0,0,0}, WIDGET_INHERIT_OPTIONS(BaseOptionSpecs) }; @@ -453,19 +454,18 @@ static void CheckbuttonVariableChanged(void *clientData, const char *value) } } -static int CheckbuttonInitialize(Tcl_Interp *interp, void *recordPtr) +static void +CheckbuttonInitialize(Tcl_Interp *interp, void *recordPtr) { Checkbutton *checkPtr = recordPtr; - Tcl_Obj *objPtr; + Tcl_Obj *variableObj; /* default -variable is the widget name: */ - objPtr = Tcl_NewStringObj(Tk_PathName(checkPtr->core.tkwin), -1); - Tcl_IncrRefCount(objPtr); - Tcl_DecrRefCount(checkPtr->checkbutton.variableObj); - checkPtr->checkbutton.variableObj = objPtr; - - return BaseInitialize(interp, recordPtr); + variableObj = Tcl_NewStringObj(Tk_PathName(checkPtr->core.tkwin), -1); + Tcl_IncrRefCount(variableObj); + checkPtr->checkbutton.variableObj = variableObj; + BaseInitialize(interp, recordPtr); } static void @@ -519,7 +519,7 @@ CheckbuttonPostConfigure(Tcl_Interp *interp, void *recordPtr, int mask) */ static int CheckbuttonInvokeCommand( - Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[], void *recordPtr) + void *recordPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]) { Checkbutton *checkPtr = recordPtr; WidgetCore *corePtr = &checkPtr->core; @@ -553,16 +553,15 @@ CheckbuttonInvokeCommand( checkPtr->checkbutton.commandObj, TCL_EVAL_GLOBAL); } -static WidgetCommandSpec CheckbuttonCommands[] = -{ - { "configure", TtkWidgetConfigureCommand }, - { "cget", TtkWidgetCgetCommand }, - { "invoke", CheckbuttonInvokeCommand }, - { "instate", TtkWidgetInstateCommand }, - { "state", TtkWidgetStateCommand }, - { "identify", TtkWidgetIdentifyCommand }, +static const Ttk_Ensemble CheckbuttonCommands[] = { + { "configure", TtkWidgetConfigureCommand,0 }, + { "cget", TtkWidgetCgetCommand,0 }, + { "invoke", CheckbuttonInvokeCommand,0 }, + { "instate", TtkWidgetInstateCommand,0 }, + { "state", TtkWidgetStateCommand,0 }, + { "identify", TtkWidgetIdentifyCommand,0 }, /* MISSING: select, deselect, toggle */ - { NULL, NULL } + { 0,0,0 } }; static WidgetSpec CheckbuttonWidgetSpec = @@ -632,7 +631,7 @@ static Tk_OptionSpec RadiobuttonOptionSpecs[] = /* * Variable trace procedure for radiobuttons. */ -static void +static void RadiobuttonVariableChanged(void *clientData, const char *value) { Radiobutton *radioPtr = clientData; @@ -705,7 +704,7 @@ RadiobuttonPostConfigure(Tcl_Interp *interp, void *recordPtr, int mask) */ static int RadiobuttonInvokeCommand( - Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[], void *recordPtr) + void *recordPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]) { Radiobutton *radioPtr = recordPtr; WidgetCore *corePtr = &radioPtr->core; @@ -731,16 +730,15 @@ RadiobuttonInvokeCommand( radioPtr->radiobutton.commandObj, TCL_EVAL_GLOBAL); } -static WidgetCommandSpec RadiobuttonCommands[] = -{ - { "configure", TtkWidgetConfigureCommand }, - { "cget", TtkWidgetCgetCommand }, - { "invoke", RadiobuttonInvokeCommand }, - { "instate", TtkWidgetInstateCommand }, - { "state", TtkWidgetStateCommand }, - { "identify", TtkWidgetIdentifyCommand }, +static const Ttk_Ensemble RadiobuttonCommands[] = { + { "configure", TtkWidgetConfigureCommand,0 }, + { "cget", TtkWidgetCgetCommand,0 }, + { "invoke", RadiobuttonInvokeCommand,0 }, + { "instate", TtkWidgetInstateCommand,0 }, + { "state", TtkWidgetStateCommand,0 }, + { "identify", TtkWidgetIdentifyCommand,0 }, /* MISSING: select, deselect */ - { NULL, NULL } + { 0,0,0 } }; static WidgetSpec RadiobuttonWidgetSpec = @@ -786,7 +784,7 @@ typedef struct /* * Option specifications: */ -static const char *directionStrings[] = { +static const char *const directionStrings[] = { "above", "below", "left", "right", "flush", NULL }; static Tk_OptionSpec MenubuttonOptionSpecs[] = @@ -802,14 +800,13 @@ static Tk_OptionSpec MenubuttonOptionSpecs[] = WIDGET_INHERIT_OPTIONS(BaseOptionSpecs) }; -static WidgetCommandSpec MenubuttonCommands[] = -{ - { "configure", TtkWidgetConfigureCommand }, - { "cget", TtkWidgetCgetCommand }, - { "instate", TtkWidgetInstateCommand }, - { "state", TtkWidgetStateCommand }, - { "identify", TtkWidgetIdentifyCommand }, - { NULL, NULL } +static const Ttk_Ensemble MenubuttonCommands[] = { + { "configure", TtkWidgetConfigureCommand,0 }, + { "cget", TtkWidgetCgetCommand,0 }, + { "instate", TtkWidgetInstateCommand,0 }, + { "state", TtkWidgetStateCommand,0 }, + { "identify", TtkWidgetIdentifyCommand,0 }, + { 0,0,0 } }; static WidgetSpec MenubuttonWidgetSpec = diff --git a/generic/ttk/ttkCache.c b/generic/ttk/ttkCache.c index a12bf30..9456d25 100644 --- a/generic/ttk/ttkCache.c +++ b/generic/ttk/ttkCache.c @@ -1,6 +1,6 @@ /* - * $Id: ttkCache.c,v 1.1 2006/10/31 01:42:26 hobbs Exp $ - * Ttk theme engine, resource cache. + * $Id: ttkCache.c,v 1.1.4.1 2010/08/26 02:06:09 hobbs Exp $ + * Theme engine resource cache. * * Copyright (c) 2004, Joe English * @@ -77,7 +77,7 @@ static void Ttk_ClearCache(Ttk_ResourceCache cache) */ entryPtr = Tcl_FirstHashEntry(&cache->fontTable, &search); while (entryPtr != NULL) { - Tcl_Obj *fontObj = (Tcl_Obj*)Tcl_GetHashValue(entryPtr); + Tcl_Obj *fontObj = Tcl_GetHashValue(entryPtr); if (fontObj) { Tk_FreeFontFromObj(cache->tkwin, fontObj); Tcl_DecrRefCount(fontObj); @@ -92,7 +92,7 @@ static void Ttk_ClearCache(Ttk_ResourceCache cache) */ entryPtr = Tcl_FirstHashEntry(&cache->colorTable, &search); while (entryPtr != NULL) { - Tcl_Obj *colorObj = (Tcl_Obj*)Tcl_GetHashValue(entryPtr); + Tcl_Obj *colorObj = Tcl_GetHashValue(entryPtr); if (colorObj) { Tk_FreeColorFromObj(cache->tkwin, colorObj); Tcl_DecrRefCount(colorObj); @@ -107,7 +107,7 @@ static void Ttk_ClearCache(Ttk_ResourceCache cache) */ entryPtr = Tcl_FirstHashEntry(&cache->borderTable, &search); while (entryPtr != NULL) { - Tcl_Obj *borderObj = (Tcl_Obj*)Tcl_GetHashValue(entryPtr); + Tcl_Obj *borderObj = Tcl_GetHashValue(entryPtr); if (borderObj) { Tk_Free3DBorderFromObj(cache->tkwin, borderObj); Tcl_DecrRefCount(borderObj); @@ -122,7 +122,7 @@ static void Ttk_ClearCache(Ttk_ResourceCache cache) */ entryPtr = Tcl_FirstHashEntry(&cache->imageTable, &search); while (entryPtr != NULL) { - Tk_Image image = (Tk_Image)Tcl_GetHashValue(entryPtr); + Tk_Image image = Tcl_GetHashValue(entryPtr); if (image) { Tk_FreeImage(image); } @@ -141,7 +141,7 @@ static void Ttk_ClearCache(Ttk_ResourceCache cache) void Ttk_FreeResourceCache(Ttk_ResourceCache cache) { - Tcl_HashEntry *entryPtr; + Tcl_HashEntry *entryPtr; Tcl_HashSearch search; Ttk_ClearCache(cache); @@ -155,7 +155,7 @@ void Ttk_FreeResourceCache(Ttk_ResourceCache cache) */ entryPtr = Tcl_FirstHashEntry(&cache->namedColors, &search); while (entryPtr != NULL) { - Tcl_Obj *colorNameObj = (Tcl_Obj*)Tcl_GetHashValue(entryPtr); + Tcl_Obj *colorNameObj = Tcl_GetHashValue(entryPtr); Tcl_DecrRefCount(colorNameObj); entryPtr = Tcl_NextHashEntry(&search); } @@ -170,7 +170,7 @@ void Ttk_FreeResourceCache(Ttk_ResourceCache cache) */ static void CacheWinEventHandler(ClientData clientData, XEvent *eventPtr) { - Ttk_ResourceCache cache = (Ttk_ResourceCache)clientData; + Ttk_ResourceCache cache = clientData; if (eventPtr->type != DestroyNotify) { return; @@ -192,7 +192,7 @@ static void InitCacheWindow(Ttk_ResourceCache cache, Tk_Window tkwin) if (cache->tkwin == NULL) { cache->tkwin = tkwin; Tk_CreateEventHandler(tkwin, StructureNotifyMask, - CacheWinEventHandler, (ClientData)cache); + CacheWinEventHandler, cache); } } @@ -200,10 +200,9 @@ static void InitCacheWindow(Ttk_ResourceCache cache, Tk_Window tkwin) * Ttk_RegisterNamedColor -- * Specify an RGB triplet as a named color. * Overrides any previous named color specification. - * */ void Ttk_RegisterNamedColor( - Ttk_ResourceCache cache, + Ttk_ResourceCache cache, const char *colorName, XColor *colorPtr) { @@ -212,18 +211,18 @@ void Ttk_RegisterNamedColor( char nameBuf[14]; Tcl_Obj *colorNameObj; - sprintf(nameBuf, "#%04X%04X%04X", + sprintf(nameBuf, "#%04X%04X%04X", colorPtr->red, colorPtr->green, colorPtr->blue); colorNameObj = Tcl_NewStringObj(nameBuf, -1); Tcl_IncrRefCount(colorNameObj); entryPtr = Tcl_CreateHashEntry(&cache->namedColors, colorName, &newEntry); if (!newEntry) { - Tcl_Obj *oldColor = (Tcl_Obj*)Tcl_GetHashValue(entryPtr); + Tcl_Obj *oldColor = Tcl_GetHashValue(entryPtr); Tcl_DecrRefCount(oldColor); } - Tcl_SetHashValue(entryPtr, (ClientData)colorNameObj); + Tcl_SetHashValue(entryPtr, colorNameObj); } /* @@ -234,10 +233,10 @@ void Ttk_RegisterNamedColor( */ static Tcl_Obj *CheckNamedColor(Ttk_ResourceCache cache, Tcl_Obj *objPtr) { - Tcl_HashEntry *entryPtr = + Tcl_HashEntry *entryPtr = Tcl_FindHashEntry(&cache->namedColors, Tcl_GetString(objPtr)); if (entryPtr) { /* Use named color instead */ - objPtr = (Tcl_Obj *)Tcl_GetHashValue(entryPtr); + objPtr = Tcl_GetHashValue(entryPtr); } return objPtr; } @@ -249,7 +248,7 @@ typedef void *(*Allocator)(Tcl_Interp *, Tk_Window, Tcl_Obj *); static Tcl_Obj *Ttk_Use( Tcl_Interp *interp, - Tcl_HashTable *table, + Tcl_HashTable *table, Allocator allocate, Tk_Window tkwin, Tcl_Obj *objPtr) @@ -260,7 +259,7 @@ static Tcl_Obj *Ttk_Use( Tcl_Obj *cacheObj; if (!newEntry) { - return (Tcl_Obj*)Tcl_GetHashValue(entryPtr); + return Tcl_GetHashValue(entryPtr); } cacheObj = Tcl_DuplicateObj(objPtr); @@ -336,7 +335,7 @@ Tk_Image Ttk_UseImage(Ttk_ResourceCache cache, Tk_Window tkwin, Tcl_Obj *objPtr) InitCacheWindow(cache, tkwin); if (!newEntry) { - return (Tk_Image)Tcl_GetHashValue(entryPtr); + return Tcl_GetHashValue(entryPtr); } image = Tk_GetImage(cache->interp, tkwin, imageName, NullImageChanged,0); diff --git a/generic/ttk/ttkClamTheme.c b/generic/ttk/ttkClamTheme.c index 2557046..1451127 100644 --- a/generic/ttk/ttkClamTheme.c +++ b/generic/ttk/ttkClamTheme.c @@ -1,5 +1,5 @@ /* - * $Id: ttkClamTheme.c,v 1.9.2.1 2008/07/04 19:06:03 jenglish Exp $ + * $Id: ttkClamTheme.c,v 1.9.2.2 2010/08/26 02:06:09 hobbs Exp $ * * Copyright (C) 2004 Joe English * @@ -119,7 +119,7 @@ static Ttk_ElementOptionSpec BorderElementOptions[] = { Tk_Offset(BorderElement,reliefObj), "flat" }, { "-borderwidth", TK_OPTION_PIXELS, Tk_Offset(BorderElement,borderWidthObj), "2" }, - {0,0,0} + { NULL, 0, 0, NULL } }; /* @@ -207,7 +207,7 @@ static Ttk_ElementOptionSpec FieldElementOptions[] = { Tk_Offset(FieldElement,darkColorObj), DARK_COLOR }, { "-fieldbackground", TK_OPTION_BORDER, Tk_Offset(FieldElement,backgroundObj), "white" }, - {0,0,0} + { NULL, 0, 0, NULL } }; static void FieldElementSize( @@ -293,7 +293,7 @@ static Ttk_ElementOptionSpec IndicatorElementOptions[] = { Tk_Offset(IndicatorElement,upperColorObj), DARKEST_COLOR }, { "-lowerbordercolor", TK_OPTION_COLOR, Tk_Offset(IndicatorElement,lowerColorObj), DARK_COLOR }, - {0,0,0} + { NULL, 0, 0, NULL } }; static void IndicatorElementSize( @@ -412,7 +412,7 @@ static Ttk_ElementOptionSpec MenuIndicatorElementOptions[] = { "-arrowpadding",TK_OPTION_STRING, Tk_Offset(MenuIndicatorElement,paddingObj), "3" }, - { NULL } + { NULL, 0, 0, NULL } }; static void MenuIndicatorElementSize( @@ -478,7 +478,7 @@ static Ttk_ElementOptionSpec GripElementOptions[] = { Tk_Offset(GripElement,borderColorObj), DARKEST_COLOR }, { "-gripcount", TK_OPTION_INT, Tk_Offset(GripElement,gripCountObj), "5" }, - {0,0,0} + { NULL, 0, 0, NULL } }; static void GripElementSize( @@ -577,7 +577,7 @@ static Ttk_ElementOptionSpec ScrollbarElementOptions[] = { Tk_Offset(ScrollbarElement,gripCountObj), "5" }, { "-sliderlength", TK_OPTION_INT, Tk_Offset(ScrollbarElement,sliderlengthObj), "30" }, - {0,0,0} + { NULL, 0, 0, NULL } }; static void TroughElementDraw( @@ -803,7 +803,7 @@ static Ttk_ElementOptionSpec NotebookElementOptions[] = { Tk_Offset(NotebookElement,lightColorObj), LIGHT_COLOR }, { "-darkcolor", TK_OPTION_COLOR, Tk_Offset(NotebookElement,darkColorObj), DARK_COLOR }, - {0,0,0} + { NULL, 0, 0, NULL } }; static void TabElementSize( diff --git a/generic/ttk/ttkClassicTheme.c b/generic/ttk/ttkClassicTheme.c index f71ca30..c4102d4 100644 --- a/generic/ttk/ttkClassicTheme.c +++ b/generic/ttk/ttkClassicTheme.c @@ -1,5 +1,5 @@ /* - * $Id: ttkClassicTheme.c,v 1.6.2.1 2008/07/04 19:06:03 jenglish Exp $ + * $Id: ttkClassicTheme.c,v 1.6.2.2 2010/08/26 02:06:09 hobbs Exp $ * * Copyright (c) 2004, Joe English * @@ -30,7 +30,7 @@ static Ttk_ElementOptionSpec HighlightElementOptions[] = { Tk_Offset(HighlightElement,highlightColorObj), DEFAULT_BACKGROUND }, { "-highlightthickness",TK_OPTION_PIXELS, Tk_Offset(HighlightElement,highlightThicknessObj), "0" }, - {NULL} + { NULL, 0, 0, NULL } }; static void HighlightElementSize( @@ -95,7 +95,7 @@ static Ttk_ElementOptionSpec ButtonBorderElementOptions[] = Tk_Offset(ButtonBorderElement,reliefObj), "flat" }, { "-default", TK_OPTION_ANY, Tk_Offset(ButtonBorderElement,defaultStateObj), "disabled" }, - {NULL} + { NULL, 0, 0, NULL } }; static void ButtonBorderElementSize( @@ -208,7 +208,7 @@ static Ttk_ElementOptionSpec ArrowElementOptions[] = { "-borderwidth", TK_OPTION_PIXELS, Tk_Offset(ArrowElement,borderWidthObj), DEFAULT_BORDERWIDTH }, { "-relief", TK_OPTION_RELIEF, Tk_Offset(ArrowElement,reliefObj),"raised" }, - { NULL } + { NULL, 0, 0, NULL } }; static void ArrowElementSize( @@ -320,7 +320,7 @@ static Ttk_ElementOptionSpec SashOptions[] = { Tk_Offset(SashElement,handleSizeObj), "8" }, { "-handlepad", TK_OPTION_PIXELS, Tk_Offset(SashElement,handlePadObj), "8" }, - {0,0,0} + { NULL, 0, 0, NULL } }; static void SashElementSize( diff --git a/generic/ttk/ttkDecls.h b/generic/ttk/ttkDecls.h index 0bdcd93..a7c28aa 100644 --- a/generic/ttk/ttkDecls.h +++ b/generic/ttk/ttkDecls.h @@ -1,5 +1,5 @@ /* - * $Id: ttkDecls.h,v 1.6.2.1 2010/02/07 23:24:13 nijtmans Exp $ + * $Id: ttkDecls.h,v 1.6.2.2 2010/08/26 02:06:09 hobbs Exp $ * * This file is (mostly) automatically generated from ttk.decls. */ @@ -25,8 +25,6 @@ extern const char *TtkInitializeStubs( #define TTK_STUBS_EPOCH 0 #define TTK_STUBS_REVISION 31 -#if !defined(USE_TTK_STUBS) - /* * Exported function declarations: */ @@ -50,7 +48,7 @@ TTKAPI int Ttk_RegisterElementSpec(Ttk_Theme theme, Ttk_ElementSpec *elementSpec, void *clientData); /* 6 */ -TTKAPI Ttk_ElementImpl Ttk_RegisterElement(Tcl_Interp *interp, +TTKAPI Ttk_ElementClass * Ttk_RegisterElement(Tcl_Interp *interp, Ttk_Theme theme, const char *elementName, Ttk_ElementSpec *elementSpec, void *clientData); @@ -133,13 +131,11 @@ TTKAPI Tcl_Obj * Ttk_NewBoxObj(Ttk_Box box); TTKAPI int Ttk_GetOrientFromObj(Tcl_Interp *interp, Tcl_Obj *objPtr, int *orient); -#endif /* !defined(USE_TTK_STUBS) */ - typedef struct TtkStubs { int magic; int epoch; int revision; - struct TtkStubHooks *hooks; + const struct TtkStubHooks *hooks; Ttk_Theme (*ttk_GetTheme) (Tcl_Interp *interp, const char *name); /* 0 */ Ttk_Theme (*ttk_GetDefaultTheme) (Tcl_Interp *interp); /* 1 */ @@ -147,7 +143,7 @@ typedef struct TtkStubs { Ttk_Theme (*ttk_CreateTheme) (Tcl_Interp *interp, const char *name, Ttk_Theme parent); /* 3 */ void (*ttk_RegisterCleanup) (Tcl_Interp *interp, void *deleteData, Ttk_CleanupProc *cleanupProc); /* 4 */ int (*ttk_RegisterElementSpec) (Ttk_Theme theme, const char *elementName, Ttk_ElementSpec *elementSpec, void *clientData); /* 5 */ - Ttk_ElementImpl (*ttk_RegisterElement) (Tcl_Interp *interp, Ttk_Theme theme, const char *elementName, Ttk_ElementSpec *elementSpec, void *clientData); /* 6 */ + Ttk_ElementClass * (*ttk_RegisterElement) (Tcl_Interp *interp, Ttk_Theme theme, const char *elementName, Ttk_ElementSpec *elementSpec, void *clientData); /* 6 */ int (*ttk_RegisterElementFactory) (Tcl_Interp *interp, const char *name, Ttk_ElementFactory factoryProc, void *clientData); /* 7 */ void (*ttk_RegisterLayout) (Ttk_Theme theme, const char *className, Ttk_LayoutSpec layoutSpec); /* 8 */ void (*reserved9)(void); @@ -198,140 +194,78 @@ extern const TtkStubs *ttkStubsPtr; * Inline function declarations: */ -#ifndef Ttk_GetTheme #define Ttk_GetTheme \ (ttkStubsPtr->ttk_GetTheme) /* 0 */ -#endif -#ifndef Ttk_GetDefaultTheme #define Ttk_GetDefaultTheme \ (ttkStubsPtr->ttk_GetDefaultTheme) /* 1 */ -#endif -#ifndef Ttk_GetCurrentTheme #define Ttk_GetCurrentTheme \ (ttkStubsPtr->ttk_GetCurrentTheme) /* 2 */ -#endif -#ifndef Ttk_CreateTheme #define Ttk_CreateTheme \ (ttkStubsPtr->ttk_CreateTheme) /* 3 */ -#endif -#ifndef Ttk_RegisterCleanup #define Ttk_RegisterCleanup \ (ttkStubsPtr->ttk_RegisterCleanup) /* 4 */ -#endif -#ifndef Ttk_RegisterElementSpec #define Ttk_RegisterElementSpec \ (ttkStubsPtr->ttk_RegisterElementSpec) /* 5 */ -#endif -#ifndef Ttk_RegisterElement #define Ttk_RegisterElement \ (ttkStubsPtr->ttk_RegisterElement) /* 6 */ -#endif -#ifndef Ttk_RegisterElementFactory #define Ttk_RegisterElementFactory \ (ttkStubsPtr->ttk_RegisterElementFactory) /* 7 */ -#endif -#ifndef Ttk_RegisterLayout #define Ttk_RegisterLayout \ (ttkStubsPtr->ttk_RegisterLayout) /* 8 */ -#endif /* Slot 9 is reserved */ -#ifndef Ttk_GetStateSpecFromObj #define Ttk_GetStateSpecFromObj \ (ttkStubsPtr->ttk_GetStateSpecFromObj) /* 10 */ -#endif -#ifndef Ttk_NewStateSpecObj #define Ttk_NewStateSpecObj \ (ttkStubsPtr->ttk_NewStateSpecObj) /* 11 */ -#endif -#ifndef Ttk_GetStateMapFromObj #define Ttk_GetStateMapFromObj \ (ttkStubsPtr->ttk_GetStateMapFromObj) /* 12 */ -#endif -#ifndef Ttk_StateMapLookup #define Ttk_StateMapLookup \ (ttkStubsPtr->ttk_StateMapLookup) /* 13 */ -#endif -#ifndef Ttk_StateTableLookup #define Ttk_StateTableLookup \ (ttkStubsPtr->ttk_StateTableLookup) /* 14 */ -#endif /* Slot 15 is reserved */ /* Slot 16 is reserved */ /* Slot 17 is reserved */ /* Slot 18 is reserved */ /* Slot 19 is reserved */ -#ifndef Ttk_GetPaddingFromObj #define Ttk_GetPaddingFromObj \ (ttkStubsPtr->ttk_GetPaddingFromObj) /* 20 */ -#endif -#ifndef Ttk_GetBorderFromObj #define Ttk_GetBorderFromObj \ (ttkStubsPtr->ttk_GetBorderFromObj) /* 21 */ -#endif -#ifndef Ttk_GetStickyFromObj #define Ttk_GetStickyFromObj \ (ttkStubsPtr->ttk_GetStickyFromObj) /* 22 */ -#endif -#ifndef Ttk_MakePadding #define Ttk_MakePadding \ (ttkStubsPtr->ttk_MakePadding) /* 23 */ -#endif -#ifndef Ttk_UniformPadding #define Ttk_UniformPadding \ (ttkStubsPtr->ttk_UniformPadding) /* 24 */ -#endif -#ifndef Ttk_AddPadding #define Ttk_AddPadding \ (ttkStubsPtr->ttk_AddPadding) /* 25 */ -#endif -#ifndef Ttk_RelievePadding #define Ttk_RelievePadding \ (ttkStubsPtr->ttk_RelievePadding) /* 26 */ -#endif -#ifndef Ttk_MakeBox #define Ttk_MakeBox \ (ttkStubsPtr->ttk_MakeBox) /* 27 */ -#endif -#ifndef Ttk_BoxContains #define Ttk_BoxContains \ (ttkStubsPtr->ttk_BoxContains) /* 28 */ -#endif -#ifndef Ttk_PackBox #define Ttk_PackBox \ (ttkStubsPtr->ttk_PackBox) /* 29 */ -#endif -#ifndef Ttk_StickBox #define Ttk_StickBox \ (ttkStubsPtr->ttk_StickBox) /* 30 */ -#endif -#ifndef Ttk_AnchorBox #define Ttk_AnchorBox \ (ttkStubsPtr->ttk_AnchorBox) /* 31 */ -#endif -#ifndef Ttk_PadBox #define Ttk_PadBox \ (ttkStubsPtr->ttk_PadBox) /* 32 */ -#endif -#ifndef Ttk_ExpandBox #define Ttk_ExpandBox \ (ttkStubsPtr->ttk_ExpandBox) /* 33 */ -#endif -#ifndef Ttk_PlaceBox #define Ttk_PlaceBox \ (ttkStubsPtr->ttk_PlaceBox) /* 34 */ -#endif -#ifndef Ttk_NewBoxObj #define Ttk_NewBoxObj \ (ttkStubsPtr->ttk_NewBoxObj) /* 35 */ -#endif /* Slot 36 is reserved */ /* Slot 37 is reserved */ /* Slot 38 is reserved */ /* Slot 39 is reserved */ -#ifndef Ttk_GetOrientFromObj #define Ttk_GetOrientFromObj \ (ttkStubsPtr->ttk_GetOrientFromObj) /* 40 */ -#endif #endif /* defined(USE_TTK_STUBS) */ diff --git a/generic/ttk/ttkDefaultTheme.c b/generic/ttk/ttkDefaultTheme.c index 118934e..07bc3ec 100644 --- a/generic/ttk/ttkDefaultTheme.c +++ b/generic/ttk/ttkDefaultTheme.c @@ -1,4 +1,4 @@ -/* $Id: ttkDefaultTheme.c,v 1.11.2.1 2008/07/04 19:06:03 jenglish Exp $ +/* $Id: ttkDefaultTheme.c,v 1.11.2.2 2010/08/26 02:06:09 hobbs Exp $ * * Copyright (c) 2003, Joe English * @@ -39,8 +39,7 @@ static const int WIN32_XDRAWLINE_HACK = 0; enum BorderColor { FLAT = 1, LITE = 2, DARK = 3, BRDR = 4 }; /* top-left outer, top-left inner, bottom-right inner, bottom-right outer */ -static int shadowColors[6][4] = -{ +static int const shadowColors[6][4] = { { FLAT, FLAT, FLAT, FLAT }, /* TK_RELIEF_FLAT = 0*/ { DARK, LITE, DARK, LITE }, /* TK_RELIEF_GROOVE = 1*/ { LITE, FLAT, DARK, BRDR }, /* TK_RELIEF_RAISED = 2*/ @@ -50,8 +49,7 @@ static int shadowColors[6][4] = }; /* top-left, bottom-right */ -static int thinShadowColors[6][4] = -{ +static int const thinShadowColors[6][4] = { { FLAT, FLAT }, /* TK_RELIEF_FLAT = 0*/ { DARK, LITE }, /* TK_RELIEF_GROOVE = 1*/ { LITE, DARK }, /* TK_RELIEF_RAISED = 2*/ @@ -204,7 +202,7 @@ void TtkArrowSize(int h, ArrowDirection dir, int *widthPtr, int *heightPtr) * TtkDrawArrow, TtkFillArrow -- * Draw an arrow in the indicated direction inside the specified box. */ -/*public*/ +/*public*/ void TtkFillArrow( Display *display, Drawable d, GC gc, Ttk_Box b, ArrowDirection dir) { @@ -214,7 +212,7 @@ void TtkFillArrow( XDrawLines(display, d, gc, points, 4, CoordModeOrigin); } -/*public*/ +/*public*/ void TtkDrawArrow( Display *display, Drawable d, GC gc, Ttk_Box b, ArrowDirection dir) { @@ -234,8 +232,7 @@ void TtkDrawArrow( * + 1 pixel padding (???) */ -typedef struct -{ +typedef struct { Tcl_Obj *borderObj; Tcl_Obj *borderColorObj; /* Extra border color */ Tcl_Obj *borderWidthObj; @@ -243,8 +240,7 @@ typedef struct Tcl_Obj *defaultStateObj; /* for buttons */ } BorderElement; -static Ttk_ElementOptionSpec BorderElementOptions[] = -{ +static Ttk_ElementOptionSpec BorderElementOptions[] = { { "-background", TK_OPTION_BORDER, Tk_Offset(BorderElement,borderObj), DEFAULT_BACKGROUND }, { "-bordercolor",TK_OPTION_COLOR, @@ -255,7 +251,7 @@ static Ttk_ElementOptionSpec BorderElementOptions[] = STRINGIFY(BORDERWIDTH) }, { "-relief", TK_OPTION_RELIEF, Tk_Offset(BorderElement,reliefObj), "flat" }, - {NULL} + { NULL, 0, 0, NULL } }; static void BorderElementSize( @@ -296,7 +292,7 @@ static void BorderElementDraw( if (defaultState == TTK_BUTTON_DEFAULT_ACTIVE) { GC gc = Tk_GCForColor(borderColor, d); - XDrawRectangle(Tk_Display(tkwin), d, gc, + XDrawRectangle(Tk_Display(tkwin), d, gc, b.x, b.y, b.width-1, b.height-1); } if (defaultState != TTK_BUTTON_DEFAULT_DISABLED) { @@ -307,8 +303,7 @@ static void BorderElementDraw( DrawBorder(tkwin, d, border, borderColor, b, borderWidth, relief); } -static Ttk_ElementSpec BorderElementSpec = -{ +static Ttk_ElementSpec BorderElementSpec = { TK_STYLE_VERSION_2, sizeof(BorderElement), BorderElementOptions, @@ -320,19 +315,17 @@ static Ttk_ElementSpec BorderElementSpec = * +++ Field element: * Used for editable fields. */ -typedef struct -{ +typedef struct { Tcl_Obj *borderObj; Tcl_Obj *borderColorObj; /* Extra border color */ } FieldElement; -static Ttk_ElementOptionSpec FieldElementOptions[] = -{ +static Ttk_ElementOptionSpec FieldElementOptions[] = { { "-fieldbackground", TK_OPTION_BORDER, Tk_Offset(FieldElement,borderObj), "white" }, { "-bordercolor",TK_OPTION_COLOR, Tk_Offset(FieldElement,borderColorObj), "black" }, - {NULL} + { NULL, 0, 0, NULL } }; static void FieldElementSize( @@ -355,8 +348,7 @@ static void FieldElementDraw( DrawFieldBorder(tkwin, d, border, borderColor, b); } -static Ttk_ElementSpec FieldElementSpec = -{ +static Ttk_ElementSpec FieldElementSpec = { TK_STYLE_VERSION_2, sizeof(FieldElement), FieldElementOptions, @@ -374,41 +366,40 @@ static Ttk_ElementSpec FieldElementSpec = /* * Indicator bitmap descriptor: */ -typedef struct -{ +typedef struct { int width; /* Width of each image */ int height; /* Height of each image */ int nimages; /* #images / row */ - char **pixels; /* array[height] of char[width*nimage] */ + const char *const *pixels; /* array[height] of char[width*nimage] */ Ttk_StateTable *map;/* used to look up image index by state */ } IndicatorSpec; #if 0 /*XPM*/ -static char *button_images[] = { +static const char *const button_images[] = { /* width height ncolors chars_per_pixel */ - "52 26 7 1", + "52 13 8 1", /* colors */ - "A c #808000000000 s background", - "B c #000080800000 s background", - "C c #808080800000 s highlight", - "D c #000000008080 s select", - "E c #808000008080 s shadow", - "F c #000080808080 s background", - "G c #000000000000 s indicator", - "H c #000080800000 s disabled", + "A c #808000000000 s shadow", + "B c #000080800000 s highlight", + "C c #808080800000 s 3dlight", + "D c #000000008080 s window", + "E c #808000008080 s 3ddark", + "F c #000080808080 s frame", + "G c #000000000000 s foreground", + "H c #000080800000 s disabledfg", }; #endif -static Ttk_StateTable checkbutton_states[] = -{ +static Ttk_StateTable checkbutton_states[] = { { 0, 0, TTK_STATE_SELECTED|TTK_STATE_DISABLED }, { 1, TTK_STATE_SELECTED, TTK_STATE_DISABLED }, { 2, TTK_STATE_DISABLED, TTK_STATE_SELECTED }, { 3, TTK_STATE_SELECTED|TTK_STATE_DISABLED, 0 }, { 0, 0, 0 } }; -static char *checkbutton_pixels[] = { + +static const char *const checkbutton_pixels[] = { "AAAAAAAAAAAABAAAAAAAAAAAABAAAAAAAAAAAABAAAAAAAAAAAAB", "AEEEEEEEEEECBAEEEEEEEEEECBAEEEEEEEEEECBAEEEEEEEEEECB", "AEDDDDDDDDDCBAEDDDDDDDDDCBAEFFFFFFFFFCBAEFFFFFFFFFCB", @@ -424,15 +415,13 @@ static char *checkbutton_pixels[] = { "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB", }; -static IndicatorSpec checkbutton_spec = -{ +static IndicatorSpec checkbutton_spec = { 13, 13, 4, /* width, height, nimages */ checkbutton_pixels, checkbutton_states }; -static Ttk_StateTable radiobutton_states[] = -{ +static Ttk_StateTable radiobutton_states[] = { { 0, 0, TTK_STATE_SELECTED|TTK_STATE_DISABLED }, { 1, TTK_STATE_SELECTED, TTK_STATE_DISABLED }, { 2, TTK_STATE_DISABLED, TTK_STATE_SELECTED }, @@ -440,10 +429,10 @@ static Ttk_StateTable radiobutton_states[] = { 0, 0, 0 } }; -static char *radiobutton_pixels[] = { +static const char *const radiobutton_pixels[] = { "FFFFAAAAFFFFFFFFFAAAAFFFFFFFFFAAAAFFFFFFFFFAAAAFFFFF", "FFAAEEEEAAFFFFFAAEEEEAAFFFFFAAEEEEAAFFFFFAAEEEEAAFFF", - "FAEEDDDDECBFFFAEEDDDDECBFFFAEEFFFFECBFFFAEEFFFFECBFF", + "FAEEDDDDEEBFFFAEEDDDDEEBFFFAEEFFFFEEBFFFAEEFFFFEEBFF", "FAEDDDDDDCBFFFAEDDDDDDCBFFFAEFFFFFFCBFFFAEFFFFFFCBFF", "AEDDDDDDDDCBFAEDDDGGDDDCBFAEFFFFFFFFCBFAEFFFHHFFFCBF", "AEDDDDDDDDCBFAEDDGGGGDDCBFAEFFFFFFFFCBFAEFFHHHHFFCBF", @@ -456,38 +445,38 @@ static char *radiobutton_pixels[] = { "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", }; -static IndicatorSpec radiobutton_spec = -{ +static IndicatorSpec radiobutton_spec = { 13, 13, 4, /* width, height, nimages */ radiobutton_pixels, radiobutton_states }; -typedef struct -{ +typedef struct { Tcl_Obj *backgroundObj; Tcl_Obj *foregroundObj; Tcl_Obj *colorObj; Tcl_Obj *lightColorObj; Tcl_Obj *shadeColorObj; + Tcl_Obj *borderColorObj; Tcl_Obj *marginObj; } IndicatorElement; -static Ttk_ElementOptionSpec IndicatorElementOptions[] = -{ - { "-background", TK_OPTION_BORDER, +static Ttk_ElementOptionSpec IndicatorElementOptions[] = { + { "-background", TK_OPTION_COLOR, Tk_Offset(IndicatorElement,backgroundObj), DEFAULT_BACKGROUND }, { "-foreground", TK_OPTION_COLOR, Tk_Offset(IndicatorElement,foregroundObj), DEFAULT_FOREGROUND }, - { "-indicatorcolor", TK_OPTION_BORDER, + { "-indicatorcolor", TK_OPTION_COLOR, Tk_Offset(IndicatorElement,colorObj), "#FFFFFF" }, { "-lightcolor", TK_OPTION_COLOR, Tk_Offset(IndicatorElement,lightColorObj), "#DDDDDD" }, { "-shadecolor", TK_OPTION_COLOR, Tk_Offset(IndicatorElement,shadeColorObj), "#888888" }, + { "-bordercolor", TK_OPTION_COLOR, + Tk_Offset(IndicatorElement,borderColorObj), "black" }, { "-indicatormargin", TK_OPTION_STRING, Tk_Offset(IndicatorElement,marginObj), "0 2 4 2" }, - {NULL} + { NULL, 0, 0, NULL } }; static void IndicatorElementSize( @@ -509,9 +498,8 @@ static void IndicatorElementDraw( IndicatorSpec *spec = clientData; IndicatorElement *indicator = elementRecord; Display *display = Tk_Display(tkwin); - Tk_3DBorder bgBorder; Ttk_Padding padding; - XColor *fgColor, *bgColor, *lightColor, *shadeColor, *selectColor; + XColor *fgColor, *frameColor, *lightColor, *shadeColor, *indicatorColor, *borderColor; int index, ix, iy; XGCValues gcValues; @@ -540,20 +528,20 @@ static void IndicatorElementDraw( * but Tk doesn't provide easy access to these in the public API.) */ fgColor = Tk_GetColorFromObj(tkwin, indicator->foregroundObj); - bgBorder = Tk_Get3DBorderFromObj(tkwin, indicator->backgroundObj); - bgColor = Tk_3DBorderColor(bgBorder); + frameColor = Tk_GetColorFromObj(tkwin, indicator->backgroundObj); lightColor = Tk_GetColorFromObj(tkwin, indicator->lightColorObj); shadeColor = Tk_GetColorFromObj(tkwin, indicator->shadeColorObj); - selectColor = Tk_GetColorFromObj(tkwin, indicator->colorObj); - - imgColors[0 /*A*/] = bgColor->pixel; - imgColors[1 /*B*/] = bgColor->pixel; - imgColors[2 /*C*/] = lightColor->pixel; - imgColors[3 /*D*/] = selectColor->pixel; - imgColors[4 /*E*/] = shadeColor->pixel; - imgColors[5 /*F*/] = bgColor->pixel; + indicatorColor = Tk_GetColorFromObj(tkwin, indicator->colorObj); + borderColor = Tk_GetColorFromObj(tkwin, indicator->borderColorObj); + + imgColors[0 /*A*/] = shadeColor->pixel; + imgColors[1 /*B*/] = indicatorColor->pixel; + imgColors[2 /*C*/] = frameColor->pixel; + imgColors[3 /*D*/] = indicatorColor->pixel; + imgColors[4 /*E*/] = borderColor->pixel; + imgColors[5 /*F*/] = frameColor->pixel; imgColors[6 /*G*/] = fgColor->pixel; - imgColors[7 /*H*/] = selectColor->pixel; + imgColors[7 /*H*/] = fgColor->pixel; /* * Create a scratch buffer to store the image: @@ -591,8 +579,7 @@ static void IndicatorElementDraw( XDestroyImage(img); } -static Ttk_ElementSpec IndicatorElementSpec = -{ +static Ttk_ElementSpec IndicatorElementSpec = { TK_STYLE_VERSION_2, sizeof(IndicatorElement), IndicatorElementOptions, @@ -608,8 +595,7 @@ static Ttk_ElementSpec IndicatorElementSpec = */ static int ArrowElements[] = { ARROW_UP, ARROW_DOWN, ARROW_LEFT, ARROW_RIGHT }; -typedef struct -{ +typedef struct { Tcl_Obj *sizeObj; Tcl_Obj *borderObj; Tcl_Obj *borderColorObj; /* Extra color for borders */ @@ -617,19 +603,18 @@ typedef struct Tcl_Obj *colorObj; /* Arrow color */ } ArrowElement; -static Ttk_ElementOptionSpec ArrowElementOptions[] = -{ +static Ttk_ElementOptionSpec ArrowElementOptions[] = { { "-arrowsize", TK_OPTION_PIXELS, Tk_Offset(ArrowElement,sizeObj), STRINGIFY(SCROLLBAR_WIDTH) }, - { "-background", TK_OPTION_BORDER, + { "-background", TK_OPTION_BORDER, Tk_Offset(ArrowElement,borderObj), DEFAULT_BACKGROUND }, - { "-bordercolor", TK_OPTION_COLOR, + { "-bordercolor", TK_OPTION_COLOR, Tk_Offset(ArrowElement,borderColorObj), "black" }, { "-relief", TK_OPTION_RELIEF, Tk_Offset(ArrowElement,reliefObj),"raised"}, { "-arrowcolor", TK_OPTION_COLOR, Tk_Offset(ArrowElement,colorObj),"black"}, - { NULL } + { NULL, 0, 0, NULL } }; /* @@ -676,8 +661,7 @@ static void ArrowElementDraw( Ttk_PadBox(b, ArrowPadding), direction); } -static Ttk_ElementSpec ArrowElementSpec = -{ +static Ttk_ElementSpec ArrowElementSpec = { TK_STYLE_VERSION_2, sizeof(ArrowElement), ArrowElementOptions, @@ -703,15 +687,14 @@ static const char *directionStrings[] = { /* See also: button.c */ }; enum { POST_ABOVE, POST_BELOW, POST_LEFT, POST_RIGHT, POST_FLUSH }; -static Ttk_ElementOptionSpec MenubuttonArrowElementOptions[] = -{ +static Ttk_ElementOptionSpec MenubuttonArrowElementOptions[] = { { "-direction", TK_OPTION_STRING, Tk_Offset(MenubuttonArrowElement,directionObj), "below" }, { "-arrowsize", TK_OPTION_PIXELS, Tk_Offset(MenubuttonArrowElement,sizeObj), STRINGIFY(MENUBUTTON_ARROW_SIZE)}, { "-arrowcolor",TK_OPTION_COLOR, Tk_Offset(MenubuttonArrowElement,colorObj), "black"}, - { NULL } + { NULL, 0, 0, NULL } }; static Ttk_Padding MenubuttonArrowPadding = { 3, 0, 3, 0 }; @@ -759,8 +742,7 @@ static void MenubuttonArrowElementDraw( TtkFillArrow(Tk_Display(tkwin), d, gc, b, arrowDirection); } -static Ttk_ElementSpec MenubuttonArrowElementSpec = -{ +static Ttk_ElementSpec MenubuttonArrowElementSpec = { TK_STYLE_VERSION_2, sizeof(MenubuttonArrowElement), MenubuttonArrowElementOptions, @@ -781,8 +763,7 @@ static Ttk_ElementSpec MenubuttonArrowElementSpec = * */ -typedef struct -{ +typedef struct { Tcl_Obj *colorObj; Tcl_Obj *borderWidthObj; Tcl_Obj *reliefObj; @@ -790,8 +771,7 @@ typedef struct Tcl_Obj *orientObj; } TroughElement; -static Ttk_ElementOptionSpec TroughElementOptions[] = -{ +static Ttk_ElementOptionSpec TroughElementOptions[] = { { "-orient", TK_OPTION_ANY, Tk_Offset(TroughElement, orientObj), "horizontal" }, { "-troughborderwidth", TK_OPTION_PIXELS, @@ -802,7 +782,7 @@ static Ttk_ElementOptionSpec TroughElementOptions[] = Tk_Offset(TroughElement,reliefObj), "sunken" }, { "-groovewidth", TK_OPTION_PIXELS, Tk_Offset(TroughElement,grooveWidthObj), "-1" }, - { NULL } + { NULL, 0, 0, NULL } }; static void TroughElementSize( @@ -848,8 +828,7 @@ static void TroughElementDraw( borderWidth, relief); } -static Ttk_ElementSpec TroughElementSpec = -{ +static Ttk_ElementSpec TroughElementSpec = { TK_STYLE_VERSION_2, sizeof(TroughElement), TroughElementOptions, @@ -862,8 +841,7 @@ static Ttk_ElementSpec TroughElementSpec = * +++ Thumb element. */ -typedef struct -{ +typedef struct { Tcl_Obj *sizeObj; Tcl_Obj *firstObj; Tcl_Obj *lastObj; @@ -873,8 +851,7 @@ typedef struct Tcl_Obj *orientObj; } ThumbElement; -static Ttk_ElementOptionSpec ThumbElementOptions[] = -{ +static Ttk_ElementOptionSpec ThumbElementOptions[] = { { "-width", TK_OPTION_PIXELS, Tk_Offset(ThumbElement,sizeObj), STRINGIFY(SCROLLBAR_WIDTH) }, { "-background", TK_OPTION_BORDER, Tk_Offset(ThumbElement,borderObj), @@ -883,7 +860,7 @@ static Ttk_ElementOptionSpec ThumbElementOptions[] = "black" }, { "-relief", TK_OPTION_RELIEF,Tk_Offset(ThumbElement,reliefObj),"raised" }, { "-orient", TK_OPTION_ANY,Tk_Offset(ThumbElement,orientObj),"horizontal"}, - { NULL } + { NULL, 0, 0, NULL } }; static void ThumbElementSize( @@ -928,8 +905,7 @@ static void ThumbElementDraw( DrawBorder(tkwin, d, border, borderColor, b, borderWidth, relief); } -static Ttk_ElementSpec ThumbElementSpec = -{ +static Ttk_ElementSpec ThumbElementSpec = { TK_STYLE_VERSION_2, sizeof(ThumbElement), ThumbElementOptions, @@ -948,8 +924,7 @@ static Ttk_ElementSpec ThumbElementSpec = * */ -typedef struct -{ +typedef struct { Tcl_Obj *lengthObj; /* Long axis dimension */ Tcl_Obj *thicknessObj; /* Short axis dimension */ Tcl_Obj *reliefObj; /* Relief for this object */ @@ -959,8 +934,7 @@ typedef struct Tcl_Obj *orientObj; /* Orientation of overall slider */ } SliderElement; -static Ttk_ElementOptionSpec SliderElementOptions[] = -{ +static Ttk_ElementOptionSpec SliderElementOptions[] = { { "-sliderlength", TK_OPTION_PIXELS, Tk_Offset(SliderElement,lengthObj), "15" }, { "-sliderthickness",TK_OPTION_PIXELS,Tk_Offset(SliderElement,thicknessObj), @@ -975,7 +949,7 @@ static Ttk_ElementOptionSpec SliderElementOptions[] = "black" }, { "-orient", TK_OPTION_ANY, Tk_Offset(SliderElement,orientObj), "horizontal" }, - { NULL } + { NULL, 0, 0, NULL } }; static void SliderElementSize( @@ -1021,8 +995,7 @@ static void SliderElementDraw( DrawBorder(tkwin, d, border, borderColor, b, borderWidth, relief); } -static Ttk_ElementSpec SliderElementSpec = -{ +static Ttk_ElementSpec SliderElementSpec = { TK_STYLE_VERSION_2, sizeof(SliderElement), SliderElementOptions, @@ -1037,22 +1010,20 @@ static Ttk_ElementSpec SliderElementSpec = #define TTK_STATE_OPEN TTK_STATE_USER1 /* XREF: treeview.c */ #define TTK_STATE_LEAF TTK_STATE_USER2 -typedef struct -{ +typedef struct { Tcl_Obj *colorObj; Tcl_Obj *marginObj; Tcl_Obj *diameterObj; } TreeitemIndicator; -static Ttk_ElementOptionSpec TreeitemIndicatorOptions[] = -{ +static Ttk_ElementOptionSpec TreeitemIndicatorOptions[] = { { "-foreground", TK_OPTION_COLOR, Tk_Offset(TreeitemIndicator,colorObj), DEFAULT_FOREGROUND }, { "-diameter", TK_OPTION_PIXELS, Tk_Offset(TreeitemIndicator,diameterObj), "9" }, { "-indicatormargins", TK_OPTION_STRING, Tk_Offset(TreeitemIndicator,marginObj), "2 2 4 2" }, - {NULL} + { NULL, 0, 0, NULL } }; static void TreeitemIndicatorSize( @@ -1101,8 +1072,7 @@ static void TreeitemIndicatorDraw( } } -static Ttk_ElementSpec TreeitemIndicatorElementSpec = -{ +static Ttk_ElementSpec TreeitemIndicatorElementSpec = { TK_STYLE_VERSION_2, sizeof(TreeitemIndicator), TreeitemIndicatorOptions, @@ -1110,9 +1080,6 @@ static Ttk_ElementSpec TreeitemIndicatorElementSpec = TreeitemIndicatorDraw }; - - - /*------------------------------------------------------------------------ * TtkAltTheme_Init -- * Install alternate theme. diff --git a/generic/ttk/ttkElements.c b/generic/ttk/ttkElements.c index 648bbc4..8e2209b 100644 --- a/generic/ttk/ttkElements.c +++ b/generic/ttk/ttkElements.c @@ -1,4 +1,4 @@ -/* $Id: ttkElements.c,v 1.10.2.1 2008/07/04 19:06:03 jenglish Exp $ +/* $Id: ttkElements.c,v 1.10.2.2 2010/08/26 02:06:09 hobbs Exp $ * * Copyright (c) 2003, Joe English * @@ -22,7 +22,7 @@ * and may be used in other engines. */ -/* public */ Ttk_ElementOptionSpec TtkNullElementOptions[] = { {NULL} }; +/* public */ Ttk_ElementOptionSpec TtkNullElementOptions[] = { { NULL, 0, 0, NULL } }; /* public */ void TtkNullElementSize( @@ -62,7 +62,7 @@ typedef struct { static Ttk_ElementOptionSpec BackgroundElementOptions[] = { { "-background", TK_OPTION_BORDER, Tk_Offset(BackgroundElement,backgroundObj), DEFAULT_BACKGROUND }, - {NULL} + { NULL, 0, 0, NULL } }; static void FillElementDraw( @@ -119,7 +119,7 @@ static Ttk_ElementOptionSpec BorderElementOptions[] = { Tk_Offset(BorderElement,borderWidthObj), DEFAULT_BORDERWIDTH }, { "-relief", TK_OPTION_RELIEF, Tk_Offset(BorderElement,reliefObj), "flat" }, - {NULL} + { NULL, 0, 0, NULL } }; static void BorderElementSize( @@ -172,7 +172,7 @@ static Ttk_ElementOptionSpec FieldElementOptions[] = { Tk_Offset(FieldElement,borderObj), "white" }, { "-borderwidth", TK_OPTION_PIXELS, Tk_Offset(FieldElement,borderWidthObj), "2" }, - {NULL} + { NULL, 0, 0, NULL } }; static void FieldElementSize( @@ -230,7 +230,7 @@ static Ttk_ElementOptionSpec PaddingElementOptions[] = { Tk_Offset(PaddingElement,reliefObj), "flat" }, { "-shiftrelief", TK_OPTION_INT, Tk_Offset(PaddingElement,shiftreliefObj), "0" }, - {NULL} + { NULL, 0, 0, NULL } }; static void PaddingElementSize( @@ -294,7 +294,7 @@ static Ttk_ElementOptionSpec FocusElementOptions[] = { Tk_Offset(FocusElement,focusColorObj), "black" }, { "-focusthickness",TK_OPTION_PIXELS, Tk_Offset(FocusElement,focusThicknessObj), "1" }, - {NULL} + { NULL, 0, 0, NULL } }; static void FocusElementSize( @@ -346,7 +346,7 @@ static Ttk_ElementOptionSpec SeparatorElementOptions[] = { Tk_Offset(SeparatorElement, orientObj), "horizontal" }, { "-background", TK_OPTION_BORDER, Tk_Offset(SeparatorElement,borderObj), DEFAULT_BACKGROUND }, - {NULL} + { NULL, 0, 0, NULL } }; static void SeparatorElementSize( @@ -507,7 +507,7 @@ static Ttk_ElementOptionSpec IndicatorElementOptions[] = { Tk_Offset(IndicatorElement,marginObj), "0 2 4 2" }, { "-borderwidth", TK_OPTION_PIXELS, Tk_Offset(IndicatorElement,borderWidthObj), DEFAULT_BORDERWIDTH }, - {NULL} + { NULL, 0, 0, NULL } }; /* @@ -653,7 +653,7 @@ static Ttk_ElementOptionSpec MenuIndicatorElementOptions[] = { Tk_Offset(MenuIndicatorElement,reliefObj),"raised" }, { "-indicatormargin", TK_OPTION_STRING, Tk_Offset(MenuIndicatorElement,marginObj), "5 0" }, - { NULL } + { NULL, 0, 0, NULL } }; static void MenuIndicatorElementSize( @@ -720,7 +720,7 @@ static Ttk_ElementOptionSpec ArrowElementOptions[] = { Tk_Offset(ArrowElement,colorObj),"black"}, { "-arrowsize", TK_OPTION_PIXELS, Tk_Offset(ArrowElement,sizeObj), "14" }, - { NULL } + { NULL, 0, 0, NULL } }; static Ttk_Padding ArrowMargins = { 3,3,3,3 }; @@ -787,7 +787,7 @@ static Ttk_ElementOptionSpec TroughElementOptions[] = { Tk_Offset(TroughElement,colorObj), DEFAULT_BACKGROUND }, { "-troughrelief",TK_OPTION_RELIEF, Tk_Offset(TroughElement,reliefObj), "sunken" }, - { NULL } + { NULL, 0, 0, NULL } }; static void TroughElementSize( @@ -851,7 +851,7 @@ static Ttk_ElementOptionSpec ThumbElementOptions[] = { Tk_Offset(ThumbElement,borderObj), DEFAULT_BACKGROUND }, { "-borderwidth", TK_OPTION_PIXELS, Tk_Offset(ThumbElement,borderWidthObj), DEFAULT_BORDERWIDTH }, - { NULL } + { NULL, 0, 0, NULL } }; static void ThumbElementSize( @@ -924,7 +924,7 @@ static Ttk_ElementOptionSpec SliderElementOptions[] = { DEFAULT_BACKGROUND }, { "-orient", TK_OPTION_ANY, Tk_Offset(SliderElement,orientObj), "horizontal" }, - { NULL } + { NULL, 0, 0, NULL } }; static void SliderElementSize( @@ -1035,7 +1035,7 @@ static Ttk_ElementOptionSpec PbarElementOptions[] = { DEFAULT_BORDERWIDTH }, { "-background", TK_OPTION_BORDER, Tk_Offset(PbarElement,borderObj), DEFAULT_BACKGROUND }, - { NULL } + { NULL, 0, 0, NULL } }; static void PbarElementSize( diff --git a/generic/ttk/ttkEntry.c b/generic/ttk/ttkEntry.c index d41010d..177295a 100644 --- a/generic/ttk/ttkEntry.c +++ b/generic/ttk/ttkEntry.c @@ -1,5 +1,5 @@ /* - * $Id: ttkEntry.c,v 1.9 2007/05/18 21:46:11 jenglish Exp $ + * $Id: ttkEntry.c,v 1.9.4.1 2010/08/26 02:06:09 hobbs Exp $ * * DERIVED FROM: tk/generic/tkEntry.c r1.35. * @@ -11,6 +11,7 @@ */ #include +#include #include #include @@ -32,7 +33,7 @@ typedef enum validateMode { VMODE_ALL, VMODE_KEY, VMODE_FOCUS, VMODE_FOCUSIN, VMODE_FOCUSOUT, VMODE_NONE } VMODE; -static const char *validateStrings[] = { +static const char *const validateStrings[] = { "all", "key", "focus", "focusin", "focusout", "none", NULL }; @@ -45,7 +46,7 @@ typedef enum validateReason { VALIDATE_FORCED } VREASON; -static const char *validateReasonStrings[] = { +static const char *const validateReasonStrings[] = { "key", "key", "focusin", "focusout", "forced", NULL }; @@ -73,8 +74,7 @@ static const char *validateReasonStrings[] = { /* Style parameters: */ -typedef struct -{ +typedef struct { Tcl_Obj *foregroundObj; /* Foreground color for normal text */ Tcl_Obj *backgroundObj; /* Entry widget background color */ Tcl_Obj *selBorderObj; /* Border and background for selection */ @@ -84,8 +84,7 @@ typedef struct Tcl_Obj *insertWidthObj; /* Insert cursor width */ } EntryStyleData; -typedef struct -{ +typedef struct { /* * Internal state: */ @@ -135,8 +134,7 @@ typedef struct } EntryPart; -typedef struct -{ +typedef struct { WidgetCore core; EntryPart entry; } Entry; @@ -158,8 +156,7 @@ typedef struct #define DEF_ENTRY_FONT "TkTextFont" #define DEF_LIST_HEIGHT "10" -static Tk_OptionSpec EntryOptionSpecs[] = -{ +static Tk_OptionSpec EntryOptionSpecs[] = { WIDGET_TAKES_FOCUS, {TK_OPTION_BOOLEAN, "-exportselection", "exportSelection", @@ -523,7 +520,7 @@ static int RunValidationScript( ExpandPercents(entryPtr, template, new, index, count, reason, &script); code = Tcl_EvalEx(interp, Tcl_DStringValue(&script), Tcl_DStringLength(&script), - TCL_EVAL_GLOBAL | TCL_EVAL_DIRECT); + TCL_EVAL_GLOBAL); Tcl_DStringFree(&script); if (WidgetDestroyed(&entryPtr->core)) return TCL_ERROR; @@ -566,7 +563,7 @@ static int EntryNeedsValidation(VMODE vmode, VREASON reason) * TCL_BREAK if the change is rejected * TCL_ERROR if any errors occured * - * The change will be rejected if -validatecommand returns 0, + * The change will be rejected if -validatecommand returns 0, * or if -validatecommand or -invalidcommand modifies the value. */ static int @@ -925,7 +922,7 @@ EntryEventProc(ClientData clientData, XEvent *eventPtr) * +++ Initialization and cleanup. */ -static int +static void EntryInitialize(Tcl_Interp *interp, void *recordPtr) { Entry *entryPtr = recordPtr; @@ -950,8 +947,6 @@ EntryInitialize(Tcl_Interp *interp, void *recordPtr) entryPtr->entry.insertPos = 0; entryPtr->entry.selectFirst = -1; entryPtr->entry.selectLast = -1; - - return TCL_OK; } static void @@ -1058,17 +1053,6 @@ static int EntryPostConfigure(Tcl_Interp *interp, void *recordPtr, int mask) * +++ Layout and display. */ -/* EntryTextArea -- - * Return bounding box of entry display ("owner-draw") area. - */ -static Ttk_Box -EntryTextArea(Entry *entryPtr) -{ - WidgetCore *corePtr = &entryPtr->core; - Ttk_LayoutNode *node = Ttk_LayoutFindNode(corePtr->layout, "textarea"); - return node ? Ttk_LayoutNodeParcel(node) : Ttk_WinBox(corePtr->tkwin); -} - /* EntryCharPosition -- * Return the X coordinate of the specified character index. * Precondition: textLayout and layoutX up-to-date. @@ -1102,7 +1086,7 @@ EntryDoLayout(void *recordPtr) Ttk_Box textarea; Ttk_PlaceLayout(corePtr->layout,corePtr->state,Ttk_WinBox(corePtr->tkwin)); - textarea = EntryTextArea(entryPtr); + textarea = Ttk_ClientRegion(corePtr->layout, "textarea"); /* Center the text vertically within the available parcel: */ @@ -1188,7 +1172,7 @@ static void EntryDisplay(void *clientData, Drawable d) EntryInitStyleData(entryPtr, &es); - showCursor = + showCursor = (entryPtr->core.flags & CURSOR_ON) != 0 && EntryEditable(entryPtr) && entryPtr->entry.insertPos >= leftIndex @@ -1250,7 +1234,7 @@ static void EntryDisplay(void *clientData, Drawable d) Tk_SetCaretPos(tkwin, cursorX, cursorY, cursorHeight); gc = EntryGetGC(entryPtr, es.insertColorObj); - XFillRectangle(Tk_Display(tkwin), d, gc, + XFillRectangle(Tk_Display(tkwin), d, gc, cursorX-cursorWidth/2, cursorY, cursorWidth, cursorHeight); Tk_FreeGC(Tk_Display(tkwin), gc); } @@ -1376,7 +1360,7 @@ badIndex: */ static int EntryBBoxCommand( - Tcl_Interp *interp, int objc, Tcl_Obj *const objv[], void *recordPtr) + void *recordPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]) { Entry *entryPtr = recordPtr; Ttk_Box b; @@ -1392,7 +1376,7 @@ EntryBBoxCommand( if ((index == entryPtr->entry.numChars) && (index > 0)) { index--; } - Tk_CharBbox(entryPtr->entry.textLayout, index, + Tk_CharBbox(entryPtr->entry.textLayout, index, &b.x, &b.y, &b.width, &b.height); b.x += entryPtr->entry.layoutX; b.y += entryPtr->entry.layoutY; @@ -1406,7 +1390,7 @@ EntryBBoxCommand( */ static int EntryDeleteCommand( - Tcl_Interp *interp, int objc, Tcl_Obj *const objv[], void *recordPtr) + void *recordPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]) { Entry *entryPtr = recordPtr; int first, last; @@ -1435,7 +1419,7 @@ EntryDeleteCommand( */ static int EntryGetCommand( - Tcl_Interp *interp, int objc, Tcl_Obj *const objv[], void *recordPtr) + void *recordPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]) { Entry *entryPtr = recordPtr; if (objc != 2) { @@ -1451,7 +1435,7 @@ EntryGetCommand( */ static int EntryICursorCommand( - Tcl_Interp *interp, int objc, Tcl_Obj *const objv[], void *recordPtr) + void *recordPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]) { Entry *entryPtr = recordPtr; if (objc != 3) { @@ -1471,7 +1455,7 @@ EntryICursorCommand( */ static int EntryIndexCommand( - Tcl_Interp *interp, int objc, Tcl_Obj *const objv[], void *recordPtr) + void *recordPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]) { Entry *entryPtr = recordPtr; int index; @@ -1493,7 +1477,7 @@ EntryIndexCommand( */ static int EntryInsertCommand( - Tcl_Interp *interp, int objc, Tcl_Obj *const objv[], void *recordPtr) + void *recordPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]) { Entry *entryPtr = recordPtr; int index; @@ -1511,11 +1495,11 @@ EntryInsertCommand( return TCL_OK; } -/* selection clear -- +/* $entry selection clear -- * Clear selection. */ static int EntrySelectionClearCommand( - Tcl_Interp *interp, int objc, Tcl_Obj *const objv[], void *recordPtr) + void *recordPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]) { Entry *entryPtr = recordPtr; @@ -1532,7 +1516,7 @@ static int EntrySelectionClearCommand( * Returns 1 if any characters are selected, 0 otherwise. */ static int EntrySelectionPresentCommand( - Tcl_Interp *interp, int objc, Tcl_Obj *const objv[], void *recordPtr) + void *recordPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]) { Entry *entryPtr = recordPtr; if (objc != 3) { @@ -1548,7 +1532,7 @@ static int EntrySelectionPresentCommand( * Explicitly set the selection range. */ static int EntrySelectionRangeCommand( - Tcl_Interp *interp, int objc, Tcl_Obj *const objv[], void *recordPtr) + void *recordPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]) { Entry *entryPtr = recordPtr; int start, end; @@ -1575,27 +1559,18 @@ static int EntrySelectionRangeCommand( return TCL_OK; } -/* $entry selection $command ?arg arg...? - * Ensemble, see above. - */ -static int EntrySelectionCommand( - Tcl_Interp *interp, int objc, Tcl_Obj *const objv[], void *recordPtr) -{ - static WidgetCommandSpec EntrySelectionCommands[] = { - { "clear", EntrySelectionClearCommand }, - { "present", EntrySelectionPresentCommand }, - { "range", EntrySelectionRangeCommand }, - {0,0} - }; - return TtkWidgetEnsembleCommand( - EntrySelectionCommands, 2, interp, objc, objv, recordPtr); -} +static const Ttk_Ensemble EntrySelectionCommands[] = { + { "clear", EntrySelectionClearCommand,0 }, + { "present", EntrySelectionPresentCommand,0 }, + { "range", EntrySelectionRangeCommand,0 }, + { 0,0,0 } +}; /* $entry set $value * Sets the value of an entry widget. */ static int EntrySetCommand( - Tcl_Interp *interp, int objc, Tcl_Obj *const objv[], void *recordPtr) + void *recordPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]) { Entry *entryPtr = recordPtr; if (objc != 3) { @@ -1611,7 +1586,7 @@ static int EntrySetCommand( * or error status from -validatecommand / -invalidcommand. */ static int EntryValidateCommand( - Tcl_Interp *interp, int objc, Tcl_Obj *const objv[], void *recordPtr) + void *recordPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]) { Entry *entryPtr = recordPtr; int code; @@ -1633,37 +1608,35 @@ static int EntryValidateCommand( /* $entry xview -- horizontal scrolling interface */ static int EntryXViewCommand( - Tcl_Interp *interp, int objc, Tcl_Obj *const objv[], void *recordPtr) + void *recordPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]) { Entry *entryPtr = recordPtr; return TtkScrollviewCommand(interp, objc, objv, entryPtr->entry.xscrollHandle); } -static WidgetCommandSpec EntryCommands[] = -{ - { "bbox", EntryBBoxCommand }, - { "cget", TtkWidgetCgetCommand }, - { "configure", TtkWidgetConfigureCommand }, - { "delete", EntryDeleteCommand }, - { "get", EntryGetCommand }, - { "icursor", EntryICursorCommand }, - { "identify", TtkWidgetIdentifyCommand }, - { "index", EntryIndexCommand }, - { "insert", EntryInsertCommand }, - { "instate", TtkWidgetInstateCommand }, - { "selection", EntrySelectionCommand }, - { "state", TtkWidgetStateCommand }, - { "validate", EntryValidateCommand }, - { "xview", EntryXViewCommand }, - {0,0} +static const Ttk_Ensemble EntryCommands[] = { + { "bbox", EntryBBoxCommand,0 }, + { "cget", TtkWidgetCgetCommand,0 }, + { "configure", TtkWidgetConfigureCommand,0 }, + { "delete", EntryDeleteCommand,0 }, + { "get", EntryGetCommand,0 }, + { "icursor", EntryICursorCommand,0 }, + { "identify", TtkWidgetIdentifyCommand,0 }, + { "index", EntryIndexCommand,0 }, + { "insert", EntryInsertCommand,0 }, + { "instate", TtkWidgetInstateCommand,0 }, + { "selection", 0,EntrySelectionCommands }, + { "state", TtkWidgetStateCommand,0 }, + { "validate", EntryValidateCommand,0 }, + { "xview", EntryXViewCommand,0 }, + { 0,0,0 } }; /*------------------------------------------------------------------------ * +++ Entry widget definition. */ -static WidgetSpec EntryWidgetSpec = -{ +static WidgetSpec EntryWidgetSpec = { "TEntry", /* className */ sizeof(Entry), /* recordSize */ EntryOptionSpecs, /* optionSpecs */ @@ -1695,8 +1668,7 @@ typedef struct { ComboboxPart combobox; } Combobox; -static Tk_OptionSpec ComboboxOptionSpecs[] = -{ +static Tk_OptionSpec ComboboxOptionSpecs[] = { {TK_OPTION_STRING, "-height", "height", "Height", DEF_LIST_HEIGHT, Tk_Offset(Combobox, combobox.heightObj), -1, 0,0,0 }, @@ -1712,13 +1684,14 @@ static Tk_OptionSpec ComboboxOptionSpecs[] = /* ComboboxInitialize -- * Initialization hook for combobox widgets. */ -static int +static void ComboboxInitialize(Tcl_Interp *interp, void *recordPtr) { Combobox *cb = recordPtr; + cb->combobox.currentIndex = -1; TtkTrackElementState(&cb->core); - return EntryInitialize(interp, recordPtr); + EntryInitialize(interp, recordPtr); } /* ComboboxConfigure -- @@ -1742,10 +1715,10 @@ ComboboxConfigure(Tcl_Interp *interp, void *recordPtr, int mask) * Setting the current index updates the combobox value, * but the value and -values may be changed independently * of the index. Instead of trying to keep currentIndex - * in sync at all times, [$cb current] double-checks + * in sync at all times, [$cb current] double-checks */ static int ComboboxCurrentCommand( - Tcl_Interp *interp, int objc, Tcl_Obj *const objv[], void *recordPtr) + void *recordPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]) { Combobox *cbPtr = recordPtr; int currentIndex = cbPtr->combobox.currentIndex; @@ -1758,7 +1731,7 @@ static int ComboboxCurrentCommand( if (objc == 2) { /* Check if currentIndex still valid: */ - if ( currentIndex < 0 + if ( currentIndex < 0 || currentIndex >= nValues || strcmp(currentValue,Tcl_GetString(values[currentIndex])) ) @@ -1783,7 +1756,7 @@ static int ComboboxCurrentCommand( return TCL_ERROR; } if (currentIndex < 0 || currentIndex >= nValues) { - Tcl_AppendResult(interp, + Tcl_AppendResult(interp, "Index ", Tcl_GetString(objv[2]), " out of range", NULL); return TCL_ERROR; @@ -1802,28 +1775,26 @@ static int ComboboxCurrentCommand( /*------------------------------------------------------------------------ * +++ Combobox widget definition. */ -static WidgetCommandSpec ComboboxCommands[] = -{ - { "bbox", EntryBBoxCommand }, - { "cget", TtkWidgetCgetCommand }, - { "configure", TtkWidgetConfigureCommand }, - { "current", ComboboxCurrentCommand }, - { "delete", EntryDeleteCommand }, - { "get", EntryGetCommand }, - { "icursor", EntryICursorCommand }, - { "identify", TtkWidgetIdentifyCommand }, - { "index", EntryIndexCommand }, - { "insert", EntryInsertCommand }, - { "instate", TtkWidgetInstateCommand }, - { "selection", EntrySelectionCommand }, - { "state", TtkWidgetStateCommand }, - { "set", EntrySetCommand }, - { "xview", EntryXViewCommand }, - {0,0} +static const Ttk_Ensemble ComboboxCommands[] = { + { "bbox", EntryBBoxCommand,0 }, + { "cget", TtkWidgetCgetCommand,0 }, + { "configure", TtkWidgetConfigureCommand,0 }, + { "current", ComboboxCurrentCommand,0 }, + { "delete", EntryDeleteCommand,0 }, + { "get", EntryGetCommand,0 }, + { "icursor", EntryICursorCommand,0 }, + { "identify", TtkWidgetIdentifyCommand,0 }, + { "index", EntryIndexCommand,0 }, + { "insert", EntryInsertCommand,0 }, + { "instate", TtkWidgetInstateCommand,0 }, + { "selection", 0,EntrySelectionCommands }, + { "state", TtkWidgetStateCommand,0 }, + { "set", EntrySetCommand,0 }, + { "xview", EntryXViewCommand,0 }, + { 0,0,0 } }; -static WidgetSpec ComboboxWidgetSpec = -{ +static WidgetSpec ComboboxWidgetSpec = { "TCombobox", /* className */ sizeof(Combobox), /* recordSize */ ComboboxOptionSpecs, /* optionSpecs */ @@ -1839,6 +1810,118 @@ static WidgetSpec ComboboxWidgetSpec = }; /*------------------------------------------------------------------------ + * +++ Spinbox widget. + */ + +typedef struct { + Tcl_Obj *valuesObj; + + Tcl_Obj *fromObj; + Tcl_Obj *toObj; + Tcl_Obj *incrementObj; + Tcl_Obj *formatObj; + + Tcl_Obj *wrapObj; + Tcl_Obj *commandObj; +} SpinboxPart; + +typedef struct { + WidgetCore core; + EntryPart entry; + SpinboxPart spinbox; +} Spinbox; + +static Tk_OptionSpec SpinboxOptionSpecs[] = { + {TK_OPTION_STRING, "-values", "values", "Values", + "", Tk_Offset(Spinbox, spinbox.valuesObj), -1, + 0,0,0 }, + + {TK_OPTION_DOUBLE, "-from", "from", "From", + "0", Tk_Offset(Spinbox,spinbox.fromObj), -1, + 0,0,0 }, + {TK_OPTION_DOUBLE, "-to", "to", "To", + "0", Tk_Offset(Spinbox,spinbox.toObj), -1, + 0,0,0 }, + {TK_OPTION_DOUBLE, "-increment", "increment", "Increment", + "1", Tk_Offset(Spinbox,spinbox.incrementObj), -1, + 0,0,0 }, + {TK_OPTION_STRING, "-format", "format", "Format", + "", Tk_Offset(Spinbox, spinbox.formatObj), -1, + 0,0,0 }, + + {TK_OPTION_STRING, "-command", "command", "Command", + "", Tk_Offset(Spinbox, spinbox.commandObj), -1, + 0,0,0 }, + {TK_OPTION_BOOLEAN, "-wrap", "wrap", "Wrap", + "0", Tk_Offset(Spinbox,spinbox.wrapObj), -1, + 0,0,0 }, + + WIDGET_INHERIT_OPTIONS(EntryOptionSpecs) +}; + +/* SpinboxInitialize -- + * Initialization hook for spinbox widgets. + */ +static void +SpinboxInitialize(Tcl_Interp *interp, void *recordPtr) +{ + Spinbox *sb = recordPtr; + TtkTrackElementState(&sb->core); + EntryInitialize(interp, recordPtr); +} + +/* SpinboxConfigure -- + * Configuration hook for spinbox widgets. + */ +static int +SpinboxConfigure(Tcl_Interp *interp, void *recordPtr, int mask) +{ + Spinbox *sb = recordPtr; + int unused; + + /* Make sure -values is a valid list: + */ + if (Tcl_ListObjLength(interp,sb->spinbox.valuesObj,&unused) != TCL_OK) + return TCL_ERROR; + + return EntryConfigure(interp, recordPtr, mask); +} + +static const Ttk_Ensemble SpinboxCommands[] = { + { "bbox", EntryBBoxCommand,0 }, + { "cget", TtkWidgetCgetCommand,0 }, + { "configure", TtkWidgetConfigureCommand,0 }, + { "delete", EntryDeleteCommand,0 }, + { "get", EntryGetCommand,0 }, + { "icursor", EntryICursorCommand,0 }, + { "identify", TtkWidgetIdentifyCommand,0 }, + { "index", EntryIndexCommand,0 }, + { "insert", EntryInsertCommand,0 }, + { "instate", TtkWidgetInstateCommand,0 }, + { "selection", 0,EntrySelectionCommands }, + { "state", TtkWidgetStateCommand,0 }, + { "set", EntrySetCommand,0 }, + { "validate", EntryValidateCommand,0 }, + { "xview", EntryXViewCommand,0 }, + { 0,0,0 } +}; + +static WidgetSpec SpinboxWidgetSpec = { + "TSpinbox", /* className */ + sizeof(Spinbox), /* recordSize */ + SpinboxOptionSpecs, /* optionSpecs */ + SpinboxCommands, /* subcommands */ + SpinboxInitialize, /* initializeProc */ + EntryCleanup, /* cleanupProc */ + SpinboxConfigure, /* configureProc */ + EntryPostConfigure, /* postConfigureProc */ + TtkWidgetGetLayout, /* getLayoutProc */ + TtkWidgetSize, /* sizeProc */ + EntryDoLayout, /* layoutProc */ + EntryDisplay /* displayProc */ +}; + +/*------------------------------------------------------------------------ * +++ Textarea element. * * Text display area for Entry widgets. @@ -1855,7 +1938,7 @@ static Ttk_ElementOptionSpec TextareaElementOptions[] = { Tk_Offset(TextareaElement,fontObj), DEF_ENTRY_FONT }, { "-width", TK_OPTION_INT, Tk_Offset(TextareaElement,widthObj), "20" }, - {0,0,0} + { NULL, 0, 0, NULL } }; static void TextareaElementSize( @@ -1902,10 +1985,18 @@ TTK_BEGIN_LAYOUT(ComboboxLayout) TTK_NODE("Combobox.textarea", TTK_FILL_BOTH))) TTK_END_LAYOUT +TTK_BEGIN_LAYOUT(SpinboxLayout) + TTK_GROUP("Spinbox.field", TTK_PACK_TOP|TTK_FILL_X, + TTK_GROUP("null", TTK_PACK_RIGHT, + TTK_NODE("Spinbox.uparrow", TTK_PACK_TOP|TTK_STICK_E) + TTK_NODE("Spinbox.downarrow", TTK_PACK_BOTTOM|TTK_STICK_E)) + TTK_GROUP("Spinbox.padding", TTK_FILL_BOTH, + TTK_NODE("Spinbox.textarea", TTK_FILL_BOTH))) +TTK_END_LAYOUT + /*------------------------------------------------------------------------ * +++ Initialization. */ - MODULE_SCOPE void TtkEntry_Init(Tcl_Interp *interp) { @@ -1915,9 +2006,11 @@ void TtkEntry_Init(Tcl_Interp *interp) Ttk_RegisterLayout(themePtr, "TEntry", EntryLayout); Ttk_RegisterLayout(themePtr, "TCombobox", ComboboxLayout); + Ttk_RegisterLayout(themePtr, "TSpinbox", SpinboxLayout); RegisterWidget(interp, "ttk::entry", &EntryWidgetSpec); RegisterWidget(interp, "ttk::combobox", &ComboboxWidgetSpec); + RegisterWidget(interp, "ttk::spinbox", &SpinboxWidgetSpec); } /*EOF*/ diff --git a/generic/ttk/ttkFrame.c b/generic/ttk/ttkFrame.c index e7e3ca6..52b40a9 100644 --- a/generic/ttk/ttkFrame.c +++ b/generic/ttk/ttkFrame.c @@ -1,4 +1,4 @@ -/* $Id: ttkFrame.c,v 1.12.2.1 2009/02/06 08:13:23 das Exp $ +/* $Id: ttkFrame.c,v 1.12.2.2 2010/08/26 02:06:09 hobbs Exp $ * Copyright (c) 2004, Joe English * * ttk::frame and ttk::labelframe widgets. @@ -47,13 +47,13 @@ static Tk_OptionSpec FrameOptionSpecs[] = { WIDGET_INHERIT_OPTIONS(ttkCoreOptionSpecs) }; -static WidgetCommandSpec FrameCommands[] = { - { "configure", TtkWidgetConfigureCommand }, - { "cget", TtkWidgetCgetCommand }, - { "instate", TtkWidgetInstateCommand }, - { "state", TtkWidgetStateCommand }, - { "identify", TtkWidgetIdentifyCommand }, - { NULL, NULL } +static const Ttk_Ensemble FrameCommands[] = { + { "configure", TtkWidgetConfigureCommand,0 }, + { "cget", TtkWidgetCgetCommand,0 }, + { "instate", TtkWidgetInstateCommand,0 }, + { "state", TtkWidgetStateCommand,0 }, + { "identify", TtkWidgetIdentifyCommand,0 }, + { 0,0,0 } }; /* @@ -515,7 +515,7 @@ static Ttk_ManagerSpec LabelframeManagerSpec = { /* LabelframeInitialize -- * Initialization hook. */ -static int LabelframeInitialize(Tcl_Interp *interp, void *recordPtr) +static void LabelframeInitialize(Tcl_Interp *interp, void *recordPtr) { Labelframe *lframe = recordPtr; @@ -524,8 +524,6 @@ static int LabelframeInitialize(Tcl_Interp *interp, void *recordPtr) lframe->label.labelWidget = 0; lframe->label.labelLayout = 0; lframe->label.labelParcel = Ttk_MakeBox(-1,-1,-1,-1); - - return TCL_OK; } /* LabelframeCleanup -- diff --git a/generic/ttk/ttkGenStubs.tcl b/generic/ttk/ttkGenStubs.tcl index b868adb..50fe412 100644 --- a/generic/ttk/ttkGenStubs.tcl +++ b/generic/ttk/ttkGenStubs.tcl @@ -8,7 +8,7 @@ # See the file "license.terms" for information on usage and redistribution # of this file, and for a DISCLAIMER OF ALL WARRANTIES. # -# $Id: ttkGenStubs.tcl,v 1.1.4.1 2010/02/07 23:24:13 nijtmans Exp $ +# $Id: ttkGenStubs.tcl,v 1.1.4.2 2010/08/26 02:06:09 hobbs Exp $ # # SOURCE: tcl/tools/genStubs.tcl, revision 1.20 # @@ -468,10 +468,7 @@ proc genStubs::makeDecl {name decl index} { append line ")" } } - append text $line - - append text ";\n" - return $text + return "$text$line;\n" } # genStubs::makeMacro -- @@ -492,14 +489,12 @@ proc genStubs::makeMacro {name decl index} { set lfname [string tolower [string index $fname 0]] append lfname [string range $fname 1 end] - set text "#ifndef $fname\n#define $fname" + set text "#define $fname \\\n\t(" if {$args == ""} { - append text " \\\n\t(*${name}StubsPtr->$lfname)" - append text " /* $index */\n#endif\n" - return $text + append text "*" } - append text " \\\n\t(${name}StubsPtr->$lfname)" - append text " /* $index */\n#endif\n" + append text "${name}StubsPtr->$lfname)" + append text " /* $index */\n" return $text } @@ -661,15 +656,10 @@ proc genStubs::ifdeffed {macro text} { # None. proc genStubs::emitDeclarations {name textVar} { - variable libraryName upvar $textVar text - set upName [string toupper $libraryName] - append text "\n#if !defined(USE_${upName}_STUBS)\n" append text "\n/*\n * Exported function declarations:\n */\n\n" forAllStubs $name makeDecl noGuard text - append text "\n#endif /* !defined(USE_${upName}_STUBS) */\n" - return } @@ -691,7 +681,7 @@ proc genStubs::emitMacros {name textVar} { set upName [string toupper $libraryName] append text "\n#if defined(USE_${upName}_STUBS)\n" append text "\n/*\n * Inline function declarations:\n */\n\n" - + forAllStubs $name makeMacro addGuard text append text "\n#endif /* defined(USE_${upName}_STUBS) */\n" @@ -730,7 +720,7 @@ proc genStubs::emitHeader {name} { foreach hook $hooks($name) { set capHook [string toupper [string index $hook 0]] append capHook [string range $hook 1 end] - append text " struct ${capHook}Stubs *${hook}Stubs;\n" + append text " const struct ${capHook}Stubs *${hook}Stubs;\n" } append text "} ${capName}StubHooks;\n" } @@ -738,13 +728,13 @@ proc genStubs::emitHeader {name} { append text " int magic;\n" append text " int epoch;\n" append text " int revision;\n" - append text " struct ${capName}StubHooks *hooks;\n\n" + append text " const struct ${capName}StubHooks *hooks;\n\n" emitSlots $name text - append text "} ${capName}Stubs;\n" + append text "} ${capName}Stubs;\n\n" - append text "\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n" + append text "#ifdef __cplusplus\nextern \"C\" {\n#endif\n" append text "extern const ${capName}Stubs *${name}StubsPtr;\n" append text "#ifdef __cplusplus\n}\n#endif\n" @@ -767,17 +757,19 @@ proc genStubs::emitHeader {name} { proc genStubs::emitInit {name textVar} { variable hooks + variable interfaces variable epoch variable revision upvar $textVar text + set root 1 set capName [string toupper [string index $name 0]] append capName [string range $name 1 end] set CAPName [string toupper $name] if {[info exists hooks($name)]} { - append text "\nstatic ${capName}StubHooks ${name}StubHooks = \{\n" + append text "\nstatic const ${capName}StubHooks ${name}StubHooks = \{\n" set sep " " foreach sub $hooks($name) { append text $sep "&${sub}Stubs" @@ -785,7 +777,20 @@ proc genStubs::emitInit {name textVar} { } append text "\n\};\n" } - append text "\n${capName}Stubs ${name}Stubs = \{\n" + foreach intf [array names interfaces] { + if {[info exists hooks($intf)]} { + if {0<=[lsearch -exact $hooks($intf) $name]} { + set root 0 + break; + } + } + } + + if {$root} { + append text "\nconst ${capName}Stubs ${name}Stubs = \{\n" + } else { + append text "\nstatic const ${capName}Stubs ${name}Stubs = \{\n" + } append text " TCL_STUB_MAGIC,\n" append text " ${CAPName}_STUBS_EPOCH,\n" append text " ${CAPName}_STUBS_REVISION,\n" diff --git a/generic/ttk/ttkImage.c b/generic/ttk/ttkImage.c index 3dcb379..0ac49c3 100644 --- a/generic/ttk/ttkImage.c +++ b/generic/ttk/ttkImage.c @@ -1,4 +1,4 @@ -/* $Id: ttkImage.c,v 1.7 2007/12/13 15:26:26 dgp Exp $ +/* $Id: ttkImage.c,v 1.7.2.1 2010/08/26 02:06:09 hobbs Exp $ * Image specifications and image element factory. * * Copyright (C) 2004 Pat Thoyts @@ -312,7 +312,7 @@ Ttk_CreateImageElement( void *clientData, Ttk_Theme theme, const char *elementName, - int objc, Tcl_Obj *CONST objv[]) + int objc, Tcl_Obj *const objv[]) { const char *optionStrings[] = { "-border","-height","-padding","-sticky","-width",NULL }; diff --git a/generic/ttk/ttkInit.c b/generic/ttk/ttkInit.c index 6e9192b..f718f97 100644 --- a/generic/ttk/ttkInit.c +++ b/generic/ttk/ttkInit.c @@ -1,4 +1,4 @@ -/* $Id: ttkInit.c,v 1.7.2.1 2010/01/29 12:41:12 nijtmans Exp $ +/* $Id: ttkInit.c,v 1.7.2.2 2010/08/26 02:06:09 hobbs Exp $ * Copyright (c) 2003, Joe English * * Ttk package: initialization routine and miscellaneous utilities. @@ -46,7 +46,7 @@ int Ttk_GetCompoundFromObj( * Legal values for the -orient option. * See also: enum Ttk_Orient. */ -CONST char *ttkOrientStrings[] = { +const char *ttkOrientStrings[] = { "horizontal", "vertical", NULL }; @@ -259,7 +259,7 @@ static void RegisterThemes(Tcl_Interp *interp) * Ttk initialization. */ -extern TtkStubs ttkStubs; +extern const TtkStubs ttkStubs; MODULE_SCOPE int Ttk_Init(Tcl_Interp *interp) @@ -276,7 +276,7 @@ Ttk_Init(Tcl_Interp *interp) Ttk_PlatformInit(interp); - Tcl_PkgProvideEx(interp, "Ttk", TTK_PATCH_LEVEL, (void*)&ttkStubs); + Tcl_PkgProvideEx(interp, "Ttk", TTK_PATCH_LEVEL, (ClientData)&ttkStubs); return TCL_OK; } diff --git a/generic/ttk/ttkLabel.c b/generic/ttk/ttkLabel.c index ffc7928..a02f4d0 100644 --- a/generic/ttk/ttkLabel.c +++ b/generic/ttk/ttkLabel.c @@ -1,4 +1,4 @@ -/* $Id: ttkLabel.c,v 1.11.2.1 2008/05/23 17:58:08 jenglish Exp $ +/* $Id: ttkLabel.c,v 1.11.2.2 2010/08/26 02:06:09 hobbs Exp $ * * text, image, and label elements. * @@ -67,7 +67,7 @@ static Ttk_ElementOptionSpec TextElementOptions[] = { Tk_Offset(TextElement,wrapLengthObj), "0" }, { "-embossed", TK_OPTION_INT, Tk_Offset(TextElement,embossedObj), "0"}, - {NULL} + { NULL, 0, 0, NULL } }; static int TextSetup(TextElement *text, Tk_Window tkwin) @@ -236,7 +236,7 @@ static Ttk_ElementOptionSpec ImageElementOptions[] = { Tk_Offset(ImageElement,stippleObj), "gray50" }, { "-background", TK_OPTION_COLOR, Tk_Offset(ImageElement,backgroundObj), DEFAULT_BACKGROUND }, - {NULL} + { NULL, 0, 0, NULL } }; /* @@ -452,8 +452,7 @@ static Ttk_ElementOptionSpec LabelElementOptions[] = { Tk_Offset(LabelElement,image.stippleObj), "gray50" }, { "-background", TK_OPTION_COLOR, Tk_Offset(LabelElement,image.backgroundObj), DEFAULT_BACKGROUND }, - - {NULL} + { NULL, 0, 0, NULL } }; /* 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 @@ -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; 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. * * @@@ <> bug: only works for horizontal orientations + * @@@ <> 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); diff --git a/generic/ttk/ttkPanedwindow.c b/generic/ttk/ttkPanedwindow.c index cac3d20..d0e5f89 100644 --- a/generic/ttk/ttkPanedwindow.c +++ b/generic/ttk/ttkPanedwindow.c @@ -1,4 +1,4 @@ -/* $Id: ttkPanedwindow.c,v 1.14 2008/02/23 17:35:28 jenglish Exp $ +/* $Id: ttkPanedwindow.c,v 1.14.2.1 2010/08/26 02:06:09 hobbs Exp $ * * Copyright (c) 2005, Joe English. Freely redistributable. * @@ -142,7 +142,7 @@ static void DestroyPane(Paned *pw, Pane *pane) */ static int ConfigurePane( Tcl_Interp *interp, Paned *pw, Pane *pane, Tk_Window slaveWindow, - int objc, Tcl_Obj *CONST objv[]) + int objc, Tcl_Obj *const objv[]) { Ttk_Manager *mgr = pw->paned.mgr; Tk_SavedOptions savedOptions; @@ -493,7 +493,7 @@ static void PanedEventProc(ClientData clientData, XEvent *eventPtr) * +++ Initialization and cleanup hooks. */ -static int PanedInitialize(Tcl_Interp *interp, void *recordPtr) +static void PanedInitialize(Tcl_Interp *interp, void *recordPtr) { Paned *pw = recordPtr; @@ -503,8 +503,6 @@ static int PanedInitialize(Tcl_Interp *interp, void *recordPtr) pw->paned.paneOptionTable = Tk_CreateOptionTable(interp,PaneOptionSpecs); pw->paned.sashLayout = 0; pw->paned.sashThickness = 1; - - return TCL_OK; } static void PanedCleanup(void *recordPtr) @@ -529,7 +527,7 @@ static int PanedPostConfigure(Tcl_Interp *interp, void *clientData, int mask) * Recalculate sash positions based on requested size. */ Tk_Window tkwin = pw->core.tkwin; - PlaceSashes(pw, + PlaceSashes(pw, pw->paned.width > 0 ? pw->paned.width : Tk_Width(tkwin), pw->paned.height > 0 ? pw->paned.height : Tk_Height(tkwin)); } @@ -575,36 +573,40 @@ static Ttk_Layout PanedGetLayout( * +++ Drawing routines. */ -static void DrawSash(Paned *pw, Drawable d, Ttk_Box b) +/* SashLayout -- + * Place the sash sublayout after the specified pane, + * in preparation for drawing. + */ +static Ttk_Layout SashLayout(Paned *pw, int index) { - Ttk_Layout sashLayout = pw->paned.sashLayout; - Ttk_State state = pw->core.state; + Pane *pane = Ttk_SlaveData(pw->paned.mgr, index); + int thickness = pw->paned.sashThickness, + height = Tk_Height(pw->core.tkwin), + width = Tk_Width(pw->core.tkwin), + sashPos = pane->sashPos; + + Ttk_PlaceLayout( + pw->paned.sashLayout, pw->core.state, + pw->paned.orient == TTK_ORIENT_HORIZONTAL + ? Ttk_MakeBox(sashPos, 0, thickness, height) + : Ttk_MakeBox(0, sashPos, width, thickness)); - Ttk_PlaceLayout(sashLayout, state, b); - Ttk_DrawLayout(sashLayout, state, d); + return pw->paned.sashLayout; +} + +static void DrawSash(Paned *pw, int index, Drawable d) +{ + Ttk_DrawLayout(SashLayout(pw, index), pw->core.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; + int i, nSashes = Ttk_NumberSlaves(pw->paned.mgr) - 1; TtkWidgetDisplay(recordPtr, d); - - /* Draw sashes: - */ - 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)); - } + for (i = 0; i < nSashes; ++i) { + DrawSash(pw, i, d); } } @@ -615,7 +617,7 @@ static void PanedDisplay(void *recordPtr, Drawable d) /* $pw add window [ options ... ] */ static int PanedAddCommand( - Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[], void *recordPtr) + void *recordPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]) { Paned *pw = recordPtr; Tk_Window slaveWindow; @@ -636,11 +638,11 @@ static int PanedAddCommand( objc - 3, objv + 3); } -/* $pw insert $index $slave ?options...? +/* $pw insert $index $slave ?-option value ...? * Insert new slave, or move existing one. */ static int PanedInsertCommand( - Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[], void *recordPtr) + void *recordPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]) { Paned *pw = recordPtr; int nSlaves = Ttk_NumberSlaves(pw->paned.mgr); @@ -648,7 +650,7 @@ static int PanedInsertCommand( Tk_Window slaveWindow; if (objc < 4) { - Tcl_WrongNumArgs(interp, 2,objv, "index slave ?options...?"); + Tcl_WrongNumArgs(interp, 2,objv, "index slave ?-option value ...?"); return TCL_ERROR; } @@ -661,7 +663,7 @@ static int PanedInsertCommand( if (!strcmp(Tcl_GetString(objv[2]), "end")) { destIndex = Ttk_NumberSlaves(pw->paned.mgr); } else if (TCL_OK != Ttk_GetSlaveIndexFromObj( - interp,pw->paned.mgr,objv[2],&destIndex)) + interp,pw->paned.mgr,objv[2],&destIndex)) { return TCL_ERROR; } @@ -685,7 +687,7 @@ static int PanedInsertCommand( /* $pw forget $pane */ static int PanedForgetCommand( - Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[], void *recordPtr) + void *recordPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]) { Paned *pw = recordPtr; int paneIndex; @@ -696,7 +698,7 @@ static int PanedForgetCommand( } if (TCL_OK != Ttk_GetSlaveIndexFromObj( - interp, pw->paned.mgr, objv[2], &paneIndex)) + interp, pw->paned.mgr, objv[2], &paneIndex)) { return TCL_ERROR; } @@ -705,24 +707,31 @@ static int PanedForgetCommand( return TCL_OK; } -/* $pw identify $x $y -- +/* $pw identify ?what? $x $y -- * Return index of sash at $x,$y */ static int PanedIdentifyCommand( - Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[], void *recordPtr) + void *recordPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]) { + const char *whatTable[] = { "element", "sash", NULL }; + enum { IDENTIFY_ELEMENT, IDENTIFY_SASH }; + int what = IDENTIFY_SASH; Paned *pw = recordPtr; int sashThickness = pw->paned.sashThickness; int nSashes = Ttk_NumberSlaves(pw->paned.mgr) - 1; int x, y, pos; int index; - 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; } @@ -731,19 +740,33 @@ static int PanedIdentifyCommand( 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)); - return TCL_OK; + /* Found it. */ + switch (what) { + case IDENTIFY_SASH: + Tcl_SetObjResult(interp, Tcl_NewIntObj(index)); + return TCL_OK; + case IDENTIFY_ELEMENT: + { + Ttk_Element element = + Ttk_IdentifyElement(SashLayout(pw, index), x, y); + if (element) { + Tcl_SetObjResult(interp, + Tcl_NewStringObj(Ttk_ElementName(element), -1)); + } + return TCL_OK; + } + } } } - return TCL_OK; /* return empty string */ + return TCL_OK; /* nothing found - return empty string */ } /* $pw pane $pane ?-option ?value -option value ...?? * Query/modify pane options. */ static int PanedPaneCommand( - Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[], void *recordPtr) + void *recordPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]) { Paned *pw = recordPtr; int paneIndex; @@ -751,7 +774,7 @@ static int PanedPaneCommand( Pane *pane; if (objc < 3) { - Tcl_WrongNumArgs(interp, 2,objv, "pane ?-option value...?"); + Tcl_WrongNumArgs(interp, 2,objv, "pane ?-option value ...?"); return TCL_ERROR; } @@ -780,7 +803,7 @@ static int PanedPaneCommand( * Return list of managed panes. */ static int PanedPanesCommand( - Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[], void *recordPtr) + void *recordPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]) { Paned *pw = recordPtr; Ttk_Manager *mgr = pw->paned.mgr; @@ -807,7 +830,7 @@ static int PanedPanesCommand( * Query or modify sash position. */ static int PanedSashposCommand( - Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[], void *recordPtr) + void *recordPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]) { Paned *pw = recordPtr; int sashIndex, position = -1; @@ -852,20 +875,19 @@ static int PanedSashposCommand( return TCL_OK; } -static WidgetCommandSpec PanedCommands[] = -{ - { "add", PanedAddCommand }, - { "configure", TtkWidgetConfigureCommand }, - { "cget", TtkWidgetCgetCommand }, - { "forget", PanedForgetCommand }, - { "identify", PanedIdentifyCommand }, - { "insert", PanedInsertCommand }, - { "instate", TtkWidgetInstateCommand }, - { "pane", PanedPaneCommand }, - { "panes", PanedPanesCommand }, - { "sashpos", PanedSashposCommand }, - { "state", TtkWidgetStateCommand }, - { 0,0 } +static const Ttk_Ensemble PanedCommands[] = { + { "add", PanedAddCommand,0 }, + { "configure", TtkWidgetConfigureCommand,0 }, + { "cget", TtkWidgetCgetCommand,0 }, + { "forget", PanedForgetCommand,0 }, + { "identify", PanedIdentifyCommand,0 }, + { "insert", PanedInsertCommand,0 }, + { "instate", TtkWidgetInstateCommand,0 }, + { "pane", PanedPaneCommand,0 }, + { "panes", PanedPanesCommand,0 }, + { "sashpos", PanedSashposCommand,0 }, + { "state", TtkWidgetStateCommand,0 }, + { 0,0,0 } }; /*------------------------------------------------------------------------ @@ -901,7 +923,7 @@ typedef struct { static Ttk_ElementOptionSpec SashElementOptions[] = { { "-sashthickness", TK_OPTION_INT, Tk_Offset(SashElement,thicknessObj), "5" }, - {NULL} + { NULL, 0, 0, NULL } }; static void SashElementSize( @@ -937,7 +959,7 @@ TTK_END_LAYOUT /*------------------------------------------------------------------------ * +++ Registration routine. */ -MODULE_SCOPE +MODULE_SCOPE void TtkPanedwindow_Init(Tcl_Interp *interp) { Ttk_Theme themePtr = Ttk_GetDefaultTheme(interp); diff --git a/generic/ttk/ttkProgress.c b/generic/ttk/ttkProgress.c index 6d6db8d..c96a49e 100644 --- a/generic/ttk/ttkProgress.c +++ b/generic/ttk/ttkProgress.c @@ -1,4 +1,4 @@ -/* $Id: ttkProgress.c,v 1.5 2007/01/11 14:49:47 jenglish Exp $ +/* $Id: ttkProgress.c,v 1.5.4.1 2010/08/26 02:06:09 hobbs Exp $ * * Copyright (c) Joe English, Pat Thoyts, Michael Kirkham * @@ -19,7 +19,7 @@ enum { TTK_PROGRESSBAR_DETERMINATE, TTK_PROGRESSBAR_INDETERMINATE }; -static const char *ProgressbarModeStrings[] = { +static const char *const ProgressbarModeStrings[] = { "determinate", "indeterminate", NULL }; @@ -185,12 +185,11 @@ static void VariableChanged(void *recordPtr, const char *value) * +++ Widget class methods: */ -static int ProgressbarInitialize(Tcl_Interp *interp, void *recordPtr) +static void ProgressbarInitialize(Tcl_Interp *interp, void *recordPtr) { Progressbar *pb = recordPtr; pb->progress.variableTrace = 0; pb->progress.timer = 0; - return TCL_OK; } static void ProgressbarCleanup(void *recordPtr) @@ -292,7 +291,7 @@ static int ProgressbarSize(void *recordPtr, int *widthPtr, int *heightPtr) static void ProgressbarDeterminateLayout( Progressbar *pb, - Ttk_LayoutNode *pbarNode, + Ttk_Element pbar, Ttk_Box parcel, double fraction, Ttk_Orient orient) @@ -307,17 +306,17 @@ static void ProgressbarDeterminateLayout( parcel.y += (parcel.height - newHeight); parcel.height = newHeight; } - Ttk_PlaceLayoutNode(pb->core.layout, pbarNode, parcel); + Ttk_PlaceElement(pb->core.layout, pbar, parcel); } static void ProgressbarIndeterminateLayout( Progressbar *pb, - Ttk_LayoutNode *pbarNode, + Ttk_Element pbar, Ttk_Box parcel, double fraction, Ttk_Orient orient) { - Ttk_Box pbarBox = Ttk_LayoutNodeParcel(pbarNode); + Ttk_Box pbarBox = Ttk_ElementParcel(pbar); fraction = fmod(fabs(fraction), 2.0); if (fraction > 1.0) { @@ -329,18 +328,16 @@ static void ProgressbarIndeterminateLayout( } else { pbarBox.y = parcel.y + (int)(fraction * (parcel.height-pbarBox.height)); } - Ttk_PlaceLayoutNode(pb->core.layout, pbarNode, pbarBox); + Ttk_PlaceElement(pb->core.layout, pbar, pbarBox); } static void ProgressbarDoLayout(void *recordPtr) { Progressbar *pb = recordPtr; WidgetCore *corePtr = &pb->core; - Ttk_LayoutNode *pbarNode = Ttk_LayoutFindNode(corePtr->layout, "pbar"); - Ttk_LayoutNode *troughNode = Ttk_LayoutFindNode(corePtr->layout, "trough"); + Ttk_Element pbar = Ttk_FindElement(corePtr->layout, "pbar"); double value = 0.0, maximum = 100.0; int orient = TTK_ORIENT_HORIZONTAL; - Ttk_Box parcel = Ttk_WinBox(corePtr->tkwin); Ttk_PlaceLayout(corePtr->layout,corePtr->state,Ttk_WinBox(corePtr->tkwin)); @@ -351,19 +348,16 @@ static void ProgressbarDoLayout(void *recordPtr) Tcl_GetDoubleFromObj(NULL, pb->progress.maximumObj, &maximum); Ttk_GetOrientFromObj(NULL, pb->progress.orientObj, &orient); - if (pbarNode) { + if (pbar) { double fraction = value / maximum; - - if (troughNode) { - parcel = Ttk_LayoutNodeInternalParcel(corePtr->layout, troughNode); - } + Ttk_Box parcel = Ttk_ClientRegion(corePtr->layout, "trough"); if (pb->progress.mode == TTK_PROGRESSBAR_DETERMINATE) { ProgressbarDeterminateLayout( - pb, pbarNode, parcel, fraction, orient); + pb, pbar, parcel, fraction, orient); } else { ProgressbarIndeterminateLayout( - pb, pbarNode, parcel, fraction, orient); + pb, pbar, parcel, fraction, orient); } } } @@ -399,7 +393,7 @@ static Ttk_Layout ProgressbarGetLayout( /* $sb step ?amount? */ static int ProgressbarStepCommand( - Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[], void *recordPtr) + void *recordPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]) { Progressbar *pb = recordPtr; double value = 0.0, stepAmount = 1.0; @@ -453,7 +447,7 @@ static int ProgressbarStepCommand( * and pass to interpreter. */ static int ProgressbarStartStopCommand( - Tcl_Interp *interp, const char *cmdName, int objc, Tcl_Obj *CONST objv[]) + Tcl_Interp *interp, const char *cmdName, int objc, Tcl_Obj *const objv[]) { Tcl_Obj *cmd = Tcl_NewListObj(objc, objv); Tcl_Obj *prefix[2]; @@ -473,30 +467,29 @@ static int ProgressbarStartStopCommand( } static int ProgressbarStartCommand( - Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[], void *recordPtr) + void *recordPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]) { return ProgressbarStartStopCommand( interp, "::ttk::progressbar::start", objc, objv); } static int ProgressbarStopCommand( - Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[], void *recordPtr) + void *recordPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]) { return ProgressbarStartStopCommand( interp, "::ttk::progressbar::stop", objc, objv); } -static WidgetCommandSpec ProgressbarCommands[] = -{ - { "configure", TtkWidgetConfigureCommand }, - { "cget", TtkWidgetCgetCommand }, - { "identify", TtkWidgetIdentifyCommand }, - { "instate", TtkWidgetInstateCommand }, - { "start", ProgressbarStartCommand }, - { "state", TtkWidgetStateCommand }, - { "step", ProgressbarStepCommand }, - { "stop", ProgressbarStopCommand }, - { NULL, NULL } +static const Ttk_Ensemble ProgressbarCommands[] = { + { "configure", TtkWidgetConfigureCommand,0 }, + { "cget", TtkWidgetCgetCommand,0 }, + { "identify", TtkWidgetIdentifyCommand,0 }, + { "instate", TtkWidgetInstateCommand,0 }, + { "start", ProgressbarStartCommand,0 }, + { "state", TtkWidgetStateCommand,0 }, + { "step", ProgressbarStepCommand,0 }, + { "stop", ProgressbarStopCommand,0 }, + { 0,0,0 } }; /* diff --git a/generic/ttk/ttkScale.c b/generic/ttk/ttkScale.c index 4c8d1eb..10ef3ce 100644 --- a/generic/ttk/ttkScale.c +++ b/generic/ttk/ttkScale.c @@ -1,4 +1,4 @@ -/* $Id: ttkScale.c,v 1.7 2007/12/13 15:26:26 dgp Exp $ +/* $Id: ttkScale.c,v 1.7.2.1 2010/08/26 02:06:09 hobbs Exp $ * Copyright (C) 2004 Pat Thoyts * * ttk::scale widget. @@ -100,12 +100,10 @@ static void ScaleVariableChanged(void *recordPtr, const char *value) /* ScaleInitialize -- * Scale widget initialization hook. */ -static int ScaleInitialize(Tcl_Interp *interp, void *recordPtr) +static void ScaleInitialize(Tcl_Interp *interp, void *recordPtr) { Scale *scalePtr = recordPtr; - TtkTrackElementState(&scalePtr->core); - return TCL_OK; } static void ScaleCleanup(void *recordPtr) @@ -189,15 +187,7 @@ ScaleGetLayout(Tcl_Interp *interp, Ttk_Theme theme, void *recordPtr) */ static Ttk_Box TroughBox(Scale *scalePtr) { - WidgetCore *corePtr = &scalePtr->core; - Ttk_LayoutNode *node = Ttk_LayoutFindNode(corePtr->layout, "trough"); - - if (node) { - return Ttk_LayoutNodeInternalParcel(corePtr->layout, node); - } else { - return Ttk_MakeBox( - 0,0, Tk_Width(corePtr->tkwin), Tk_Height(corePtr->tkwin)); - } + return Ttk_ClientRegion(scalePtr->core.layout, "trough"); } /* @@ -208,13 +198,13 @@ static Ttk_Box TroughBox(Scale *scalePtr) static Ttk_Box TroughRange(Scale *scalePtr) { Ttk_Box troughBox = TroughBox(scalePtr); - Ttk_LayoutNode *slider=Ttk_LayoutFindNode(scalePtr->core.layout,"slider"); + Ttk_Element slider = Ttk_FindElement(scalePtr->core.layout,"slider"); /* * If this is a scale widget, adjust range for slider: */ if (slider) { - Ttk_Box sliderBox = Ttk_LayoutNodeParcel(slider); + Ttk_Box sliderBox = Ttk_ElementParcel(slider); if (scalePtr->scale.orient == TTK_ORIENT_HORIZONTAL) { troughBox.x += sliderBox.width / 2; troughBox.width -= sliderBox.width; @@ -252,7 +242,7 @@ static double ScaleFraction(Scale *scalePtr, double value) */ static int ScaleGetCommand( - Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[], void *recordPtr) + void *recordPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]) { Scale *scalePtr = recordPtr; int x, y, r = TCL_OK; @@ -280,7 +270,7 @@ ScaleGetCommand( */ static int ScaleSetCommand( - Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[], void *recordPtr) + void *recordPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]) { Scale *scalePtr = recordPtr; double from = 0.0, to = 1.0, value; @@ -348,7 +338,7 @@ ScaleSetCommand( static int ScaleCoordsCommand( - Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[], void *recordPtr) + void *recordPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]) { Scale *scalePtr = recordPtr; double value; @@ -378,16 +368,16 @@ ScaleCoordsCommand( static void ScaleDoLayout(void *clientData) { WidgetCore *corePtr = clientData; - Ttk_LayoutNode *sliderNode = Ttk_LayoutFindNode(corePtr->layout, "slider"); + Ttk_Element slider = Ttk_FindElement(corePtr->layout, "slider"); Ttk_PlaceLayout(corePtr->layout,corePtr->state,Ttk_WinBox(corePtr->tkwin)); /* Adjust the slider position: */ - if (sliderNode) { + if (slider) { Scale *scalePtr = clientData; Ttk_Box troughBox = TroughBox(scalePtr); - Ttk_Box sliderBox = Ttk_LayoutNodeParcel(sliderNode); + Ttk_Box sliderBox = Ttk_ElementParcel(slider); double value = 0.0; double fraction; int range; @@ -402,7 +392,7 @@ static void ScaleDoLayout(void *clientData) range = troughBox.height - sliderBox.height; sliderBox.y += (int)(fraction * range); } - Ttk_PlaceLayoutNode(corePtr->layout, sliderNode, sliderBox); + Ttk_PlaceElement(corePtr->layout, slider, sliderBox); } } @@ -472,17 +462,16 @@ ValueToPoint(Scale *scalePtr, double value) return pt; } -static WidgetCommandSpec ScaleCommands[] = -{ - { "configure", TtkWidgetConfigureCommand }, - { "cget", TtkWidgetCgetCommand }, - { "state", TtkWidgetStateCommand }, - { "instate", TtkWidgetInstateCommand }, - { "identify", TtkWidgetIdentifyCommand }, - { "set", ScaleSetCommand }, - { "get", ScaleGetCommand }, - { "coords", ScaleCoordsCommand }, - { 0, 0 } +static const Ttk_Ensemble ScaleCommands[] = { + { "configure", TtkWidgetConfigureCommand,0 }, + { "cget", TtkWidgetCgetCommand,0 }, + { "state", TtkWidgetStateCommand,0 }, + { "instate", TtkWidgetInstateCommand,0 }, + { "identify", TtkWidgetIdentifyCommand,0 }, + { "set", ScaleSetCommand,0 }, + { "get", ScaleGetCommand,0 }, + { "coords", ScaleCoordsCommand,0 }, + { 0,0,0 } }; static WidgetSpec ScaleWidgetSpec = diff --git a/generic/ttk/ttkScroll.c b/generic/ttk/ttkScroll.c index afc1d78..bbf1b46 100644 --- a/generic/ttk/ttkScroll.c +++ b/generic/ttk/ttkScroll.c @@ -1,4 +1,4 @@ -/* $Id: ttkScroll.c,v 1.5.4.1 2008/08/19 14:48:00 jenglish Exp $ +/* $Id: ttkScroll.c,v 1.5.4.2 2010/08/26 02:06:09 hobbs Exp $ * * Copyright 2004, Joe English * diff --git a/generic/ttk/ttkScrollbar.c b/generic/ttk/ttkScrollbar.c index 82bb880..d0f91de 100644 --- a/generic/ttk/ttkScrollbar.c +++ b/generic/ttk/ttkScrollbar.c @@ -1,4 +1,4 @@ -/* $Id: ttkScrollbar.c,v 1.7 2007/12/13 15:26:26 dgp Exp $ +/* $Id: ttkScrollbar.c,v 1.7.2.1 2010/08/26 02:06:09 hobbs Exp $ * Copyright (c) 2003, Joe English * * ttk::scrollbar widget. @@ -49,7 +49,7 @@ static Tk_OptionSpec ScrollbarOptionSpecs[] = * +++ Widget hooks. */ -static int +static void ScrollbarInitialize(Tcl_Interp *interp, void *recordPtr) { Scrollbar *sb = recordPtr; @@ -57,8 +57,6 @@ ScrollbarInitialize(Tcl_Interp *interp, void *recordPtr) sb->scrollbar.last = 1.0; TtkTrackElementState(&sb->core); - - return TCL_OK; } static Ttk_Layout ScrollbarGetLayout( @@ -80,7 +78,7 @@ static void ScrollbarDoLayout(void *recordPtr) { Scrollbar *sb = recordPtr; WidgetCore *corePtr = &sb->core; - Ttk_LayoutNode *thumb; + Ttk_Element thumb; Ttk_Box thumbBox; int thumbWidth, thumbHeight; double first, last, size; @@ -94,11 +92,11 @@ static void ScrollbarDoLayout(void *recordPtr) /* * Locate thumb element, extract parcel and requested minimum size: */ - thumb = Ttk_LayoutFindNode(corePtr->layout, "thumb"); + thumb = Ttk_FindElement(corePtr->layout, "thumb"); if (!thumb) /* Something has gone wrong -- bail */ return; - sb->scrollbar.troughBox = thumbBox = Ttk_LayoutNodeParcel(thumb); + sb->scrollbar.troughBox = thumbBox = Ttk_ElementParcel(thumb); Ttk_LayoutNodeReqSize( corePtr->layout, thumb, &thumbWidth,&thumbHeight); @@ -120,7 +118,7 @@ static void ScrollbarDoLayout(void *recordPtr) thumbBox.width = (int)(size * last) + minSize - (int)(size * first); } sb->scrollbar.minSize = minSize; - Ttk_PlaceLayoutNode(corePtr->layout, thumb, thumbBox); + Ttk_PlaceElement(corePtr->layout, thumb, thumbBox); } /*------------------------------------------------------------------------ @@ -132,7 +130,7 @@ static void ScrollbarDoLayout(void *recordPtr) */ static int ScrollbarSetCommand( - Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[], void *recordPtr) + void *recordPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]) { Scrollbar *scrollbar = recordPtr; Tcl_Obj *firstObj, *lastObj; @@ -183,7 +181,7 @@ ScrollbarSetCommand( */ static int ScrollbarGetCommand( - Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[], void *recordPtr) + void *recordPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]) { Scrollbar *scrollbar = recordPtr; Tcl_Obj *result[2]; @@ -206,7 +204,7 @@ ScrollbarGetCommand( */ static int ScrollbarDeltaCommand( - Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[], void *recordPtr) + void *recordPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]) { Scrollbar *sb = recordPtr; double dx, dy; @@ -246,7 +244,7 @@ ScrollbarDeltaCommand( */ static int ScrollbarFractionCommand( - Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[], void *recordPtr) + void *recordPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]) { Scrollbar *sb = recordPtr; Ttk_Box b = sb->scrollbar.troughBox; @@ -280,18 +278,17 @@ ScrollbarFractionCommand( return TCL_OK; } -static WidgetCommandSpec ScrollbarCommands[] = -{ - { "configure", TtkWidgetConfigureCommand }, - { "cget", TtkWidgetCgetCommand }, - { "delta", ScrollbarDeltaCommand }, - { "fraction", ScrollbarFractionCommand }, - { "get", ScrollbarGetCommand }, - { "identify", TtkWidgetIdentifyCommand }, - { "instate", TtkWidgetInstateCommand }, - { "set", ScrollbarSetCommand }, - { "state", TtkWidgetStateCommand }, - { 0,0 } +static const Ttk_Ensemble ScrollbarCommands[] = { + { "configure", TtkWidgetConfigureCommand,0 }, + { "cget", TtkWidgetCgetCommand,0 }, + { "delta", ScrollbarDeltaCommand,0 }, + { "fraction", ScrollbarFractionCommand,0 }, + { "get", ScrollbarGetCommand,0 }, + { "identify", TtkWidgetIdentifyCommand,0 }, + { "instate", TtkWidgetInstateCommand,0 }, + { "set", ScrollbarSetCommand,0 }, + { "state", TtkWidgetStateCommand,0 }, + { 0,0,0 } }; /*------------------------------------------------------------------------ diff --git a/generic/ttk/ttkSeparator.c b/generic/ttk/ttkSeparator.c index aff3f1b..3a34348 100644 --- a/generic/ttk/ttkSeparator.c +++ b/generic/ttk/ttkSeparator.c @@ -1,4 +1,4 @@ -/* $Id: ttkSeparator.c,v 1.7 2007/12/13 15:26:26 dgp Exp $ +/* $Id: ttkSeparator.c,v 1.7.2.1 2010/08/26 02:06:09 hobbs Exp $ * * Copyright (c) 2004, Joe English * @@ -49,14 +49,13 @@ static Ttk_Layout SeparatorGetLayout( /* * Widget commands: */ -static WidgetCommandSpec SeparatorCommands[] = -{ - { "configure", TtkWidgetConfigureCommand }, - { "cget", TtkWidgetCgetCommand }, - { "identify", TtkWidgetIdentifyCommand }, - { "instate", TtkWidgetInstateCommand }, - { "state", TtkWidgetStateCommand }, - { NULL, NULL } +static const Ttk_Ensemble SeparatorCommands[] = { + { "configure", TtkWidgetConfigureCommand,0 }, + { "cget", TtkWidgetCgetCommand,0 }, + { "identify", TtkWidgetIdentifyCommand,0 }, + { "instate", TtkWidgetInstateCommand,0 }, + { "state", TtkWidgetStateCommand,0 }, + { 0,0,0 } }; /* @@ -86,14 +85,13 @@ TTK_END_LAYOUT * Has no options or methods other than the standard ones. */ -static WidgetCommandSpec SizegripCommands[] = -{ - { "configure", TtkWidgetConfigureCommand }, - { "cget", TtkWidgetCgetCommand }, - { "identify", TtkWidgetIdentifyCommand }, - { "instate", TtkWidgetInstateCommand }, - { "state", TtkWidgetStateCommand }, - { NULL, NULL } +static const Ttk_Ensemble SizegripCommands[] = { + { "configure", TtkWidgetConfigureCommand,0 }, + { "cget", TtkWidgetCgetCommand,0 }, + { "identify", TtkWidgetIdentifyCommand,0 }, + { "instate", TtkWidgetInstateCommand,0 }, + { "state", TtkWidgetStateCommand,0 }, + { 0,0,0 } }; static WidgetSpec SizegripWidgetSpec = diff --git a/generic/ttk/ttkSquare.c b/generic/ttk/ttkSquare.c index b5ff73b..d2f4540 100644 --- a/generic/ttk/ttkSquare.c +++ b/generic/ttk/ttkSquare.c @@ -2,14 +2,14 @@ * * Minimal sample ttk widget. * - * $Id: ttkSquare.c,v 1.6 2007/12/13 15:26:26 dgp Exp $ + * $Id: ttkSquare.c,v 1.6.2.1 2010/08/26 02:06:09 hobbs Exp $ */ #include #include "ttkTheme.h" #include "ttkWidget.h" -#ifdef TTK_SQUARE_WIDGET +#if defined(TTK_SQUARE_WIDGET) || 1 #ifndef DEFAULT_BORDERWIDTH #define DEFAULT_BORDERWIDTH "2" @@ -100,9 +100,9 @@ SquareDoLayout(void *clientData) { WidgetCore *corePtr = (WidgetCore *)clientData; Ttk_Box winBox; - Ttk_LayoutNode *squareNode; + Ttk_Element squareNode; - squareNode = Ttk_LayoutFindNode(corePtr->layout, "square"); + squareNode = Ttk_FindElement(corePtr->layout, "square"); winBox = Ttk_WinBox(corePtr->tkwin); Ttk_PlaceLayout(corePtr->layout, corePtr->state, winBox); @@ -116,12 +116,12 @@ SquareDoLayout(void *clientData) Tk_Anchor anchor = TK_ANCHOR_CENTER; Ttk_Box b; - b = Ttk_LayoutNodeParcel(squareNode); + b = Ttk_ElementParcel(squareNode); if (squarePtr->square.anchorObj != NULL) Tk_GetAnchorFromObj(NULL, squarePtr->square.anchorObj, &anchor); b = Ttk_AnchorBox(winBox, b.width, b.height, anchor); - Ttk_PlaceLayoutNode(corePtr->layout, squareNode, b); + Ttk_PlaceElement(corePtr->layout, squareNode, b); } } @@ -131,14 +131,13 @@ SquareDoLayout(void *clientData) * that are sufficient for our needs. */ -static WidgetCommandSpec SquareCommands[] = -{ - { "configure", TtkWidgetConfigureCommand }, - { "cget", TtkWidgetCgetCommand }, - { "identify", TtkWidgetIdentifyCommand }, - { "instate", TtkWidgetInstateCommand }, - { "state", TtkWidgetStateCommand }, - { NULL, NULL } +static const Ttk_Ensemble SquareCommands[] = { + { "configure", TtkWidgetConfigureCommand,0 }, + { "cget", TtkWidgetCgetCommand,0 }, + { "identify", TtkWidgetIdentifyCommand,0 }, + { "instate", TtkWidgetInstateCommand,0 }, + { "state", TtkWidgetStateCommand,0 }, + { 0,0,0 } }; /* @@ -192,7 +191,7 @@ static Ttk_ElementOptionSpec SquareElementOptions[] = "raised" }, { "-width", TK_OPTION_PIXELS, Tk_Offset(SquareElement,widthObj), "20"}, { "-height", TK_OPTION_PIXELS, Tk_Offset(SquareElement,heightObj), "20"}, - { NULL } + { NULL, 0, 0, NULL } }; /* diff --git a/generic/ttk/ttkState.c b/generic/ttk/ttkState.c index 1c0db7d..71c4d3f 100644 --- a/generic/ttk/ttkState.c +++ b/generic/ttk/ttkState.c @@ -1,5 +1,5 @@ /* - * $Id: ttkState.c,v 1.1.4.1 2009/05/14 00:53:04 patthoyts Exp $ + * $Id: ttkState.c,v 1.1.4.2 2010/08/26 02:06:09 hobbs Exp $ * * Tk widget state utilities. * @@ -16,7 +16,7 @@ * Table of state names. Must be kept in sync with TTK_STATE_* * #defines in ttkTheme.h. */ -static const char *stateNames[] = +static const char *const stateNames[] = { "active", /* Mouse cursor is over widget or element */ "disabled", /* Widget is disabled */ @@ -83,7 +83,7 @@ static int StateSpecSetFromAny(Tcl_Interp *interp, Tcl_Obj *objPtr) return status; for (i = 0; i < objc; ++i) { - char *stateName = Tcl_GetString(objv[i]); + const char *stateName = Tcl_GetString(objv[i]); int on, j; if (*stateName == '!') { @@ -226,7 +226,7 @@ Tcl_Obj *Ttk_StateMapLookup( /* Ttk_GetStateMapFromObj -- * Returns a Ttk_StateMap from a Tcl_Obj*. - * Since a Ttk_StateMap is just a specially-formatted Tcl_Obj, + * Since a Ttk_StateMap is just a specially-formatted Tcl_Obj, * this basically just checks for errors. */ Ttk_StateMap Ttk_GetStateMapFromObj( diff --git a/generic/ttk/ttkStubInit.c b/generic/ttk/ttkStubInit.c index 11b60f9..3a203b5 100644 --- a/generic/ttk/ttkStubInit.c +++ b/generic/ttk/ttkStubInit.c @@ -1,5 +1,5 @@ /* - * $Id: ttkStubInit.c,v 1.2 2006/11/03 03:06:22 das Exp $ + * $Id: ttkStubInit.c,v 1.2.4.1 2010/08/26 02:06:09 hobbs Exp $ * * This file is (mostly) automatically generated from ttk.decls. * It is compiled and linked in with the ttk package proper. @@ -8,11 +8,11 @@ #include "tk.h" #include "ttkTheme.h" -MODULE_SCOPE TtkStubs ttkStubs; +MODULE_SCOPE const TtkStubs ttkStubs; /* !BEGIN!: Do not edit below this line. */ -TtkStubs ttkStubs = { +const TtkStubs ttkStubs = { TCL_STUB_MAGIC, TTK_STUBS_EPOCH, TTK_STUBS_REVISION, diff --git a/generic/ttk/ttkStubLib.c b/generic/ttk/ttkStubLib.c index 15d4d28..a5f5f8e 100644 --- a/generic/ttk/ttkStubLib.c +++ b/generic/ttk/ttkStubLib.c @@ -1,5 +1,5 @@ /* - * $Id: ttkStubLib.c,v 1.5 2008/03/27 12:04:02 das Exp $ + * $Id: ttkStubLib.c,v 1.5.2.1 2010/08/26 02:06:09 hobbs Exp $ * SOURCE: tk/generic/tkStubLib.c, version 1.9 2004/03/17 */ @@ -8,10 +8,8 @@ * contains no references to any of the tcl stub functions. */ -#ifndef USE_TCL_STUBS +#undef USE_TCL_STUBS #define USE_TCL_STUBS -#endif -#undef USE_TCL_STUB_PROCS #include "tk.h" @@ -44,9 +42,9 @@ TtkInitializeStubs( const char *packageName = "Ttk"; const char *errMsg = NULL; ClientData pkgClientData = NULL; - const char *actualVersion= Tcl_PkgRequireEx( + const char *actualVersion = Tcl_PkgRequireEx( interp, packageName, version, exact, &pkgClientData); - TtkStubs *stubsPtr = pkgClientData; + const TtkStubs *stubsPtr = pkgClientData; if (!actualVersion) { return NULL; diff --git a/generic/ttk/ttkTagSet.c b/generic/ttk/ttkTagSet.c index 85624a2..fd4c538 100644 --- a/generic/ttk/ttkTagSet.c +++ b/generic/ttk/ttkTagSet.c @@ -1,6 +1,6 @@ -/* $Id: ttkTagSet.c,v 1.3 2007/01/11 19:59:26 jenglish Exp $ +/* $Id: ttkTagSet.c,v 1.3.4.1 2010/08/26 02:06:09 hobbs Exp $ * - * Ttk widget set: tag tables. Half-baked, work in progress. + * Tag tables. 3/4-baked, work in progress. * * Copyright (C) 2005, Joe English. Freely redistributable. */ @@ -16,53 +16,55 @@ * +++ Internal data structures. */ struct TtkTag { - Tcl_Obj **tagRecord; /* ... hrmph. */ + int priority; /* 1=>highest */ + const char *tagName; /* Back-pointer to hash table entry */ + void *tagRecord; /* User data */ }; struct TtkTagTable { - Tk_OptionTable tagOptionTable; /* ... */ - int tagRecordSize; /* size of tag record */ + Tk_Window tkwin; /* owner window */ + Tk_OptionSpec *optionSpecs; /* ... */ + Tk_OptionTable optionTable; /* ... */ + int recordSize; /* size of tag record */ + int nTags; /* #tags defined so far */ Tcl_HashTable tags; /* defined tags */ }; /*------------------------------------------------------------------------ * +++ Tags. */ -static Ttk_Tag NewTag(Ttk_TagTable tagTable) +static Ttk_Tag NewTag(Ttk_TagTable tagTable, const char *tagName) { Ttk_Tag tag = (Ttk_Tag)ckalloc(sizeof(*tag)); - tag->tagRecord = (Tcl_Obj **)ckalloc(tagTable->tagRecordSize); - memset(tag->tagRecord, 0, tagTable->tagRecordSize); + tag->tagRecord = ckalloc(tagTable->recordSize); + memset(tag->tagRecord, 0, tagTable->recordSize); + /* Don't need Tk_InitOptions() here, all defaults should be NULL. */ + tag->priority = ++tagTable->nTags; + tag->tagName = tagName; return tag; } -static void DeleteTag(Ttk_Tag tag, int nOptions) +static void DeleteTag(Ttk_TagTable tagTable, Ttk_Tag tag) { - int i; - for (i = 0; i < nOptions; ++i) { - if (tag->tagRecord[i]) { - Tcl_DecrRefCount(tag->tagRecord[i]); - } - } - ckfree((void*)tag->tagRecord); + Tk_FreeConfigOptions(tag->tagRecord,tagTable->optionTable,tagTable->tkwin); + ckfree(tag->tagRecord); ckfree((void*)tag); } -Tcl_Obj **Ttk_TagRecord(Ttk_Tag tag) -{ - return tag->tagRecord; -} - /*------------------------------------------------------------------------ * +++ Tag tables. */ Ttk_TagTable Ttk_CreateTagTable( - Tk_OptionTable tagOptionTable, int tagRecordSize) + Tcl_Interp *interp, Tk_Window tkwin, + Tk_OptionSpec optionSpecs[], int recordSize) { Ttk_TagTable tagTable = (Ttk_TagTable)ckalloc(sizeof(*tagTable)); - tagTable->tagOptionTable = tagOptionTable; - tagTable->tagRecordSize = tagRecordSize; + tagTable->tkwin = tkwin; + tagTable->optionSpecs = optionSpecs; + tagTable->optionTable = Tk_CreateOptionTable(interp, optionSpecs); + tagTable->recordSize = recordSize; + tagTable->nTags = 0; Tcl_InitHashTable(&tagTable->tags, TCL_STRING_KEYS); return tagTable; } @@ -71,11 +73,10 @@ void Ttk_DeleteTagTable(Ttk_TagTable tagTable) { Tcl_HashSearch search; Tcl_HashEntry *entryPtr; - int nOptions = tagTable->tagRecordSize / sizeof(Tcl_Obj *); entryPtr = Tcl_FirstHashEntry(&tagTable->tags, &search); while (entryPtr != NULL) { - DeleteTag(Tcl_GetHashValue(entryPtr), nOptions); + DeleteTag(tagTable, Tcl_GetHashValue(entryPtr)); entryPtr = Tcl_NextHashEntry(&search); } @@ -90,7 +91,8 @@ Ttk_Tag Ttk_GetTag(Ttk_TagTable tagTable, const char *tagName) &tagTable->tags, tagName, &isNew); if (isNew) { - Tcl_SetHashValue(entryPtr, NewTag(tagTable)); + tagName = Tcl_GetHashKey(&tagTable->tags, entryPtr); + Tcl_SetHashValue(entryPtr, NewTag(tagTable,tagName)); } return Tcl_GetHashValue(entryPtr); } @@ -100,48 +102,206 @@ Ttk_Tag Ttk_GetTagFromObj(Ttk_TagTable tagTable, Tcl_Obj *objPtr) return Ttk_GetTag(tagTable, Tcl_GetString(objPtr)); } -/* Ttk_GetTagListFromObj -- +/*------------------------------------------------------------------------ + * +++ Tag sets. + */ + +/* Ttk_GetTagSetFromObj -- * Extract an array of pointers to Ttk_Tags from a Tcl_Obj. - * (suitable for passing to Tk_BindEvent). + * objPtr may be NULL, in which case a new empty tag set is returned. + * + * Returns NULL and leaves an error message in interp->result on error. * - * Result must be passed to Ttk_FreeTagList(). + * Non-NULL results must be passed to Ttk_FreeTagSet(). */ -extern int Ttk_GetTagListFromObj( - Tcl_Interp *interp, - Ttk_TagTable tagTable, - Tcl_Obj *objPtr, - int *nTags_rtn, - void **taglist_rtn) +Ttk_TagSet Ttk_GetTagSetFromObj( + Tcl_Interp *interp, Ttk_TagTable tagTable, Tcl_Obj *objPtr) { + Ttk_TagSet tagset = (Ttk_TagSet)(ckalloc(sizeof *tagset)); Tcl_Obj **objv; int i, objc; - void **tags; - - *taglist_rtn = NULL; *nTags_rtn = 0; if (objPtr == NULL) { - return TCL_OK; + tagset->tags = NULL; + tagset->nTags = 0; + return tagset; } if (Tcl_ListObjGetElements(interp, objPtr, &objc, &objv) != TCL_OK) { - return TCL_ERROR; + ckfree((ClientData)tagset); + return NULL; } - tags = (void**)ckalloc((objc+1) * sizeof(void*)); + tagset->tags = (Ttk_Tag*)ckalloc((objc+1) * sizeof(Ttk_Tag)); for (i=0; itags[i] = Ttk_GetTagFromObj(tagTable, objv[i]); + } + tagset->tags[i] = NULL; + tagset->nTags = objc; + + return tagset; +} + +/* Ttk_NewTagSetObj -- + * Construct a fresh Tcl_Obj * from a tag set. + */ +Tcl_Obj *Ttk_NewTagSetObj(Ttk_TagSet tagset) +{ + Tcl_Obj *result = Tcl_NewListObj(0,0); + int i; + + for (i = 0; i < tagset->nTags; ++i) { + Tcl_ListObjAppendElement( + NULL, result, Tcl_NewStringObj(tagset->tags[i]->tagName, -1)); } - tags[i] = NULL; + return result; +} - *taglist_rtn = tags; - *nTags_rtn = objc; +void Ttk_FreeTagSet(Ttk_TagSet tagset) +{ + ckfree((ClientData)tagset->tags); + ckfree((ClientData)tagset); +} + +/* Ttk_TagSetContains -- test if tag set contains a tag. + */ +int Ttk_TagSetContains(Ttk_TagSet tagset, Ttk_Tag tag) +{ + int i; + for (i = 0; i < tagset->nTags; ++i) { + if (tagset->tags[i] == tag) { + return 1; + } + } + return 0; +} - return TCL_OK; +/* Ttk_TagSetAdd -- add a tag to a tag set. + * + * Returns: 0 if tagset already contained tag, + * 1 if tagset was modified. + */ +int Ttk_TagSetAdd(Ttk_TagSet tagset, Ttk_Tag tag) +{ + int i; + for (i = 0; i < tagset->nTags; ++i) { + if (tagset->tags[i] == tag) { + return 0; + } + } + tagset->tags = (void*)ckrealloc((void*)tagset->tags, + (tagset->nTags+1)*sizeof(tagset->tags[0])); + tagset->tags[tagset->nTags++] = tag; + return 1; } -void Ttk_FreeTagList(void **taglist) +/* Ttk_TagSetRemove -- remove a tag from a tag set. + * + * Returns: 0 if tagset did not contain tag, + * 1 if tagset was modified. + */ +int Ttk_TagSetRemove(Ttk_TagSet tagset, Ttk_Tag tag) { - if (taglist) - ckfree((ClientData)taglist); + int i = 0, j = 0; + while (i < tagset->nTags) { + if ((tagset->tags[j] = tagset->tags[i]) != tag) { + ++j; + } + ++i; + } + tagset->nTags = j; + return j != i; +} + +/*------------------------------------------------------------------------ + * +++ Utilities for widget commands. + */ + +/* Ttk_EnumerateTags -- implements [$w tag names] + */ +int Ttk_EnumerateTags( + Tcl_Interp *interp, Ttk_TagTable tagTable) +{ + return TtkEnumerateHashTable(interp, &tagTable->tags); +} + +/* Ttk_EnumerateTagOptions -- implements [$w tag configure $tag] + */ +int Ttk_EnumerateTagOptions( + Tcl_Interp *interp, Ttk_TagTable tagTable, Ttk_Tag tag) +{ + return TtkEnumerateOptions(interp, tag->tagRecord, + tagTable->optionSpecs, tagTable->optionTable, tagTable->tkwin); +} + +/* Ttk_TagOptionValue -- implements [$w tag configure $tag -option] + */ +Tcl_Obj *Ttk_TagOptionValue( + Tcl_Interp *interp, + Ttk_TagTable tagTable, + Ttk_Tag tag, + Tcl_Obj *optionName) +{ + return Tk_GetOptionValue(interp, + tag->tagRecord, tagTable->optionTable, optionName, tagTable->tkwin); +} + +/* Ttk_ConfigureTag -- implements [$w tag configure $tag -option value...] + */ +int Ttk_ConfigureTag( + Tcl_Interp *interp, + Ttk_TagTable tagTable, + Ttk_Tag tag, + int objc, Tcl_Obj *const objv[]) +{ + return Tk_SetOptions( + interp, tag->tagRecord, tagTable->optionTable, + objc, objv, tagTable->tkwin, NULL/*savedOptions*/, NULL/*mask*/); +} + +/*------------------------------------------------------------------------ + * +++ Tag values. + */ + +#define OBJ_AT(record, offset) (*(Tcl_Obj**)(((char*)record)+offset)) + +void Ttk_TagSetValues(Ttk_TagTable tagTable, Ttk_TagSet tagSet, void *record) +{ + const int LOWEST_PRIORITY = 0x7FFFFFFF; + int i, j; + + memset(record, 0, tagTable->recordSize); + + for (i = 0; tagTable->optionSpecs[i].type != TK_OPTION_END; ++i) { + Tk_OptionSpec *optionSpec = tagTable->optionSpecs + i; + int offset = optionSpec->objOffset; + int prio = LOWEST_PRIORITY; + + for (j = 0; j < tagSet->nTags; ++j) { + Ttk_Tag tag = tagSet->tags[j]; + if (OBJ_AT(tag->tagRecord, offset) != 0 && tag->priority < prio) { + OBJ_AT(record, offset) = OBJ_AT(tag->tagRecord, offset); + prio = tag->priority; + } + } + } +} + +void Ttk_TagSetApplyStyle( + Ttk_TagTable tagTable, Ttk_Style style, Ttk_State state, void *record) +{ + Tk_OptionSpec *optionSpec = tagTable->optionSpecs; + + while (optionSpec->type != TK_OPTION_END) { + int offset = optionSpec->objOffset; + const char *optionName = optionSpec->optionName; + Tcl_Obj *val = Ttk_StyleMap(style, optionName, state); + if (val) { + OBJ_AT(record, offset) = val; + } else if (OBJ_AT(record, offset) == 0) { + OBJ_AT(record, offset) = Ttk_StyleDefault(style, optionName); + } + ++optionSpec; + } } diff --git a/generic/ttk/ttkTheme.c b/generic/ttk/ttkTheme.c index 04dab19..c39d457 100644 --- a/generic/ttk/ttkTheme.c +++ b/generic/ttk/ttkTheme.c @@ -9,20 +9,16 @@ * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * $Id: ttkTheme.c,v 1.11.2.1 2009/03/25 09:10:04 dkf Exp $ + * $Id: ttkTheme.c,v 1.11.2.2 2010/08/26 02:06:09 hobbs Exp $ */ #include #include #include +#include #include "ttkThemeInt.h" -#ifdef NO_PRIVATE_HEADERS -EXTERN CONST Tk_OptionSpec *TkGetOptionSpec (CONST char *name, - Tk_OptionTable optionTable); -#else -#include -#endif +#define PKG_ASSOC_KEY "Ttk" /*------------------------------------------------------------------------ * +++ Styles. @@ -65,7 +61,7 @@ static void FreeStyle(Style *stylePtr) entryPtr = Tcl_FirstHashEntry(&stylePtr->settingsTable, &search); while (entryPtr != NULL) { - Ttk_StateMap stateMap = (Ttk_StateMap)Tcl_GetHashValue(entryPtr); + Ttk_StateMap stateMap = Tcl_GetHashValue(entryPtr); Tcl_DecrRefCount(stateMap); entryPtr = Tcl_NextHashEntry(&search); } @@ -73,7 +69,7 @@ static void FreeStyle(Style *stylePtr) entryPtr = Tcl_FirstHashEntry(&stylePtr->defaultsTable, &search); while (entryPtr != NULL) { - Tcl_Obj *defaultValue = (Ttk_StateMap)Tcl_GetHashValue(entryPtr); + Tcl_Obj *defaultValue = Tcl_GetHashValue(entryPtr); Tcl_DecrRefCount(defaultValue); entryPtr = Tcl_NextHashEntry(&search); } @@ -81,38 +77,39 @@ static void FreeStyle(Style *stylePtr) Ttk_FreeLayoutTemplate(stylePtr->layoutTemplate); - ckfree((char*)stylePtr); + ckfree((ClientData)stylePtr); } /* - * LookupStateMap -- - * Look up dynamic resource settings in the in the specified style. + * Ttk_StyleMap -- + * Look up state-specific option value from specified style. */ - -static Ttk_StateMap LookupStateMap(Ttk_Style stylePtr, const char *optionName) +Tcl_Obj *Ttk_StyleMap(Ttk_Style style, const char *optionName, Ttk_State state) { - while (stylePtr) { + while (style) { Tcl_HashEntry *entryPtr = - Tcl_FindHashEntry(&stylePtr->settingsTable, optionName); - if (entryPtr) - return (Ttk_StateMap)Tcl_GetHashValue(entryPtr); - stylePtr = stylePtr->parentStyle; + Tcl_FindHashEntry(&style->settingsTable, optionName); + if (entryPtr) { + Ttk_StateMap stateMap = Tcl_GetHashValue(entryPtr); + return Ttk_StateMapLookup(NULL, stateMap, state); + } + style = style->parentStyle; } return 0; } /* - * LookupDefault -- + * Ttk_StyleDefault -- * Look up default resource setting the in the specified style. */ -static Tcl_Obj *LookupDefault(Ttk_Style stylePtr, const char *optionName) +Tcl_Obj *Ttk_StyleDefault(Ttk_Style style, const char *optionName) { - while (stylePtr) { + while (style) { Tcl_HashEntry *entryPtr = - Tcl_FindHashEntry(&stylePtr->defaultsTable, optionName); + Tcl_FindHashEntry(&style->defaultsTable, optionName); if (entryPtr) - return (Tcl_Obj *)Tcl_GetHashValue(entryPtr); - stylePtr = stylePtr->parentStyle; + return Tcl_GetHashValue(entryPtr); + style= style->parentStyle; } return 0; } @@ -123,8 +120,7 @@ static Tcl_Obj *LookupDefault(Ttk_Style stylePtr, const char *optionName) typedef const Tk_OptionSpec **OptionMap; /* array of Tk_OptionSpecs mapping widget options to element options */ -typedef struct Ttk_ElementImpl_ /* Element implementation */ -{ +struct Ttk_ElementClass_ { const char *name; /* Points to hash table key */ Ttk_ElementSpec *specPtr; /* Template provided during registration. */ void *clientData; /* Client data passed in at registration time */ @@ -132,7 +128,7 @@ typedef struct Ttk_ElementImpl_ /* Element implementation */ int nResources; /* #Element options */ Tcl_Obj **defaultValues; /* Array of option default values */ Tcl_HashTable optMapCache; /* Map: Tk_OptionTable * -> OptionMap */ -} ElementImpl; +}; /* TTKGetOptionSpec -- * Look up a Tk_OptionSpec by name from a Tk_OptionTable, @@ -183,14 +179,14 @@ static const Tk_OptionSpec *TTKGetOptionSpec( * Construct the mapping from element options to widget options. */ static OptionMap -BuildOptionMap(ElementImpl *elementImpl, Tk_OptionTable optionTable) +BuildOptionMap(Ttk_ElementClass *elementClass, Tk_OptionTable optionTable) { OptionMap optionMap = (OptionMap)ckalloc( - sizeof(const Tk_OptionSpec) * elementImpl->nResources + 1); + sizeof(const Tk_OptionSpec) * elementClass->nResources + 1); int i; - for (i = 0; i < elementImpl->nResources; ++i) { - Ttk_ElementOptionSpec *e = elementImpl->specPtr->options+i; + for (i = 0; i < elementClass->nResources; ++i) { + Ttk_ElementOptionSpec *e = elementClass->specPtr->options+i; optionMap[i] = TTKGetOptionSpec(e->optionName, optionTable, e->type); } @@ -202,71 +198,72 @@ BuildOptionMap(ElementImpl *elementImpl, Tk_OptionTable optionTable) * for the specified element, creating it if necessary. */ static OptionMap -GetOptionMap(ElementImpl *elementImpl, Tk_OptionTable optionTable) +GetOptionMap(Ttk_ElementClass *elementClass, Tk_OptionTable optionTable) { OptionMap optionMap; int isNew; Tcl_HashEntry *entryPtr = Tcl_CreateHashEntry( - &elementImpl->optMapCache, (ClientData)optionTable, &isNew); + &elementClass->optMapCache, (void*)optionTable, &isNew); if (isNew) { - optionMap = BuildOptionMap(elementImpl, optionTable); + optionMap = BuildOptionMap(elementClass, optionTable); Tcl_SetHashValue(entryPtr, optionMap); } else { - optionMap = (OptionMap)(Tcl_GetHashValue(entryPtr)); + optionMap = Tcl_GetHashValue(entryPtr); } return optionMap; } /* - * NewElementImpl -- - * Allocate and initialize an element implementation record + * NewElementClass -- + * Allocate and initialize an element class record * from the specified element specification. */ -static ElementImpl * -NewElementImpl(const char *name, Ttk_ElementSpec *specPtr,void *clientData) +static Ttk_ElementClass * +NewElementClass(const char *name, Ttk_ElementSpec *specPtr,void *clientData) { - ElementImpl *elementImpl = (ElementImpl*)ckalloc(sizeof(ElementImpl)); + Ttk_ElementClass *elementClass = + (Ttk_ElementClass*)ckalloc(sizeof(Ttk_ElementClass)); int i; - elementImpl->name = name; - elementImpl->specPtr = specPtr; - elementImpl->clientData = clientData; - elementImpl->elementRecord = ckalloc(specPtr->elementSize); + elementClass->name = name; + elementClass->specPtr = specPtr; + elementClass->clientData = clientData; + elementClass->elementRecord = ckalloc(specPtr->elementSize); /* Count #element resources: */ for (i = 0; specPtr->options[i].optionName != 0; ++i) continue; - elementImpl->nResources = i; + elementClass->nResources = i; /* Initialize default values: */ - elementImpl->defaultValues = (Tcl_Obj**) - ckalloc(elementImpl->nResources * sizeof(Tcl_Obj *) + 1); - for (i=0; i < elementImpl->nResources; ++i) { + elementClass->defaultValues = (Tcl_Obj**) + ckalloc(elementClass->nResources * sizeof(Tcl_Obj *) + 1); + for (i=0; i < elementClass->nResources; ++i) { const char *defaultValue = specPtr->options[i].defaultValue; if (defaultValue) { - elementImpl->defaultValues[i] = Tcl_NewStringObj(defaultValue,-1); - Tcl_IncrRefCount(elementImpl->defaultValues[i]); + elementClass->defaultValues[i] = Tcl_NewStringObj(defaultValue,-1); + Tcl_IncrRefCount(elementClass->defaultValues[i]); } else { - elementImpl->defaultValues[i] = 0; + elementClass->defaultValues[i] = 0; } } /* Initialize option map cache: */ - Tcl_InitHashTable(&elementImpl->optMapCache, TCL_ONE_WORD_KEYS); + Tcl_InitHashTable(&elementClass->optMapCache, TCL_ONE_WORD_KEYS); - return elementImpl; + return elementClass; } /* - * FreeElementImpl -- - * Release resources associated with an element implementation record. + * FreeElementClass -- + * Release resources associated with an element class record. */ -static void FreeElementImpl(ElementImpl *elementImpl) +static void FreeElementClass(Ttk_ElementClass *elementClass) { Tcl_HashSearch search; Tcl_HashEntry *entryPtr; @@ -275,28 +272,27 @@ static void FreeElementImpl(ElementImpl *elementImpl) /* * Free default values: */ - for (i = 0; i < elementImpl->nResources; ++i) { - if (elementImpl->defaultValues[i]) { - Tcl_DecrRefCount(elementImpl->defaultValues[i]); + for (i = 0; i < elementClass->nResources; ++i) { + if (elementClass->defaultValues[i]) { + Tcl_DecrRefCount(elementClass->defaultValues[i]); } } - ckfree((ClientData)elementImpl->defaultValues); + ckfree((ClientData)elementClass->defaultValues); /* * Free option map cache: */ - entryPtr = Tcl_FirstHashEntry(&elementImpl->optMapCache, &search); + entryPtr = Tcl_FirstHashEntry(&elementClass->optMapCache, &search); while (entryPtr != NULL) { ckfree(Tcl_GetHashValue(entryPtr)); entryPtr = Tcl_NextHashEntry(&search); } - Tcl_DeleteHashTable(&elementImpl->optMapCache); + Tcl_DeleteHashTable(&elementClass->optMapCache); - ckfree(elementImpl->elementRecord); - ckfree((ClientData)elementImpl); + ckfree(elementClass->elementRecord); + ckfree((ClientData)elementClass); } - /*------------------------------------------------------------------------ * +++ Themes. */ @@ -307,7 +303,7 @@ static int ThemeEnabled(Ttk_Theme theme, void *clientData) { return 1; } typedef struct Ttk_Theme_ { Ttk_Theme parentPtr; /* Parent theme. */ - Tcl_HashTable elementTable; /* Map element names to ElementImpls */ + Tcl_HashTable elementTable; /* Map element names to class records */ Tcl_HashTable styleTable; /* Map style names to Styles */ Ttk_Style rootStyle; /* "." style, root of chain */ Ttk_ThemeEnabledProc *enabledProc; /* Function called by SetTheme */ @@ -333,10 +329,10 @@ static Theme *NewTheme(Ttk_ResourceCache cache, Ttk_Theme parent) */ entryPtr = Tcl_CreateHashEntry(&themePtr->styleTable, ".", &unused); themePtr->rootStyle = NewStyle(); - themePtr->rootStyle->styleName = + themePtr->rootStyle->styleName = Tcl_GetHashKey(&themePtr->styleTable, entryPtr); themePtr->rootStyle->cache = themePtr->cache; - Tcl_SetHashValue(entryPtr, (ClientData)themePtr->rootStyle); + Tcl_SetHashValue(entryPtr, themePtr->rootStyle); return themePtr; } @@ -347,12 +343,12 @@ static void FreeTheme(Theme *themePtr) Tcl_HashEntry *entryPtr; /* - * Free associated ElementImpl's + * Free element table: */ entryPtr = Tcl_FirstHashEntry(&themePtr->elementTable, &search); while (entryPtr != NULL) { - ElementImpl *elementImpl = (ElementImpl *)Tcl_GetHashValue(entryPtr); - FreeElementImpl(elementImpl); + Ttk_ElementClass *elementClass = Tcl_GetHashValue(entryPtr); + FreeElementClass(elementClass); entryPtr = Tcl_NextHashEntry(&search); } Tcl_DeleteHashTable(&themePtr->elementTable); @@ -362,7 +358,7 @@ static void FreeTheme(Theme *themePtr) */ entryPtr = Tcl_FirstHashEntry(&themePtr->styleTable, &search); while (entryPtr != NULL) { - Style *stylePtr = (Style*)Tcl_GetHashValue(entryPtr); + Style *stylePtr = Tcl_GetHashValue(entryPtr); FreeStyle(stylePtr); entryPtr = Tcl_NextHashEntry(&search); } @@ -371,7 +367,7 @@ static void FreeTheme(Theme *themePtr) /* * Free theme record: */ - ckfree((char *)themePtr); + ckfree((ClientData)themePtr); return; } @@ -415,10 +411,9 @@ static void ThemeChangedProc(ClientData); /* Forward */ */ static void Ttk_StylePkgFree(ClientData clientData, Tcl_Interp *interp) { - StylePackageData *pkgPtr = (StylePackageData *)clientData; + StylePackageData *pkgPtr = clientData; Tcl_HashSearch search; Tcl_HashEntry *entryPtr; - Theme *themePtr; Cleanup *cleanup; /* @@ -433,7 +428,7 @@ static void Ttk_StylePkgFree(ClientData clientData, Tcl_Interp *interp) */ entryPtr = Tcl_FirstHashEntry(&pkgPtr->themeTable, &search); while (entryPtr != NULL) { - themePtr = (Theme *) Tcl_GetHashValue(entryPtr); + Theme *themePtr = Tcl_GetHashValue(entryPtr); FreeTheme(themePtr); entryPtr = Tcl_NextHashEntry(&search); } @@ -465,7 +460,7 @@ static void Ttk_StylePkgFree(ClientData clientData, Tcl_Interp *interp) cleanup = next; } - ckfree((char*)pkgPtr); + ckfree((ClientData)pkgPtr); } /* @@ -475,7 +470,7 @@ static void Ttk_StylePkgFree(ClientData clientData, Tcl_Interp *interp) static StylePackageData *GetStylePackageData(Tcl_Interp *interp) { - return (StylePackageData*)Tcl_GetAssocData(interp, "StylePackage", NULL); + return Tcl_GetAssocData(interp, PKG_ASSOC_KEY, NULL); } /* @@ -499,7 +494,7 @@ void Ttk_RegisterCleanup( pkgPtr->cleanupList = cleanup; } -/* ThemeChangedProc -- +/* ThemeChangedProc -- * Notify all widgets that the theme has been changed. * Scheduled as an idle callback; clientData is a StylePackageData *. * @@ -508,13 +503,13 @@ void Ttk_RegisterCleanup( * which in turn recreates the layout. * * The Tk C API doesn't doesn't provide an easy way to traverse - * the widget hierarchy, so this is done by evaluating a Tcl script. + * the widget hierarchy, so this is done by evaluating a Tcl script. */ static void ThemeChangedProc(ClientData clientData) { static char ThemeChangedScript[] = "ttk::ThemeChanged"; - StylePackageData *pkgPtr = (StylePackageData *)clientData; + StylePackageData *pkgPtr = clientData; if (Tcl_GlobalEval(pkgPtr->interp, ThemeChangedScript) != TCL_OK) { Tcl_BackgroundError(pkgPtr->interp); @@ -567,12 +562,11 @@ Ttk_CreateTheme( if (!parent) parent = pkgPtr->defaultTheme; themePtr = NewTheme(pkgPtr->cache, parent); - Tcl_SetHashValue(entryPtr, (ClientData) themePtr); + Tcl_SetHashValue(entryPtr, themePtr); return themePtr; } - /* * Ttk_SetThemeEnabledProc -- * Sets a procedure that is used to check that this theme is available. @@ -587,7 +581,7 @@ void Ttk_SetThemeEnabledProc( /* * LookupTheme -- - * Retrieve a registered theme by name. If not found, + * Retrieve a registered theme by name. If not found, * returns NULL and leaves an error message in interp's result. */ @@ -605,7 +599,7 @@ static Ttk_Theme LookupTheme( return NULL; } - return (Ttk_Theme)Tcl_GetHashValue(entryPtr); + return Tcl_GetHashValue(entryPtr); } /* @@ -715,10 +709,10 @@ Ttk_Style Ttk_GetStyle(Ttk_Theme themePtr, const char *styleName) stylePtr->styleName = Tcl_GetHashKey(&themePtr->styleTable, entryPtr); stylePtr->cache = stylePtr->parentStyle->cache; - Tcl_SetHashValue(entryPtr, (ClientData)stylePtr); + Tcl_SetHashValue(entryPtr, stylePtr); return stylePtr; } - return (Style*)Tcl_GetHashValue(entryPtr); + return Tcl_GetHashValue(entryPtr); } /* FindLayoutTemplate -- @@ -749,12 +743,12 @@ const char *Ttk_StyleName(Ttk_Style stylePtr) /* * Ttk_GetElement -- - * Look up an element implementation by name in a given theme. + * Look up an element class by name in a given theme. * If not found, try generic element names in this theme, then * repeat the lookups in the parent theme. * If not found, return the null element. */ -Ttk_ElementImpl Ttk_GetElement(Ttk_Theme themePtr, const char *elementName) +Ttk_ElementClass *Ttk_GetElement(Ttk_Theme themePtr, const char *elementName) { Tcl_HashEntry *entryPtr; const char *dot = elementName; @@ -764,7 +758,7 @@ Ttk_ElementImpl Ttk_GetElement(Ttk_Theme themePtr, const char *elementName) */ entryPtr = Tcl_FindHashEntry(&themePtr->elementTable, elementName); if (entryPtr) { - return (Ttk_ElementImpl)Tcl_GetHashValue(entryPtr); + return Tcl_GetHashValue(entryPtr); } /* @@ -775,7 +769,7 @@ Ttk_ElementImpl Ttk_GetElement(Ttk_Theme themePtr, const char *elementName) entryPtr = Tcl_FindHashEntry(&themePtr->elementTable, dot); } if (entryPtr) { - return (ElementImpl *)Tcl_GetHashValue(entryPtr); + return Tcl_GetHashValue(entryPtr); } /* @@ -791,12 +785,12 @@ Ttk_ElementImpl Ttk_GetElement(Ttk_Theme themePtr, const char *elementName) */ entryPtr = Tcl_FindHashEntry(&themePtr->elementTable, ""); /* ASSERT: entryPtr != 0 */ - return (Ttk_ElementImpl)Tcl_GetHashValue(entryPtr); + return Tcl_GetHashValue(entryPtr); } -const char *Ttk_ElementName(ElementImpl *elementImpl) +const char *Ttk_ElementClassName(Ttk_ElementClass *elementClass) { - return elementImpl->name; + return elementClass->name; } /* @@ -825,17 +819,16 @@ int Ttk_RegisterElementFactory( return TCL_OK; } - /* Ttk_CloneElement -- element factory procedure. * (style element create $name) "from" $theme ?$element? */ static int Ttk_CloneElement( Tcl_Interp *interp, void *clientData, Ttk_Theme theme, const char *elementName, - int objc, Tcl_Obj *CONST objv[]) + int objc, Tcl_Obj *const objv[]) { Ttk_Theme fromTheme; - ElementImpl *fromElement; + Ttk_ElementClass *fromElement; if (objc <= 0 || objc > 2) { Tcl_WrongNumArgs(interp, 0, objv, "theme ?element?"); @@ -867,18 +860,18 @@ static int Ttk_CloneElement( /* Ttk_RegisterElement-- * Register an element in the given theme. * Returns: Element handle if successful, NULL otherwise. - * On failure, leaves an error message in interp's result + * On failure, leaves an error message in interp's result * if interp is non-NULL. */ -Ttk_ElementImpl Ttk_RegisterElement( +Ttk_ElementClass *Ttk_RegisterElement( Tcl_Interp *interp, /* Where to leave error messages */ Ttk_Theme theme, /* Style engine providing the implementation. */ const char *name, /* Name of new element */ Ttk_ElementSpec *specPtr, /* Static template information */ void *clientData) /* application-specific data */ { - ElementImpl *elementImpl; + Ttk_ElementClass *elementClass; Tcl_HashEntry *entryPtr; int newEntry; @@ -903,10 +896,10 @@ Ttk_ElementImpl Ttk_RegisterElement( } name = Tcl_GetHashKey(&theme->elementTable, entryPtr); - elementImpl = NewElementImpl(name, specPtr, clientData); - Tcl_SetHashValue(entryPtr, elementImpl); + elementClass = NewElementClass(name, specPtr, clientData); + Tcl_SetHashValue(entryPtr, elementClass); - return elementImpl; + return elementClass; } /* Ttk_RegisterElementSpec (deprecated) -- @@ -915,7 +908,7 @@ Ttk_ElementImpl Ttk_RegisterElement( int Ttk_RegisterElementSpec(Ttk_Theme theme, const char *name, Ttk_ElementSpec *specPtr, void *clientData) { - return Ttk_RegisterElement(NULL, theme, name, specPtr, clientData) + return Ttk_RegisterElement(NULL, theme, name, specPtr, clientData) ? TCL_OK : TCL_ERROR; } @@ -975,32 +968,27 @@ static int AllocateResource( static int InitializeElementRecord( - ElementImpl *element, /* Element instance to initialize */ + Ttk_ElementClass *eclass, /* Element instance to initialize */ Ttk_Style style, /* Style table */ char *widgetRecord, /* Source of widget option values */ Tk_OptionTable optionTable, /* Option table describing widget record */ Tk_Window tkwin, /* Corresponding window */ Ttk_State state) /* Widget or element state */ { - char *elementRecord = element->elementRecord; - OptionMap optionMap = GetOptionMap(element,optionTable); - int nResources = element->nResources; + char *elementRecord = eclass->elementRecord; + OptionMap optionMap = GetOptionMap(eclass,optionTable); + int nResources = eclass->nResources; Ttk_ResourceCache cache = style->cache; - Ttk_ElementOptionSpec *elementOption = element->specPtr->options; + Ttk_ElementOptionSpec *elementOption = eclass->specPtr->options; int i; for (i=0; ioffset); const char *optionName = elementOption->optionName; - Tcl_Obj *stateMap = LookupStateMap(style, optionName); - Tcl_Obj *dynamicSetting = 0; + Tcl_Obj *dynamicSetting = Ttk_StyleMap(style, optionName, state); Tcl_Obj *widgetValue = 0; - Tcl_Obj *elementDefault = element->defaultValues[i]; - - if (stateMap) { - dynamicSetting = Ttk_StateMapLookup(NULL, stateMap, state); - } + Tcl_Obj *elementDefault = eclass->defaultValues[i]; if (optionMap[i]) { widgetValue = *(Tcl_Obj **) @@ -1012,7 +1000,7 @@ int InitializeElementRecord( } else if (dynamicSetting) { *dest = dynamicSetting; } else { - Tcl_Obj *styleDefault = LookupDefault(style, optionName); + Tcl_Obj *styleDefault = Ttk_StyleDefault(style, optionName); *dest = styleDefault ? styleDefault : elementDefault; } @@ -1039,7 +1027,6 @@ Tcl_Obj *Ttk_QueryStyle( const char *optionName, /* Option name */ Ttk_State state) /* Current state */ { - Tcl_Obj *stateMap; const Tk_OptionSpec *optionSpec; Tcl_Obj *result; @@ -1057,18 +1044,15 @@ Tcl_Obj *Ttk_QueryStyle( /* * Check dynamic settings: */ - stateMap = LookupStateMap(style, optionName); - if (stateMap) { - result = Ttk_StateMapLookup(NULL, stateMap, state); - if (result) { - return result; - } + result = Ttk_StyleMap(style, optionName, state); + if (result) { + return result; } /* * Use style default: */ - return LookupDefault(style, optionName); + return Ttk_StyleDefault(style, optionName); } /* @@ -1078,7 +1062,7 @@ Tcl_Obj *Ttk_QueryStyle( void Ttk_ElementSize( - ElementImpl *element, /* Element to query */ + Ttk_ElementClass *eclass, /* Element to query */ Ttk_Style style, /* Style settings */ char *recordPtr, /* The widget record. */ Tk_OptionTable optionTable, /* Description of widget record */ @@ -1091,10 +1075,13 @@ Ttk_ElementSize( paddingPtr->left = paddingPtr->right = paddingPtr->top = paddingPtr->bottom = *widthPtr = *heightPtr = 0; - if (!InitializeElementRecord(element, style, recordPtr, optionTable, tkwin, state)) + if (!InitializeElementRecord( + eclass, style, recordPtr, optionTable, tkwin, state)) + { return; - element->specPtr->size( - element->clientData, element->elementRecord, + } + eclass->specPtr->size( + eclass->clientData, eclass->elementRecord, tkwin, widthPtr, heightPtr, paddingPtr); } @@ -1105,7 +1092,7 @@ Ttk_ElementSize( void Ttk_DrawElement( - ElementImpl *element, /* Element instance */ + Ttk_ElementClass *eclass, /* Element instance */ Ttk_Style style, /* Style settings */ char *recordPtr, /* The widget record. */ Tk_OptionTable optionTable, /* Description of option table */ @@ -1116,10 +1103,13 @@ Ttk_DrawElement( { if (b.width <= 0 || b.height <= 0) return; - if (!InitializeElementRecord(element, style, recordPtr, optionTable, tkwin, state)) + if (!InitializeElementRecord( + eclass, style, recordPtr, optionTable, tkwin, state)) + { return; - element->specPtr->draw( - element->clientData, element->elementRecord, + } + eclass->specPtr->draw( + eclass->clientData, eclass->elementRecord, tkwin, d, b, state); } @@ -1128,7 +1118,7 @@ Ttk_DrawElement( */ /* - * EnumerateHashTable -- + * TtkEnumerateHashTable -- * Helper routine. Sets interp's result to the list of all keys * in the hash table. * @@ -1136,7 +1126,8 @@ Ttk_DrawElement( * Side effects: Sets interp's result. */ -static int EnumerateHashTable(Tcl_Interp *interp, Tcl_HashTable *ht) +MODULE_SCOPE +int TtkEnumerateHashTable(Tcl_Interp *interp, Tcl_HashTable *ht) { Tcl_HashSearch search; Tcl_Obj *result = Tcl_NewListObj(0, NULL); @@ -1153,7 +1144,7 @@ static int EnumerateHashTable(Tcl_Interp *interp, Tcl_HashTable *ht) } /* HashTableToDict -- - * Helper routine. Converts a TCL_STRING_KEYS Tcl_HashTable + * Helper routine. Converts a TCL_STRING_KEYS Tcl_HashTable * with Tcl_Obj * entries into a dictionary. */ static Tcl_Obj* HashTableToDict(Tcl_HashTable *ht) @@ -1164,7 +1155,7 @@ static Tcl_Obj* HashTableToDict(Tcl_HashTable *ht) while (entryPtr != NULL) { Tcl_Obj *nameObj = Tcl_NewStringObj(Tcl_GetHashKey(ht, entryPtr),-1); - Tcl_Obj *valueObj = (Tcl_Obj*)Tcl_GetHashValue(entryPtr); + Tcl_Obj *valueObj = Tcl_GetHashValue(entryPtr); Tcl_ListObjAppendElement(NULL, result, nameObj); Tcl_ListObjAppendElement(NULL, result, valueObj); entryPtr = Tcl_NextHashEntry(&search); @@ -1183,9 +1174,9 @@ StyleMapCmd( ClientData clientData, /* Master StylePackageData pointer */ Tcl_Interp *interp, /* Current interpreter */ int objc, /* Number of arguments */ - Tcl_Obj * CONST objv[]) /* Argument objects */ + Tcl_Obj *const objv[]) /* Argument objects */ { - StylePackageData *pkgPtr = (StylePackageData *)clientData; + StylePackageData *pkgPtr = clientData; Ttk_Theme theme = pkgPtr->currentTheme; const char *styleName; Style *stylePtr; @@ -1208,7 +1199,7 @@ usage: return TCL_OK; } else if (objc == 4) { /* style map $styleName -option */ const char *optionName = Tcl_GetString(objv[3]); - Tcl_HashEntry *entryPtr = + Tcl_HashEntry *entryPtr = Tcl_FindHashEntry(&stylePtr->settingsTable, optionName); if (entryPtr) { Tcl_SetObjResult(interp, (Tcl_Obj*)Tcl_GetHashValue(entryPtr)); @@ -1247,9 +1238,9 @@ usage: /* + style configure $style -option ?value... */ static int StyleConfigureCmd( - ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj * CONST objv[]) + ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]) { - StylePackageData *pkgPtr = (StylePackageData *)clientData; + StylePackageData *pkgPtr = clientData; Ttk_Theme theme = pkgPtr->currentTheme; const char *styleName; Style *stylePtr; @@ -1269,7 +1260,7 @@ usage: return TCL_OK; } else if (objc == 4) { /* style default $styleName -option */ const char *optionName = Tcl_GetString(objv[3]); - Tcl_HashEntry *entryPtr = + Tcl_HashEntry *entryPtr = Tcl_FindHashEntry(&stylePtr->defaultsTable, optionName); if (entryPtr) { Tcl_SetObjResult(interp, (Tcl_Obj*)Tcl_GetHashValue(entryPtr)); @@ -1302,7 +1293,7 @@ usage: /* + style lookup $style -option ?statespec? ?defaultValue? */ static int StyleLookupCmd( - ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj * CONST objv[]) + ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]) { StylePackageData *pkgPtr = clientData; Ttk_Theme theme = pkgPtr->currentTheme; @@ -1343,12 +1334,45 @@ static int StyleLookupCmd( return TCL_OK; } +static int StyleThemeCurrentCmd( + ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj * const objv[]) +{ + StylePackageData *pkgPtr = clientData; + Tcl_HashSearch search; + Tcl_HashEntry *entryPtr = NULL; + const char *name = NULL; + + if (objc != 3) { + Tcl_WrongNumArgs(interp, 3, objv, ""); + return TCL_ERROR; + } + + entryPtr = Tcl_FirstHashEntry(&pkgPtr->themeTable, &search); + while (entryPtr != NULL) { + Theme *ptr = Tcl_GetHashValue(entryPtr); + if (ptr == pkgPtr->currentTheme) { + name = Tcl_GetHashKey(&pkgPtr->themeTable, entryPtr); + break; + } + entryPtr = Tcl_NextHashEntry(&search); + } + + if (name == NULL) { + Tcl_SetObjResult(interp, + Tcl_NewStringObj("error: failed to get theme name", -1)); + return TCL_ERROR; + } + + Tcl_SetObjResult(interp, Tcl_NewStringObj(name, -1)); + return TCL_OK; +} + /* + style theme create name ?-parent $theme? ?-settings { script }? */ static int StyleThemeCreateCmd( - ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj * CONST objv[]) + ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]) { - StylePackageData *pkgPtr = (StylePackageData *)clientData; + StylePackageData *pkgPtr = clientData; static const char *optStrings[] = { "-parent", "-settings", NULL }; enum { OP_PARENT, OP_SETTINGS }; @@ -1358,7 +1382,7 @@ static int StyleThemeCreateCmd( int i; if (objc < 4 || objc % 2 != 0) { - Tcl_WrongNumArgs(interp, 3, objv, "name ?options?"); + Tcl_WrongNumArgs(interp, 3, objv, "name ?-option value ...?"); return TCL_ERROR; } @@ -1410,10 +1434,10 @@ static int StyleThemeCreateCmd( * Return list of registered themes. */ static int StyleThemeNamesCmd( - ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj * CONST objv[]) + ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]) { StylePackageData *pkgPtr = clientData; - return EnumerateHashTable(interp, &pkgPtr->themeTable); + return TtkEnumerateHashTable(interp, &pkgPtr->themeTable); } /* + style theme settings $theme $script @@ -1426,9 +1450,9 @@ StyleThemeSettingsCmd( ClientData clientData, /* Master StylePackageData pointer */ Tcl_Interp *interp, /* Current interpreter */ int objc, /* Number of arguments */ - Tcl_Obj * CONST objv[]) /* Argument objects */ + Tcl_Obj *const objv[]) /* Argument objects */ { - StylePackageData *pkgPtr = (StylePackageData *)clientData; + StylePackageData *pkgPtr = clientData; Ttk_Theme oldTheme = pkgPtr->currentTheme; Ttk_Theme newTheme; int status; @@ -1452,16 +1476,16 @@ StyleThemeSettingsCmd( /* + style element create name type ? ...args ? */ static int StyleElementCreateCmd( - ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj * CONST objv[]) + ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]) { - StylePackageData *pkgPtr = (StylePackageData *)clientData; + StylePackageData *pkgPtr = clientData; Ttk_Theme theme = pkgPtr->currentTheme; const char *elementName, *factoryName; Tcl_HashEntry *entryPtr; FactoryRec *recPtr; if (objc < 5) { - Tcl_WrongNumArgs(interp, 3, objv, "name type ?options...?"); + Tcl_WrongNumArgs(interp, 3, objv, "name type ?-option value ...?"); return TCL_ERROR; } @@ -1474,7 +1498,7 @@ static int StyleElementCreateCmd( return TCL_ERROR; } - recPtr = (FactoryRec *)Tcl_GetHashValue(entryPtr); + recPtr = Tcl_GetHashValue(entryPtr); return recPtr->factory(interp, recPtr->clientData, theme, elementName, objc - 5, objv + 5); @@ -1484,28 +1508,28 @@ static int StyleElementCreateCmd( * Return a list of elements defined in the current theme. */ static int StyleElementNamesCmd( - ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj * CONST objv[]) + ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]) { - StylePackageData *pkgPtr = (StylePackageData *)clientData; + StylePackageData *pkgPtr = clientData; Ttk_Theme theme = pkgPtr->currentTheme; if (objc != 3) { Tcl_WrongNumArgs(interp, 3, objv, NULL); return TCL_ERROR; } - return EnumerateHashTable(interp, &theme->elementTable); + return TtkEnumerateHashTable(interp, &theme->elementTable); } /* + style element options $element -- * Return list of element options for specified element */ static int StyleElementOptionsCmd( - ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj * CONST objv[]) + ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]) { StylePackageData *pkgPtr = clientData; Ttk_Theme theme = pkgPtr->currentTheme; const char *elementName; - ElementImpl *elementImpl; + Ttk_ElementClass *elementClass; if (objc != 4) { Tcl_WrongNumArgs(interp, 3, objv, "element"); @@ -1513,9 +1537,9 @@ static int StyleElementOptionsCmd( } elementName = Tcl_GetString(objv[3]); - elementImpl = Ttk_GetElement(theme, elementName); - if (elementImpl) { - Ttk_ElementSpec *specPtr = elementImpl->specPtr; + elementClass = Ttk_GetElement(theme, elementName); + if (elementClass) { + Ttk_ElementSpec *specPtr = elementClass->specPtr; Ttk_ElementOptionSpec *option = specPtr->options; Tcl_Obj *result = Tcl_NewListObj(0,0); @@ -1536,9 +1560,9 @@ static int StyleElementOptionsCmd( /* + style layout name ?spec? */ static int StyleLayoutCmd( - ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj * CONST objv[]) + ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]) { - StylePackageData *pkgPtr = (StylePackageData *)clientData; + StylePackageData *pkgPtr = clientData; Ttk_Theme theme = pkgPtr->currentTheme; const char *layoutName; Ttk_LayoutTemplate layoutTemplate; @@ -1576,16 +1600,20 @@ StyleThemeUseCmd( ClientData clientData, /* Master StylePackageData pointer */ Tcl_Interp *interp, /* Current interpreter */ int objc, /* Number of arguments */ - Tcl_Obj * CONST objv[]) /* Argument objects */ + Tcl_Obj *const objv[]) /* Argument objects */ { StylePackageData *pkgPtr = clientData; Ttk_Theme theme; - if (objc != 4) { - Tcl_WrongNumArgs(interp, 3, objv, "theme"); + if (objc < 3 || objc > 4) { + Tcl_WrongNumArgs(interp, 3, objv, "?theme?"); return TCL_ERROR; } + if (objc == 3) { + return StyleThemeCurrentCmd(clientData, interp, objc, objv); + } + theme = LookupTheme(interp, pkgPtr, Tcl_GetString(objv[3])); if (!theme) { return TCL_ERROR; @@ -1599,13 +1627,7 @@ StyleThemeUseCmd( * Implementation of the [style] command. */ -struct Ensemble { - const char *name; /* subcommand name */ - Tcl_ObjCmdProc *command; /* subcommand implementation, OR: */ - struct Ensemble *ensemble; /* subcommand ensemble */ -}; - -static struct Ensemble StyleThemeEnsemble[] = { +static const Ttk_Ensemble StyleThemeEnsemble[] = { { "create", StyleThemeCreateCmd, 0 }, { "names", StyleThemeNamesCmd, 0 }, { "settings", StyleThemeSettingsCmd, 0 }, @@ -1613,14 +1635,14 @@ static struct Ensemble StyleThemeEnsemble[] = { { NULL, 0, 0 } }; -static struct Ensemble StyleElementEnsemble[] = { +static const Ttk_Ensemble StyleElementEnsemble[] = { { "create", StyleElementCreateCmd, 0 }, { "names", StyleElementNamesCmd, 0 }, { "options", StyleElementOptionsCmd, 0 }, { NULL, 0, 0 } }; -static struct Ensemble StyleEnsemble[] = { +static const Ttk_Ensemble StyleEnsemble[] = { { "configure", StyleConfigureCmd, 0 }, { "map", StyleMapCmd, 0 }, { "lookup", StyleLookupCmd, 0 }, @@ -1635,15 +1657,20 @@ StyleObjCmd( ClientData clientData, /* Master StylePackageData pointer */ Tcl_Interp *interp, /* Current interpreter */ int objc, /* Number of arguments */ - Tcl_Obj * CONST objv[]) /* Argument objects */ + Tcl_Obj *const objv[]) /* Argument objects */ { - struct Ensemble *ensemble = StyleEnsemble; - int optPtr = 1; - int index; + return Ttk_InvokeEnsemble(StyleEnsemble, 1, clientData,interp,objc,objv); +} - while (optPtr < objc) { +MODULE_SCOPE +int Ttk_InvokeEnsemble( /* Run an ensemble command */ + const Ttk_Ensemble *ensemble, int cmdIndex, + void *clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]) +{ + while (cmdIndex < objc) { + int index; if (Tcl_GetIndexFromObjStruct(interp, - objv[optPtr], ensemble, sizeof(ensemble[0]), + objv[cmdIndex], ensemble, sizeof(ensemble[0]), "command", 0, &index) != TCL_OK) { @@ -1654,9 +1681,9 @@ StyleObjCmd( return ensemble[index].command(clientData, interp, objc, objv); } ensemble = ensemble[index].ensemble; - ++optPtr; + ++cmdIndex; } - Tcl_WrongNumArgs(interp, optPtr, objv, "option ?arg arg...?"); + Tcl_WrongNumArgs(interp, cmdIndex, objv, "option ?arg ...?"); return TCL_ERROR; } @@ -1680,8 +1707,7 @@ void Ttk_StylePkgInit(Tcl_Interp *interp) pkgPtr->cache = Ttk_CreateResourceCache(interp); pkgPtr->themeChangePending = 0; - Tcl_SetAssocData(interp, "StylePackage", Ttk_StylePkgFree, - (ClientData)pkgPtr); + Tcl_SetAssocData(interp, PKG_ASSOC_KEY, Ttk_StylePkgFree, pkgPtr); /* * Create the default system theme: @@ -1702,11 +1728,9 @@ void Ttk_StylePkgInit(Tcl_Interp *interp) /* * Register commands: */ - Tcl_CreateObjCommand(interp, "::ttk::style", StyleObjCmd, - (ClientData)pkgPtr, 0); + Tcl_CreateObjCommand(interp, "::ttk::style", StyleObjCmd, pkgPtr, 0); - nsPtr = Tcl_FindNamespace(interp, "::ttk", (Tcl_Namespace *) NULL, - TCL_LEAVE_ERR_MSG); + nsPtr = Tcl_FindNamespace(interp, "::ttk", NULL, TCL_LEAVE_ERR_MSG); Tcl_Export(interp, nsPtr, "style", 0 /* dontResetList */); Ttk_RegisterElementFactory(interp, "from", Ttk_CloneElement, 0); diff --git a/generic/ttk/ttkTheme.h b/generic/ttk/ttkTheme.h index 6d95c01..6b454b5 100644 --- a/generic/ttk/ttkTheme.h +++ b/generic/ttk/ttkTheme.h @@ -1,4 +1,4 @@ -/* $Id: ttkTheme.h,v 1.13.2.1 2009/05/14 00:53:04 patthoyts Exp $ +/* $Id: ttkTheme.h,v 1.13.2.2 2010/08/26 02:06:10 hobbs Exp $ * Copyright (c) 2003 Joe English. Freely redistributable. * * Declarations for Tk theme engine. @@ -202,9 +202,10 @@ TTKAPI Ttk_Box Ttk_PositionBox(Ttk_Box *cavity, int w, int h, Ttk_PositionSpec); MODULE_SCOPE void Ttk_StylePkgInit(Tcl_Interp *); typedef struct Ttk_Theme_ *Ttk_Theme; -typedef struct Ttk_ElementImpl_ *Ttk_ElementImpl; +typedef struct Ttk_ElementClass_ Ttk_ElementClass; typedef struct Ttk_Layout_ *Ttk_Layout; -typedef struct Ttk_LayoutNode_ Ttk_LayoutNode; +typedef struct Ttk_LayoutNode_ *Ttk_Element; +typedef struct Ttk_Style_ *Ttk_Style; TTKAPI Ttk_Theme Ttk_GetTheme(Tcl_Interp *interp, const char *name); TTKAPI Ttk_Theme Ttk_GetDefaultTheme(Tcl_Interp *interp); @@ -235,10 +236,10 @@ typedef void (Ttk_ElementDrawProc)(void *clientData, void *elementRecord, typedef struct Ttk_ElementOptionSpec { - char *optionName; /* Command-line name of the widget option */ + const char *optionName; /* Command-line name of the widget option */ Tk_OptionType type; /* Accepted option types */ int offset; /* Offset of Tcl_Obj* field in element record */ - char *defaultValue; /* Default value to used if resource missing */ + const char *defaultValue; /* Default value to used if resource missing */ } Ttk_ElementOptionSpec; #define TK_OPTION_ANY TK_OPTION_STRING @@ -251,7 +252,7 @@ typedef struct Ttk_ElementSpec { Ttk_ElementDrawProc *draw; /* Draw the element */ } Ttk_ElementSpec; -TTKAPI Ttk_ElementImpl Ttk_RegisterElement( +TTKAPI Ttk_ElementClass *Ttk_RegisterElement( Tcl_Interp *interp, Ttk_Theme theme, const char *elementName, Ttk_ElementSpec *, void *clientData); @@ -327,20 +328,27 @@ MODULE_SCOPE void Ttk_DrawLayout(Ttk_Layout, Ttk_State, Drawable); MODULE_SCOPE void Ttk_RebindSublayout(Ttk_Layout, void *recordPtr); -MODULE_SCOPE Ttk_LayoutNode *Ttk_LayoutIdentify(Ttk_Layout, int x, int y); -MODULE_SCOPE Ttk_LayoutNode *Ttk_LayoutFindNode(Ttk_Layout, const char *nodeName); +MODULE_SCOPE Ttk_Element Ttk_IdentifyElement(Ttk_Layout, int x, int y); +MODULE_SCOPE Ttk_Element Ttk_FindElement(Ttk_Layout, const char *nodeName); -MODULE_SCOPE const char *Ttk_LayoutNodeName(Ttk_LayoutNode *); -MODULE_SCOPE Ttk_Box Ttk_LayoutNodeParcel(Ttk_LayoutNode *); -MODULE_SCOPE Ttk_Box Ttk_LayoutNodeInternalParcel(Ttk_Layout,Ttk_LayoutNode *); -MODULE_SCOPE Ttk_Padding Ttk_LayoutNodeInternalPadding(Ttk_Layout,Ttk_LayoutNode *); -MODULE_SCOPE void Ttk_LayoutNodeReqSize(Ttk_Layout, Ttk_LayoutNode *, int *w, int *h); +MODULE_SCOPE const char *Ttk_ElementName(Ttk_Element); +MODULE_SCOPE Ttk_Box Ttk_ElementParcel(Ttk_Element); -MODULE_SCOPE void Ttk_PlaceLayoutNode(Ttk_Layout,Ttk_LayoutNode *, Ttk_Box); -MODULE_SCOPE void Ttk_ChangeElementState(Ttk_LayoutNode *,unsigned set,unsigned clr); +MODULE_SCOPE Ttk_Box Ttk_ClientRegion(Ttk_Layout, const char *elementName); + +MODULE_SCOPE Ttk_Box Ttk_LayoutNodeInternalParcel(Ttk_Layout,Ttk_Element); +MODULE_SCOPE Ttk_Padding Ttk_LayoutNodeInternalPadding(Ttk_Layout,Ttk_Element); +MODULE_SCOPE void Ttk_LayoutNodeReqSize(Ttk_Layout, Ttk_Element, int *w, int *h); + +MODULE_SCOPE void Ttk_PlaceElement(Ttk_Layout, Ttk_Element, Ttk_Box); +MODULE_SCOPE void Ttk_ChangeElementState(Ttk_Element,unsigned set,unsigned clr); MODULE_SCOPE Tcl_Obj *Ttk_QueryOption(Ttk_Layout, const char *, Ttk_State); +TTKAPI Ttk_Style Ttk_LayoutStyle(Ttk_Layout); +TTKAPI Tcl_Obj *Ttk_StyleDefault(Ttk_Style, const char *optionName); +TTKAPI Tcl_Obj *Ttk_StyleMap(Ttk_Style, const char *optionName, Ttk_State); + /*------------------------------------------------------------------------ * +++ Resource cache. * See resource.c for explanation. @@ -400,7 +408,23 @@ typedef enum { /* -orient option values */ } Ttk_Orient; /*------------------------------------------------------------------------ - * +++ Stub table declarations: + * +++ Utilities. + */ + +typedef struct TtkEnsemble { + const char *name; /* subcommand name */ + Tcl_ObjCmdProc *command; /* subcommand implementation, OR: */ + const struct TtkEnsemble *ensemble; /* subcommand ensemble */ +} Ttk_Ensemble; + +MODULE_SCOPE int Ttk_InvokeEnsemble( /* Run an ensemble command */ + const Ttk_Ensemble *commands, int cmdIndex, + void *clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]); + +MODULE_SCOPE int TtkEnumerateHashTable(Tcl_Interp *, Tcl_HashTable *); + +/*------------------------------------------------------------------------ + * +++ Stub table declarations. */ #include "ttkDecls.h" diff --git a/generic/ttk/ttkThemeInt.h b/generic/ttk/ttkThemeInt.h index a7c19aa..4c461cd 100644 --- a/generic/ttk/ttkThemeInt.h +++ b/generic/ttk/ttkThemeInt.h @@ -1,5 +1,5 @@ /* - * $Id: ttkThemeInt.h,v 1.5 2007/12/13 15:26:26 dgp Exp $ + * $Id: ttkThemeInt.h,v 1.5.2.1 2010/08/26 02:06:10 hobbs Exp $ * * Theme engine: private definitions. * @@ -11,18 +11,17 @@ #include "ttkTheme.h" -typedef struct Ttk_Style_ *Ttk_Style; typedef struct Ttk_TemplateNode_ Ttk_TemplateNode, *Ttk_LayoutTemplate; -MODULE_SCOPE Ttk_ElementImpl Ttk_GetElement(Ttk_Theme theme, const char *name); -MODULE_SCOPE const char *Ttk_ElementName(Ttk_ElementImpl); +MODULE_SCOPE Ttk_ElementClass *Ttk_GetElement(Ttk_Theme, const char *name); +MODULE_SCOPE const char *Ttk_ElementClassName(Ttk_ElementClass *); MODULE_SCOPE void Ttk_ElementSize( - Ttk_ElementImpl element, Ttk_Style, char *recordPtr, Tk_OptionTable, + Ttk_ElementClass *, Ttk_Style, char *recordPtr, Tk_OptionTable, Tk_Window tkwin, Ttk_State state, int *widthPtr, int *heightPtr, Ttk_Padding*); MODULE_SCOPE void Ttk_DrawElement( - Ttk_ElementImpl element, Ttk_Style, char *recordPtr, Tk_OptionTable, + Ttk_ElementClass *, Ttk_Style, char *recordPtr, Tk_OptionTable, Tk_Window tkwin, Drawable d, Ttk_Box b, Ttk_State state); MODULE_SCOPE Tcl_Obj *Ttk_QueryStyle( diff --git a/generic/ttk/ttkTrace.c b/generic/ttk/ttkTrace.c index 37a319b..1550248 100644 --- a/generic/ttk/ttkTrace.c +++ b/generic/ttk/ttkTrace.c @@ -1,4 +1,4 @@ -/* $Id: ttkTrace.c,v 1.1 2006/10/31 01:42:26 hobbs Exp $ +/* $Id: ttkTrace.c,v 1.1.4.1 2010/08/26 02:06:10 hobbs Exp $ * * Copyright 2003, Joe English * @@ -27,8 +27,8 @@ static char * VarTraceProc( ClientData clientData, /* Widget record pointer */ Tcl_Interp *interp, /* Interpreter containing variable. */ - CONST char *name1, /* (unused) */ - CONST char *name2, /* (unused) */ + const char *name1, /* (unused) */ + const char *name2, /* (unused) */ int flags) /* Information about what happened. */ { Ttk_TraceHandle *tracePtr = clientData; diff --git a/generic/ttk/ttkTrack.c b/generic/ttk/ttkTrack.c index d6e89fa..c129e8b 100644 --- a/generic/ttk/ttkTrack.c +++ b/generic/ttk/ttkTrack.c @@ -1,4 +1,4 @@ -/* $Id: ttkTrack.c,v 1.4 2007/12/13 15:26:26 dgp Exp $ +/* $Id: ttkTrack.c,v 1.4.2.1 2010/08/26 02:06:10 hobbs Exp $ * Copyright (c) 2004, Joe English * * TtkTrackElementState() -- helper routine for widgets @@ -27,11 +27,11 @@ #include "ttkTheme.h" #include "ttkWidget.h" -typedef struct -{ - WidgetCore *corePtr; /* Widget to track */ - Ttk_LayoutNode *activeElement; /* element under the mouse cursor */ - Ttk_LayoutNode *pressedElement; /* currently pressed element */ +typedef struct { + WidgetCore *corePtr; /* widget to track */ + Ttk_Layout tracking; /* current layout being tracked */ + Ttk_Element activeElement; /* element under the mouse cursor */ + Ttk_Element pressedElement; /* currently pressed element */ } ElementStateTracker; /* @@ -42,9 +42,9 @@ typedef struct * The active element has TTK_STATE_ACTIVE set _unless_ * another element is 'pressed' */ -static void ActivateElement(ElementStateTracker *es, Ttk_LayoutNode *node) +static void ActivateElement(ElementStateTracker *es, Ttk_Element element) { - if (es->activeElement == node) { + if (es->activeElement == element) { /* No change */ return; } @@ -53,15 +53,15 @@ static void ActivateElement(ElementStateTracker *es, Ttk_LayoutNode *node) if (es->activeElement) { /* Deactivate old element */ Ttk_ChangeElementState(es->activeElement, 0,TTK_STATE_ACTIVE); - } - if (node) { + } + if (element) { /* Activate new element */ - Ttk_ChangeElementState(node, TTK_STATE_ACTIVE,0); + Ttk_ChangeElementState(element, TTK_STATE_ACTIVE,0); } TtkRedisplayWidget(es->corePtr); } - es->activeElement = node; + es->activeElement = element; } /* ReleaseElement -- @@ -87,18 +87,18 @@ static void ReleaseElement(ElementStateTracker *es) /* PressElement -- * Presses the specified element. */ -static void PressElement(ElementStateTracker *es, Ttk_LayoutNode *node) +static void PressElement(ElementStateTracker *es, Ttk_Element element) { if (es->pressedElement) { ReleaseElement(es); } - if (node) { + if (element) { Ttk_ChangeElementState( - node, TTK_STATE_PRESSED|TTK_STATE_ACTIVE, 0); + element, TTK_STATE_PRESSED|TTK_STATE_ACTIVE, 0); } - es->pressedElement = node; + es->pressedElement = element; TtkRedisplayWidget(es->corePtr); } @@ -107,10 +107,10 @@ static void PressElement(ElementStateTracker *es, Ttk_LayoutNode *node) */ static const unsigned ElementStateMask = - ButtonPressMask - | ButtonReleaseMask - | PointerMotionMask - | LeaveWindowMask + ButtonPressMask + | ButtonReleaseMask + | PointerMotionMask + | LeaveWindowMask | EnterWindowMask | StructureNotifyMask ; @@ -118,15 +118,23 @@ static const unsigned ElementStateMask = static void ElementStateEventProc(ClientData clientData, XEvent *ev) { - ElementStateTracker *es = (ElementStateTracker *)clientData; - Ttk_LayoutNode *node; + ElementStateTracker *es = clientData; + Ttk_Layout layout = es->corePtr->layout; + Ttk_Element element; + + /* Guard against dangling pointers [#2431428] + */ + if (es->tracking != layout) { + es->pressedElement = es->activeElement = 0; + es->tracking = layout; + } switch (ev->type) { case MotionNotify : - node = Ttk_LayoutIdentify( - es->corePtr->layout,ev->xmotion.x,ev->xmotion.y); - ActivateElement(es, node); + element = Ttk_IdentifyElement( + layout, ev->xmotion.x, ev->xmotion.y); + ActivateElement(es, element); break; case LeaveNotify: ActivateElement(es, 0); @@ -134,21 +142,21 @@ ElementStateEventProc(ClientData clientData, XEvent *ev) PressElement(es, 0); break; case EnterNotify: - node = Ttk_LayoutIdentify( - es->corePtr->layout,ev->xcrossing.x,ev->xcrossing.y); - ActivateElement(es, node); + element = Ttk_IdentifyElement( + layout, ev->xcrossing.x, ev->xcrossing.y); + ActivateElement(es, element); break; case ButtonPress: - node = Ttk_LayoutIdentify( - es->corePtr->layout, ev->xbutton.x, ev->xbutton.y); - if (node) - PressElement(es, node); + element = Ttk_IdentifyElement( + layout, ev->xbutton.x, ev->xbutton.y); + if (element) + PressElement(es, element); break; case ButtonRelease: ReleaseElement(es); break; case DestroyNotify: - /* Unregister this event handler and free client data. + /* Unregister this event handler and free client data. */ Tk_DeleteEventHandler(es->corePtr->tkwin, ElementStateMask, ElementStateEventProc, es); @@ -167,6 +175,7 @@ void TtkTrackElementState(WidgetCore *corePtr) { ElementStateTracker *es = (ElementStateTracker*)ckalloc(sizeof(*es)); es->corePtr = corePtr; + es->tracking = 0; es->activeElement = es->pressedElement = 0; Tk_CreateEventHandler(corePtr->tkwin, ElementStateMask,ElementStateEventProc,es); diff --git a/generic/ttk/ttkTreeview.c b/generic/ttk/ttkTreeview.c index d9f61f9..b144103 100644 --- a/generic/ttk/ttkTreeview.c +++ b/generic/ttk/ttkTreeview.c @@ -1,10 +1,11 @@ -/* $Id: ttkTreeview.c,v 1.23.2.1 2010/05/31 17:22:48 jenglish Exp $ +/* $Id: ttkTreeview.c,v 1.23.2.2 2010/08/26 02:06:10 hobbs Exp $ * Copyright (c) 2004, Joe English * * ttk::treeview widget implementation. */ #include +#include #include #include "ttkTheme.h" #include "ttkWidget.h" @@ -33,8 +34,7 @@ static const int HALO = 4; /* separator */ */ typedef struct TreeItemRec TreeItem; -struct TreeItemRec -{ +struct TreeItemRec { Tcl_HashEntry *entryPtr; /* Back-pointer to hash table entry */ TreeItem *parent; /* Parent item */ TreeItem *children; /* Linked list of child items */ @@ -50,16 +50,24 @@ struct TreeItemRec Tcl_Obj *valuesObj; Tcl_Obj *openObj; Tcl_Obj *tagsObj; + + /* + * Derived resources: + */ + Ttk_TagSet tagset; + Ttk_ImageSpec *imagespec; }; -static Tk_OptionSpec ItemOptionSpecs[] = -{ +#define ITEM_OPTION_TAGS_CHANGED 0x100 +#define ITEM_OPTION_IMAGE_CHANGED 0x200 + +static Tk_OptionSpec ItemOptionSpecs[] = { {TK_OPTION_STRING, "-text", "text", "Text", "", Tk_Offset(TreeItem,textObj), -1, 0,0,0 }, {TK_OPTION_STRING, "-image", "image", "Image", NULL, Tk_Offset(TreeItem,imageObj), -1, - TK_OPTION_NULL_OK,0,0 }, + TK_OPTION_NULL_OK,0,ITEM_OPTION_IMAGE_CHANGED }, {TK_OPTION_STRING, "-values", "values", "Values", NULL, Tk_Offset(TreeItem,valuesObj), -1, TK_OPTION_NULL_OK,0,0 }, @@ -68,7 +76,7 @@ static Tk_OptionSpec ItemOptionSpecs[] = 0,0,0 }, {TK_OPTION_STRING, "-tags", "tags", "Tags", NULL, Tk_Offset(TreeItem,tagsObj), -1, - TK_OPTION_NULL_OK,0,0 }, + TK_OPTION_NULL_OK,0,ITEM_OPTION_TAGS_CHANGED }, {TK_OPTION_END, 0,0,0, NULL, -1,-1, 0,0,0} }; @@ -90,6 +98,9 @@ static TreeItem *NewItem(void) item->openObj = NULL; item->tagsObj = NULL; + item->tagset = NULL; + item->imagespec = NULL; + return item; } @@ -103,6 +114,10 @@ static void FreeItem(TreeItem *item) if (item->valuesObj) { Tcl_DecrRefCount(item->valuesObj); } if (item->openObj) { Tcl_DecrRefCount(item->openObj); } if (item->tagsObj) { Tcl_DecrRefCount(item->tagsObj); } + + if (item->tagset) { Ttk_FreeTagSet(item->tagset); } + if (item->imagespec) { TtkFreeImageSpec(item->imagespec); } + ckfree((ClientData)item); } @@ -168,14 +183,13 @@ static TreeItem *NextPreorder(TreeItem *item) typedef struct { Tcl_Obj *textObj; /* taken from item / data cell */ Tcl_Obj *imageObj; /* taken from item */ - Tcl_Obj *anchorObj; /* from column */ + Tcl_Obj *anchorObj; /* from column <> */ Tcl_Obj *backgroundObj; /* remainder from tag */ Tcl_Obj *foregroundObj; Tcl_Obj *fontObj; } DisplayItem; -static Tk_OptionSpec TagOptionSpecs[] = -{ +static Tk_OptionSpec TagOptionSpecs[] = { {TK_OPTION_STRING, "-text", "text", "Text", NULL, Tk_Offset(DisplayItem,textObj), -1, TK_OPTION_NULL_OK,0,0 }, @@ -184,14 +198,14 @@ static Tk_OptionSpec TagOptionSpecs[] = TK_OPTION_NULL_OK,0,0 }, {TK_OPTION_ANCHOR, "-anchor", "anchor", "Anchor", NULL, Tk_Offset(DisplayItem,anchorObj), -1, - TK_OPTION_NULL_OK, 0, GEOMETRY_CHANGED}, - {TK_OPTION_STRING, "-background", "windowColor", "WindowColor", /*SB:COLOR*/ + TK_OPTION_NULL_OK, 0, GEOMETRY_CHANGED}, /* <> */ + {TK_OPTION_COLOR, "-background", "windowColor", "WindowColor", NULL, Tk_Offset(DisplayItem,backgroundObj), -1, TK_OPTION_NULL_OK,0,0 }, - {TK_OPTION_STRING, "-foreground", "textColor", "TextColor", /*SB:COLOR*/ + {TK_OPTION_COLOR, "-foreground", "textColor", "TextColor", NULL, Tk_Offset(DisplayItem,foregroundObj), -1, TK_OPTION_NULL_OK,0,0 }, - {TK_OPTION_STRING, "-font", "font", "Font", /* SB:FONT */ + {TK_OPTION_FONT, "-font", "font", "Font", NULL, Tk_Offset(DisplayItem,fontObj), -1, TK_OPTION_NULL_OK,0,GEOMETRY_CHANGED }, @@ -211,7 +225,7 @@ typedef struct { int stretch; /* Should column stretch while resizing? */ Tcl_Obj *idObj; /* Column identifier, from -columns option */ - Tcl_Obj *anchorObj; /* -anchor for cell data */ + Tcl_Obj *anchorObj; /* -anchor for cell data <> */ /* Column heading data: */ @@ -259,8 +273,7 @@ static void FreeColumn(TreeColumn *column) /* Don't touch column->data, it's scratch storage */ } -static Tk_OptionSpec ColumnOptionSpecs[] = -{ +static Tk_OptionSpec ColumnOptionSpecs[] = { {TK_OPTION_INT, "-width", "width", "Width", DEF_COLWIDTH, -1, Tk_Offset(TreeColumn,width), 0,0,GEOMETRY_CHANGED }, @@ -271,7 +284,7 @@ static Tk_OptionSpec ColumnOptionSpecs[] = "1", -1, Tk_Offset(TreeColumn,stretch), 0,0,0 }, {TK_OPTION_ANCHOR, "-anchor", "anchor", "Anchor", - "w", Tk_Offset(TreeColumn,anchorObj), -1, + "w", Tk_Offset(TreeColumn,anchorObj), -1, /* <> */ 0,0,0 }, {TK_OPTION_STRING, "-id", "id", "ID", NULL, Tk_Offset(TreeColumn,idObj), -1, @@ -279,8 +292,7 @@ static Tk_OptionSpec ColumnOptionSpecs[] = {TK_OPTION_END, 0,0,0, NULL, -1,-1, 0,0,0} }; -static Tk_OptionSpec HeadingOptionSpecs[] = -{ +static Tk_OptionSpec HeadingOptionSpecs[] = { {TK_OPTION_STRING, "-text", "text", "Text", "", Tk_Offset(TreeColumn,headingObj), -1, 0,0,0 }, @@ -349,8 +361,7 @@ static int GetEnumSetFromObj( * headingHeight: [layout] * rowHeight, indent: style */ -typedef struct -{ +typedef struct { /* Resources acquired at initialization-time: */ Tk_OptionTable itemOptionTable; @@ -381,6 +392,7 @@ typedef struct TreeColumn *columns; /* Array of column options for data columns */ TreeItem *focus; /* Current focus item */ + TreeItem *endPtr; /* See EndPosition() */ /* Widget options: */ @@ -425,8 +437,7 @@ typedef struct { static const char *SelectModeStrings[] = { "none", "browse", "extended", NULL }; -static Tk_OptionSpec TreeviewOptionSpecs[] = -{ +static Tk_OptionSpec TreeviewOptionSpecs[] = { WIDGET_TAKES_FOCUS, {TK_OPTION_STRING, "-columns", "columns", "Columns", @@ -581,7 +592,7 @@ static TreeItem *FindItem( Tcl_AppendResult(interp, "Item ", itemName, " not found", NULL); return 0; } - return (TreeItem*)Tcl_GetHashValue(entryPtr); + return Tcl_GetHashValue(entryPtr); } /* + GetItemListFromObj -- @@ -887,14 +898,14 @@ static int DistributeWidth(Treeview *tv, int n) /* + ResizeColumns -- * Recompute column widths based on available width. - * Pick up slack first; + * Pick up slack first; * Distribute the remainder evenly across stretchable columns; * If any is still left over due to minwidth constraints, shove left. */ static void ResizeColumns(Treeview *tv, int newWidth) { int delta = newWidth - (TreeWidth(tv) + tv->tree.slack); - DepositSlack(tv, + DepositSlack(tv, ShoveLeft(tv, tv->tree.nDisplayColumns - 1, DistributeWidth(tv, PickupSlack(tv, delta)))); } @@ -915,7 +926,7 @@ static void DragColumn(Treeview *tv, int i, int delta) * +++ Event handlers. */ -static TreeItem *IdentifyItem(Treeview *tv,int y,Ttk_Box *itemPos); /*forward*/ +static TreeItem *IdentifyItem(Treeview *tv, int y); /*forward*/ static const unsigned int TreeviewBindEventMask = KeyPressMask|KeyReleaseMask @@ -928,14 +939,11 @@ static void TreeviewBindEventProc(void *clientData, XEvent *event) { Treeview *tv = clientData; TreeItem *item = NULL; - Ttk_Box unused; - void *taglist; - int nTags; + Ttk_TagSet tagset; /* * Figure out where to deliver the event. */ - switch (event->type) { case KeyPress: @@ -945,10 +953,10 @@ static void TreeviewBindEventProc(void *clientData, XEvent *event) break; case ButtonPress: case ButtonRelease: - item = IdentifyItem(tv, event->xbutton.y, &unused); + item = IdentifyItem(tv, event->xbutton.y); break; case MotionNotify: - item = IdentifyItem(tv, event->xmotion.y, &unused); + item = IdentifyItem(tv, event->xmotion.y); break; default: break; @@ -958,25 +966,28 @@ static void TreeviewBindEventProc(void *clientData, XEvent *event) return; } - /* ASSERT: Ttk_GetTagListFromObj returns TCL_OK. */ - Ttk_GetTagListFromObj(NULL, tv->tree.tagTable, item->tagsObj, - &nTags, &taglist); + /* ASSERT: Ttk_GetTagSetFromObj succeeds. + * NB: must use a local copy of the tagset, + * in case a binding script stomps on -tags. + */ + tagset = Ttk_GetTagSetFromObj(NULL, tv->tree.tagTable, item->tagsObj); /* * Fire binding: */ Tcl_Preserve(clientData); - Tk_BindEvent(tv->tree.bindingTable, event, tv->core.tkwin, nTags, taglist); + Tk_BindEvent(tv->tree.bindingTable, event, tv->core.tkwin, + tagset->nTags, (void **)tagset->tags); Tcl_Release(clientData); - Ttk_FreeTagList(taglist); + Ttk_FreeTagSet(tagset); } /*------------------------------------------------------------------------ * +++ Initialization and cleanup. */ -static int TreeviewInitialize(Tcl_Interp *interp, void *recordPtr) +static void TreeviewInitialize(Tcl_Interp *interp, void *recordPtr) { Treeview *tv = recordPtr; int unused; @@ -991,7 +1002,7 @@ static int TreeviewInitialize(Tcl_Interp *interp, void *recordPtr) Tk_CreateOptionTable(interp, TagOptionSpecs); tv->tree.tagTable = Ttk_CreateTagTable( - tv->tree.tagOptionTable, sizeof(DisplayItem)); + interp, tv->core.tkwin, TagOptionSpecs, sizeof(DisplayItem)); tv->tree.bindingTable = Tk_CreateBindingTable(interp); Tk_CreateEventHandler(tv->core.tkwin, TreeviewBindEventMask, TreeviewBindEventProc, tv); @@ -1021,13 +1032,14 @@ static int TreeviewInitialize(Tcl_Interp *interp, void *recordPtr) Tcl_InitHashTable(&tv->tree.items, TCL_STRING_KEYS); tv->tree.serial = 0; - tv->tree.focus = 0; + tv->tree.focus = tv->tree.endPtr = 0; /* Create root item "": */ tv->tree.root = NewItem(); Tk_InitOptions(interp, (ClientData)tv->tree.root, tv->tree.itemOptionTable, tv->core.tkwin); + tv->tree.root->tagset = Ttk_GetTagSetFromObj(NULL, tv->tree.tagTable, NULL); tv->tree.root->entryPtr = Tcl_CreateHashEntry(&tv->tree.items, "", &unused); Tcl_SetHashValue(tv->tree.root->entryPtr, tv->tree.root); @@ -1040,8 +1052,6 @@ static int TreeviewInitialize(Tcl_Interp *interp, void *recordPtr) */ tv->tree.treeArea = tv->tree.headingArea = Ttk_MakeBox(0,0,0,0); tv->tree.slack = 0; - - return TCL_OK; } static void TreeviewCleanup(void *recordPtr) @@ -1122,9 +1132,13 @@ static int ConfigureItem( int objc, Tcl_Obj *const objv[]) { Tk_SavedOptions savedOptions; + int mask; + Ttk_ImageSpec *newImageSpec = NULL; + Ttk_TagSet newTagSet = NULL; if (Tk_SetOptions(interp, (ClientData)item, tv->tree.itemOptionTable, - objc, objv, tv->core.tkwin,&savedOptions,0) != TCL_OK) + objc, objv, tv->core.tkwin, &savedOptions, &mask) + != TCL_OK) { return TCL_ERROR; } @@ -1137,15 +1151,24 @@ static int ConfigureItem( goto error; } - /* Validate -image option. + /* Check -image. */ - if (item->imageObj) { - Ttk_ImageSpec *imageSpec = - TtkGetImageSpec(interp, tv->core.tkwin, item->imageObj); - if (!imageSpec) { + if ((mask & ITEM_OPTION_IMAGE_CHANGED) && item->imageObj) { + newImageSpec = TtkGetImageSpec(interp, tv->core.tkwin, item->imageObj); + if (!newImageSpec) { + goto error; + } + } + + /* Check -tags. + * Side effect: may create new tags. + */ + if (mask & ITEM_OPTION_TAGS_CHANGED) { + newTagSet = Ttk_GetTagSetFromObj( + interp, tv->tree.tagTable, item->tagsObj); + if (!newTagSet) { goto error; } - TtkFreeImageSpec(imageSpec); /* @@@TODO: Keep this around */ } /* Keep TTK_STATE_OPEN flag in sync with item->openObj. @@ -1162,28 +1185,24 @@ static int ConfigureItem( item->state &= ~TTK_STATE_OPEN; } - /* Make sure -tags is a valid list - * (side effect: may create new tags) - */ - if (item->tagsObj) { - void *taglist; - int nTags; - if (Ttk_GetTagListFromObj(interp, tv->tree.tagTable, item->tagsObj, - &nTags, &taglist) != TCL_OK) - { - goto error; - } - Ttk_FreeTagList(taglist); - } - /* All OK. */ Tk_FreeSavedOptions(&savedOptions); + if (mask & ITEM_OPTION_TAGS_CHANGED) { + if (item->tagset) { Ttk_FreeTagSet(item->tagset); } + item->tagset = newTagSet; + } + if (mask & ITEM_OPTION_IMAGE_CHANGED) { + if (item->imagespec) { TtkFreeImageSpec(item->imagespec); } + item->imagespec = newImageSpec; + } TtkRedisplayWidget(&tv->core); return TCL_OK; error: Tk_RestoreSavedOptions(&savedOptions); + if (newTagSet) { Ttk_FreeTagSet(newTagSet); } + if (newImageSpec) { TtkFreeImageSpec(newImageSpec); } return TCL_ERROR; } @@ -1300,21 +1319,18 @@ static int CountRows(TreeItem *item) static TreeItem *IdentifyRow( Treeview *tv, /* Widget record */ TreeItem *item, /* Where to start search */ - Ttk_Box *bp, /* Scan position */ + int *ypos, /* Scan position */ int y) /* Target y coordinate */ { while (item) { - int next_ypos = bp->y + tv->tree.rowHeight; - if (bp->y <= y && y <= next_ypos) { - bp->height = tv->tree.rowHeight; + int next_ypos = *ypos + tv->tree.rowHeight; + if (*ypos <= y && y <= next_ypos) { return item; } - bp->y = next_ypos; + *ypos = next_ypos; if (item->state & TTK_STATE_OPEN) { - TreeItem *subitem = IdentifyRow(tv, item->children, bp, y); + TreeItem *subitem = IdentifyRow(tv, item->children, ypos, y); if (subitem) { - bp->x += tv->tree.indent; - bp->width -= tv->tree.indent; return subitem; } } @@ -1325,17 +1341,12 @@ static TreeItem *IdentifyRow( /* + IdentifyItem -- * Locate the item at the specified y position, if any. - * On return, *itemPos holds the parcel of the tree item. */ -static TreeItem *IdentifyItem(Treeview *tv, int y, Ttk_Box *itemPos) +static TreeItem *IdentifyItem(Treeview *tv, int y) { int rowHeight = tv->tree.rowHeight; - *itemPos = Ttk_MakeBox( - tv->tree.treeArea.x, - tv->tree.treeArea.y - tv->tree.yscroll.first * rowHeight, - tv->tree.column0.width, - rowHeight); - return IdentifyRow(tv, tv->tree.root->children, itemPos, y); + int ypos = tv->tree.treeArea.y - rowHeight * tv->tree.yscroll.first; + return IdentifyRow(tv, tv->tree.root->children, &ypos, y); } /* + IdentifyDisplayColumn -- @@ -1345,7 +1356,7 @@ static TreeItem *IdentifyItem(Treeview *tv, int y, Ttk_Box *itemPos) static int IdentifyDisplayColumn(Treeview *tv, int x, int *x1) { int colno = FirstColumn(tv); - int xpos = tv->tree.treeArea.x; + int xpos = tv->tree.treeArea.x - tv->tree.xscroll.first; while (colno < tv->tree.nDisplayColumns) { TreeColumn *column = tv->tree.displayColumns[colno]; @@ -1361,6 +1372,51 @@ static int IdentifyDisplayColumn(Treeview *tv, int x, int *x1) return -1; } +/* + RowNumber -- + * Calculate which row the specified item appears on; + * returns -1 if the item is not viewable. + * Xref: DrawForest, IdentifyItem. + */ +static int RowNumber(Treeview *tv, TreeItem *item) +{ + TreeItem *p = tv->tree.root->children; + int n = 0; + + while (p) { + if (p == item) + return n; + + ++n; + + /* Find next viewable item in preorder traversal order + */ + if (p->children && (p->state & TTK_STATE_OPEN)) { + p = p->children; + } else { + while (!p->next && p && p->parent) + p = p->parent; + if (p) + p = p->next; + } + } + + return -1; +} + +/* + ItemDepth -- return the depth of a tree item. + * The depth of an item is equal to the number of proper ancestors, + * not counting the root node. + */ +static int ItemDepth(TreeItem *item) +{ + int depth = 0; + while (item->parent) { + ++depth; + item = item->parent; + } + return depth-1; +} + /* + ItemRow -- * Returns row number of specified item relative to root, * -1 if item is not viewable. @@ -1388,6 +1444,97 @@ static int ItemRow(Treeview *tv, TreeItem *p) } } +/* + BoundingBox -- + * Compute the parcel of the specified column of the specified item, + * (or the entire item if column is NULL) + * Returns: 0 if item or column is not viewable, 1 otherwise. + */ +static int BoundingBox( + Treeview *tv, /* treeview widget */ + TreeItem *item, /* desired item */ + TreeColumn *column, /* desired column */ + Ttk_Box *bbox_rtn) /* bounding box of item */ +{ + int row = ItemRow(tv, item); + Ttk_Box bbox = tv->tree.treeArea; + + if (row < tv->tree.yscroll.first || row > tv->tree.yscroll.last) { + /* not viewable, or off-screen */ + return 0; + } + + bbox.y += (row - tv->tree.yscroll.first) * tv->tree.rowHeight; + bbox.height = tv->tree.rowHeight; + + bbox.x -= tv->tree.xscroll.first; + bbox.width = TreeWidth(tv); + + if (column) { + int xpos = 0, i = FirstColumn(tv); + while (i < tv->tree.nDisplayColumns) { + if (tv->tree.displayColumns[i] == column) { + break; + } + xpos += tv->tree.displayColumns[i]->width; + ++i; + } + if (i == tv->tree.nDisplayColumns) { /* specified column unviewable */ + return 0; + } + bbox.x += xpos; + bbox.width = column->width; + + /* Account for indentation in tree column: + */ + if (column == &tv->tree.column0) { + int indent = tv->tree.indent * ItemDepth(item); + bbox.x += indent; + bbox.width -= indent; + } + } + *bbox_rtn = bbox; + return 1; +} + +/* + IdentifyRegion -- + */ + +typedef enum { + REGION_NOTHING = 0, + REGION_HEADING, + REGION_SEPARATOR, + REGION_TREE, + REGION_CELL +} TreeRegion; + +static const char *regionStrings[] = { + "nothing", "heading", "separator", "tree", "cell", 0 +}; + +static TreeRegion IdentifyRegion(Treeview *tv, int x, int y) +{ + int x1 = 0, colno; + + colno = IdentifyDisplayColumn(tv, x, &x1); + if (Ttk_BoxContains(tv->tree.headingArea, x, y)) { + if (colno < 0) { + return REGION_NOTHING; + } else if (-HALO <= x1 - x && x1 - x <= HALO) { + return REGION_SEPARATOR; + } else { + return REGION_HEADING; + } + } else if (Ttk_BoxContains(tv->tree.treeArea, x, y)) { + TreeItem *item = IdentifyItem(tv, y); + if (item && colno > 0) { + return REGION_CELL; + } else if (item) { + return REGION_TREE; + } + } + return REGION_NOTHING; +} + /*------------------------------------------------------------------------ * +++ Display routines. */ @@ -1430,11 +1577,11 @@ static Ttk_Layout TreeviewGetLayout( && GetSublayout(interp, themePtr, treeLayout, ".Item", tv->tree.tagOptionTable, &tv->tree.itemLayout) && GetSublayout(interp, themePtr, treeLayout, ".Cell", - tv->tree.tagOptionTable, &tv->tree.cellLayout) /*@@@HERE*/ + tv->tree.tagOptionTable, &tv->tree.cellLayout) && GetSublayout(interp, themePtr, treeLayout, ".Heading", tv->tree.headingOptionTable, &tv->tree.headingLayout) && GetSublayout(interp, themePtr, treeLayout, ".Row", - tv->tree.tagOptionTable, &tv->tree.rowLayout) /*@@@HERE*/ + tv->tree.tagOptionTable, &tv->tree.rowLayout) )) { return 0; } @@ -1470,15 +1617,12 @@ static Ttk_Layout TreeviewGetLayout( static void TreeviewDoLayout(void *clientData) { Treeview *tv = clientData; - Ttk_LayoutNode *clientNode = Ttk_LayoutFindNode(tv->core.layout,"treearea"); int visibleRows; /* ASSERT: SLACKINVARIANT */ Ttk_PlaceLayout(tv->core.layout,tv->core.state,Ttk_WinBox(tv->core.tkwin)); - tv->tree.treeArea = clientNode - ? Ttk_LayoutNodeInternalParcel(tv->core.layout,clientNode) - : Ttk_WinBox(tv->core.tkwin) ; + tv->tree.treeArea = Ttk_ClientRegion(tv->core.layout, "treearea"); ResizeColumns(tv, tv->tree.treeArea.width); /* ASSERT: SLACKINVARIANT */ @@ -1488,7 +1632,6 @@ static void TreeviewDoLayout(void *clientData) tv->tree.xscroll.first + tv->tree.treeArea.width, TreeWidth(tv)); - tv->tree.treeArea.x -= tv->tree.xscroll.first; if (tv->tree.showFlags & SHOW_HEADINGS) { tv->tree.headingArea = Ttk_PackBox( &tv->tree.treeArea, 1, tv->tree.headingHeight, TTK_SIDE_TOP); @@ -1502,7 +1645,6 @@ static void TreeviewDoLayout(void *clientData) tv->tree.yscroll.first, tv->tree.yscroll.first + visibleRows, CountRows(tv->tree.root) - 1); - } /* + TreeviewSize -- @@ -1544,14 +1686,17 @@ static Ttk_State ItemState(Treeview *tv, TreeItem *item) /* + DrawHeadings -- * Draw tree headings. */ -static void DrawHeadings(Treeview *tv, Drawable d, Ttk_Box b) +static void DrawHeadings(Treeview *tv, Drawable d) { + const int x0 = tv->tree.headingArea.x - tv->tree.xscroll.first; + const int y0 = tv->tree.headingArea.y; + const int h0 = tv->tree.headingArea.height; int i = FirstColumn(tv); int x = 0; while (i < tv->tree.nDisplayColumns) { TreeColumn *column = tv->tree.displayColumns[i]; - Ttk_Box parcel = Ttk_MakeBox(b.x+x, b.y, column->width, b.height); + Ttk_Box parcel = Ttk_MakeBox(x0+x, y0, column->width, h0); DisplayLayout(tv->tree.headingLayout, column, column->headingState, parcel, d); x += column->width; @@ -1560,34 +1705,16 @@ static void DrawHeadings(Treeview *tv, Drawable d, Ttk_Box b) } /* + PrepareItem -- - * Fill in a displayItem record from tag settings. + * Fill in a displayItem record. */ -static void PrepareItem(Treeview *tv, TreeItem *item, DisplayItem *displayItem) +static void PrepareItem( + Treeview *tv, TreeItem *item, DisplayItem *displayItem) { - const int nOptions = sizeof(*displayItem)/sizeof(Tcl_Obj*); - Tcl_Obj **dest = (Tcl_Obj**)displayItem; - Tcl_Obj **objv = NULL; - int objc = 0; - - memset(displayItem, 0, sizeof(*displayItem)); + Ttk_Style style = Ttk_LayoutStyle(tv->core.layout); + Ttk_State state = ItemState(tv, item); - if ( item->tagsObj - && Tcl_ListObjGetElements(NULL, item->tagsObj, &objc, &objv) == TCL_OK) - { - int i, j; - for (i=0; itree.tagTable, objv[i]); - Tcl_Obj **tagRecord = Ttk_TagRecord(tag); - - if (tagRecord) { - for (j=0; jtree.tagTable, item->tagset, displayItem); + Ttk_TagSetApplyStyle(tv->tree.tagTable, style, state, displayItem); } /* + DrawCells -- @@ -1595,7 +1722,7 @@ static void PrepareItem(Treeview *tv, TreeItem *item, DisplayItem *displayItem) */ static void DrawCells( Treeview *tv, TreeItem *item, DisplayItem *displayItem, - Drawable d, Ttk_Box b, int x, int y) + Drawable d, int x, int y) { Ttk_Layout layout = tv->tree.cellLayout; Ttk_State state = ItemState(tv, item); @@ -1617,10 +1744,10 @@ static void DrawCells( for (i = 1; i < tv->tree.nDisplayColumns; ++i) { TreeColumn *column = tv->tree.displayColumns[i]; Ttk_Box parcel = Ttk_PadBox( - Ttk_MakeBox(b.x+x, b.y+y, column->width, rowHeight), cellPadding); + Ttk_MakeBox(x, y, column->width, rowHeight), cellPadding); displayItem->textObj = column->data; - displayItem->anchorObj = column->anchorObj; + displayItem->anchorObj = column->anchorObj; /* <> */ DisplayLayout(layout, displayItem, state, parcel, d); x += column->width; @@ -1631,13 +1758,13 @@ static void DrawCells( * Draw an item (row background, tree label, and cells). */ static void DrawItem( - Treeview *tv, TreeItem *item, Drawable d, Ttk_Box b, int depth, int row) + Treeview *tv, TreeItem *item, Drawable d, int depth, int row) { Ttk_State state = ItemState(tv, item); DisplayItem displayItem; int rowHeight = tv->tree.rowHeight; - int x = depth * tv->tree.indent; - int y = (row - tv->tree.yscroll.first) * tv->tree.rowHeight; + int x = tv->tree.treeArea.x - tv->tree.xscroll.first; + int y = tv->tree.treeArea.y + rowHeight * (row - tv->tree.yscroll.first); if (row % 2) state |= TTK_STATE_ALTERNATE; @@ -1646,27 +1773,27 @@ static void DrawItem( /* Draw row background: */ { - Ttk_Box rowBox = Ttk_MakeBox(b.x, b.y+y, TreeWidth(tv), rowHeight); + Ttk_Box rowBox = Ttk_MakeBox(x, y, TreeWidth(tv), rowHeight); DisplayLayout(tv->tree.rowLayout, &displayItem, state, rowBox, d); } /* Draw tree label: */ if (tv->tree.showFlags & SHOW_TREE) { + int indent = depth * tv->tree.indent; int colwidth = tv->tree.column0.width; - Ttk_Box parcel = Ttk_MakeBox(b.x + x, b.y + y, colwidth - x, rowHeight); - displayItem.textObj = item->textObj; - displayItem.imageObj = item->imageObj; - displayItem.anchorObj = 0; + Ttk_Box parcel = Ttk_MakeBox( + x+indent, y, colwidth-indent, rowHeight); + if (item->textObj) { displayItem.textObj = item->textObj; } + if (item->imageObj) { displayItem.imageObj = item->imageObj; } + /* ??? displayItem.anchorObj = 0; <> */ DisplayLayout(tv->tree.itemLayout, &displayItem, state, parcel, d); - x = colwidth; - } else { - x = 0; + x += colwidth; } /* Draw data cells: */ - DrawCells(tv, item, &displayItem, d, b, x, y); + DrawCells(tv, item, &displayItem, d, x, y); } /* + DrawSubtree -- @@ -1677,17 +1804,17 @@ static void DrawItem( */ static int DrawForest( /* forward */ - Treeview *tv, TreeItem *item, Drawable d, Ttk_Box b, int depth, int row); + Treeview *tv, TreeItem *item, Drawable d, int depth, int row); static int DrawSubtree( - Treeview *tv, TreeItem *item, Drawable d, Ttk_Box b, int depth, int row) + Treeview *tv, TreeItem *item, Drawable d, int depth, int row) { if (row >= tv->tree.yscroll.first) { - DrawItem(tv, item, d, b, depth, row); + DrawItem(tv, item, d, depth, row); } if (item->state & TTK_STATE_OPEN) { - return DrawForest(tv, item->children, d, b, depth + 1, row + 1); + return DrawForest(tv, item->children, d, depth + 1, row + 1); } else { return row + 1; } @@ -1700,10 +1827,10 @@ static int DrawSubtree( * Row number of the last item drawn. */ static int DrawForest( - Treeview *tv, TreeItem *item, Drawable d, Ttk_Box b, int depth, int row) + Treeview *tv, TreeItem *item, Drawable d, int depth, int row) { while (item && row <= tv->tree.yscroll.last) { - row = DrawSubtree(tv, item, d, b, depth, row); + row = DrawSubtree(tv, item, d, depth, row); item = item->next; } return row; @@ -1718,9 +1845,9 @@ static void TreeviewDisplay(void *clientData, Drawable d) Ttk_DrawLayout(tv->core.layout, tv->core.state, d); if (tv->tree.showFlags & SHOW_HEADINGS) { - DrawHeadings(tv, d, tv->tree.headingArea); + DrawHeadings(tv, d); } - DrawForest(tv, tv->tree.root->children, d, tv->tree.treeArea, 0,0); + DrawForest(tv, tv->tree.root->children, d, 0,0); } /*------------------------------------------------------------------------ @@ -1748,16 +1875,33 @@ static TreeItem *InsertPosition(TreeItem *parent, int index) /* + EndPosition -- * Locate the last child of the specified node. + * + * To avoid quadratic-time behavior in the common cases + * where the treeview is populated in breadth-first or + * depth-first order using [$tv insert $parent end ...], + * we cache the result from the last call to EndPosition() + * and start the search from there on a cache hit. + * */ -static TreeItem *EndPosition(TreeItem *parent) +static TreeItem *EndPosition(Treeview *tv, TreeItem *parent) { - TreeItem *sibling = parent->children; - if (sibling) { - while (sibling->next) { - sibling = sibling->next; + TreeItem *endPtr = tv->tree.endPtr; + + while (endPtr && endPtr->parent != parent) { + endPtr = endPtr->parent; + } + if (!endPtr) { + endPtr = parent->children; + } + + if (endPtr) { + while (endPtr->next) { + endPtr = endPtr->next; } + tv->tree.endPtr = endPtr; } - return sibling; + + return endPtr; } /* + AncestryCheck -- @@ -1802,51 +1946,6 @@ static TreeItem *DeleteItems(TreeItem *item, TreeItem *delq) return delq; } -/* + RowNumber -- - * Calculate which row the specified item appears on; - * returns -1 if the item is not viewable. - * Xref: DrawForest, IdentifyItem. - */ -static int RowNumber(Treeview *tv, TreeItem *item) -{ - TreeItem *p = tv->tree.root->children; - int n = 0; - - while (p) { - if (p == item) - return n; - - ++n; - - /* Find next viewable item in preorder traversal order - */ - if (p->children && (p->state & TTK_STATE_OPEN)) { - p = p->children; - } else { - while (!p->next && p && p->parent) - p = p->parent; - if (p) - p = p->next; - } - } - - return -1; -} - -/* + ItemDepth -- return the depth of a tree item. - * The depth of an item is equal to the number of proper ancestors, - * not counting the root node. - */ -static int ItemDepth(TreeItem *item) -{ - int depth = 0; - while (item->parent) { - ++depth; - item = item->parent; - } - return depth-1; -} - /*------------------------------------------------------------------------ * +++ Widget commands -- item inquiry. */ @@ -1855,7 +1954,7 @@ static int ItemDepth(TreeItem *item) * Return the list of children associated with $item */ static int TreeviewChildrenCommand( - Tcl_Interp *interp, int objc, Tcl_Obj *const objv[], void *recordPtr) + void *recordPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]) { Treeview *tv = recordPtr; TreeItem *item; @@ -1935,7 +2034,7 @@ static int TreeviewChildrenCommand( * Return the item ID of $item's parent. */ static int TreeviewParentCommand( - Tcl_Interp *interp, int objc, Tcl_Obj *const objv[], void *recordPtr) + void *recordPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]) { Treeview *tv = recordPtr; TreeItem *item; @@ -1963,7 +2062,7 @@ static int TreeviewParentCommand( * Return the ID of $item's next sibling. */ static int TreeviewNextCommand( - Tcl_Interp *interp, int objc, Tcl_Obj *const objv[], void *recordPtr) + void *recordPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]) { Treeview *tv = recordPtr; TreeItem *item; @@ -1988,7 +2087,7 @@ static int TreeviewNextCommand( * Return the ID of $item's previous sibling. */ static int TreeviewPrevCommand( - Tcl_Interp *interp, int objc, Tcl_Obj *const objv[], void *recordPtr) + void *recordPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]) { Treeview *tv = recordPtr; TreeItem *item; @@ -2013,7 +2112,7 @@ static int TreeviewPrevCommand( * Return the index of $item within its parent. */ static int TreeviewIndexCommand( - Tcl_Interp *interp, int objc, Tcl_Obj *const objv[], void *recordPtr) + void *recordPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]) { Treeview *tv = recordPtr; TreeItem *item; @@ -2041,7 +2140,7 @@ static int TreeviewIndexCommand( * Test if the specified item id is present in the tree. */ static int TreeviewExistsCommand( - Tcl_Interp *interp, int objc, Tcl_Obj *const objv[], void *recordPtr) + void *recordPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]) { Treeview *tv = recordPtr; Tcl_HashEntry *entryPtr; @@ -2060,12 +2159,11 @@ static int TreeviewExistsCommand( * Return bounding box [x y width height] of specified item. */ static int TreeviewBBoxCommand( - Tcl_Interp *interp, int objc, Tcl_Obj *const objv[], void *recordPtr) + void *recordPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]) { Treeview *tv = recordPtr; TreeItem *item = 0; TreeColumn *column = 0; - int row; Ttk_Box bbox; if (objc < 3 || objc > 4) { @@ -2081,47 +2179,10 @@ static int TreeviewBBoxCommand( return TCL_ERROR; } - /* Compute bounding box of item: - */ - row = ItemRow(tv, item); - if (row < tv->tree.yscroll.first || row > tv->tree.yscroll.last) { - /* not viewable, or off-screen */ - return TCL_OK; - } - - bbox = tv->tree.treeArea; - bbox.y += (row - tv->tree.yscroll.first) * tv->tree.rowHeight; - bbox.height = tv->tree.rowHeight; - - /* If column has been specified, compute bounding box of cell - */ - if (column) { - int xpos = 0, i = FirstColumn(tv); - while (i < tv->tree.nDisplayColumns) { - if (tv->tree.displayColumns[i] == column) { - break; - } - xpos += tv->tree.displayColumns[i]->width; - ++i; - } - if (i == tv->tree.nDisplayColumns) { /* specified column unviewable */ - return TCL_OK; - } - bbox.x += xpos; - bbox.width = column->width; - - /* Special case for tree column -- account for indentation: - * (@@@ NOTE: doesn't account for tree indicator or image; - * @@@ this may or may not be the right thing.) - */ - if (column == &tv->tree.column0) { - int indent = tv->tree.indent * ItemDepth(item); - bbox.x += indent; - bbox.width -= indent; - } + if (BoundingBox(tv, item, column, &bbox)) { + Tcl_SetObjResult(interp, Ttk_NewBoxObj(bbox)); } - Tcl_SetObjResult(interp, Ttk_NewBoxObj(bbox)); return TCL_OK; } @@ -2166,24 +2227,25 @@ static int TreeviewHorribleIdentify( } detail = dcolbuf; } else if (Ttk_BoxContains(tv->tree.treeArea,x,y)) { - Ttk_Box itemBox; - item = IdentifyItem(tv, y, &itemBox); + item = IdentifyItem(tv, y); if (item && dColumnNumber > 0) { what = "cell"; detail = dcolbuf; } else if (item) { Ttk_Layout layout = tv->tree.itemLayout; + Ttk_Box itemBox; DisplayItem displayItem; - Ttk_LayoutNode *element; + Ttk_Element element; + BoundingBox(tv, item, NULL, &itemBox); PrepareItem(tv, item, &displayItem); /*@@@ FIX: -text, etc*/ Ttk_RebindSublayout(layout, &displayItem); Ttk_PlaceLayout(layout, ItemState(tv,item), itemBox); - element = Ttk_LayoutIdentify(layout, x, y); + element = Ttk_IdentifyElement(layout, x, y); if (element) { what = "item"; - detail = Ttk_LayoutNodeName(element); + detail = Ttk_ElementName(element); } else { what = "row"; } @@ -2207,53 +2269,99 @@ done: */ static int TreeviewIdentifyCommand( - 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 *componentStrings[] = - { "row", "column", NULL }; - enum { I_ROW, I_COLUMN }; + static const char *submethodStrings[] = + { "region", "item", "column", "row", "element", NULL }; + enum { I_REGION, I_ITEM, I_COLUMN, I_ROW, I_ELEMENT }; Treeview *tv = recordPtr; - int component, x, y; + int submethod; + int x, y; + + TreeRegion region; + Ttk_Box bbox; + TreeItem *item; + TreeColumn *column = 0; + int colno, x1; if (objc == 4) { /* Old form */ return TreeviewHorribleIdentify(interp, objc, objv, tv); } else if (objc != 5) { - Tcl_WrongNumArgs(interp, 2, objv, "component x y"); + Tcl_WrongNumArgs(interp, 2, objv, "command x y"); return TCL_ERROR; } if ( Tcl_GetIndexFromObj(interp, objv[2], - componentStrings, "component", TCL_EXACT, &component) != TCL_OK + submethodStrings, "command", TCL_EXACT, &submethod) != TCL_OK || Tcl_GetIntFromObj(interp, objv[3], &x) != TCL_OK || Tcl_GetIntFromObj(interp, objv[4], &y) != TCL_OK ) { return TCL_ERROR; } - switch (component) + region = IdentifyRegion(tv, x, y); + item = IdentifyItem(tv, y); + colno = IdentifyDisplayColumn(tv, x, &x1); + column = (colno >= 0) ? tv->tree.displayColumns[colno] : NULL; + + switch (submethod) { + case I_REGION : + Tcl_SetObjResult(interp,Tcl_NewStringObj(regionStrings[region],-1)); + break; + + case I_ITEM : case I_ROW : - { - Ttk_Box itemBox; - TreeItem *item = IdentifyItem(tv, y, &itemBox); if (item) { Tcl_SetObjResult(interp, ItemID(tv, item)); } break; - } case I_COLUMN : - { - int x1; - int column = IdentifyDisplayColumn(tv, x, &x1); - - if (column >= 0) { + if (colno >= 0) { char dcolbuf[16]; - sprintf(dcolbuf, "#%d", column); + sprintf(dcolbuf, "#%d", colno); Tcl_SetObjResult(interp, Tcl_NewStringObj(dcolbuf, -1)); } break; + + case I_ELEMENT : + { + Ttk_Layout layout = 0; + DisplayItem displayItem; + Ttk_Element element; + + switch (region) { + case REGION_NOTHING: + layout = tv->core.layout; + return TCL_OK; /* @@@ NYI */ + case REGION_HEADING: + case REGION_SEPARATOR: + layout = tv->tree.headingLayout; + return TCL_OK; /* @@@ NYI */ + case REGION_TREE: + layout = tv->tree.itemLayout; + break; + case REGION_CELL: + layout = tv->tree.cellLayout; + break; + } + + if (!BoundingBox(tv, item, column, &bbox)) { + return TCL_OK; + } + + PrepareItem(tv, item, &displayItem); /*@@@ FIX: fill in -text,etc */ + Ttk_RebindSublayout(layout, &displayItem); + Ttk_PlaceLayout(layout, ItemState(tv,item), bbox); + element = Ttk_IdentifyElement(layout, x, y); + + if (element) { + const char *elementName = Ttk_ElementName(element); + Tcl_SetObjResult(interp, Tcl_NewStringObj(elementName, -1)); + } + break; } } return TCL_OK; @@ -2267,7 +2375,7 @@ static int TreeviewIdentifyCommand( * Query or configure item options. */ static int TreeviewItemCommand( - Tcl_Interp *interp, int objc, Tcl_Obj *const objv[], void *recordPtr) + void *recordPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]) { Treeview *tv = recordPtr; TreeItem *item; @@ -2295,7 +2403,7 @@ static int TreeviewItemCommand( * Column data accessor */ static int TreeviewColumnCommand( - Tcl_Interp *interp, int objc, Tcl_Obj *const objv[], void *recordPtr) + void *recordPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]) { Treeview *tv = recordPtr; TreeColumn *column; @@ -2323,7 +2431,7 @@ static int TreeviewColumnCommand( * Heading data accessor */ static int TreeviewHeadingCommand( - Tcl_Interp *interp, int objc, Tcl_Obj *const objv[], void *recordPtr) + void *recordPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]) { Treeview *tv = recordPtr; Tk_OptionTable optionTable = tv->tree.headingOptionTable; @@ -2353,7 +2461,7 @@ static int TreeviewHeadingCommand( * Query or configure cell values */ static int TreeviewSetCommand( - Tcl_Interp *interp, int objc, Tcl_Obj *const objv[], void *recordPtr) + void *recordPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]) { Treeview *tv = recordPtr; TreeItem *item; @@ -2441,11 +2549,11 @@ static int TreeviewSetCommand( * +++ Widget commands -- tree modification. */ -/* + $tv insert $parent $index ?-id id? ?-option value...? +/* + $tv insert $parent $index ?-id id? ?-option value ...? * Insert a new item. */ static int TreeviewInsertCommand( - Tcl_Interp *interp, int objc, Tcl_Obj *const objv[], void *recordPtr) + void *recordPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]) { Treeview *tv = recordPtr; TreeItem *parent, *sibling, *newItem; @@ -2466,7 +2574,7 @@ static int TreeviewInsertCommand( /* Locate previous sibling based on $index: */ if (!strcmp(Tcl_GetString(objv[3]), "end")) { - sibling = EndPosition(parent); + sibling = EndPosition(tv, parent); } else { int index; if (Tcl_GetIntFromObj(interp, objv[3], &index) != TCL_OK) @@ -2501,6 +2609,7 @@ static int TreeviewInsertCommand( newItem = NewItem(); Tk_InitOptions( interp, (ClientData)newItem, tv->tree.itemOptionTable, tv->core.tkwin); + newItem->tagset = Ttk_GetTagSetFromObj(NULL, tv->tree.tagTable, NULL); if (ConfigureItem(interp, tv, newItem, objc, objv) != TCL_OK) { Tcl_DeleteHashEntry(entryPtr); FreeItem(newItem); @@ -2522,7 +2631,7 @@ static int TreeviewInsertCommand( * Unlink $item from the tree. */ static int TreeviewDetachCommand( - Tcl_Interp *interp, int objc, Tcl_Obj *const objv[], void *recordPtr) + void *recordPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]) { Treeview *tv = recordPtr; TreeItem **items; @@ -2567,7 +2676,7 @@ static int TreeviewDetachCommand( */ static int TreeviewDeleteCommand( - Tcl_Interp *interp, int objc, Tcl_Obj *const objv[], void *recordPtr) + void *recordPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]) { Treeview *tv = recordPtr; TreeItem **items, *delq; @@ -2605,6 +2714,8 @@ static int TreeviewDeleteCommand( TreeItem *next = delq->next; if (tv->tree.focus == delq) tv->tree.focus = 0; + if (tv->tree.endPtr == delq) + tv->tree.endPtr = 0; FreeItem(delq); delq = next; } @@ -2618,7 +2729,7 @@ static int TreeviewDeleteCommand( * Move $item to the specified $index in $parent's child list. */ static int TreeviewMoveCommand( - Tcl_Interp *interp, int objc, Tcl_Obj *const objv[], void *recordPtr) + void *recordPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]) { Treeview *tv = recordPtr; TreeItem *item, *parent; @@ -2637,7 +2748,7 @@ static int TreeviewMoveCommand( /* Locate previous sibling based on $index: */ if (!strcmp(Tcl_GetString(objv[4]), "end")) { - sibling = EndPosition(parent); + sibling = EndPosition(tv, parent); } else { TreeItem *p; int index; @@ -2651,7 +2762,7 @@ static int TreeviewMoveCommand( if (p != item) { --index; } /* else -- moving node forward, count index+1 nodes */ - sibling = p; + sibling = p; } } @@ -2681,14 +2792,14 @@ static int TreeviewMoveCommand( */ static int TreeviewXViewCommand( - Tcl_Interp *interp, int objc, Tcl_Obj *const objv[], void *recordPtr) + void *recordPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]) { Treeview *tv = recordPtr; return TtkScrollviewCommand(interp, objc, objv, tv->tree.xscrollHandle); } static int TreeviewYViewCommand( - Tcl_Interp *interp, int objc, Tcl_Obj *const objv[], void *recordPtr) + void *recordPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]) { Treeview *tv = recordPtr; return TtkScrollviewCommand(interp, objc, objv, tv->tree.yscrollHandle); @@ -2698,7 +2809,7 @@ static int TreeviewYViewCommand( * Ensure that $item is visible. */ static int TreeviewSeeCommand( - Tcl_Interp *interp, int objc, Tcl_Obj *const objv[], void *recordPtr) + void *recordPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]) { Treeview *tv = recordPtr; TreeItem *item, *parent; @@ -2744,10 +2855,10 @@ static int TreeviewSeeCommand( * Set right edge of display column $column to x position $X */ static int TreeviewDragCommand( - Tcl_Interp *interp, int objc, Tcl_Obj *const objv[], void *recordPtr) + void *recordPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]) { Treeview *tv = recordPtr; - int left = tv->tree.treeArea.x; + int left = tv->tree.treeArea.x - tv->tree.xscroll.first; int i = FirstColumn(tv); TreeColumn *column; int newx; @@ -2789,7 +2900,7 @@ static int TreeviewDragCommand( /* + $tree focus ?item? */ static int TreeviewFocusCommand( - Tcl_Interp *interp, int objc, Tcl_Obj *const objv[], void *recordPtr) + void *recordPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]) { Treeview *tv = recordPtr; @@ -2814,7 +2925,7 @@ static int TreeviewFocusCommand( /* + $tree selection ?add|remove|set|toggle $items? */ static int TreeviewSelectionCommand( - Tcl_Interp *interp, int objc, Tcl_Obj *const objv[], void *recordPtr) + void *recordPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]) { enum { SELECTION_SET, SELECTION_ADD, SELECTION_REMOVE, SELECTION_TOGGLE @@ -2891,7 +3002,7 @@ static int TreeviewSelectionCommand( /* + $tv tag bind $tag ?$sequence ?$script?? */ static int TreeviewTagBindCommand( - Tcl_Interp *interp, int objc, Tcl_Obj *const objv[], void *recordPtr) + void *recordPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]) { Treeview *tv = recordPtr; Ttk_TagTable tagTable = tv->tree.tagTable; @@ -2944,10 +3055,10 @@ static int TreeviewTagBindCommand( /* + $tv tag configure $tag ?-option ?value -option value...?? */ static int TreeviewTagConfigureCommand( - Tcl_Interp *interp, int objc, Tcl_Obj *const objv[], void *recordPtr) + void *recordPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]) { Treeview *tv = recordPtr; - void *tagRecord; + Ttk_TagTable tagTable = tv->tree.tagTable; Ttk_Tag tag; if (objc < 4) { @@ -2955,79 +3066,205 @@ static int TreeviewTagConfigureCommand( return TCL_ERROR; } - tag = Ttk_GetTagFromObj(tv->tree.tagTable, objv[3]); - tagRecord = Ttk_TagRecord(tag); + tag = Ttk_GetTagFromObj(tagTable, objv[3]); if (objc == 4) { - return TtkEnumerateOptions(interp, tagRecord, TagOptionSpecs, - tv->tree.tagOptionTable, tv->core.tkwin); + return Ttk_EnumerateTagOptions(interp, tagTable, tag); } else if (objc == 5) { - return TtkGetOptionValue(interp, tagRecord, objv[4], - tv->tree.tagOptionTable, tv->core.tkwin); + Tcl_Obj *result = Ttk_TagOptionValue(interp, tagTable, tag, objv[4]); + if (result) { + Tcl_SetObjResult(interp, result); + return TCL_OK; + } /* else */ + return TCL_ERROR; } /* else */ TtkRedisplayWidget(&tv->core); - return Tk_SetOptions( - interp, tagRecord, tv->tree.tagOptionTable, - objc - 4, objv + 4, tv->core.tkwin, - NULL/*savedOptions*/, NULL/*mask*/); + return Ttk_ConfigureTag(interp, tagTable, tag, objc - 4, objv + 4); } -/* + $tv tag option args... +/* + $tv tag has $tag ?$item? */ -static int TreeviewTagCommand( - Tcl_Interp *interp, int objc, Tcl_Obj *const objv[], void *recordPtr) +static int TreeviewTagHasCommand( + void *recordPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]) { - static WidgetCommandSpec TreeviewTagCommands[] = { - { "bind", TreeviewTagBindCommand }, - { "configure", TreeviewTagConfigureCommand }, - {0,0} - }; - return TtkWidgetEnsembleCommand( - TreeviewTagCommands, 2, interp, objc, objv, recordPtr); + Treeview *tv = recordPtr; + + if (objc == 4) { /* Return list of all items with tag */ + Ttk_Tag tag = Ttk_GetTagFromObj(tv->tree.tagTable, objv[3]); + TreeItem *item = tv->tree.root; + Tcl_Obj *result = Tcl_NewListObj(0,0); + + while (item) { + if (Ttk_TagSetContains(item->tagset, tag)) { + Tcl_ListObjAppendElement(NULL, result, ItemID(tv, item)); + } + item = NextPreorder(item); + } + + Tcl_SetObjResult(interp, result); + return TCL_OK; + } else if (objc == 5) { /* Test if item has specified tag */ + Ttk_Tag tag = Ttk_GetTagFromObj(tv->tree.tagTable, objv[3]); + TreeItem *item = FindItem(interp, tv, objv[4]); + if (!item) { + return TCL_ERROR; + } + Tcl_SetObjResult(interp, + Tcl_NewBooleanObj(Ttk_TagSetContains(item->tagset, tag))); + return TCL_OK; + } else { + Tcl_WrongNumArgs(interp, 3, objv, "tagName ?item?"); + return TCL_ERROR; + } } +/* + $tv tag names $tag + */ +static int TreeviewTagNamesCommand( + void *recordPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]) +{ + Treeview *tv = recordPtr; + + if (objc != 3) { + Tcl_WrongNumArgs(interp, 3, objv, ""); + return TCL_ERROR; + } + + return Ttk_EnumerateTags(interp, tv->tree.tagTable); +} + +/* + $tv tag add $tag $items + */ +static void AddTag(TreeItem *item, Ttk_Tag tag) +{ + if (Ttk_TagSetAdd(item->tagset, tag)) { + Tcl_DecrRefCount(item->tagsObj); + item->tagsObj = Ttk_NewTagSetObj(item->tagset); + Tcl_IncrRefCount(item->tagsObj); + } +} + +static int TreeviewTagAddCommand( + void *recordPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]) +{ + Treeview *tv = recordPtr; + Ttk_Tag tag; + TreeItem **items; + int i; + + if (objc != 5) { + Tcl_WrongNumArgs(interp, 3, objv, "tagName items"); + return TCL_ERROR; + } + + tag = Ttk_GetTagFromObj(tv->tree.tagTable, objv[3]); + items = GetItemListFromObj(interp, tv, objv[4]); + + if (!items) { + return TCL_ERROR; + } + + for (i=0; items[i]; ++i) { + AddTag(items[i], tag); + } + + return TCL_OK; +} + +/* + $tv tag remove $tag $items + */ +static void RemoveTag(TreeItem *item, Ttk_Tag tag) +{ + if (Ttk_TagSetRemove(item->tagset, tag)) { + Tcl_DecrRefCount(item->tagsObj); + item->tagsObj = Ttk_NewTagSetObj(item->tagset); + Tcl_IncrRefCount(item->tagsObj); + } +} + +static int TreeviewTagRemoveCommand( + void *recordPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]) +{ + Treeview *tv = recordPtr; + Ttk_Tag tag; + + if (objc < 4) { + Tcl_WrongNumArgs(interp, 3, objv, "tagName items"); + return TCL_ERROR; + } + + tag = Ttk_GetTagFromObj(tv->tree.tagTable, objv[3]); + + if (objc == 5) { + TreeItem **items = GetItemListFromObj(interp, tv, objv[4]); + int i; + + if (!items) { + return TCL_ERROR; + } + for (i=0; items[i]; ++i) { + RemoveTag(items[i], tag); + } + } else if (objc == 4) { + TreeItem *item = tv->tree.root; + while (item) { + RemoveTag(item, tag); + item=NextPreorder(item); + } + } + return TCL_OK; +} + +static const Ttk_Ensemble TreeviewTagCommands[] = { + { "add", TreeviewTagAddCommand,0 }, + { "bind", TreeviewTagBindCommand,0 }, + { "configure", TreeviewTagConfigureCommand,0 }, + { "has", TreeviewTagHasCommand,0 }, + { "names", TreeviewTagNamesCommand,0 }, + { "remove", TreeviewTagRemoveCommand,0 }, + { 0,0,0 } +}; + /*------------------------------------------------------------------------ * +++ Widget commands record. */ -static WidgetCommandSpec TreeviewCommands[] = -{ - { "bbox", TreeviewBBoxCommand }, - { "children", TreeviewChildrenCommand }, - { "cget", TtkWidgetCgetCommand }, - { "column", TreeviewColumnCommand }, - { "configure", TtkWidgetConfigureCommand }, - { "delete", TreeviewDeleteCommand }, - { "detach", TreeviewDetachCommand }, - { "drag", TreeviewDragCommand }, - { "exists", TreeviewExistsCommand }, - { "focus", TreeviewFocusCommand }, - { "heading", TreeviewHeadingCommand }, - { "identify", TreeviewIdentifyCommand }, - { "index", TreeviewIndexCommand }, - { "instate", TtkWidgetInstateCommand }, - { "insert", TreeviewInsertCommand }, - { "item", TreeviewItemCommand }, - { "move", TreeviewMoveCommand }, - { "next", TreeviewNextCommand }, - { "parent", TreeviewParentCommand }, - { "prev", TreeviewPrevCommand }, - { "see", TreeviewSeeCommand }, - { "selection" , TreeviewSelectionCommand }, - { "set", TreeviewSetCommand }, - { "state", TtkWidgetStateCommand }, - { "tag", TreeviewTagCommand }, - { "xview", TreeviewXViewCommand }, - { "yview", TreeviewYViewCommand }, - { NULL, NULL } +static const Ttk_Ensemble TreeviewCommands[] = { + { "bbox", TreeviewBBoxCommand,0 }, + { "children", TreeviewChildrenCommand,0 }, + { "cget", TtkWidgetCgetCommand,0 }, + { "column", TreeviewColumnCommand,0 }, + { "configure", TtkWidgetConfigureCommand,0 }, + { "delete", TreeviewDeleteCommand,0 }, + { "detach", TreeviewDetachCommand,0 }, + { "drag", TreeviewDragCommand,0 }, + { "exists", TreeviewExistsCommand,0 }, + { "focus", TreeviewFocusCommand,0 }, + { "heading", TreeviewHeadingCommand,0 }, + { "identify", TreeviewIdentifyCommand,0 }, + { "index", TreeviewIndexCommand,0 }, + { "instate", TtkWidgetInstateCommand,0 }, + { "insert", TreeviewInsertCommand,0 }, + { "item", TreeviewItemCommand,0 }, + { "move", TreeviewMoveCommand,0 }, + { "next", TreeviewNextCommand,0 }, + { "parent", TreeviewParentCommand,0 }, + { "prev", TreeviewPrevCommand,0 }, + { "see", TreeviewSeeCommand,0 }, + { "selection" , TreeviewSelectionCommand,0 }, + { "set", TreeviewSetCommand,0 }, + { "state", TtkWidgetStateCommand,0 }, + { "tag", 0,TreeviewTagCommands }, + { "xview", TreeviewXViewCommand,0 }, + { "yview", TreeviewYViewCommand,0 }, + { 0,0,0 } }; /*------------------------------------------------------------------------ * +++ Widget definition. */ -static WidgetSpec TreeviewWidgetSpec = -{ +static WidgetSpec TreeviewWidgetSpec = { "Treeview", /* className */ sizeof(Treeview), /* recordSize */ TreeviewOptionSpecs, /* optionSpecs */ @@ -3080,22 +3317,20 @@ TTK_END_LAYOUT_TABLE * +++ Tree indicator element. */ -typedef struct -{ +typedef struct { Tcl_Obj *colorObj; Tcl_Obj *sizeObj; Tcl_Obj *marginsObj; } TreeitemIndicator; -static Ttk_ElementOptionSpec TreeitemIndicatorOptions[] = -{ +static Ttk_ElementOptionSpec TreeitemIndicatorOptions[] = { { "-foreground", TK_OPTION_COLOR, Tk_Offset(TreeitemIndicator,colorObj), DEFAULT_FOREGROUND }, { "-indicatorsize", TK_OPTION_PIXELS, Tk_Offset(TreeitemIndicator,sizeObj), "12" }, { "-indicatormargins", TK_OPTION_STRING, Tk_Offset(TreeitemIndicator,marginsObj), "2 2 4 2" }, - {NULL} + { NULL, 0, 0, NULL } }; static void TreeitemIndicatorSize( @@ -3140,8 +3375,7 @@ static void TreeitemIndicatorDraw( Tk_FreeGC(Tk_Display(tkwin), gc); } -static Ttk_ElementSpec TreeitemIndicatorElementSpec = -{ +static Ttk_ElementSpec TreeitemIndicatorElementSpec = { TK_STYLE_VERSION_2, sizeof(TreeitemIndicator), TreeitemIndicatorOptions, @@ -3153,19 +3387,17 @@ static Ttk_ElementSpec TreeitemIndicatorElementSpec = * +++ Row element. */ -typedef struct -{ +typedef struct { Tcl_Obj *backgroundObj; Tcl_Obj *rowNumberObj; } RowElement; -static Ttk_ElementOptionSpec RowElementOptions[] = -{ +static Ttk_ElementOptionSpec RowElementOptions[] = { { "-background", TK_OPTION_COLOR, Tk_Offset(RowElement,backgroundObj), DEFAULT_BACKGROUND }, { "-rownumber", TK_OPTION_INT, Tk_Offset(RowElement,rowNumberObj), "0" }, - {NULL} + { NULL, 0, 0, NULL } }; static void RowElementDraw( @@ -3179,8 +3411,7 @@ static void RowElementDraw( b.x, b.y, b.width, b.height); } -static Ttk_ElementSpec RowElementSpec = -{ +static Ttk_ElementSpec RowElementSpec = { TK_STYLE_VERSION_2, sizeof(RowElement), RowElementOptions, @@ -3192,7 +3423,7 @@ static Ttk_ElementSpec RowElementSpec = * +++ Initialisation. */ -MODULE_SCOPE +MODULE_SCOPE void TtkTreeview_Init(Tcl_Interp *interp) { Ttk_Theme theme = Ttk_GetDefaultTheme(interp); diff --git a/generic/ttk/ttkWidget.c b/generic/ttk/ttkWidget.c index 6bc085b..9efcc57 100644 --- a/generic/ttk/ttkWidget.c +++ b/generic/ttk/ttkWidget.c @@ -1,4 +1,4 @@ -/* $Id: ttkWidget.c,v 1.11.2.2 2009/05/14 00:53:04 patthoyts Exp $ +/* $Id: ttkWidget.c,v 1.11.2.3 2010/08/26 02:06:10 hobbs Exp $ * Copyright (c) 2003, Joe English * * Core widget utilities. @@ -61,7 +61,7 @@ static void SizeChanged(WidgetCore *corePtr) static Drawable BeginDrawing(Tk_Window tkwin) { return Tk_GetPixmap(Tk_Display(tkwin), Tk_WindowId(tkwin), - Tk_Width(tkwin), Tk_Height(tkwin),Tk_Depth(tkwin)); + Tk_Width(tkwin), Tk_Height(tkwin), Tk_Depth(tkwin)); } /* EndDrawing -- @@ -115,7 +115,7 @@ void TtkRedisplayWidget(WidgetCore *corePtr) } if (!(corePtr->flags & REDISPLAY_PENDING)) { - Tcl_DoWhenIdle(DrawWidget, (ClientData) corePtr); + Tcl_DoWhenIdle(DrawWidget, corePtr); corePtr->flags |= REDISPLAY_PENDING; } } @@ -146,78 +146,94 @@ void TtkWidgetChangeState(WidgetCore *corePtr, } } -/* TtkWidgetEnsembleCommand -- - * Invoke an ensemble defined by a WidgetCommandSpec. - */ -int TtkWidgetEnsembleCommand( - const WidgetCommandSpec *commands, /* Ensemble definition */ - int cmdIndex, /* Index of command word */ - Tcl_Interp *interp, /* Interpreter to use */ - int objc, Tcl_Obj *const objv[], /* Argument vector */ - void *clientData) /* User data (widget record pointer) */ -{ - int index; - - if (objc <= cmdIndex) { - Tcl_WrongNumArgs(interp, cmdIndex, objv, "option ?arg arg...?"); - return TCL_ERROR; - } - if (Tcl_GetIndexFromObjStruct(interp, objv[cmdIndex], commands, - sizeof(commands[0]), "command", 0, &index) != TCL_OK) - { - return TCL_ERROR; - } - return commands[index].command(interp, objc, objv, clientData); -} - -/* - * WidgetInstanceObjCmd -- +/* WidgetInstanceObjCmd -- * Widget instance command implementation. */ static int WidgetInstanceObjCmd( - ClientData clientData, /* Widget record pointer */ - Tcl_Interp *interp, /* Current interpreter. */ - int objc, /* Number of arguments. */ - Tcl_Obj * const objv[]) /* Argument objects. */ + ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]) { - WidgetCore *corePtr = (WidgetCore *)clientData; - const WidgetCommandSpec *commands = corePtr->widgetSpec->commands; - int status = TCL_OK; + WidgetCore *corePtr = clientData; + const Ttk_Ensemble *commands = corePtr->widgetSpec->commands; + int status; Tcl_Preserve(clientData); - status = TtkWidgetEnsembleCommand(commands,1, interp,objc,objv,clientData); + status = Ttk_InvokeEnsemble(commands,1, clientData,interp,objc,objv); Tcl_Release(clientData); return status; } -/* - * Command deletion callback for widget instance commands. +/*------------------------------------------------------------------------ + * +++ Widget destruction. + * + * A widget can be destroyed when the application explicitly + * destroys the window or one of its ancestors via [destroy] + * or Tk_DestroyWindow(); when the application deletes the widget + * instance command; when there is an error in the widget constructor; + * or when another application calls XDestroyWindow on the window ID. + * + * The window receives a event in all cases, + * so we do the bulk of the cleanup there. See [#2207435] for + * further notes (esp. re: Tk_FreeConfigOptions). + * + * Widget code that reenters the interp should only do so + * when the widtget is Tcl_Preserve()d, and should check + * the WIDGET_DESTROYED flag bit upon return. + */ + +/* WidgetInstanceObjCmdDeleted -- + * Widget instance command deletion callback. */ static void WidgetInstanceObjCmdDeleted(ClientData clientData) { - WidgetCore *corePtr = (WidgetCore *) clientData; + WidgetCore *corePtr = clientData; corePtr->widgetCmd = NULL; if (corePtr->tkwin != NULL) Tk_DestroyWindow(corePtr->tkwin); } -/* - * WidgetCleanup -- - * Final cleanup for widget. - * - * @@@ TODO: check all code paths leading to widget destruction, - * @@@ describe here. - * @@@ Call widget-specific cleanup routine at an appropriate point. +/* FreeWidget -- + * Final cleanup for widget; called via Tcl_EventuallyFree(). */ static void -WidgetCleanup(char *memPtr) +FreeWidget(char *memPtr) { ckfree(memPtr); } +/* DestroyWidget -- + * Main widget destructor; called from event handler. + */ +static void +DestroyWidget(WidgetCore *corePtr) +{ + corePtr->flags |= WIDGET_DESTROYED; + + corePtr->widgetSpec->cleanupProc(corePtr); + + Tk_FreeConfigOptions( + (ClientData)corePtr, corePtr->optionTable, corePtr->tkwin); + + if (corePtr->layout) { + Ttk_FreeLayout(corePtr->layout); + } + + if (corePtr->flags & REDISPLAY_PENDING) { + Tcl_CancelIdleCall(DrawWidget, corePtr); + } + + corePtr->tkwin = NULL; + if (corePtr->widgetCmd) { + Tcl_Command cmd = corePtr->widgetCmd; + corePtr->widgetCmd = 0; + /* NB: this can reenter the interpreter via a command traces */ + Tcl_DeleteCommandFromToken(corePtr->interp, cmd); + } + Tcl_EventuallyFree(corePtr, FreeWidget); +} + /* * CoreEventProc -- * Event handler for basic events. @@ -247,7 +263,7 @@ static const unsigned CoreEventMask static void CoreEventProc(ClientData clientData, XEvent *eventPtr) { - WidgetCore *corePtr = (WidgetCore *) clientData; + WidgetCore *corePtr = clientData; switch (eventPtr->type) { @@ -260,35 +276,10 @@ static void CoreEventProc(ClientData clientData, XEvent *eventPtr) } break; case DestroyNotify : - corePtr->flags |= WIDGET_DESTROYED; - - Tk_DeleteEventHandler(corePtr->tkwin, - CoreEventMask,CoreEventProc,clientData); - - if (corePtr->flags & REDISPLAY_PENDING) { - Tcl_CancelIdleCall(DrawWidget, clientData); - } - - corePtr->widgetSpec->cleanupProc(corePtr); - - Tk_UndefineCursor(corePtr->tkwin); /* workaround for #2207435 */ - Tk_FreeConfigOptions( - clientData, corePtr->optionTable, corePtr->tkwin); - corePtr->tkwin = NULL; - - if (corePtr->layout) { - Ttk_FreeLayout(corePtr->layout); - } - - /* NB: this can reenter the interpreter via a command traces */ - if (corePtr->widgetCmd) { - Tcl_Command cmd = corePtr->widgetCmd; - corePtr->widgetCmd = 0; - Tcl_DeleteCommandFromToken(corePtr->interp, cmd); - } - Tcl_EventuallyFree(clientData, WidgetCleanup); + Tk_DeleteEventHandler( + corePtr->tkwin, CoreEventMask,CoreEventProc,clientData); + DestroyWidget(corePtr); break; - case FocusIn: case FocusOut: /* Don't process "virtual crossing" events */ @@ -339,14 +330,16 @@ static void CoreEventProc(ClientData clientData, XEvent *eventPtr) */ static void WidgetWorldChanged(ClientData clientData) { - WidgetCore *corePtr = (WidgetCore*)clientData; + WidgetCore *corePtr = clientData; SizeChanged(corePtr); TtkRedisplayWidget(corePtr); } -static struct Tk_ClassProcs widgetClassProcs = { - sizeof(Tk_ClassProcs), - WidgetWorldChanged +static Tk_ClassProcs widgetClassProcs = { + sizeof(Tk_ClassProcs), /* size */ + WidgetWorldChanged, /* worldChangedProc */ + NULL, /* createProc */ + NULL /* modalProc */ }; /* @@ -355,55 +348,45 @@ static struct Tk_ClassProcs widgetClassProcs = { * ClientData is a WidgetSpec *. */ int TtkWidgetConstructorObjCmd( - ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) + ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]) { - WidgetSpec *widgetSpec = (WidgetSpec *)clientData; + WidgetSpec *widgetSpec = clientData; const char *className = widgetSpec->className; - WidgetCore *corePtr; - ClientData recordPtr; + Tk_OptionTable optionTable = + Tk_CreateOptionTable(interp, widgetSpec->optionSpecs); Tk_Window tkwin; - Tk_OptionTable optionTable; + void *recordPtr; + WidgetCore *corePtr; + Tk_SavedOptions savedOptions; int i; - if (objc < 2 || objc % 1 == 1) { - Tcl_WrongNumArgs(interp, 1, objv, "pathName ?options?"); + if (objc < 2 || objc % 2 == 1) { + Tcl_WrongNumArgs(interp, 1, objv, "pathName ?-option value ...?"); return TCL_ERROR; } - tkwin = Tk_CreateWindowFromPath(interp, Tk_MainWindow(interp), - Tcl_GetStringFromObj(objv[1], NULL), (char *) NULL); - if (tkwin == NULL) - return TCL_ERROR; - - /* - * Check if a -class resource has been specified: + /* Check if a -class option has been specified. * We have to do this before the InitOptions() call, * since InitOptions() is affected by the widget class. */ for (i = 2; i < objc; i += 2) { - const char *resourceName = Tcl_GetString(objv[i]); - if (!strcmp(resourceName, "-class")) { + if (!strcmp(Tcl_GetString(objv[i]), "-class")) { className = Tcl_GetString(objv[i+1]); break; } } - Tk_SetClass(tkwin, className); - - /* - * Set the BackgroundPixmap to ParentRelative here, so - * subclasses don't need to worry about setting the background. - */ - Tk_SetWindowBackgroundPixmap(tkwin, ParentRelative); - - optionTable = Tk_CreateOptionTable(interp, widgetSpec->optionSpecs); + tkwin = Tk_CreateWindowFromPath( + interp, Tk_MainWindow(interp), Tcl_GetString(objv[1]), NULL); + if (tkwin == NULL) + return TCL_ERROR; /* * Allocate and initialize the widget record. */ recordPtr = ckalloc(widgetSpec->recordSize); memset(recordPtr, 0, widgetSpec->recordSize); - corePtr = (WidgetCore *)recordPtr; + corePtr = recordPtr; corePtr->tkwin = tkwin; corePtr->interp = interp; @@ -411,52 +394,57 @@ int TtkWidgetConstructorObjCmd( corePtr->widgetCmd = Tcl_CreateObjCommand(interp, Tk_PathName(tkwin), WidgetInstanceObjCmd, recordPtr, WidgetInstanceObjCmdDeleted); corePtr->optionTable = optionTable; + corePtr->layout = NULL; + corePtr->flags = 0; + corePtr->state = 0; + Tk_SetClass(tkwin, className); Tk_SetClassProcs(tkwin, &widgetClassProcs, recordPtr); + Tk_SetWindowBackgroundPixmap(tkwin, ParentRelative); - if (Tk_InitOptions(interp, recordPtr, optionTable, tkwin) != TCL_OK) - goto error_nocleanup; + widgetSpec->initializeProc(interp, recordPtr); - if (widgetSpec->initializeProc(interp, recordPtr) != TCL_OK) - goto error_nocleanup; + Tk_CreateEventHandler(tkwin, CoreEventMask, CoreEventProc, recordPtr); - if (Tk_SetOptions(interp, recordPtr, optionTable, objc - 2, - objv + 2, tkwin, NULL/*savePtr*/, (int *)NULL/*maskPtr*/) != TCL_OK) + /* + * Initial configuration. + */ + + Tcl_Preserve(corePtr); + if (Tk_InitOptions(interp, recordPtr, optionTable, tkwin) != TCL_OK) { goto error; + } + if (Tk_SetOptions(interp, recordPtr, optionTable, + objc - 2, objv + 2, tkwin, &savedOptions, NULL) != TCL_OK) { + Tk_RestoreSavedOptions(&savedOptions); + goto error; + } else { + Tk_FreeSavedOptions(&savedOptions); + } if (widgetSpec->configureProc(interp, recordPtr, ~0) != TCL_OK) goto error; - if (widgetSpec->postConfigureProc(interp, recordPtr, ~0) != TCL_OK) goto error; if (WidgetDestroyed(corePtr)) goto error; - if (UpdateLayout(interp, corePtr) != TCL_OK) - goto error; + Tcl_Release(corePtr); SizeChanged(corePtr); - Tk_CreateEventHandler(tkwin, CoreEventMask, CoreEventProc, recordPtr); - Tk_MakeWindowExist(tkwin); Tcl_SetObjResult(interp, Tcl_NewStringObj(Tk_PathName(tkwin), -1)); - return TCL_OK; error: - widgetSpec->cleanupProc(recordPtr); -error_nocleanup: - if (corePtr->layout) { - Ttk_FreeLayout(corePtr->layout); - corePtr->layout = 0; + if (WidgetDestroyed(corePtr)) { + Tcl_SetResult(interp, "Widget has been destroyed", TCL_STATIC); + } else { + Tk_DestroyWindow(tkwin); } - Tk_FreeConfigOptions(recordPtr, optionTable, tkwin); - Tk_DestroyWindow(tkwin); - corePtr->tkwin = 0; - Tcl_DeleteCommandFromToken(interp, corePtr->widgetCmd); - ckfree(recordPtr); + Tcl_Release(corePtr); return TCL_ERROR; } @@ -532,9 +520,8 @@ Ttk_Layout TtkWidgetGetOrientedLayout( /* TtkNullInitialize -- * Default widget initializeProc (no-op) */ -int TtkNullInitialize(Tcl_Interp *interp, void *recordPtr) +void TtkNullInitialize(Tcl_Interp *interp, void *recordPtr) { - return TCL_OK; } /* TtkNullPostConfigure -- @@ -604,7 +591,7 @@ int TtkWidgetSize(void *recordPtr, int *widthPtr, int *heightPtr) /* $w cget -option */ int TtkWidgetCgetCommand( -Tcl_Interp *interp, int objc, Tcl_Obj * CONST objv[], void *recordPtr) + void *recordPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]) { WidgetCore *corePtr = recordPtr; Tcl_Obj *result; @@ -624,14 +611,14 @@ Tcl_Interp *interp, int objc, Tcl_Obj * CONST objv[], void *recordPtr) /* $w configure ?-option ?value ....?? */ int TtkWidgetConfigureCommand( -Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[], void *recordPtr) + void *recordPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]) { WidgetCore *corePtr = recordPtr; Tcl_Obj *result; if (objc == 2) { result = Tk_GetOptionInfo(interp, recordPtr, - corePtr->optionTable, (Tcl_Obj *) NULL, corePtr->tkwin); + corePtr->optionTable, NULL, corePtr->tkwin); } else if (objc == 3) { result = Tk_GetOptionInfo(interp, recordPtr, corePtr->optionTable, objv[2], corePtr->tkwin); @@ -661,6 +648,10 @@ Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[], void *recordPtr) Tk_FreeSavedOptions(&savedOptions); status = corePtr->widgetSpec->postConfigureProc(interp,recordPtr,mask); + if (WidgetDestroyed(corePtr)) { + Tcl_SetResult(interp, "Widget has been destroyed", TCL_STATIC); + status = TCL_ERROR; + } if (status != TCL_OK) { return status; } @@ -689,7 +680,7 @@ Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[], void *recordPtr) */ int TtkWidgetStateCommand( - Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[], void *recordPtr) + void *recordPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]) { WidgetCore *corePtr = recordPtr; Ttk_StateSpec spec; @@ -729,7 +720,7 @@ int TtkWidgetStateCommand( */ int TtkWidgetInstateCommand( - Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[], void *recordPtr) + void *recordPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]) { WidgetCore *corePtr = recordPtr; Ttk_State state = corePtr->state; @@ -756,27 +747,39 @@ int TtkWidgetInstateCommand( } /* $w identify $x $y + * $w identify element $x $y * Returns: name of element at $x, $y */ int TtkWidgetIdentifyCommand( - Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[], void *recordPtr) + void *recordPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]) { WidgetCore *corePtr = recordPtr; - Ttk_LayoutNode *node; - int x, y; + Ttk_Element element; + static const char *whatTable[] = { "element", NULL }; + int x, y, what; - 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 (objc == 5) { + /* $w identify element $x $y */ + if (Tcl_GetIndexFromObj(interp,objv[2],whatTable,"option",0,&what) + != TCL_OK) + { + 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 + ) { return TCL_ERROR; + } - node = Ttk_LayoutIdentify(corePtr->layout, x, y); - if (node) { - const char *elementName = Ttk_LayoutNodeName(node); + element = Ttk_IdentifyElement(corePtr->layout, x, y); + if (element) { + const char *elementName = Ttk_ElementName(element); Tcl_SetObjResult(interp,Tcl_NewStringObj(elementName,-1)); } diff --git a/generic/ttk/ttkWidget.h b/generic/ttk/ttkWidget.h index 21cb1b3..882b8ec 100644 --- a/generic/ttk/ttkWidget.h +++ b/generic/ttk/ttkWidget.h @@ -1,4 +1,4 @@ -/* $Id: ttkWidget.h,v 1.9 2008/01/06 22:33:14 jenglish Exp $ +/* $Id: ttkWidget.h,v 1.9.2.1 2010/08/26 02:06:10 hobbs Exp $ * Copyright (c) 2003, Joe English * Helper routines for widget implementations. */ @@ -49,20 +49,6 @@ typedef struct } WidgetCore; /* - * Subcommand specifications: - */ -typedef int (*WidgetSubcommandProc)( - Tcl_Interp *interp, int objc, Tcl_Obj *const objv[], void *recordPtr); -typedef struct { - const char *name; - WidgetSubcommandProc command; -} WidgetCommandSpec; - -MODULE_SCOPE int TtkWidgetEnsembleCommand( /* Run an ensemble command */ - const WidgetCommandSpec *commands, int cmdIndex, - Tcl_Interp *interp, int objc, Tcl_Obj *const objv[], void *recordPtr); - -/* * Widget specifications: */ struct WidgetSpec_ @@ -70,12 +56,12 @@ struct WidgetSpec_ const char *className; /* Widget class name */ size_t recordSize; /* #bytes in widget record */ const Tk_OptionSpec *optionSpecs; /* Option specifications */ - const WidgetCommandSpec *commands; /* Widget instance subcommands */ + const Ttk_Ensemble *commands; /* Widget instance subcommands */ /* * Hooks: */ - int (*initializeProc)(Tcl_Interp *, void *recordPtr); + void (*initializeProc)(Tcl_Interp *, void *recordPtr); void (*cleanupProc)(void *recordPtr); int (*configureProc)(Tcl_Interp *, void *recordPtr, int flags); int (*postConfigureProc)(Tcl_Interp *, void *recordPtr, int flags); @@ -88,7 +74,7 @@ struct WidgetSpec_ /* * Common factors for widget implementations: */ -MODULE_SCOPE int TtkNullInitialize(Tcl_Interp *, void *); +MODULE_SCOPE void TtkNullInitialize(Tcl_Interp *, void *); MODULE_SCOPE int TtkNullPostConfigure(Tcl_Interp *, void *, int); MODULE_SCOPE void TtkNullCleanup(void *recordPtr); MODULE_SCOPE Ttk_Layout TtkWidgetGetLayout( @@ -104,15 +90,15 @@ MODULE_SCOPE int TtkCoreConfigure(Tcl_Interp*, void *, int mask); /* Common widget commands: */ MODULE_SCOPE int TtkWidgetConfigureCommand( - Tcl_Interp *, int, Tcl_Obj*const[], void *); + void *,Tcl_Interp *, int, Tcl_Obj*const[]); MODULE_SCOPE int TtkWidgetCgetCommand( - Tcl_Interp *, int, Tcl_Obj*const[], void *); + void *,Tcl_Interp *, int, Tcl_Obj*const[]); MODULE_SCOPE int TtkWidgetInstateCommand( - Tcl_Interp *, int, Tcl_Obj*const[], void *); + void *,Tcl_Interp *, int, Tcl_Obj*const[]); MODULE_SCOPE int TtkWidgetStateCommand( - Tcl_Interp *, int, Tcl_Obj*const[], void *); + void *,Tcl_Interp *, int, Tcl_Obj*const[]); MODULE_SCOPE int TtkWidgetIdentifyCommand( - Tcl_Interp *, int, Tcl_Obj*const[], void *); + void *,Tcl_Interp *, int, Tcl_Obj*const[]); /* Widget constructor: */ @@ -211,20 +197,42 @@ MODULE_SCOPE void TtkScrollbarUpdateRequired(ScrollHandle); typedef struct TtkTag *Ttk_Tag; typedef struct TtkTagTable *Ttk_TagTable; +typedef struct TtkTagSet { /* TODO: make opaque */ + Ttk_Tag *tags; + int nTags; +} *Ttk_TagSet; -MODULE_SCOPE Ttk_TagTable Ttk_CreateTagTable(Tk_OptionTable, int tagRecSize); +MODULE_SCOPE Ttk_TagTable Ttk_CreateTagTable( + Tcl_Interp *, Tk_Window tkwin, Tk_OptionSpec[], int recordSize); MODULE_SCOPE void Ttk_DeleteTagTable(Ttk_TagTable); MODULE_SCOPE Ttk_Tag Ttk_GetTag(Ttk_TagTable, const char *tagName); MODULE_SCOPE Ttk_Tag Ttk_GetTagFromObj(Ttk_TagTable, Tcl_Obj *); -MODULE_SCOPE Tcl_Obj **Ttk_TagRecord(Ttk_Tag); +MODULE_SCOPE Tcl_Obj *Ttk_TagOptionValue( + Tcl_Interp *, Ttk_TagTable, Ttk_Tag, Tcl_Obj *optionName); + +MODULE_SCOPE int Ttk_EnumerateTagOptions( + Tcl_Interp *, Ttk_TagTable, Ttk_Tag); + +MODULE_SCOPE int Ttk_EnumerateTags(Tcl_Interp *, Ttk_TagTable); + +MODULE_SCOPE int Ttk_ConfigureTag( + Tcl_Interp *interp, Ttk_TagTable tagTable, Ttk_Tag tag, + int objc, Tcl_Obj *const objv[]); + +MODULE_SCOPE Ttk_TagSet Ttk_GetTagSetFromObj( + Tcl_Interp *interp, Ttk_TagTable, Tcl_Obj *objPtr); +MODULE_SCOPE Tcl_Obj *Ttk_NewTagSetObj(Ttk_TagSet); + +MODULE_SCOPE void Ttk_FreeTagSet(Ttk_TagSet); -MODULE_SCOPE int Ttk_GetTagListFromObj( - Tcl_Interp *interp, Ttk_TagTable, Tcl_Obj *objPtr, - int *nTags_rtn, void **taglist_rtn); +MODULE_SCOPE int Ttk_TagSetContains(Ttk_TagSet, Ttk_Tag tag); +MODULE_SCOPE int Ttk_TagSetAdd(Ttk_TagSet, Ttk_Tag tag); +MODULE_SCOPE int Ttk_TagSetRemove(Ttk_TagSet, Ttk_Tag tag); -MODULE_SCOPE void Ttk_FreeTagList(void **taglist); +MODULE_SCOPE void Ttk_TagSetValues(Ttk_TagTable, Ttk_TagSet, void *record); +MODULE_SCOPE void Ttk_TagSetApplyStyle(Ttk_TagTable,Ttk_Style,Ttk_State,void*); /* * Useful widget base classes: diff --git a/library/ttk/altTheme.tcl b/library/ttk/altTheme.tcl index c92e3d5..28e1bc1 100644 --- a/library/ttk/altTheme.tcl +++ b/library/ttk/altTheme.tcl @@ -1,5 +1,5 @@ # -# $Id: altTheme.tcl,v 1.6 2007/12/13 15:27:07 dgp Exp $ +# $Id: altTheme.tcl,v 1.6.2.1 2010/08/26 02:06:10 hobbs Exp $ # # Ttk widget set: Alternate theme # @@ -11,6 +11,7 @@ namespace eval ttk::theme::alt { -frame "#d9d9d9" -window "#ffffff" -darker "#c3c3c3" + -border "#414141" -activebg "#ececec" -disabledfg "#a3a3a3" -selectbg "#4a6984" @@ -23,6 +24,7 @@ namespace eval ttk::theme::alt { -background $colors(-frame) \ -foreground black \ -troughcolor $colors(-darker) \ + -bordercolor $colors(-border) \ -selectbackground $colors(-selectbg) \ -selectforeground $colors(-selectfg) \ -font TkDefaultFont \ @@ -59,6 +61,13 @@ namespace eval ttk::theme::alt { ttk::style configure TCombobox -padding 1 ttk::style map TCombobox -fieldbackground \ [list readonly $colors(-frame) disabled $colors(-frame)] + ttk::style configure ComboboxPopdownFrame \ + -relief solid -borderwidth 1 + + ttk::style configure TSpinbox -arrowsize 10 -padding {2 0 10 0} + ttk::style map TSpinbox -fieldbackground \ + [list readonly $colors(-frame) disabled $colors(-frame)] \ + -arrowcolor [list disabled $colors(-disabledfg)] ttk::style configure Toolbutton -relief flat -padding 2 ttk::style map Toolbutton -relief \ @@ -80,15 +89,8 @@ namespace eval ttk::theme::alt { # Treeview: ttk::style configure Heading -font TkHeadingFont -relief raised - ttk::style configure Row -background $colors(-window) - ttk::style configure Cell -background $colors(-window) - ttk::style map Row \ - -background [list selected $colors(-selectbg)] \ - -foreground [list selected $colors(-selectfg)] ; - ttk::style map Cell \ - -background [list selected $colors(-selectbg)] \ - -foreground [list selected $colors(-selectfg)] ; - ttk::style map Item \ + ttk::style configure Treeview -background $colors(-window) + ttk::style map Treeview \ -background [list selected $colors(-selectbg)] \ -foreground [list selected $colors(-selectfg)] ; diff --git a/library/ttk/aquaTheme.tcl b/library/ttk/aquaTheme.tcl index 8ff2ea0..471e919 100644 --- a/library/ttk/aquaTheme.tcl +++ b/library/ttk/aquaTheme.tcl @@ -1,5 +1,5 @@ # -# $Id: aquaTheme.tcl,v 1.11.2.1 2008/07/22 17:02:31 das Exp $ +# $Id: aquaTheme.tcl,v 1.11.2.2 2010/08/26 02:06:10 hobbs Exp $ # # Aqua theme (OSX native look and feel) # @@ -31,25 +31,20 @@ namespace eval ttk::theme::aqua { ttk::style configure TButton -anchor center -width -6 ttk::style configure Toolbutton -padding 4 - # See Apple HIG figs 14-63, 14-65 - ttk::style configure TNotebook -tabposition n -padding {20 12} - ttk::style configure TNotebook.Tab -padding {10 2 10 2} + + ttk::style configure TNotebook -tabmargins {10 0} -tabposition n + ttk::style configure TNotebook -padding {18 8 18 17} + ttk::style configure TNotebook.Tab -padding {12 3 12 2} # Combobox: ttk::style configure TCombobox -postoffset {5 -2 -10 0} # Treeview: - ttk::style configure Treeview -rowheight 18 ttk::style configure Heading -font TkHeadingFont - ttk::style map Row \ + ttk::style configure Treeview -rowheight 18 -background White + ttk::style map Treeview \ -background {{selected background} systemHighlightSecondary selected systemHighlight} - ttk::style map Cell \ - -foreground {{selected background} systemModelessDialogInactiveText - selected systemModelessDialogActiveText} - ttk::style map Item \ - -foreground {{selected background} systemModelessDialogInactiveText - selected systemModelessDialogActiveText} # Enable animation for ttk::progressbar widget: ttk::style configure TProgressbar -period 100 -maxphase 255 diff --git a/library/ttk/button.tcl b/library/ttk/button.tcl index 494a674..fc9c1bb 100644 --- a/library/ttk/button.tcl +++ b/library/ttk/button.tcl @@ -1,5 +1,5 @@ # -# $Id: button.tcl,v 1.2 2006/11/27 06:53:55 jenglish Exp $ +# $Id: button.tcl,v 1.2.4.1 2010/08/26 02:06:10 hobbs Exp $ # # Bindings for Buttons, Checkbuttons, and Radiobuttons. # @@ -54,7 +54,7 @@ bind TRadiobutton { ttk::button::RadioTraverse %W +1 } proc ttk::button::activate {w} { $w instate disabled { return } set oldState [$w state pressed] - update idletasks; after 100 + update idletasks; after 100 ;# block event loop to avoid reentrancy $w state $oldState $w invoke } diff --git a/library/ttk/clamTheme.tcl b/library/ttk/clamTheme.tcl index c4c8184..ea29abe 100644 --- a/library/ttk/clamTheme.tcl +++ b/library/ttk/clamTheme.tcl @@ -1,5 +1,5 @@ # -# $Id: clamTheme.tcl,v 1.6 2007/12/13 15:27:08 dgp Exp $ +# $Id: clamTheme.tcl,v 1.6.2.1 2010/08/26 02:06:10 hobbs Exp $ # # "Clam" theme. # @@ -105,6 +105,13 @@ namespace eval ttk::theme::clam { readonly $colors(-frame)] \ -foreground [list {readonly focus} $colors(-selectfg)] \ ; + ttk::style configure ComboboxPopdownFrame \ + -relief solid -borderwidth 1 + + ttk::style configure TSpinbox -arrowsize 10 -padding {2 0 10 0} + ttk::style map TSpinbox \ + -background [list readonly $colors(-frame)] \ + -arrowcolor [list disabled $colors(-disabledfg)] ttk::style configure TNotebook.Tab -padding {6 2 6 2} ttk::style map TNotebook.Tab \ @@ -116,15 +123,8 @@ namespace eval ttk::theme::clam { # Treeview: ttk::style configure Heading \ -font TkHeadingFont -relief raised -padding {3} - ttk::style configure Row -background $colors(-window) - ttk::style configure Cell -background $colors(-window) - ttk::style map Row \ - -background [list selected $colors(-selectbg)] \ - -foreground [list selected $colors(-selectfg)] ; - ttk::style map Cell \ - -background [list selected $colors(-selectbg)] \ - -foreground [list selected $colors(-selectfg)] ; - ttk::style map Item \ + ttk::style configure Treeview -background $colors(-window) + ttk::style map Treeview \ -background [list selected $colors(-selectbg)] \ -foreground [list selected $colors(-selectfg)] ; diff --git a/library/ttk/classicTheme.tcl b/library/ttk/classicTheme.tcl index c96d7ff..bd165a5 100644 --- a/library/ttk/classicTheme.tcl +++ b/library/ttk/classicTheme.tcl @@ -1,5 +1,5 @@ # -# $Id: classicTheme.tcl,v 1.6 2007/12/13 15:27:08 dgp Exp $ +# $Id: classicTheme.tcl,v 1.6.2.1 2010/08/26 02:06:10 hobbs Exp $ # # "classic" Tk theme. # @@ -70,6 +70,12 @@ namespace eval ttk::theme::classic { ttk::style configure TCombobox -padding 1 ttk::style map TCombobox -fieldbackground \ [list readonly $colors(-frame) disabled $colors(-frame)] + ttk::style configure ComboboxPopdownFrame \ + -relief solid -borderwidth 1 + + ttk::style configure TSpinbox -arrowsize 10 -padding {2 0 10 0} + ttk::style map TSpinbox -fieldbackground \ + [list readonly $colors(-frame) disabled $colors(-frame)] ttk::style configure TLabelframe -borderwidth 2 -relief groove @@ -87,12 +93,8 @@ namespace eval ttk::theme::classic { # Treeview: ttk::style configure Heading -font TkHeadingFont -relief raised - ttk::style configure Row -background $colors(-window) - ttk::style configure Cell -background $colors(-window) - ttk::style map Row \ - -background [list selected $colors(-selectbg)] \ - -foreground [list selected $colors(-selectfg)] ; - ttk::style map Cell \ + ttk::style configure Treeview -background $colors(-window) + ttk::style map Treeview \ -background [list selected $colors(-selectbg)] \ -foreground [list selected $colors(-selectfg)] ; diff --git a/library/ttk/combobox.tcl b/library/ttk/combobox.tcl index 6f34f69..f04aaaa 100644 --- a/library/ttk/combobox.tcl +++ b/library/ttk/combobox.tcl @@ -1,13 +1,8 @@ # -# $Id: combobox.tcl,v 1.12.2.3 2010/01/20 23:43:51 patthoyts Exp $ +# $Id: combobox.tcl,v 1.12.2.4 2010/08/26 02:06:10 hobbs Exp $ # # Combobox bindings. # -# Each combobox $cb has a child $cb.popdown, which contains -# a listbox $cb.popdown.l and a scrollbar. The listbox -listvariable -# is set to a namespace variable, which is used to synchronize the -# combobox values with the listbox values. -# # <>: # # Need to set [wm transient] just before mapping the popdown @@ -60,12 +55,9 @@ bind TCombobox { ttk::combobox::Press "s" %W %x %y } bind TCombobox { ttk::combobox::Press "2" %W %x %y } bind TCombobox { ttk::combobox::Press "3" %W %x %y } bind TCombobox { ttk::combobox::Drag %W %x } +bind TCombobox { ttk::combobox::Motion %W %x %y } -bind TCombobox { ttk::combobox::Scroll %W [expr {%D/-120}] } -if {[tk windowingsystem] eq "x11"} { - bind TCombobox { ttk::combobox::Scroll %W -1 } - bind TCombobox { ttk::combobox::Scroll %W 1 } -} +ttk::bindMouseWheel TCombobox [list ttk::combobox::Scroll %W] bind TCombobox <> { ttk::combobox::TraverseIn %W } @@ -152,6 +144,19 @@ proc ttk::combobox::Drag {w x} { } } +## Motion -- +# Set cursor. +# +proc ttk::combobox::Motion {w x y} { + if { [$w identify $x $y] eq "textarea" + && [$w instate {!readonly !disabled}] + } { + ttk::setCursor $w text + } else { + ttk::setCursor $w "" + } +} + ## TraverseIn -- receive focus due to keyboard navigation # For editable comboboxes, set the selection and insert cursor. # @@ -216,9 +221,9 @@ proc ttk::combobox::LBTab {lb dir} { LBSelect $lb Unpost $cb # The [grab release] call in [Unpost] queues events that later - # re-set the focus. [update] to make sure these get processed first: - update - ttk::traverseTo $newFocus + # re-set the focus (@@@ NOTE: this might not be true anymore). + # Set new focus later: + after 0 [list ttk::traverseTo $newFocus] } } @@ -265,7 +270,8 @@ proc ttk::combobox::PopdownWindow {cb} { variable scrollbar if {![winfo exists $cb.popdown]} { - set popdown [PopdownToplevel $cb.popdown] + set poplevel [PopdownToplevel $cb.popdown] + set popdown [ttk::frame $poplevel.f -style ComboboxPopdownFrame] $scrollbar $popdown.sb \ -orient vertical -command [list $popdown.l yview] @@ -280,9 +286,14 @@ proc ttk::combobox::PopdownWindow {cb} { bindtags $popdown.l \ [list $popdown.l ComboboxListbox Listbox $popdown all] - grid $popdown.l $popdown.sb -sticky news + grid $popdown.l -row 0 -column 0 -padx {1 0} -pady 1 -sticky nsew + grid $popdown.sb -row 0 -column 1 -padx {0 1} -pady 1 -sticky ns grid columnconfigure $popdown 0 -weight 1 grid rowconfigure $popdown 0 -weight 1 + + grid $popdown -sticky news -padx 0 -pady 0 + grid rowconfigure $poplevel 0 -weight 1 + grid columnconfigure $poplevel 0 -weight 1 } return $cb.popdown } @@ -297,13 +308,14 @@ proc ttk::combobox::PopdownToplevel {w} { switch -- [tk windowingsystem] { default - x11 { - $w configure -relief solid -borderwidth 1 + $w configure -relief flat -borderwidth 0 wm attributes $w -type combo wm overrideredirect $w true } win32 { - $w configure -relief solid -borderwidth 1 + $w configure -relief flat -borderwidth 0 wm overrideredirect $w true + wm attributes $w -topmost 1 } aqua { $w configure -relief solid -borderwidth 0 @@ -322,7 +334,7 @@ proc ttk::combobox::PopdownToplevel {w} { proc ttk::combobox::ConfigureListbox {cb} { variable Values - set popdown [PopdownWindow $cb] + set popdown [PopdownWindow $cb].f set values [$cb cget -values] set current [$cb current] if {$current < 0} { @@ -337,8 +349,10 @@ proc ttk::combobox::ConfigureListbox {cb} { if {$height > [$cb cget -height]} { set height [$cb cget -height] grid $popdown.sb + grid configure $popdown.l -padx {1 0} } else { grid remove $popdown.sb + grid configure $popdown.l -padx 1 } $popdown.l configure -height $height } @@ -383,7 +397,7 @@ proc ttk::combobox::Post {cb} { set popdown [PopdownWindow $cb] ConfigureListbox $cb - update idletasks + update idletasks ;# needed for geometry propagation. PlacePopdown $cb $popdown # See <> switch -- [tk windowingsystem] { @@ -411,7 +425,7 @@ proc ttk::combobox::Unpost {cb} { # Return the combobox main widget that owns the listbox. # proc ttk::combobox::LBMaster {lb} { - winfo parent [winfo parent $lb] + winfo parent [winfo parent [winfo parent $lb]] } ## LBSelect $lb -- diff --git a/library/ttk/cursors.tcl b/library/ttk/cursors.tcl index f5abd54..23198bd 100644 --- a/library/ttk/cursors.tcl +++ b/library/ttk/cursors.tcl @@ -1,5 +1,5 @@ # -# $Id: cursors.tcl,v 1.1.4.1 2009/04/10 16:39:47 das Exp $ +# $Id: cursors.tcl,v 1.1.4.2 2010/08/26 02:06:10 hobbs Exp $ # # Map symbolic cursor names to platform-appropriate cursors. # diff --git a/library/ttk/defaults.tcl b/library/ttk/defaults.tcl index 500562d..30830de 100644 --- a/library/ttk/defaults.tcl +++ b/library/ttk/defaults.tcl @@ -1,5 +1,5 @@ # -# $Id: defaults.tcl,v 1.6 2007/12/13 15:27:08 dgp Exp $ +# $Id: defaults.tcl,v 1.6.2.1 2010/08/26 02:06:10 hobbs Exp $ # # Settings for default theme. # @@ -8,7 +8,9 @@ namespace eval ttk::theme::default { variable colors array set colors { -frame "#d9d9d9" + -foreground "#000000" -window "#ffffff" + -text "#000000" -activebg "#ececec" -selectbg "#4a6984" -selectfg "#ffffff" @@ -22,7 +24,7 @@ namespace eval ttk::theme::default { ttk::style configure "." \ -borderwidth 1 \ -background $colors(-frame) \ - -foreground black \ + -foreground $colors(-foreground) \ -troughcolor $colors(-darker) \ -font TkDefaultFont \ -selectborderwidth 1 \ @@ -64,6 +66,11 @@ namespace eval ttk::theme::default { ttk::style map TCombobox -fieldbackground \ [list readonly $colors(-frame) disabled $colors(-frame)] + ttk::style configure TSpinbox -arrowsize 10 -padding {2 0 10 0} + ttk::style map TSpinbox -fieldbackground \ + [list readonly $colors(-frame) disabled $colors(-frame)] \ + -arrowcolor [list disabled $colors(-disabledfg)] + ttk::style configure TLabelframe \ -relief groove -borderwidth 2 @@ -85,18 +92,20 @@ namespace eval ttk::theme::default { # Treeview. # ttk::style configure Heading -font TkHeadingFont -relief raised - ttk::style configure Row -background $colors(-window) - ttk::style configure Cell -background $colors(-window) - ttk::style map Row \ - -background [list selected $colors(-selectbg)] \ - -foreground [list selected $colors(-selectfg)] ; - ttk::style map Cell \ - -background [list selected $colors(-selectbg)] \ - -foreground [list selected $colors(-selectfg)] ; - ttk::style map Item \ + ttk::style configure Treeview \ + -background $colors(-window) \ + -foreground $colors(-text) ; + ttk::style map Treeview \ -background [list selected $colors(-selectbg)] \ -foreground [list selected $colors(-selectfg)] ; + # Combobox popdown frame + ttk::style layout ComboboxPopdownFrame { + ComboboxPopdownFrame.border -sticky nswe + } + ttk::style configure ComboboxPopdownFrame \ + -borderwidth 1 -relief solid + # # Toolbar buttons: # diff --git a/library/ttk/entry.tcl b/library/ttk/entry.tcl index 37a2419..ef769cd 100644 --- a/library/ttk/entry.tcl +++ b/library/ttk/entry.tcl @@ -1,5 +1,5 @@ # -# $Id: entry.tcl,v 1.4 2007/12/13 15:27:08 dgp Exp $ +# $Id: entry.tcl,v 1.4.2.1 2010/08/26 02:06:10 hobbs Exp $ # # DERIVED FROM: tk/library/entry.tcl r1.22 # @@ -34,6 +34,10 @@ namespace eval ttk { } } +### Option database settings. +# +option add *TEntry.cursor [ttk::cursor text] + ### Bindings. # # Removed the following standard Tk bindings: @@ -91,19 +95,19 @@ bind TEntry <> { ttk::entry::ScanRelease %W %x } ## Keyboard navigation bindings: # -bind TEntry { ttk::entry::Move %W prevchar } -bind TEntry { ttk::entry::Move %W nextchar } -bind TEntry { ttk::entry::Move %W prevword } -bind TEntry { ttk::entry::Move %W nextword } -bind TEntry { ttk::entry::Move %W home } -bind TEntry { ttk::entry::Move %W end } +bind TEntry <> { ttk::entry::Move %W prevchar } +bind TEntry <> { ttk::entry::Move %W nextchar } +bind TEntry <> { ttk::entry::Move %W prevword } +bind TEntry <> { ttk::entry::Move %W nextword } +bind TEntry <> { ttk::entry::Move %W home } +bind TEntry <> { ttk::entry::Move %W end } -bind TEntry { ttk::entry::Extend %W prevchar } -bind TEntry { ttk::entry::Extend %W nextchar } -bind TEntry { ttk::entry::Extend %W prevword } -bind TEntry { ttk::entry::Extend %W nextword } -bind TEntry { ttk::entry::Extend %W home } -bind TEntry { ttk::entry::Extend %W end } +bind TEntry <> { ttk::entry::Extend %W prevchar } +bind TEntry <> { ttk::entry::Extend %W nextchar } +bind TEntry <> { ttk::entry::Extend %W prevword } +bind TEntry <> { ttk::entry::Extend %W nextword } +bind TEntry <> { ttk::entry::Extend %W home } +bind TEntry <> { ttk::entry::Extend %W end } bind TEntry { %W selection range 0 end } bind TEntry { %W selection clear } @@ -133,6 +137,9 @@ bind TEntry {# nothing} if {[tk windowingsystem] eq "aqua"} { bind TEntry {# nothing} } +# Tk-on-Cocoa generates characters for these two keys. [Bug 2971663] +bind TEntry {# nothing} +bind TEntry {# nothing} ## Additional emacs-like bindings: # @@ -224,7 +231,7 @@ proc ttk::entry::See {w {index insert}} { # position following the next end-of-word position. # set ::ttk::entry::State(startNext) \ - [string equal $tcl_platform(platform) "windows"] + [string equal $::tcl_platform(platform) "windows"] proc ttk::entry::NextWord {w start} { variable State diff --git a/library/ttk/notebook.tcl b/library/ttk/notebook.tcl index 4fe58cc..cf5ffc1 100644 --- a/library/ttk/notebook.tcl +++ b/library/ttk/notebook.tcl @@ -1,5 +1,5 @@ # -# $Id: notebook.tcl,v 1.4 2007/02/24 09:15:07 das Exp $ +# $Id: notebook.tcl,v 1.4.4.1 2010/08/26 02:06:10 hobbs Exp $ # # Bindings for TNotebook widget # @@ -21,21 +21,26 @@ bind TNotebook { ttk::notebook::Cleanup %W } # ActivateTab $nb $tab -- # Select the specified tab and set focus. # -# If $tab was already the current tab, set the focus to the -# notebook widget. Otherwise, set the focus to the first -# traversable widget in the pane. The behavior is that the -# notebook takes focus when the user selects the same tab -# a second time. This mirrors Windows tab behavior. +# Desired behavior: +# + take focus when reselecting the currently-selected tab; +# + keep focus if the notebook already has it; +# + otherwise set focus to the first traversable widget +# in the newly-selected tab; +# + do not leave the focus in a deselected tab. # proc ttk::notebook::ActivateTab {w tab} { - if {[$w index $tab] eq [$w index current]} { - focus $w + set oldtab [$w select] + $w select $tab + set newtab [$w select] ;# NOTE: might not be $tab, if $tab is disabled + + if {[focus] eq $w} { return } + if {$newtab eq $oldtab} { focus $w ; return } + + update idletasks ;# needed so focus logic sees correct mapped states + if {[set f [ttk::focusFirst $newtab]] ne ""} { + ttk::traverseTo $f } else { - $w select $tab - update ;# needed so focus logic sees correct mapped/unmapped states - if {[set f [ttk::focusFirst [$w select]]] ne ""} { - tk::TabToWindow $f - } + focus $w } } @@ -102,6 +107,8 @@ proc ttk::notebook::enableTraversal {nb} { if {![info exists TLNotebooks($top)]} { # Augment $top bindings: # + bind $top {+ttk::notebook::TLCycleTab %W 1} + bind $top {+ttk::notebook::TLCycleTab %W -1} bind $top {+ttk::notebook::TLCycleTab %W 1} bind $top {+ttk::notebook::TLCycleTab %W -1} catch { diff --git a/library/ttk/panedwindow.tcl b/library/ttk/panedwindow.tcl index 423baa9..06c6c50 100644 --- a/library/ttk/panedwindow.tcl +++ b/library/ttk/panedwindow.tcl @@ -1,5 +1,5 @@ # -# $Id: panedwindow.tcl,v 1.5 2007/12/13 15:27:08 dgp Exp $ +# $Id: panedwindow.tcl,v 1.5.2.1 2010/08/26 02:06:10 hobbs Exp $ # # Bindings for ttk::panedwindow widget. # @@ -27,7 +27,6 @@ bind TPanedwindow { ttk::panedwindow::ResetCursor %W } # See <> bind TPanedwindow <> { ttk::panedwindow::ResetCursor %W } - ## Sash movement: # proc ttk::panedwindow::Press {w x y} { @@ -66,22 +65,20 @@ proc ttk::panedwindow::Release {w x y} { proc ttk::panedwindow::ResetCursor {w} { variable State if {!$State(pressed)} { - $w configure -cursor {} + ttk::setCursor $w {} } } proc ttk::panedwindow::SetCursor {w x y} { - variable ::ttk::Cursors - - if {![llength [$w identify $x $y]]} { - ResetCursor $w - } else { + set cursor "" + if {[llength [$w identify $x $y]]} { # Assume we're over a sash. switch -- [$w cget -orient] { - horizontal { $w configure -cursor $Cursors(hresize) } - vertical { $w configure -cursor $Cursors(vresize) } + horizontal { set cursor hresize } + vertical { set cursor vresize } } } + ttk::setCursor $w $cursor } #*EOF* diff --git a/library/ttk/scale.tcl b/library/ttk/scale.tcl index b660809..2025588 100644 --- a/library/ttk/scale.tcl +++ b/library/ttk/scale.tcl @@ -2,7 +2,7 @@ # # Bindings for the TScale widget # -# $Id: scale.tcl,v 1.1.4.1 2008/10/17 12:44:04 patthoyts Exp $ +# $Id: scale.tcl,v 1.1.4.2 2010/08/26 02:06:10 hobbs Exp $ namespace eval ttk::scale { variable State diff --git a/library/ttk/sizegrip.tcl b/library/ttk/sizegrip.tcl index f167b00..1b9119b 100644 --- a/library/ttk/sizegrip.tcl +++ b/library/ttk/sizegrip.tcl @@ -1,14 +1,22 @@ # -# $Id: sizegrip.tcl,v 1.1.4.1 2009/12/23 04:30:51 jenglish Exp $ +# $Id: sizegrip.tcl,v 1.1.4.2 2010/08/26 02:06:10 hobbs Exp $ # -# Ttk widget set -- sizegrip widget bindings. +# Sizegrip widget bindings. # # Dragging a sizegrip widget resizes the containing toplevel. # # NOTE: the sizegrip widget must be in the lower right hand corner. # -option add *TSizegrip.cursor $::ttk::Cursors(seresize) +switch -- [tk windowingsystem] { + x11 - + win32 { + option add *TSizegrip.cursor [ttk::cursor seresize] + } + aqua { + # Aqua sizegrips use default Arrow cursor. + } +} namespace eval ttk::sizegrip { variable State @@ -20,6 +28,8 @@ namespace eval ttk::sizegrip { height 0 widthInc 1 heightInc 1 + resizeX 1 + resizeY 1 toplevel {} } } @@ -31,8 +41,16 @@ bind TSizegrip { ttk::sizegrip::Release %W %X %Y } proc ttk::sizegrip::Press {W X Y} { variable State + if {[$W instate disabled]} { return } + set top [winfo toplevel $W] + # If the toplevel is not resizable then bail + foreach {State(resizeX) State(resizeY)} [wm resizable $top] break + if {!$State(resizeX) && !$State(resizeY)} { + return + } + # Sanity-checks: # If a negative X or Y position was specified for [wm geometry], # just bail out -- there's no way to handle this cleanly. @@ -64,8 +82,14 @@ proc ttk::sizegrip::Press {W X Y} { proc ttk::sizegrip::Drag {W X Y} { variable State if {!$State(pressed)} { return } - set w [expr {$State(width) + ($X - $State(pressX))/$State(widthInc)}] - set h [expr {$State(height) + ($Y - $State(pressY))/$State(heightInc)}] + set w $State(width) + set h $State(height) + if {$State(resizeX)} { + set w [expr {$w + ($X - $State(pressX))/$State(widthInc)}] + } + if {$State(resizeY)} { + set h [expr {$h + ($Y - $State(pressY))/$State(heightInc)}] + } if {$w <= 0} { set w 1 } if {$h <= 0} { set h 1 } set x $State(x) ; set y $State(y) diff --git a/library/ttk/spinbox.tcl b/library/ttk/spinbox.tcl new file mode 100644 index 0000000..a717379 --- /dev/null +++ b/library/ttk/spinbox.tcl @@ -0,0 +1,175 @@ +# +# $Id: spinbox.tcl,v 1.3.2.2 2010/08/26 02:06:10 hobbs Exp $ +# +# ttk::spinbox bindings +# + +namespace eval ttk::spinbox { } + +### Spinbox bindings. +# +# Duplicate the Entry bindings, override if needed: +# + +ttk::copyBindings TEntry TSpinbox + +bind TSpinbox { ttk::spinbox::Motion %W %x %y } +bind TSpinbox { ttk::spinbox::Press %W %x %y } +bind TSpinbox { ttk::spinbox::Release %W } +bind TSpinbox { ttk::spinbox::DoubleClick %W %x %y } +bind TSpinbox {} ;# disable TEntry triple-click + +bind TSpinbox { event generate %W <> } +bind TSpinbox { event generate %W <> } + +bind TSpinbox <> { ttk::spinbox::Spin %W +1 } +bind TSpinbox <> { ttk::spinbox::Spin %W -1 } + +ttk::bindMouseWheel TSpinbox [list ttk::spinbox::MouseWheel %W] + +## Motion -- +# Sets cursor. +# +proc ttk::spinbox::Motion {w x y} { + if { [$w identify $x $y] eq "textarea" + && [$w instate {!readonly !disabled}] + } { + ttk::setCursor $w text + } else { + ttk::setCursor $w "" + } +} + +## Press -- +# +proc ttk::spinbox::Press {w x y} { + if {[$w instate disabled]} { return } + focus $w + switch -glob -- [$w identify $x $y] { + *textarea { ttk::entry::Press $w $x } + *rightarrow - + *uparrow { ttk::Repeatedly event generate $w <> } + *leftarrow - + *downarrow { ttk::Repeatedly event generate $w <> } + *spinbutton { + if {$y * 2 >= [winfo height $w]} { + set event <> + } else { + set event <> + } + ttk::Repeatedly event generate $w $event + } + } +} + +## DoubleClick -- +# Select all if over the text area; otherwise same as Press. +# +proc ttk::spinbox::DoubleClick {w x y} { + if {[$w instate disabled]} { return } + + switch -glob -- [$w identify $x $y] { + *textarea { SelectAll $w } + * { Press $w $x $y } + } +} + +proc ttk::spinbox::Release {w} { + ttk::CancelRepeat +} + +## MouseWheel -- +# Mousewheel callback. Turn these into <> (-1, up) +# or < (+1, down) events. +# +proc ttk::spinbox::MouseWheel {w dir} { + if {$dir < 0} { + event generate $w <> + } else { + event generate $w <> + } +} + +## SelectAll -- +# Select widget contents. +# +proc ttk::spinbox::SelectAll {w} { + $w selection range 0 end + $w icursor end +} + +## Limit -- +# Limit $v to lie between $min and $max +# +proc ttk::spinbox::Limit {v min max} { + if {$v < $min} { return $min } + if {$v > $max} { return $max } + return $v +} + +## Wrap -- +# Adjust $v to lie between $min and $max, wrapping if out of bounds. +# +proc ttk::spinbox::Wrap {v min max} { + if {$v < $min} { return $max } + if {$v > $max} { return $min } + return $v +} + +## Adjust -- +# Limit or wrap spinbox value depending on -wrap. +# +proc ttk::spinbox::Adjust {w v min max} { + if {[$w cget -wrap]} { + return [Wrap $v $min $max] + } else { + return [Limit $v $min $max] + } +} + +## Spin -- +# Handle <> and <> events. +# If -values is specified, cycle through the list. +# Otherwise cycle through numeric range based on +# -from, -to, and -increment. +# +proc ttk::spinbox::Spin {w dir} { + set nvalues [llength [set values [$w cget -values]]] + set value [$w get] + if {$nvalues} { + set current [lsearch -exact $values $value] + set index [Adjust $w [expr {$current + $dir}] 0 [expr {$nvalues - 1}]] + $w set [lindex $values $index] + } else { + if {[catch { + set v [expr {[scan [$w get] %f] + $dir * [$w cget -increment]}] + }]} { + set v [$w cget -from] + } + $w set [FormatValue $w [Adjust $w $v [$w cget -from] [$w cget -to]]] + } + SelectAll $w + uplevel #0 [$w cget -command] +} + +## FormatValue -- +# Reformat numeric value based on -format. +# +proc ttk::spinbox::FormatValue {w val} { + set fmt [$w cget -format] + if {$fmt eq ""} { + # Try to guess a suitable -format based on -increment. + set delta [expr {abs([$w cget -increment])}] + if {0 < $delta && $delta < 1} { + # NB: This guesses wrong if -increment has more than 1 + # significant digit itself, e.g., -increment 0.25 + set nsd [expr {int(ceil(-log10($delta)))}] + set fmt "%.${nsd}f" + } else { + set fmt "%.0f" + } + } + return [format $fmt $val] +} + +#*EOF* diff --git a/library/ttk/treeview.tcl b/library/ttk/treeview.tcl index 796b356..632bf7a 100644 --- a/library/ttk/treeview.tcl +++ b/library/ttk/treeview.tcl @@ -1,4 +1,4 @@ -# $Id: treeview.tcl,v 1.4.2.1 2008/06/20 14:14:20 jenglish Exp $ +# $Id: treeview.tcl,v 1.4.2.2 2010/08/26 02:06:10 hobbs Exp $ # # ttk::treeview widget bindings and utilities. # @@ -21,15 +21,6 @@ namespace eval ttk::treeview { # For pressmode == "heading" set State(heading) {} - - # Provide [lassign] if not already present - # (@@@ TODO: check if this is still needed after horrible-identify purge) - # - if {![llength [info commands lassign]]} { - proc lassign {vals args} { - uplevel 1 [list foreach $args $vals break] - } - } } ### Widget bindings. @@ -112,21 +103,15 @@ proc ttk::treeview::Keynav {w dir} { # Sets cursor, active element ... # proc ttk::treeview::Motion {w x y} { - variable ::ttk::Cursors - variable State - set cursor {} set activeHeading {} - lassign [$w identify $x $y] what where detail - switch -- $what { - separator { set cursor $Cursors(hresize) } - heading { set activeHeading $where } + switch -- [$w identify region $x $y] { + separator { set cursor hresize } + heading { set activeHeading [$w identify column $x $y] } } - if {[$w cget -cursor] ne $cursor} { - $w configure -cursor $cursor - } + ttk::setCursor $w $cursor ActivateHeading $w $activeHeading } @@ -170,19 +155,20 @@ proc ttk::treeview::DoubleClick {w x y} { ## Press -- ButtonPress binding. # proc ttk::treeview::Press {w x y} { - lassign [$w identify $x $y] what where detail - focus $w ;# or: ClickToFocus? - - switch -- $what { + focus $w + switch -- [$w identify region $x $y] { nothing { } - heading { heading.press $w $where } - separator { resize.press $w $x $where } - cell - - row - - item { SelectOp $w $where choose } - } - if {$what eq "item" && [string match *indicator $detail]} { - Toggle $w $where + heading { heading.press $w $x $y } + separator { resize.press $w $x $y } + tree - + cell { + set item [$w identify item $x $y] + SelectOp $w $item choose + switch -glob -- [$w identify element $x $y] { + *indicator - + *disclosure { Toggle $w $item } + } + } } } @@ -208,10 +194,10 @@ proc ttk::treeview::Release {w x y} { ### Interactive column resizing. # -proc ttk::treeview::resize.press {w x column} { +proc ttk::treeview::resize.press {w x y} { variable State set State(pressMode) "resize" - set State(resizeColumn) $column + set State(resizeColumn) [$w identify column $x $y] } proc ttk::treeview::resize.drag {w x} { @@ -226,8 +212,9 @@ proc ttk::treeview::resize.release {w x} { ### Heading activation. # -proc ttk::treeview::heading.press {w column} { +proc ttk::treeview::heading.press {w x y} { variable State + set column [$w identify column $x $y] set State(pressMode) "heading" set State(heading) $column $w heading $column state pressed @@ -235,8 +222,9 @@ proc ttk::treeview::heading.press {w column} { proc ttk::treeview::heading.drag {w x y} { variable State - lassign [$w identify $x $y] what where detail - if {$what eq "heading" && $where eq $State(heading)} { + if { [$w identify region $x $y] eq "heading" + && [$w identify column $x $y] eq $State(heading) + } { $w heading $State(heading) state pressed } else { $w heading $State(heading) state !pressed @@ -246,7 +234,7 @@ proc ttk::treeview::heading.drag {w x y} { proc ttk::treeview::heading.release {w} { variable State if {[lsearch -exact [$w heading $State(heading) state] pressed] >= 0} { - after idle [$w heading $State(heading) -command] + after 0 [$w heading $State(heading) -command] } $w heading $State(heading) state !pressed } diff --git a/library/ttk/ttk.tcl b/library/ttk/ttk.tcl index 70e5121..6740d17 100644 --- a/library/ttk/ttk.tcl +++ b/library/ttk/ttk.tcl @@ -1,5 +1,5 @@ # -# $Id: ttk.tcl,v 1.8.2.1 2009/05/14 00:53:04 patthoyts Exp $ +# $Id: ttk.tcl,v 1.8.2.2 2010/08/26 02:06:10 hobbs Exp $ # # Ttk widget set initialization script. # @@ -44,8 +44,11 @@ proc ttk::deprecated'warning {old new} { ### Backward-compatibility. # - -package ifneeded tile 0.8.0 { package require Tk ; package provide tile 0.8.0 } +# +# Make [package require tile] an effective no-op; +# see SF#3016598 for discussion. +# +package ifneeded tile 0.8.6 { package provide tile 0.8.6 } # ttk::panedwindow used to be named ttk::paned. Keep the alias for now. # @@ -105,6 +108,7 @@ source [file join $::ttk::library notebook.tcl] source [file join $::ttk::library panedwindow.tcl] source [file join $::ttk::library entry.tcl] source [file join $::ttk::library combobox.tcl] ;# dependency: entry.tcl +source [file join $::ttk::library spinbox.tcl] ;# dependency: entry.tcl source [file join $::ttk::library treeview.tcl] source [file join $::ttk::library sizegrip.tcl] @@ -143,7 +147,7 @@ ttk::LoadThemes; rename ::ttk::LoadThemes {} ### Select platform-specific default theme: # -# Notes: +# Notes: # + On OSX, aqua theme is the default # + On Windows, xpnative takes precedence over winnative if available. # + On X11, users can use the X resource database to diff --git a/library/ttk/utils.tcl b/library/ttk/utils.tcl index 1de8ec8..60aa5a7 100644 --- a/library/ttk/utils.tcl +++ b/library/ttk/utils.tcl @@ -1,22 +1,52 @@ # -# $Id: utils.tcl,v 1.6 2008/01/06 19:16:12 jenglish Exp $ +# $Id: utils.tcl,v 1.6.2.1 2010/08/26 02:06:10 hobbs Exp $ # # Utilities for widget implementations. # ### Focus management. # +# See also: #1516479 +# ## ttk::takefocus -- # This is the default value of the "-takefocus" option -# for widgets that participate in keyboard navigation. +# for ttk::* widgets that participate in keyboard navigation. +# +# NOTES: +# tk::FocusOK (called by tk_focusNext) tests [winfo viewable] +# if -takefocus is 1, empty, or missing; but not if it's a +# script prefix, so we have to check that here as well. # -# See also: tk::FocusOK # proc ttk::takefocus {w} { expr {[$w instate !disabled] && [winfo viewable $w]} } +## ttk::GuessTakeFocus -- +# This routine is called as a fallback for widgets +# with a missing or empty -takefocus option. +# +# It implements the same heuristics as tk::FocusOK. +# +proc ttk::GuessTakeFocus {w} { + # Don't traverse to widgets with '-state disabled': + # + if {![catch {$w cget -state} state] && $state eq "disabled"} { + return 0 + } + + # Allow traversal to widgets with explicit key or focus bindings: + # + if {[regexp {Key|Focus} [concat [bind $w] [bind [winfo class $w]]]]} { + return 1; + } + + # Default is nontraversable: + # + return 0; +} + ## ttk::traverseTo $w -- # Set the keyboard focus to the specified window. # @@ -38,36 +68,26 @@ proc ttk::clickToFocus {w} { } ## ttk::takesFocus w -- -# Test if the widget can take keyboard focus: +# Test if the widget can take keyboard focus. # -# + widget is viewable, AND: -# - if -takefocus is missing or empty, return 0, OR -# - if -takefocus is 0 or 1, return that value, OR -# - append the widget name to -takefocus and evaluate it -# as a script. -# -# See also: tk::FocusOK -# -# Note: This routine doesn't implement the same fallback heuristics -# as tk::FocusOK. +# See the description of the -takefocus option in options(n) +# for details. # proc ttk::takesFocus {w} { - - if {![winfo viewable $w]} { return 0 } - - if {![catch {$w cget -takefocus} takefocus]} { + if {![winfo viewable $w]} { + return 0 + } elseif {[catch {$w cget -takefocus} takefocus]} { + return [GuessTakeFocus $w] + } else { switch -- $takefocus { - 0 - - 1 { return $takefocus } - "" { return 0 } + "" { return [GuessTakeFocus $w] } + 0 { return 0 } + 1 { return 1 } default { - set value [uplevel #0 $takefocus [list $w]] - return [expr {$value eq 1}] + return [expr {[uplevel #0 $takefocus [list $w]] == 1}] } } } - - return 0 } ## ttk::focusFirst $w -- @@ -251,10 +271,7 @@ proc ttk::copyBindings {from to} { } } -## Standard mousewheel bindings. -# -# Usage: [ttk::copyBindings TtkScrollable $bindtag] -# adds mousewheel support to a scrollable widget. +### Mousewheel bindings. # # Platform inconsistencies: # @@ -278,6 +295,35 @@ proc ttk::copyBindings {from to} { # Gtk+ and Qt do not appear to use as large a factor). # +## ttk::bindMouseWheel $bindtag $command... +# Adds basic mousewheel support to $bindtag. +# $command will be passed one additional argument +# specifying the mousewheel direction (-1: up, +1: down). +# + +proc ttk::bindMouseWheel {bindtag callback} { + switch -- [tk windowingsystem] { + x11 { + bind $bindtag "$callback -1" + bind $bindtag "$callback +1" + } + win32 { + bind $bindtag [append callback { [expr {-(%D/120)}]}] + } + aqua { + bind $bindtag [append callback { [expr {-(%D)}]} ] + } + } +} + +## Mousewheel bindings for standard scrollable widgets. +# +# Usage: [ttk::copyBindings TtkScrollable $bindtag] +# +# $bindtag should be for a widget that supports the +# standard scrollbar protocol. +# + switch -- [tk windowingsystem] { x11 { bind TtkScrollable { %W yview scroll -5 units } diff --git a/library/ttk/vistaTheme.tcl b/library/ttk/vistaTheme.tcl index 9b9418d..107f227 100644 --- a/library/ttk/vistaTheme.tcl +++ b/library/ttk/vistaTheme.tcl @@ -57,18 +57,6 @@ namespace eval ttk::theme::vista { -background [list selected SystemHighlight] \ -foreground [list selected SystemHighlightText] ; - ttk::style configure Row -background SystemWindow - ttk::style configure Cell -background SystemWindow - ttk::style map Row \ - -background [list selected SystemHighlight] \ - -foreground [list selected SystemHighlightText] ; - ttk::style map Cell \ - -background [list selected SystemHighlight] \ - -foreground [list selected SystemHighlightText] ; - ttk::style map Item \ - -background [list selected SystemHighlight] \ - -foreground [list selected SystemHighlightText] ; - # Label and Toolbutton ttk::style configure TLabelframe.Label -foreground "#0046d5" @@ -230,4 +218,4 @@ namespace eval ttk::theme::vista { unset -nocomplain cx cy package provide ttk::theme::vista 1.0 } -} \ No newline at end of file +} diff --git a/library/ttk/winTheme.tcl b/library/ttk/winTheme.tcl index 20f45de..9ccb98e 100644 --- a/library/ttk/winTheme.tcl +++ b/library/ttk/winTheme.tcl @@ -1,5 +1,5 @@ # -# $Id: winTheme.tcl,v 1.6 2007/12/13 15:27:08 dgp Exp $ +# $Id: winTheme.tcl,v 1.6.2.1 2010/08/26 02:06:10 hobbs Exp $ # # Settings for 'winnative' theme. # @@ -45,6 +45,12 @@ namespace eval ttk::theme::winnative { -focusfill [list {readonly focus} SystemHighlight] \ ; + ttk::style element create ComboboxPopdownFrame.border from default + ttk::style configure ComboboxPopdownFrame \ + -borderwidth 1 -relief solid + + ttk::style configure TSpinbox -padding {2 0 16 0} + ttk::style configure TLabelframe -borderwidth 2 -relief groove ttk::style configure Toolbutton -relief flat -padding {8 4} @@ -59,15 +65,8 @@ namespace eval ttk::theme::winnative { # Treeview: ttk::style configure Heading -font TkHeadingFont -relief raised - ttk::style configure Row -background SystemWindow - ttk::style configure Cell -background SystemWindow - ttk::style map Row \ - -background [list selected SystemHighlight] \ - -foreground [list selected SystemHighlightText] ; - ttk::style map Cell \ - -background [list selected SystemHighlight] \ - -foreground [list selected SystemHighlightText] ; - ttk::style map Item \ + ttk::style configure Treeview -background SystemWindow + ttk::style map Treeview \ -background [list selected SystemHighlight] \ -foreground [list selected SystemHighlightText] ; diff --git a/library/ttk/xpTheme.tcl b/library/ttk/xpTheme.tcl index 8a0400e..edf5fa4 100644 --- a/library/ttk/xpTheme.tcl +++ b/library/ttk/xpTheme.tcl @@ -1,5 +1,5 @@ # -# $Id: xpTheme.tcl,v 1.6.2.3 2009/12/03 23:58:35 patthoyts Exp $ +# $Id: xpTheme.tcl,v 1.6.2.4 2010/08/26 02:06:10 hobbs Exp $ # # Settings for 'xpnative' theme # @@ -36,18 +36,6 @@ namespace eval ttk::theme::xpnative { -background [list selected SystemHighlight] \ -foreground [list selected SystemHighlightText] ; - ttk::style configure Row -background SystemWindow - ttk::style configure Cell -background SystemWindow - ttk::style map Row \ - -background [list selected SystemHighlight] \ - -foreground [list selected SystemHighlightText] ; - ttk::style map Cell \ - -background [list selected SystemHighlight] \ - -foreground [list selected SystemHighlightText] ; - ttk::style map Item \ - -background [list selected SystemHighlight] \ - -foreground [list selected SystemHighlightText] ; - ttk::style configure TLabelframe.Label -foreground "#0046d5" # OR: -padding {3 3 3 6}, which some apps seem to use. @@ -64,6 +52,13 @@ namespace eval ttk::theme::xpnative { -focusfill [list {readonly focus} SystemHighlight] \ ; + ttk::style configure TSpinbox -padding {2 0 14 0} + ttk::style map TSpinbox \ + -selectbackground [list !focus SystemWindow] \ + -selectforeground [list !focus SystemWindowText] \ + ; + ttk::style configure Toolbutton -padding {4 4} + } } diff --git a/macosx/ttkMacOSXTheme.c b/macosx/ttkMacOSXTheme.c index 843dea7..a6dafaf 100644 --- a/macosx/ttkMacOSXTheme.c +++ b/macosx/ttkMacOSXTheme.c @@ -27,7 +27,7 @@ * top-level window, not to the Tk_Window. BoxToRect() * accounts for this. * - * RCS: @(#) $Id: ttkMacOSXTheme.c,v 1.21.2.3 2009/10/24 20:52:06 dkf Exp $ + * RCS: @(#) $Id: ttkMacOSXTheme.c,v 1.21.2.4 2010/08/26 02:06:10 hobbs Exp $ */ #include "tkMacOSXPrivate.h" @@ -479,6 +479,57 @@ static Ttk_ElementSpec ComboboxElementSpec = { }; /*---------------------------------------------------------------------- + * +++ Spinbuttons. + * + * From Apple HIG, part III, section "Controls", "The Stepper Control": + * there should be 2 pixels of space between the stepper control + * (AKA IncDecButton, AKA "little arrows") and the text field it modifies. + */ + +static Ttk_Padding SpinbuttonMargins = {2,0,2,0}; +static void SpinButtonElementSize( + void *clientData, void *elementRecord, Tk_Window tkwin, + int *widthPtr, int *heightPtr, Ttk_Padding *paddingPtr) +{ + SInt32 s; + + ChkErr(GetThemeMetric, kThemeMetricLittleArrowsWidth, &s); + *widthPtr = s + Ttk_PaddingWidth(SpinbuttonMargins); + ChkErr(GetThemeMetric, kThemeMetricLittleArrowsHeight, &s); + *heightPtr = s + Ttk_PaddingHeight(SpinbuttonMargins); +} + +static void SpinButtonElementDraw( + void *clientData, void *elementRecord, Tk_Window tkwin, + Drawable d, Ttk_Box b, Ttk_State state) +{ + Rect bounds = BoxToRect(d, Ttk_PadBox(b, SpinbuttonMargins)); + ThemeButtonDrawInfo info; + + /* @@@ can't currently distinguish PressedUp (== Pressed) from PressedDown; + * ignore this bit for now [see #2219588] + */ + info.state = Ttk_StateTableLookup(ThemeStateTable, + state & ~TTK_STATE_PRESSED); + info.value = Ttk_StateTableLookup(ButtonValueTable, state); + info.adornment = kThemeAdornmentNone; + + BEGIN_DRAWING(d) + ChkErr(DrawThemeButton, + &bounds, kThemeIncDecButton, &info, NULL, NULL, NULL, 0); + END_DRAWING +} + +static Ttk_ElementSpec SpinButtonElementSpec = { + TK_STYLE_VERSION_2, + sizeof(NullElement), + TtkNullElementOptions, + SpinButtonElementSize, + SpinButtonElementDraw +}; + + +/*---------------------------------------------------------------------- * +++ DrawThemeTrack-based elements -- * Progress bars and scales. (See also: <>) */ @@ -553,15 +604,14 @@ static void TrackElementDraw( info.enableState = Ttk_StateTableLookup(ThemeTrackEnableTable, state); switch (data->kind) { - case kThemeProgressBar: - info.trackInfo.progress.phase = 0; /* 1-4: animation phase */ - break; - case kThemeSlider: - info.trackInfo.slider.pressState = state & TTK_STATE_PRESSED ? - kThemeThumbPressed : 0; - info.trackInfo.slider.thumbDir = kThemeThumbPlain; + case kThemeProgressBar: + info.trackInfo.progress.phase = 0; /* 1-4: animation phase */ + break; + case kThemeSlider: + info.trackInfo.slider.pressState = 0; /* @@@ fill this in */ + info.trackInfo.slider.thumbDir = kThemeThumbPlain; /* kThemeThumbUpward, kThemeThumbDownward, kThemeThumbPlain */ - break; + break; } BEGIN_DRAWING(d) @@ -909,8 +959,11 @@ static void DisclosureElementSize( int *widthPtr, int *heightPtr, Ttk_Padding *paddingPtr) { SInt32 s; - GetThemeMetric(kThemeMetricDisclosureTriangleWidth, &s); *widthPtr = s; - GetThemeMetric(kThemeMetricDisclosureTriangleHeight, &s); *heightPtr = s; + + ChkErr(GetThemeMetric, kThemeMetricDisclosureTriangleWidth, &s); + *widthPtr = s; + ChkErr(GetThemeMetric, kThemeMetricDisclosureTriangleHeight, &s); + *heightPtr = s; } static void DisclosureElementDraw( @@ -983,6 +1036,11 @@ TTK_LAYOUT("Tab", TTK_NODE("Notebook.label", TTK_EXPAND|TTK_FILL_BOTH)))) /* Progress bars -- track only */ +TTK_LAYOUT("TSpinbox", + TTK_NODE("Spinbox.spinbutton", TTK_PACK_RIGHT|TTK_STICK_E) + TTK_GROUP("Spinbox.field", TTK_EXPAND|TTK_FILL_X, + TTK_NODE("Spinbox.textarea", TTK_EXPAND|TTK_FILL_X))) + TTK_LAYOUT("TProgressbar", TTK_NODE("Progressbar.track", TTK_EXPAND|TTK_FILL_BOTH)) @@ -992,7 +1050,7 @@ TTK_LAYOUT("Heading", TTK_NODE("Treeheading.image", TTK_PACK_RIGHT) TTK_NODE("Treeheading.text", 0)) -/* Tree items -- omit focus ring */ +/* Tree items -- omit focus ring */ TTK_LAYOUT("Item", TTK_GROUP("Treeitem.padding", TTK_FILL_BOTH, TTK_NODE("Treeitem.indicator", TTK_PACK_LEFT) @@ -1031,6 +1089,8 @@ static int AquaTheme_Init(Tcl_Interp *interp) &ButtonElementSpec, &BevelButtonParms); Ttk_RegisterElementSpec(themePtr, "Menubutton.button", &ButtonElementSpec, &PopupButtonParms); + Ttk_RegisterElementSpec(themePtr, "Spinbox.spinbutton", + &SpinButtonElementSpec, 0); Ttk_RegisterElementSpec(themePtr, "Combobox.button", &ComboboxElementSpec, 0); Ttk_RegisterElementSpec(themePtr, "Treeitem.indicator", @@ -1043,6 +1103,7 @@ static int AquaTheme_Init(Tcl_Interp *interp) Ttk_RegisterElementSpec(themePtr, "Labelframe.border",&GroupElementSpec,0); Ttk_RegisterElementSpec(themePtr, "Entry.field",&EntryElementSpec,0); + Ttk_RegisterElementSpec(themePtr, "Spinbox.field",&EntryElementSpec,0); Ttk_RegisterElementSpec(themePtr, "separator",&SeparatorElementSpec,0); Ttk_RegisterElementSpec(themePtr, "hseparator",&SeparatorElementSpec,0); diff --git a/tests/ttk/checkbutton.test b/tests/ttk/checkbutton.test new file mode 100644 index 0000000..49c62dd --- /dev/null +++ b/tests/ttk/checkbutton.test @@ -0,0 +1,49 @@ +# $Id: checkbutton.test,v 1.1.2.2 2010/08/26 02:06:10 hobbs Exp $ +# +# ttk::checkbutton widget tests. +# + +package require Tk +package require tcltest ; namespace import -force tcltest::* +loadTestedCommands + +test checkbutton-1.1 "Checkbutton check" -body { + pack [ttk::checkbutton .cb -text "TCheckbutton" -variable cb] +} +test checkbutton-1.2 "Checkbutton invoke" -body { + .cb invoke + list [set ::cb] [.cb instate selected] +} -result [list 1 1] +test checkbutton-1.3 "Checkbutton reinvoke" -body { + .cb invoke + list [set ::cb] [.cb instate selected] +} -result [list 0 0] + +test checkbutton-1.4 "Checkbutton variable" -body { + set result [] + set ::cb 1 + lappend result [.cb instate selected] + set ::cb 0 + lappend result [.cb instate selected] +} -result {1 0} + +test checkbutton-1.5 "Unset checkbutton variable" -body { + set result [] + unset ::cb + lappend result [.cb instate alternate] [info exists ::cb] + set ::cb 1 + lappend result [.cb instate alternate] [info exists ::cb] +} -result {1 0 0 1} + +# See #1257319 +test checkbutton-1.6 "Checkbutton default variable" -body { + destroy .cb ; unset -nocomplain {} ; set result [list] + ttk::checkbutton .cb -onvalue on -offvalue off + lappend result [.cb cget -variable] [info exists .cb] [.cb state] + .cb invoke + lappend result [info exists .cb] [set .cb] [.cb state] + .cb invoke + lappend result [info exists .cb] [set .cb] [.cb state] +} -result [list .cb 0 alternate 1 on selected 1 off {}] + +tcltest::cleanupTests diff --git a/tests/ttk/combobox.test b/tests/ttk/combobox.test index 8f25a81..43f3cf1 100644 --- a/tests/ttk/combobox.test +++ b/tests/ttk/combobox.test @@ -56,8 +56,8 @@ test combobox-1890211 "ComboboxSelected event after listbox unposted" -body { lappend result Start 0 [.cb get] ttk::combobox::Post .cb lappend result Post [winfo ismapped .cb.popdown] [.cb get] - .cb.popdown.l selection clear 0 end; .cb.popdown.l selection set 1 - ttk::combobox::LBSelected .cb.popdown.l + .cb.popdown.f.l selection clear 0 end; .cb.popdown.f.l selection set 1 + ttk::combobox::LBSelected .cb.popdown.f.l lappend result Select [winfo ismapped .cb.popdown] [.cb get] update set result diff --git a/tests/ttk/radiobutton.test b/tests/ttk/radiobutton.test new file mode 100644 index 0000000..6858659 --- /dev/null +++ b/tests/ttk/radiobutton.test @@ -0,0 +1,49 @@ +# $Id: radiobutton.test,v 1.1.2.2 2010/08/26 02:06:10 hobbs Exp $ +# +# ttk::radiobutton widget tests. +# + +package require Tk +package require tcltest ; namespace import -force tcltest::* +loadTestedCommands + +test radiobutton-1.1 "Radiobutton check" -body { + pack \ + [ttk::radiobutton .rb1 -text "One" -variable choice -value 1] \ + [ttk::radiobutton .rb2 -text "Two" -variable choice -value 2] \ + [ttk::radiobutton .rb3 -text "Three" -variable choice -value 3] \ + ; +} +test radiobutton-1.2 "Radiobutton invoke" -body { + .rb1 invoke + set ::choice +} -result 1 + +test radiobutton-1.3 "Radiobutton state" -body { + .rb1 instate selected +} -result 1 + +test radiobutton-1.4 "Other radiobutton invoke" -body { + .rb2 invoke + set ::choice +} -result 2 + +test radiobutton-1.5 "Other radiobutton state" -body { + .rb2 instate selected +} -result 1 + +test radiobutton-1.6 "First radiobutton state" -body { + .rb1 instate selected +} -result 0 + +test radiobutton-1.7 "Unset radiobutton variable" -body { + unset ::choice + list [info exists ::choice] [.rb1 instate alternate] [.rb2 instate alternate] +} -result {0 1 1} + +test radiobutton-1.8 "Reset radiobutton variable" -body { + set ::choice 2 + list [info exists ::choice] [.rb1 instate alternate] [.rb2 instate alternate] +} -result {1 0 0} + +tcltest::cleanupTests diff --git a/tests/ttk/spinbox.test b/tests/ttk/spinbox.test new file mode 100644 index 0000000..3397e37 --- /dev/null +++ b/tests/ttk/spinbox.test @@ -0,0 +1,280 @@ +# +# ttk::spinbox widget tests +# + +package require Tk +package require tcltest ; namespace import -force tcltest::* +loadTestedCommands + +test spinbox-1.0 "Spinbox tests -- setup" -body { + ttk::spinbox .sb +} -cleanup { destroy .sb } -result .sb + +test spinbox-1.1 "Bad -values list" -setup { + ttk::spinbox .sb +} -body { + .sb configure -values "bad \{list" +} -cleanup { + destroy .sb +} -returnCodes error -result "unmatched open brace in list" + +test spinbox-1.3.1 "get retrieves value" -setup { + ttk::spinbox .sb -from 0 -to 100 +} -body { + .sb set 50 + .sb get +} -cleanup { + destroy .sb +} -result 50 + +test spinbox-1.3.2 "get retrieves value" -setup { + ttk::spinbox .sb -from 0 -to 100 -values 55 +} -body { + .sb set 55 + .sb get +} -cleanup { + destroy .sb +} -result 55 + +test spinbox-1.4.1 "set changes value" -setup { + ttk::spinbox .sb -from 0 -to 100 +} -body { + .sb set 33 + .sb get +} -cleanup { + destroy .sb +} -result 33 + +test spinbox-1.4.2 "set changes value" -setup { + ttk::spinbox .sb -from 0 -to 100 -values 55 +} -body { + .sb set 33 + .sb get +} -cleanup { + destroy .sb +} -result 33 + + +test spinbox-1.6.1 "insert start" -setup { + ttk::spinbox .sb -from 0 -to 100 +} -body { + .sb set 5 + .sb insert 0 4 + .sb get +} -cleanup { + destroy .sb +} -result 45 + +test spinbox-1.6.2 "insert end" -setup { + ttk::spinbox .sb -from 0 -to 100 +} -body { + .sb set 5 + .sb insert end 4 + .sb get +} -cleanup { + destroy .sb +} -result 54 + +test spinbox-1.6.3 "insert invalid index" -setup { + ttk::spinbox .sb -from 0 -to 100 +} -body { + .sb set 5 + .sb insert 100 4 + .sb get +} -cleanup { + destroy .sb +} -result 54 + +test spinbox-1.7.1 "-command option: set doesnt fire" -setup { + ttk::spinbox .sb -from 0 -to 100 -command {set ::spinbox_test 1} +} -body { + set ::spinbox_test 0 + .sb set 50 + set ::spinbox_test +} -cleanup { + destroy .sb +} -result 0 + +test spinbox-1.7.2 "-command option: button handler will fire" -setup { + ttk::spinbox .sb -from 0 -to 100 -command {set ::spinbox_test 1} +} -body { + set ::spinbox_test 0 + .sb set 50 + event generate .sb <> + set ::spinbox_test +} -cleanup { + destroy .sb +} -result 1 + +test spinbox-1.8.1 "option -validate" -setup { + ttk::spinbox .sb -from 0 -to 100 +} -body { + .sb configure -validate all + .sb cget -validate +} -cleanup { + destroy .sb +} -result {all} + +test spinbox-1.8.2 "option -validate" -setup { + ttk::spinbox .sb -from 0 -to 100 +} -body { + .sb configure -validate key + .sb configure -validate focus + .sb configure -validate focusin + .sb configure -validate focusout + .sb configure -validate none + .sb cget -validate +} -cleanup { + destroy .sb +} -result {none} + +test spinbox-1.8.3 "option -validate" -setup { + ttk::spinbox .sb -from 0 -to 100 +} -body { + .sb configure -validate bogus +} -cleanup { + destroy .sb +} -returnCodes error -result {bad validate "bogus": must be all, key, focus, focusin, focusout, or none} + +test spinbox-1.8.4 "-validate option: " -setup { + set ::spinbox_test {} + ttk::spinbox .sb -from 0 -to 100 +} -body { + .sb configure -validate all -validatecommand {lappend ::spinbox_test %P} + pack .sb + .sb set 50 + focus .sb + after 100 {set ::spinbox_wait 1} ; vwait ::spinbox_wait + set ::spinbox_test +} -cleanup { + destroy .sb +} -result {50} + + +test spinbox-2.0 "current command -- unset should be 0" -constraints nyi -setup { + ttk::spinbox .sb -values [list a b c d e a] +} -body { + .sb current +} -cleanup { + destroy .sb +} -result 0 +# @@@ for combobox, this is -1. + +test spinbox-2.1 "current command -- set index" -constraints nyi -setup { + ttk::spinbox .sb -values [list a b c d e a] +} -body { + .sb current 5 + .sb get +} -cleanup { + destroy .sb +} -result a + +test spinbox-2.2 "current command -- change -values" -constraints nyi -setup { + ttk::spinbox .sb -values [list a b c d e a] +} -body { + .sb current 5 + .sb configure -values [list c b a d e] + .sb current +} -cleanup { + destroy .sb +} -result 2 + +test spinbox-2.3 "current command -- change value" -constraints nyi -setup { + ttk::spinbox .sb -values [list c b a d e] +} -body { + .sb current 2 + .sb set "b" + .sb current +} -cleanup { + destroy .sb +} -result 1 + +test spinbox-2.4 "current command -- value not in list" -constraints nyi -setup { + ttk::spinbox .sb -values [list c b a d e] +} -body { + .sb current 2 + .sb set "z" + .sb current +} -cleanup { + destroy .sb +} -result -1 + +# nostomp: NB intentional difference between ttk::spinbox and tk::spinbox; +# see also #1439266 +# +test spinbox-nostomp-1 "don't stomp on -variable (init; -from/to)" -body { + set SBV 55 + ttk::spinbox .sb -textvariable SBV -from 0 -to 100 -increment 5 + list $SBV [.sb get] +} -cleanup { + unset SBV + destroy .sb +} -result [list 55 55] + +test spinbox-nostomp-2 "don't stomp on -variable (init; -values)" -body { + set SBV Apr + ttk::spinbox .sb -textvariable SBV -values {Jan Feb Mar Apr May Jun Jul Aug} + list $SBV [.sb get] +} -cleanup { + unset SBV + destroy .sb +} -result [list Apr Apr] + +test spinbox-nostomp-3 "don't stomp on -variable (configure; -from/to)" -body { + set SBV 55 + ttk::spinbox .sb + .sb configure -textvariable SBV -from 0 -to 100 -increment 5 + list $SBV [.sb get] +} -cleanup { + unset SBV + destroy .sb +} -result [list 55 55] + +test spinbox-nostomp-4 "don't stomp on -variable (configure; -values)" -body { + set SBV Apr + ttk::spinbox .sb + .sb configure -textvariable SBV -values {Jan Feb Mar Apr May Jun Jul Aug} + list $SBV [.sb get] +} -cleanup { + unset SBV + destroy .sb +} -result [list Apr Apr] + +test spinbox-dieoctaldie-1 "Cope with leading zeros" -body { + # See SF#2358545 -- ttk::spinbox also affected + set secs 07 + ttk::spinbox .sb -from 0 -to 59 -format %02.0f -textvariable secs + + set result [list $secs] + event generate .sb <>; lappend result $secs + event generate .sb <>; lappend result $secs + event generate .sb <>; lappend result $secs + event generate .sb <>; lappend result $secs + + event generate .sb <>; lappend result $secs + event generate .sb <>; lappend result $secs + event generate .sb <>; lappend result $secs + event generate .sb <>; lappend result $secs + + set result +} -result [list 07 08 09 10 11 10 09 08 07] -cleanup { + destroy .sb + unset secs +} + +test spinbox-dieoctaldie-2 "Cope with general bad input" -body { + set result [list] + ttk::spinbox .sb -from 0 -to 100 -format %03.0f + .sb set asdfasdf ; lappend result [.sb get] + event generate .sb <> ; lappend result [.sb get] + .sb set asdfasdf ; lappend result [.sb get] + event generate .sb <> ; lappend result [.sb get] +} -result [list asdfasdf 000 asdfasdf 000] -cleanup { + destroy .sb +} + +tcltest::cleanupTests + +# Local variables: +# mode: tcl +# End: diff --git a/tests/ttk/treetags.test b/tests/ttk/treetags.test index fe4dbcd..5f1287d 100644 --- a/tests/ttk/treetags.test +++ b/tests/ttk/treetags.test @@ -1,48 +1,147 @@ # -# $Id: treetags.test,v 1.2 2007/05/18 16:53:18 dgp Exp $ +# $Id: treetags.test,v 1.2.4.1 2010/08/26 02:06:10 hobbs Exp $ # -package require Tk 8.5 +package require Tk package require tcltest ; namespace import -force tcltest::* loadTestedCommands -tk useinputmethods 0 -testConstraint treeview [llength [info commands ttk::treeview]] -testConstraint nyi 0 +### treeview tag invariants: +# + +proc assert {expr {message ""}} { + if {![uplevel 1 [list expr $expr]]} { + error "PANIC: $message ($expr failed)" + } +} +proc in {e l} { expr {[lsearch -exact $l $e] >= 0} } + +proc itemConstraints {tv item} { + # $tag in [$tv item $item -tags] <==> [$tv tag has $tag $item] + foreach tag [$tv item $item -tags] { + assert {[in $item [$tv tag has $tag]]} + } + foreach child [$tv children $item] { + itemConstraints $tv $child + } +} + +proc treeConstraints {tv} { + # $item in [$tv tag has $tag] <==> [$tv tag has $tag $item] + # + foreach tag [$tv tag names] { + foreach item [$tv tag has $tag] { + assert {[in $tag [$tv item $item -tags]]} + } + } -test treetags-1.0 "Setup" -constraints treeview -body { + itemConstraints $tv {} +} +# +### + +test treetags-1.0 "Setup" -body { set tv [ttk::treeview .tv] .tv insert {} end -id item1 -text "Item 1" - pack .tv + pack .tv +} -cleanup { + treeConstraints $tv } -test treetags-1.1 "Bad tag list" -constraints treeview -body { +test treetags-1.1 "Bad tag list" -body { $tv item item1 -tags {bad {list}here bad} + $tv item item1 -tags } -returnCodes error -result "list element in braces *" -match glob -test treetags-1.2 "Good tag list" -constraints treeview -body { +test treetags-1.2 "Good tag list" -body { $tv item item1 -tags tag1 $tv item item1 -tags +} -cleanup { + assert {[$tv tag has tag1 item1]} + treeConstraints $tv } -result [list tag1] -test treetags-1.3 "Bad events" -constraints treeview -body { - $tv tag bind bad { puts "Entered!" } -} -returnCodes 1 -result "unsupported event *" -match glob +test treetags-1.3 "tag has - test" -body { + $tv insert {} end -id item2 -text "Item 2" -tags tag2 + set result [list] + foreach item {item1 item2} { + foreach tag {tag1 tag2 tag3} { + lappend result $item $tag [$tv tag has $tag $item] + } + } + set result +} -cleanup { + treeConstraints $tv +} -result [list \ + item1 tag1 1 item1 tag2 0 item1 tag3 0 \ + item2 tag1 0 item2 tag2 1 item2 tag3 0 ] + +test treetags-1.4 "tag has - query" -body { + list [$tv tag has tag1] [$tv tag has tag2] [$tv tag has tag3] +} -cleanup { + treeConstraints $tv +} -result [list [list item1] [list item2] [list]] + +test treetags-1.5 "tag add" -body { + $tv tag add tag3 {item1 item2} + list [$tv tag has tag1] [$tv tag has tag2] [$tv tag has tag3] +} -cleanup { + treeConstraints $tv +} -result [list [list item1] [list item2] [list item1 item2]] + +test treetags-1.6 "tag remove - list" -body { + $tv tag remove tag3 {item1 item2} + list [$tv tag has tag1] [$tv tag has tag2] [$tv tag has tag3] +} -cleanup { + treeConstraints $tv +} -result [list [list item1] [list item2] [list]] + +test treetags-1.7 "tag remove - all items" -body { + $tv tag remove tag1 + list [$tv tag has tag1] [$tv tag has tag2] [$tv tag has tag3] +} -cleanup { + treeConstraints $tv +} -result [list [list] [list item2] [list]] + +test treetags-1.8 "tag names" -body { + lsort [$tv tag names] +} -result [list tag1 tag2 tag3] + +test treetags-1.9 "tag names - tag added to item" -body { + $tv item item1 -tags tag4 + lsort [$tv tag names] +} -result [list tag1 tag2 tag3 tag4] + +test treetags-1.10 "tag names - tag configured" -body { + $tv tag configure tag5 + lsort [$tv tag names] +} -result [list tag1 tag2 tag3 tag4 tag5] + +test treetags-1.end "cleanup" -body { + $tv item item1 -tags tag1 + $tv item item2 -tags tag2 + list [$tv tag has tag1] [$tv tag has tag2] [$tv tag has tag3] +} -cleanup { + treeConstraints $tv +} -result [list [list item1] [list item2] [list]] -test treetags-2.0 "tag bind" -constraints treeview -body { +test treetags-2.0 "tag bind" -body { $tv tag bind tag1 {set ::KEY %A} $tv tag bind tag1 +} -cleanup { + treeConstraints $tv } -result {set ::KEY %A} -test treetags-2.1 "Events delivered to tags" -constraints treeview -body { +test treetags-2.1 "Events delivered to tags" -body { focus -force $tv ; update ;# needed so [event generate] delivers KeyPress $tv focus item1 - event generate .tv + event generate $tv set ::KEY +} -cleanup { + treeConstraints $tv } -result a -test treetags-2.2 "Events delivered to correct tags" -constraints treeview -body { - $tv insert {} end -id item2 -tags tag2 +test treetags-2.2 "Events delivered to correct tags" -body { $tv tag bind tag2 [list set ::KEY2 %A] $tv focus item1 @@ -51,9 +150,11 @@ test treetags-2.2 "Events delivered to correct tags" -constraints treeview -body event generate $tv list $::KEY $::KEY2 +} -cleanup { + treeConstraints $tv } -result [list b c] -test treetags-2.3 "Virtual events delivered to focus item" -constraints treeview -body { +test treetags-2.3 "Virtual events delivered to focus item" -body { set ::bong 0 $tv tag bind tag2 <> { incr bong } $tv focus item2 @@ -61,18 +162,63 @@ test treetags-2.3 "Virtual events delivered to focus item" -constraints treeview $tv focus item1 event generate $tv <> set bong +} -cleanup { + treeConstraints $tv } -result 1 +test treetags-2.4 "Bad events" -body { + $tv tag bind bad { puts "Entered!" } +} -returnCodes 1 -result "unsupported event *" -match glob -test treetags-3.0 "tag configure" -constraints treeview -body { +test treetags-3.0 "tag configure - set" -body { $tv tag configure tag1 -foreground blue -background red +} -cleanup { + treeConstraints $tv } -result {} -test treetags-3.1 "tag configure" -constraints treeview -body { +test treetags-3.1 "tag configure - get" -body { $tv tag configure tag1 -foreground -} -result [list blue] +} -cleanup { + treeConstraints $tv +} -result blue + +# @@@ fragile test +test treetags-3.2 "tag configure - enumerate" -body { + $tv tag configure tag1 +} -cleanup { + treeConstraints $tv +} -result [list \ + -text {} -image {} -anchor {} -background red -foreground blue -font {} \ +] + +# The next test exercises tag resource management. +# If options are not properly freed, the message: +# Test file error: "Font times 20 still in cache." +# will show up on stderr at program exit. +# +test treetags-3.3 "tag configure - set font" -body { + $tv tag configure tag2 -font {times 20} +} + +test treetags-3.4 "stomp tags in tag binding procedure" -body { + set result [list] + $tv tag bind rm1 <> { lappend ::result rm1 [%W focus] <> } + $tv tag bind rm2 <> { + lappend ::result rm2 [%W focus] <> + %W item [%W focus] -tags {tag1} + } + $tv tag bind rm3 <> { lappend ::result rm3 [%W focus] <> } + $tv item item1 -tags {rm1 rm2 rm3} + $tv focus item1 + event generate $tv <> + set result +} -cleanup { + treeConstraints $tv +} -result [list rm1 item1 <> rm2 item1 <> rm3 item1 <>] + +# -test treetags-end "Cleanup" -constraints treeview -body { destroy .tv } +test treetags-end "Cleanup" -body { destroy $tv } tcltest::cleanupTests diff --git a/tests/ttk/treeview.test b/tests/ttk/treeview.test index c97b27a..5bc7a80 100644 --- a/tests/ttk/treeview.test +++ b/tests/ttk/treeview.test @@ -1,5 +1,5 @@ # -# $Id: treeview.test,v 1.3.2.2 2010/05/31 17:22:49 jenglish Exp $ +# $Id: treeview.test,v 1.3.2.3 2010/08/26 02:06:10 hobbs Exp $ # # [7Jun2005] TO CHECK: [$tv see {}] -- shouldn't work (at least, shouldn't do # what it currently does) @@ -245,7 +245,7 @@ test treeview-3.15 "Consecutive duplicate entries in children list" -body { } -result [list x1 x2 x3] test treeview-3.16 "Insert child after self" -body { - .tv move x2 newfirstone 1 + .tv move x2 newfirstone 1 consistencyCheck .tv .tv children newfirstone } -result [list x1 x2 x3] @@ -262,7 +262,6 @@ test treeview-3.18 "Insert last child after end" -body { .tv children newfirstone } -result [list x1 x2 x3] - test treeview-4.1 "opened - initial state" -body { .tv item newnode -open } -result 0 @@ -290,12 +289,12 @@ test treeview-5.3 "Heading" -body { test treeview-5.4 "get cell" -body { set l [list a b c] .tv item newnode -values $l - .tv set newnode 1 + .tv set newnode 1 } -result b test treeview-5.5 "set cell" -body { .tv set newnode 1 XXX - .tv item newnode -values + .tv item newnode -values } -result [list a XXX c] test treeview-5.6 "set illegal cell" -body { @@ -408,11 +407,11 @@ test treeview-7.1 "move" -body { test treeview-7.2 "illegal move" -body { .tv move d d2 end -} -returnCodes 1 -result "Cannot insert d as a descendant of d2" +} -returnCodes 1 -result "Cannot insert d as a descendant of d2" test treeview-7.3 "illegal move has no effect" -body { consistencyCheck .tv - .tv children d + .tv children d } -result [list d3 d1 d2] test treeview-7.4 "Replace children" -body { @@ -474,8 +473,128 @@ test treeview-9.0 "scroll callback - empty tree" -body { set ::scrolldata } -result [list 0.0 1.0] -### NEED: tests for focus item, selection +### identify tests: +# +proc identify* {tv comps args} { + foreach {x y} $args { + foreach comp $comps { + lappend result [$tv identify $comp $x $y] + } + } + return $result +} +# get list of column IDs from list of display column ids. +# +proc columnids {tv dcols} { + set result [list] + foreach dcol $dcols { + if {[catch { + lappend result [$tv column $dcol -id] + }]} { + lappend result ERROR + } + } + return $result +} + +test treeview-identify-setup "identify series - setup" -body { + destroy .tv + ttk::setTheme default + ttk::treeview .tv -columns [list A B C] + .tv insert {} end -id branch -text branch -open true + .tv insert branch end -id item1 -text item1 + .tv insert branch end -id item2 -text item2 + .tv insert branch end -id item3 -text item3 + + .tv column #0 -width 50 ;# 0-50 + .tv column A -width 50 ;# 50-100 + .tv column B -width 50 ;# 100-150 + .tv column C -width 50 ;# 150-200 (plus slop for margins) + + wm geometry . {} ; pack .tv ; update +} + +test treeview-identify-1 "identify heading" -body { + .tv configure -show {headings tree} + update idletasks + identify* .tv {region column} 10 10 +} -result [list heading #0] + +test treeview-identify-2 "identify columns" -body { + .tv configure -displaycolumns #all + update idletasks + columnids .tv [identify* .tv column 25 10 75 10 125 10 175 10] +} -result [list {} A B C] + +test treeview-identify-3 "reordered columns" -body { + .tv configure -displaycolumns {B A C} + update idletasks + columnids .tv [identify* .tv column 25 10 75 10 125 10 175 10] +} -result [list {} B A C] + +test treeview-identify-4 "no tree column" -body { + .tv configure -displaycolumns #all -show {headings} + update idletasks + identify* .tv {region column} 25 10 75 10 125 10 175 10 +} -result [list heading #1 heading #2 heading #3 nothing {}] + +# Item height in default theme is 20px +test treeview-identify-5 "vertical scan - no headings" -body { + .tv configure -displaycolumns #all -show {tree} + update idletasks + identify* .tv {region item} 25 10 25 30 25 50 25 70 25 90 +} -result [list tree branch tree item1 tree item2 tree item3 nothing {}] + +test treeview-identify-6 "vertical scan - with headings" -body { + .tv configure -displaycolumns #all -show {tree headings} + update idletasks + identify* .tv {region item} 25 10 25 30 25 50 25 70 25 90 +} -result [list heading {} tree branch tree item1 tree item2 tree item3] + +test treeview-identify-7 "vertical scan - headings, no tree" -body { + .tv configure -displaycolumns #all -show {headings} + update idletasks + identify* .tv {region item} 25 10 25 30 25 50 25 70 25 90 +} -result [list heading {} cell branch cell item1 cell item2 cell item3] + +# In default theme, -indent and -itemheight both 20px +# Disclosure element name is "Treeitem.indicator" +set disclosure "*.indicator" +test treeview-identify-8 "identify element" -body { + .tv configure -show {tree} + .tv insert branch 0 -id branch2 -open true + .tv insert branch2 0 -id branch3 -open true + .tv insert branch3 0 -id leaf3 + update idletasks; + identify* .tv {item element} 10 10 30 30 50 50 +} -match glob -result [list \ + branch $disclosure branch2 $disclosure branch3 $disclosure] + +# See #2381555 +test treeview-identify-9 "identify works when horizontally scrolled" -setup { + .tv configure -show {tree headings} + foreach column {#0 A B C} { + .tv column $column -stretch 0 -width 50 + } + place .tv -x 0 -y 0 -width 100 +} -body { + set result [list] + foreach xoffs {0 50 100} { + .tv xview $xoffs ; update + lappend result [identify* .tv {region column} 10 10 60 10] + } + set result +} -result [list \ + [list heading #0 heading #1] \ + [list heading #1 heading #2] \ + [list heading #2 heading #3] ] + +test treeview-identify-cleanup "identify - cleanup" -body { + destroy .tv +} + +### NEED: tests for focus item, selection ### Misc. tests: diff --git a/tests/ttk/ttk.test b/tests/ttk/ttk.test index a1430ff..9732f46 100644 --- a/tests/ttk/ttk.test +++ b/tests/ttk/ttk.test @@ -28,24 +28,19 @@ test ttk-6.2 "Checkbutton self-destructed" -body { winfo exists .sd } -result 0 -test ttk-6.3 "Test package cleanup" -body { - interp create foo - foo eval { if {[catch {package require Tk}]} { load {} Tk } } - foo eval { destroy . } - interp delete foo -} +# test ttk-6.3 not applicable [see #2175411] -test ttk-6.4 "Defeat evil intentions" -body { +test ttk-6.4 "Destroy widget in configure" -setup { + set OUCH ouch trace variable OUCH r { kill.b } proc kill.b {args} { destroy .b } +} -cleanup { + unset OUCH +} -body { pack [ttk::checkbutton .b] - .b configure -variable OUCH - # At this point, .b should be gone. - .b invoke - list [set OUCH] [winfo exists .b] - # Mostly we just care that we haven't crashed the interpreter. - # -} -returnCodes error -match glob -result "*" + set rc [catch { .b configure -variable OUCH } msg] + list $rc $msg [winfo exists .b] [info commands .b] +} -result [list 1 "Widget has been destroyed" 0 {}] test ttk-6.5 "Clean up -textvariable traces" -body { foreach class {ttk::button ttk::checkbutton ttk::radiobutton} { @@ -66,7 +61,6 @@ test ttk-6.6 "Bad color spec in styles" -body { set ::bgerror } -result {unknown color name "badColor"} -# This should move to be a standard test per widget test file test ttk-6.7 "Basic destruction test" -body { foreach widget { button checkbutton radiobutton sizegrip separator notebook @@ -85,9 +79,6 @@ test ttk-6.8 "Button command removes itself" -body { set ::A } -result {it worked} -# -# - test ttk-6.9 "Bad font spec in styles" -setup { ttk::style theme create badfont -settings { ttk::style configure . -font {Helvetica 12 Bogus} @@ -103,10 +94,41 @@ test ttk-6.9 "Bad font spec in styles" -setup { set ::bgerror } -result {unknown font style "Bogus"} +test ttk-construction-failure-1 "Excercise construction failure path" -setup { + option add *TLabel.cursor badCursor 1 +} -cleanup { + option add *TLabel.cursor {} 1 +} -body { + catch {ttk::label .l} errmsg + list $errmsg [info commands .l] [winfo exists .l] +} -result [list {bad cursor spec "badCursor"} {} 0] + +test ttk-construction-failure-2 "Destroy widget in constructor" -setup { + set OUCH ouch + trace variable OUCH r { kill.b } + proc kill.b {args} { destroy .b } +} -cleanup { + unset OUCH +} -body { + list \ + [catch { ttk::checkbutton .b -variable OUCH } msg] \ + $msg \ + [winfo exists .b] \ + [info commands .b] \ + ; +} -result [list 1 "Widget has been destroyed" 0 {}] + +test ttk-selfdestruct-ok-1 "Intentional self-destruction" -body { + # see #2298720 + toplevel .t + ttk::button .t.b -command [list destroy .t] + .t.b invoke + list [winfo exists .t] [winfo exists .t.b] +} -result [list 0 0] + # # Basic tests. # - test ttk-1.1 "Create button" -body { pack [ttk::button .t] -expand true -fill both update @@ -116,8 +138,11 @@ test ttk-1.2 "Check style" -body { .t cget -style } -result {} +test ttk-1.3 "Set bad style" -body { + .t configure -style "nosuchstyle" +} -returnCodes 1 -result {Layout nosuchstyle not found} -test ttk-1.4 "Restore default style" -body { +test ttk-1.4 "Original style preserved" -body { .t cget -style } -result "" @@ -172,7 +197,6 @@ test ttk-2.7 "instate scripts, true" -body { set x } -result 1 - # misc. error detection test ttk-3.0 "Bad option" -body { ttk::button .bad -badoption foo @@ -191,6 +215,10 @@ test ttk-3.2 "Propagate errors from variable traces" -body { unset ::A ; destroy .cb } -returnCodes error -result {can't set "A": failure} +test ttk-3.3 "Constructor failure with cursor" -body { + ttk::button .b -cursor bottom_right_corner -style BadStyle +} -returnCodes 1 -result "Layout BadStyle not found" + test ttk-3.4 "SF#2009213" -body { ttk::style configure TScale -sliderrelief {} pack [ttk::scale .s] @@ -241,90 +269,6 @@ test ttk-4.4 "Bad resource specifications" -body { } # -# checkbutton tests -# -test ttk-5.1 "Checkbutton check" -body { - pack [ttk::checkbutton .cb -text "TCheckbutton" -variable cb] -} -test ttk-5.2 "Checkbutton invoke" -body { - .cb invoke - list [set ::cb] [.cb instate selected] -} -result [list 1 1] -test ttk-5.3 "Checkbutton reinvoke" -body { - .cb invoke - list [set ::cb] [.cb instate selected] -} -result [list 0 0] - -test ttk-5.4 "Checkbutton variable" -body { - set result [] - set ::cb 1 - lappend result [.cb instate selected] - set ::cb 0 - lappend result [.cb instate selected] -} -result {1 0} - -test ttk-5.5 "Unset checkbutton variable" -body { - set result [] - unset ::cb - lappend result [.cb instate alternate] [info exists ::cb] - set ::cb 1 - lappend result [.cb instate alternate] [info exists ::cb] -} -result {1 0 0 1} - -# See #1257319 -test ttk-5.6 "Checkbutton default variable" -body { - destroy .cb ; unset -nocomplain {} ; set result [list] - ttk::checkbutton .cb -onvalue on -offvalue off - lappend result [.cb cget -variable] [info exists .cb] [.cb state] - .cb invoke - lappend result [info exists .cb] [set .cb] [.cb state] - .cb invoke - lappend result [info exists .cb] [set .cb] [.cb state] -} -result [list .cb 0 alternate 1 on selected 1 off {}] - -# -# radiobutton tests -# -test ttk-7.1 "Radiobutton check" -body { - pack \ - [ttk::radiobutton .rb1 -text "One" -variable choice -value 1] \ - [ttk::radiobutton .rb2 -text "Two" -variable choice -value 2] \ - [ttk::radiobutton .rb3 -text "Three" -variable choice -value 3] \ - ; -} -test ttk-7.2 "Radiobutton invoke" -body { - .rb1 invoke - set ::choice -} -result 1 - -test ttk-7.3 "Radiobutton state" -body { - .rb1 instate selected -} -result 1 - -test ttk-7.4 "Other radiobutton invoke" -body { - .rb2 invoke - set ::choice -} -result 2 - -test ttk-7.5 "Other radiobutton state" -body { - .rb2 instate selected -} -result 1 - -test ttk-7.6 "First radiobutton state" -body { - .rb1 instate selected -} -result 0 - -test ttk-7.7 "Unset radiobutton variable" -body { - unset ::choice - list [info exists ::choice] [.rb1 instate alternate] [.rb2 instate alternate] -} -result {0 1 1} - -test ttk-7.8 "Reset radiobutton variable" -body { - set ::choice 2 - list [info exists ::choice] [.rb1 instate alternate] [.rb2 instate alternate] -} -result {1 0 0} - -# # -compound tests: # variable iconData \ @@ -444,7 +388,7 @@ test ttk-9.6 "Unset -textvariable" -body { test ttk-9.7 "Unset textvariable, comparison" -body { # -# NB: the ttk label behaves differently from the standard label here; +# NB: ttk::label behaves differently from the standard label here; # NB: this is on purpose: I believe the standard behaviour is the Wrong Thing # unset -nocomplain V1 V2 @@ -554,7 +498,6 @@ test ttk-12.4 "-borderwidth frame option" -body { update } - test ttk-13.1 "Custom styles -- bad -style option" -body { ttk::button .tb1 -style badstyle } -returnCodes 1 -result "*badstyle not found*" -match glob @@ -596,16 +539,44 @@ test ttk-14.3 "-textvariable in nonexistant namespace" -body { -match glob -cleanup { destroy .tw } -test ttk-15.1 "style element create: insufficient args" -body { +## Test ensemble processing: +# +# (See also: SF#2021443) +# +proc wrong#args {args} { + return "wrong # args: should be \"$args\"" +} +proc wrong#varargs {varpart args} { + set usage $args + append usage " ?$varpart ...?" + return "wrong # args: should be \"$usage\"" +} + +test ttk-ensemble-0 "style element create: insufficient args" -body { + ttk::style +} -returnCodes 1 -result \ + [wrong#varargs arg ttk::style option] + +test ttk-ensemble-1 "style element create: insufficient args" -body { + ttk::style element +} -returnCodes 1 -result \ + [wrong#varargs arg ttk::style element option] + +test ttk-ensemble-2 "style element create: insufficient args" -body { ttk::style element create -} -returnCodes 1 -result "wrong # args: should be \"ttk::style element create name type ?options...?\"" -test ttk-15.2 "style element create: insufficient args" -body { +} -returnCodes 1 -result \ + [wrong#varargs {-option value} ttk::style element create name type] + +test ttk-ensemble-3 "style element create: insufficient args" -body { ttk::style element create plain.background -} -returnCodes 1 -result "wrong # args: should be \"ttk::style element create name type ?options...?\"" -test ttk-15.3 "style element create: insufficient args" -body { +} -returnCodes 1 -result \ + [wrong#varargs {-option value} ttk::style element create name type] + +test ttk-ensemble-4 "style element create: insufficient args" -body { ttk::style element create plain.background from -} -returnCodes 1 -result "wrong # args: should be \"theme ?element?\"" -test ttk-15.4 "style element create: valid" -body { +} -returnCodes 1 -result [wrong#args theme ?element?] + +test ttk-ensemble-5 "style element create: valid" -body { ttk::style element create plain.background from default } -returnCodes 0 -result "" diff --git a/tests/ttk/vsapi.test b/tests/ttk/vsapi.test index 7000e3e..21898bb 100644 --- a/tests/ttk/vsapi.test +++ b/tests/ttk/vsapi.test @@ -1,5 +1,5 @@ # -*- tcl -*- -# $Id: vsapi.test,v 1.1.2.2 2009/05/14 00:53:04 patthoyts Exp $ +# $Id: vsapi.test,v 1.1.2.3 2010/08/26 02:06:10 hobbs Exp $ # package require Tk 8.5 diff --git a/win/ttkWinMonitor.c b/win/ttkWinMonitor.c index 2753518..0f28d48 100644 --- a/win/ttkWinMonitor.c +++ b/win/ttkWinMonitor.c @@ -1,4 +1,4 @@ -/* $Id: ttkWinMonitor.c,v 1.16 2007/12/13 15:28:56 dgp Exp $ +/* $Id: ttkWinMonitor.c,v 1.16.2.1 2010/08/26 02:06:10 hobbs Exp $ */ #ifdef _MSC_VER @@ -75,8 +75,8 @@ CreateThemeMonitorWindow(HINSTANCE hinst, Tcl_Interp *interp) { WNDCLASSEX wc; HWND hwnd = NULL; - CHAR title[32] = "TtkMonitorWindow"; - CHAR name[32] = "TtkMonitorClass"; + TCHAR title[32] = TEXT("TtkMonitorWindow"); + TCHAR name[32] = TEXT("TtkMonitorClass"); wc.cbSize = sizeof(WNDCLASSEX); wc.style = CS_HREDRAW | CS_VREDRAW; diff --git a/win/ttkWinTheme.c b/win/ttkWinTheme.c index 749fe3f..0137408 100644 --- a/win/ttkWinTheme.c +++ b/win/ttkWinTheme.c @@ -1,6 +1,6 @@ /* winTheme.c - Copyright (C) 2004 Pat Thoyts * - * $Id: ttkWinTheme.c,v 1.13 2008/01/08 17:01:00 jenglish Exp $ + * $Id: ttkWinTheme.c,v 1.13.2.1 2010/08/26 02:06:10 hobbs Exp $ */ #ifdef _MSC_VER @@ -104,10 +104,12 @@ typedef struct { Ttk_Padding margins; /* additional placement padding */ } FrameControlElementData; -#define _FIXEDSIZE 0x8000 +#define _FIXEDSIZE 0x80000000L +#define _HALFMETRIC 0x40000000L #define FIXEDSIZE(id) (id|_FIXEDSIZE) +#define HALFMETRIC(id) (id|_HALFMETRIC) #define GETMETRIC(m) \ - ((m) & _FIXEDSIZE ? (m) & ~_FIXEDSIZE : GetSystemMetrics(m)) + ((m) & _FIXEDSIZE ? (int)((m) & ~_FIXEDSIZE) : GetSystemMetrics((m)&0x0fffffff)) static FrameControlElementData FrameControlElements[] = { { "Checkbutton.indicator", @@ -131,6 +133,12 @@ static FrameControlElementData FrameControlElements[] = { { "sizegrip", DFC_SCROLL, DFCS_SCROLLSIZEGRIP, SM_CXVSCROLL, SM_CYHSCROLL, arrow_statemap, {0,0,0,0} }, + { "Spinbox.uparrow", + DFC_SCROLL, DFCS_SCROLLUP, SM_CXVSCROLL, HALFMETRIC(SM_CYVSCROLL), + arrow_statemap, {0,0,0,0} }, + { "Spinbox.downarrow", + DFC_SCROLL, DFCS_SCROLLDOWN, SM_CXVSCROLL, HALFMETRIC(SM_CYVSCROLL), + arrow_statemap, {0,0,0,0} }, { 0,0,0,0,0,0, {0,0,0,0} } }; @@ -142,8 +150,12 @@ static void FrameControlElementSize( int *widthPtr, int *heightPtr, Ttk_Padding *paddingPtr) { FrameControlElementData *p = clientData; - *widthPtr = GETMETRIC(p->cxId) + Ttk_PaddingWidth(p->margins); - *heightPtr = GETMETRIC(p->cyId) + Ttk_PaddingHeight(p->margins); + int cx = GETMETRIC(p->cxId); + int cy = GETMETRIC(p->cyId); + if (p->cxId & _HALFMETRIC) cx /= 2; + if (p->cyId & _HALFMETRIC) cy /= 2; + *widthPtr = cx + Ttk_PaddingWidth(p->margins); + *heightPtr = cy + Ttk_PaddingHeight(p->margins); } static void FrameControlElementDraw( @@ -179,7 +191,7 @@ typedef struct { static Ttk_ElementOptionSpec BorderElementOptions[] = { { "-relief",TK_OPTION_RELIEF,Tk_Offset(BorderElement,reliefObj), "flat" }, - {NULL} + {NULL, 0, 0, NULL} }; static void BorderElementSize( @@ -230,7 +242,7 @@ typedef struct { static Ttk_ElementOptionSpec FieldElementOptions[] = { { "-fieldbackground", TK_OPTION_BORDER, Tk_Offset(FieldElement,backgroundObj), "white" }, - {NULL} + { NULL, 0, 0, NULL } }; static void FieldElementSize( @@ -285,7 +297,7 @@ static Ttk_ElementOptionSpec ButtonBorderElementOptions[] = { Tk_Offset(ButtonBorderElement,highlightColorObj), "black" }, { "-default", TK_OPTION_ANY, Tk_Offset(ButtonBorderElement,defaultStateObj), "disabled" }, - {NULL} + {NULL, 0, 0, NULL} }; static void ButtonBorderElementSize( @@ -409,7 +421,7 @@ typedef struct { static Ttk_ElementOptionSpec FillFocusElementOptions[] = { { "-focusfill", TK_OPTION_COLOR, Tk_Offset(FillFocusElement,fillColorObj), "white" }, - { NULL } + {NULL, 0, 0, NULL} }; /* @@@ FIX THIS */ @@ -533,7 +545,7 @@ typedef struct { static Ttk_ElementOptionSpec ThumbElementOptions[] = { { "-orient", TK_OPTION_ANY,Tk_Offset(ThumbElement,orientObj),"horizontal"}, - { NULL } + { NULL, 0, 0, NULL } }; static void ThumbElementSize( @@ -590,7 +602,7 @@ typedef struct { static Ttk_ElementOptionSpec SliderElementOptions[] = { { "-orient", TK_OPTION_ANY, Tk_Offset(SliderElement,orientObj), "horizontal" }, - { NULL } + { NULL, 0, 0, NULL } }; static void SliderElementSize( diff --git a/win/ttkWinXPTheme.c b/win/ttkWinXPTheme.c index 5502206..c4a921e 100644 --- a/win/ttkWinXPTheme.c +++ b/win/ttkWinXPTheme.c @@ -1,5 +1,5 @@ /* - * $Id: ttkWinXPTheme.c,v 1.18.2.2 2009/12/03 23:58:35 patthoyts Exp $ + * $Id: ttkWinXPTheme.c,v 1.18.2.3 2010/08/26 02:06:10 hobbs Exp $ * * Tk theme engine which uses the Windows XP "Visual Styles" API * Adapted from Georgios Petasis' XP theme patch. @@ -101,7 +101,7 @@ LoadXPThemeProcs(HINSTANCE *phlib) * if we are running at least on Windows XP. */ HINSTANCE handle; - *phlib = handle = LoadLibrary("uxtheme.dll"); + *phlib = handle = LoadLibrary(TEXT("uxtheme.dll")); if (handle != 0) { /* @@ -321,6 +321,14 @@ static Ttk_StateTable rightarrow_statemap[] = { ABS_RIGHTNORMAL, 0, 0 } }; +static Ttk_StateTable spinbutton_statemap[] = +{ + { DNS_DISABLED, TTK_STATE_DISABLED, 0 }, + { DNS_PRESSED, TTK_STATE_PRESSED, 0 }, + { DNS_HOT, TTK_STATE_ACTIVE, 0 }, + { DNS_NORMAL, 0, 0 }, +}; + /* * Trackbar thumb: (Tk: "scale slider") */ @@ -591,6 +599,36 @@ static Ttk_ElementSpec GenericSizedElementSpec = { }; /*---------------------------------------------------------------------- + * +++ Spinbox arrow element. + * These are half-height scrollbar buttons. + */ + +static void +SpinboxArrowElementSize( + void *clientData, void *elementRecord, Tk_Window tkwin, + int *widthPtr, int *heightPtr, Ttk_Padding *paddingPtr) +{ + ElementData *elementData = clientData; + + if (!InitElementData(elementData, tkwin, 0)) + return; + + GenericSizedElementSize(clientData, elementRecord, tkwin, + widthPtr, heightPtr, paddingPtr); + + /* force the arrow button height to half size */ + *heightPtr /= 2; +} + +static Ttk_ElementSpec SpinboxArrowElementSpec = { + TK_STYLE_VERSION_2, + sizeof(NullElement), + TtkNullElementOptions, + SpinboxArrowElementSize, + GenericElementDraw +}; + +/*---------------------------------------------------------------------- * +++ Scrollbar thumb element. * Same as a GenericElement, but don't draw in the disabled state. */ @@ -979,6 +1017,14 @@ static ElementInfo ElementInfoTable[] = { HP_HEADERITEM, header_statemap, PAD(4,0,4,0),0 }, { "sizegrip", &GenericElementSpec, L"STATUS", SP_GRIPPER, null_statemap, NOPAD,0 }, + { "Spinbox.field", &GenericElementSpec, L"EDIT", + EP_EDITTEXT, edittext_statemap, PAD(1, 1, 1, 1), 0 }, + { "Spinbox.uparrow", &SpinboxArrowElementSpec, L"SPIN", + SPNP_UP, spinbutton_statemap, NOPAD, + PAD_MARGINS | ((SM_CXVSCROLL << 8) | SM_CYVSCROLL) }, + { "Spinbox.downarrow", &SpinboxArrowElementSpec, L"SPIN", + SPNP_DOWN, spinbutton_statemap, NOPAD, + PAD_MARGINS | ((SM_CXVSCROLL << 8) | SM_CYVSCROLL) }, #if BROKEN_TEXT_ELEMENT { "Labelframe.text", &TextElementSpec, L"BUTTON", -- cgit v0.12