Pratt 1.5.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.exrc +61 -0
- data/.gitignore +4 -0
- data/History.txt +6 -0
- data/Manifest.txt +46 -0
- data/Pratt.gemspec +351 -0
- data/README.txt +66 -0
- data/Rakefile +85 -0
- data/TODO +54 -0
- data/VERSION +1 -0
- data/bin/pratt.rb +13 -0
- data/config.rb +34 -0
- data/lib/pratt.rb +527 -0
- data/lib/pratt/array.rb +11 -0
- data/lib/pratt/string.rb +18 -0
- data/models/app.rb +40 -0
- data/models/customer.rb +24 -0
- data/models/payment.rb +22 -0
- data/models/pratt.rb +19 -0
- data/models/project.rb +82 -0
- data/models/whence.rb +70 -0
- data/pkgs/tile-0.8.2.tar.gz +0 -0
- data/pkgs/tile-0.8.2/ANNOUNCE.txt +95 -0
- data/pkgs/tile-0.8.2/ChangeLog +4651 -0
- data/pkgs/tile-0.8.2/Makefile +250 -0
- data/pkgs/tile-0.8.2/Makefile.in +250 -0
- data/pkgs/tile-0.8.2/README.txt +86 -0
- data/pkgs/tile-0.8.2/aclocal.m4 +2 -0
- data/pkgs/tile-0.8.2/altTheme.o +0 -0
- data/pkgs/tile-0.8.2/blink.o +0 -0
- data/pkgs/tile-0.8.2/button.o +0 -0
- data/pkgs/tile-0.8.2/cache.o +0 -0
- data/pkgs/tile-0.8.2/clamTheme.o +0 -0
- data/pkgs/tile-0.8.2/classicTheme.o +0 -0
- data/pkgs/tile-0.8.2/config.log +1330 -0
- data/pkgs/tile-0.8.2/config.status +795 -0
- data/pkgs/tile-0.8.2/configure +15248 -0
- data/pkgs/tile-0.8.2/configure.in +89 -0
- data/pkgs/tile-0.8.2/demos/autocomplete.tcl +59 -0
- data/pkgs/tile-0.8.2/demos/demo.tcl +870 -0
- data/pkgs/tile-0.8.2/demos/dirbrowser.tcl +167 -0
- data/pkgs/tile-0.8.2/demos/dlgtest.tcl +97 -0
- data/pkgs/tile-0.8.2/demos/iconlib.tcl +110 -0
- data/pkgs/tile-0.8.2/demos/repeater.tcl +117 -0
- data/pkgs/tile-0.8.2/demos/toolbutton.tcl +101 -0
- data/pkgs/tile-0.8.2/doc/Geometry.3 +230 -0
- data/pkgs/tile-0.8.2/doc/INDEX.MAP +153 -0
- data/pkgs/tile-0.8.2/doc/Makefile +36 -0
- data/pkgs/tile-0.8.2/doc/TILE.XML +45 -0
- data/pkgs/tile-0.8.2/doc/Theme.3 +34 -0
- data/pkgs/tile-0.8.2/doc/button.n +75 -0
- data/pkgs/tile-0.8.2/doc/checkbutton.n +61 -0
- data/pkgs/tile-0.8.2/doc/combobox.n +98 -0
- data/pkgs/tile-0.8.2/doc/converting.txt +97 -0
- data/pkgs/tile-0.8.2/doc/dialog.n +122 -0
- data/pkgs/tile-0.8.2/doc/entry.n +438 -0
- data/pkgs/tile-0.8.2/doc/frame.n +43 -0
- data/pkgs/tile-0.8.2/doc/html/Geometry.html +304 -0
- data/pkgs/tile-0.8.2/doc/html/Theme.html +48 -0
- data/pkgs/tile-0.8.2/doc/html/button.html +120 -0
- data/pkgs/tile-0.8.2/doc/html/category-index.html +18 -0
- data/pkgs/tile-0.8.2/doc/html/checkbutton.html +94 -0
- data/pkgs/tile-0.8.2/doc/html/combobox.html +164 -0
- data/pkgs/tile-0.8.2/doc/html/converting.txt +97 -0
- data/pkgs/tile-0.8.2/doc/html/dialog.html +159 -0
- data/pkgs/tile-0.8.2/doc/html/entry.html +613 -0
- data/pkgs/tile-0.8.2/doc/html/frame.html +76 -0
- data/pkgs/tile-0.8.2/doc/html/image.html +100 -0
- data/pkgs/tile-0.8.2/doc/html/index.html +25 -0
- data/pkgs/tile-0.8.2/doc/html/keyword-index.html +228 -0
- data/pkgs/tile-0.8.2/doc/html/label.html +133 -0
- data/pkgs/tile-0.8.2/doc/html/labelframe.html +91 -0
- data/pkgs/tile-0.8.2/doc/html/manpage.css +212 -0
- data/pkgs/tile-0.8.2/doc/html/menubutton.html +63 -0
- data/pkgs/tile-0.8.2/doc/html/notebook.html +280 -0
- data/pkgs/tile-0.8.2/doc/html/paned.html +149 -0
- data/pkgs/tile-0.8.2/doc/html/progressbar.html +138 -0
- data/pkgs/tile-0.8.2/doc/html/radiobutton.html +89 -0
- data/pkgs/tile-0.8.2/doc/html/scrollbar.html +221 -0
- data/pkgs/tile-0.8.2/doc/html/separator.html +48 -0
- data/pkgs/tile-0.8.2/doc/html/sizegrip.html +62 -0
- data/pkgs/tile-0.8.2/doc/html/style.html +172 -0
- data/pkgs/tile-0.8.2/doc/html/tile-intro.html +164 -0
- data/pkgs/tile-0.8.2/doc/html/treeview.html +634 -0
- data/pkgs/tile-0.8.2/doc/html/widget.html +342 -0
- data/pkgs/tile-0.8.2/doc/image.n +81 -0
- data/pkgs/tile-0.8.2/doc/internals.txt +409 -0
- data/pkgs/tile-0.8.2/doc/label.n +75 -0
- data/pkgs/tile-0.8.2/doc/labelframe.n +64 -0
- data/pkgs/tile-0.8.2/doc/man.macros +239 -0
- data/pkgs/tile-0.8.2/doc/menubutton.n +41 -0
- data/pkgs/tile-0.8.2/doc/notebook.n +188 -0
- data/pkgs/tile-0.8.2/doc/paned.n +95 -0
- data/pkgs/tile-0.8.2/doc/progressbar.n +79 -0
- data/pkgs/tile-0.8.2/doc/radiobutton.n +57 -0
- data/pkgs/tile-0.8.2/doc/scrollbar.n +160 -0
- data/pkgs/tile-0.8.2/doc/separator.n +30 -0
- data/pkgs/tile-0.8.2/doc/sizegrip.n +53 -0
- data/pkgs/tile-0.8.2/doc/style.n +119 -0
- data/pkgs/tile-0.8.2/doc/tile-intro.n +165 -0
- data/pkgs/tile-0.8.2/doc/tmml.options +4 -0
- data/pkgs/tile-0.8.2/doc/treeview.n +415 -0
- data/pkgs/tile-0.8.2/doc/widget.n +227 -0
- data/pkgs/tile-0.8.2/doc/xml/Geometry.tmml +379 -0
- data/pkgs/tile-0.8.2/doc/xml/INDEX.MAP +153 -0
- data/pkgs/tile-0.8.2/doc/xml/Theme.tmml +63 -0
- data/pkgs/tile-0.8.2/doc/xml/button.tmml +134 -0
- data/pkgs/tile-0.8.2/doc/xml/checkbutton.tmml +119 -0
- data/pkgs/tile-0.8.2/doc/xml/combobox.tmml +184 -0
- data/pkgs/tile-0.8.2/doc/xml/dialog.tmml +195 -0
- data/pkgs/tile-0.8.2/doc/xml/entry.tmml +630 -0
- data/pkgs/tile-0.8.2/doc/xml/frame.tmml +98 -0
- data/pkgs/tile-0.8.2/doc/xml/image.tmml +101 -0
- data/pkgs/tile-0.8.2/doc/xml/label.tmml +154 -0
- data/pkgs/tile-0.8.2/doc/xml/labelframe.tmml +116 -0
- data/pkgs/tile-0.8.2/doc/xml/menubutton.tmml +80 -0
- data/pkgs/tile-0.8.2/doc/xml/notebook.tmml +306 -0
- data/pkgs/tile-0.8.2/doc/xml/paned.tmml +154 -0
- data/pkgs/tile-0.8.2/doc/xml/progressbar.tmml +151 -0
- data/pkgs/tile-0.8.2/doc/xml/radiobutton.tmml +109 -0
- data/pkgs/tile-0.8.2/doc/xml/scrollbar.tmml +233 -0
- data/pkgs/tile-0.8.2/doc/xml/separator.tmml +59 -0
- data/pkgs/tile-0.8.2/doc/xml/sizegrip.tmml +82 -0
- data/pkgs/tile-0.8.2/doc/xml/style.tmml +171 -0
- data/pkgs/tile-0.8.2/doc/xml/tile-intro.tmml +192 -0
- data/pkgs/tile-0.8.2/doc/xml/treeview.tmml +604 -0
- data/pkgs/tile-0.8.2/doc/xml/widget.tmml +372 -0
- data/pkgs/tile-0.8.2/entry.o +0 -0
- data/pkgs/tile-0.8.2/frame.o +0 -0
- data/pkgs/tile-0.8.2/generic/Makefile.in +221 -0
- data/pkgs/tile-0.8.2/generic/TODO +493 -0
- data/pkgs/tile-0.8.2/generic/altTheme.c +1172 -0
- data/pkgs/tile-0.8.2/generic/blink.c +168 -0
- data/pkgs/tile-0.8.2/generic/button.c +858 -0
- data/pkgs/tile-0.8.2/generic/cache.c +354 -0
- data/pkgs/tile-0.8.2/generic/clamTheme.c +974 -0
- data/pkgs/tile-0.8.2/generic/classicTheme.c +518 -0
- data/pkgs/tile-0.8.2/generic/configure +10334 -0
- data/pkgs/tile-0.8.2/generic/configure.in +100 -0
- data/pkgs/tile-0.8.2/generic/entry.c +1922 -0
- data/pkgs/tile-0.8.2/generic/frame.c +648 -0
- data/pkgs/tile-0.8.2/generic/gunk.h +44 -0
- data/pkgs/tile-0.8.2/generic/image.c +416 -0
- data/pkgs/tile-0.8.2/generic/label.c +663 -0
- data/pkgs/tile-0.8.2/generic/layout.c +1215 -0
- data/pkgs/tile-0.8.2/generic/manager.c +554 -0
- data/pkgs/tile-0.8.2/generic/manager.h +91 -0
- data/pkgs/tile-0.8.2/generic/notebook.c +1380 -0
- data/pkgs/tile-0.8.2/generic/paned.c +958 -0
- data/pkgs/tile-0.8.2/generic/pkgIndex.tcl.in +7 -0
- data/pkgs/tile-0.8.2/generic/progress.c +549 -0
- data/pkgs/tile-0.8.2/generic/scale.c +526 -0
- data/pkgs/tile-0.8.2/generic/scroll.c +253 -0
- data/pkgs/tile-0.8.2/generic/scrollbar.c +346 -0
- data/pkgs/tile-0.8.2/generic/separator.c +132 -0
- data/pkgs/tile-0.8.2/generic/square.c +306 -0
- data/pkgs/tile-0.8.2/generic/tagset.c +147 -0
- data/pkgs/tile-0.8.2/generic/tile.c +296 -0
- data/pkgs/tile-0.8.2/generic/tkElements.c +1280 -0
- data/pkgs/tile-0.8.2/generic/tkTheme.c +1708 -0
- data/pkgs/tile-0.8.2/generic/tkTheme.h +419 -0
- data/pkgs/tile-0.8.2/generic/tkThemeInt.h +45 -0
- data/pkgs/tile-0.8.2/generic/tkstate.c +268 -0
- data/pkgs/tile-0.8.2/generic/trace.c +145 -0
- data/pkgs/tile-0.8.2/generic/track.c +174 -0
- data/pkgs/tile-0.8.2/generic/treeview.c +3211 -0
- data/pkgs/tile-0.8.2/generic/ttk.decls +154 -0
- data/pkgs/tile-0.8.2/generic/ttkDecls.h +340 -0
- data/pkgs/tile-0.8.2/generic/ttkStubInit.c +61 -0
- data/pkgs/tile-0.8.2/generic/ttkStubLib.c +70 -0
- data/pkgs/tile-0.8.2/generic/widget.c +785 -0
- data/pkgs/tile-0.8.2/generic/widget.h +263 -0
- data/pkgs/tile-0.8.2/image.o +0 -0
- data/pkgs/tile-0.8.2/label.o +0 -0
- data/pkgs/tile-0.8.2/layout.o +0 -0
- data/pkgs/tile-0.8.2/library/altTheme.tcl +101 -0
- data/pkgs/tile-0.8.2/library/aquaTheme.tcl +62 -0
- data/pkgs/tile-0.8.2/library/button.tcl +85 -0
- data/pkgs/tile-0.8.2/library/clamTheme.tcl +139 -0
- data/pkgs/tile-0.8.2/library/classicTheme.tcl +108 -0
- data/pkgs/tile-0.8.2/library/combobox.tcl +439 -0
- data/pkgs/tile-0.8.2/library/cursors.tcl +36 -0
- data/pkgs/tile-0.8.2/library/defaults.tcl +118 -0
- data/pkgs/tile-0.8.2/library/dialog.tcl +274 -0
- data/pkgs/tile-0.8.2/library/entry.tcl +580 -0
- data/pkgs/tile-0.8.2/library/fonts.tcl +153 -0
- data/pkgs/tile-0.8.2/library/icons.tcl +105 -0
- data/pkgs/tile-0.8.2/library/keynav.tcl +192 -0
- data/pkgs/tile-0.8.2/library/menubutton.tcl +171 -0
- data/pkgs/tile-0.8.2/library/notebook.tcl +193 -0
- data/pkgs/tile-0.8.2/library/paned.tcl +87 -0
- data/pkgs/tile-0.8.2/library/progress.tcl +51 -0
- data/pkgs/tile-0.8.2/library/scale.tcl +54 -0
- data/pkgs/tile-0.8.2/library/scrollbar.tcl +125 -0
- data/pkgs/tile-0.8.2/library/sizegrip.tcl +77 -0
- data/pkgs/tile-0.8.2/library/tile.tcl +211 -0
- data/pkgs/tile-0.8.2/library/treeview.tcl +382 -0
- data/pkgs/tile-0.8.2/library/utils.tcl +254 -0
- data/pkgs/tile-0.8.2/library/winTheme.tcl +77 -0
- data/pkgs/tile-0.8.2/library/xpTheme.tcl +63 -0
- data/pkgs/tile-0.8.2/libtile0.8.2.so +0 -0
- data/pkgs/tile-0.8.2/libttkstub.a +0 -0
- data/pkgs/tile-0.8.2/license.terms +24 -0
- data/pkgs/tile-0.8.2/macosx/aquaTheme.c +1076 -0
- data/pkgs/tile-0.8.2/manager.o +0 -0
- data/pkgs/tile-0.8.2/notebook.o +0 -0
- data/pkgs/tile-0.8.2/paned.o +0 -0
- data/pkgs/tile-0.8.2/pkgIndex.tcl +3 -0
- data/pkgs/tile-0.8.2/progress.o +0 -0
- data/pkgs/tile-0.8.2/scale.o +0 -0
- data/pkgs/tile-0.8.2/scroll.o +0 -0
- data/pkgs/tile-0.8.2/scrollbar.o +0 -0
- data/pkgs/tile-0.8.2/separator.o +0 -0
- data/pkgs/tile-0.8.2/tagset.o +0 -0
- data/pkgs/tile-0.8.2/tclconfig/install-sh +119 -0
- data/pkgs/tile-0.8.2/tclconfig/tcl.m4 +4069 -0
- data/pkgs/tile-0.8.2/tclconfig/teax.m4 +109 -0
- data/pkgs/tile-0.8.2/tests/all.tcl +18 -0
- data/pkgs/tile-0.8.2/tests/bwidget.test +103 -0
- data/pkgs/tile-0.8.2/tests/cbtest.tcl +125 -0
- data/pkgs/tile-0.8.2/tests/combobox.test +51 -0
- data/pkgs/tile-0.8.2/tests/compound.tcl +92 -0
- data/pkgs/tile-0.8.2/tests/entry.test +285 -0
- data/pkgs/tile-0.8.2/tests/entrytest.tcl +78 -0
- data/pkgs/tile-0.8.2/tests/image.test +94 -0
- data/pkgs/tile-0.8.2/tests/labelframe.tcl +41 -0
- data/pkgs/tile-0.8.2/tests/labelframe.test +137 -0
- data/pkgs/tile-0.8.2/tests/layout.test +33 -0
- data/pkgs/tile-0.8.2/tests/misc.test +35 -0
- data/pkgs/tile-0.8.2/tests/nbtest.tcl +66 -0
- data/pkgs/tile-0.8.2/tests/notebook.test +500 -0
- data/pkgs/tile-0.8.2/tests/paned.test +298 -0
- data/pkgs/tile-0.8.2/tests/progress.test +92 -0
- data/pkgs/tile-0.8.2/tests/pwtest.tcl +90 -0
- data/pkgs/tile-0.8.2/tests/sbtest.tcl +79 -0
- data/pkgs/tile-0.8.2/tests/scrollbar.test +77 -0
- data/pkgs/tile-0.8.2/tests/sgtest.tcl +52 -0
- data/pkgs/tile-0.8.2/tests/testutils.tcl +20 -0
- data/pkgs/tile-0.8.2/tests/tile.test +674 -0
- data/pkgs/tile-0.8.2/tests/treetags.test +78 -0
- data/pkgs/tile-0.8.2/tests/treeview.test +563 -0
- data/pkgs/tile-0.8.2/tests/tvtest.tcl +332 -0
- data/pkgs/tile-0.8.2/tests/validate.test +278 -0
- data/pkgs/tile-0.8.2/tile.o +0 -0
- data/pkgs/tile-0.8.2/tkElements.o +0 -0
- data/pkgs/tile-0.8.2/tkTheme.o +0 -0
- data/pkgs/tile-0.8.2/tkstate.o +0 -0
- data/pkgs/tile-0.8.2/tools/genStubs.tcl +861 -0
- data/pkgs/tile-0.8.2/trace.o +0 -0
- data/pkgs/tile-0.8.2/track.o +0 -0
- data/pkgs/tile-0.8.2/treeview.o +0 -0
- data/pkgs/tile-0.8.2/ttkStubInit.o +0 -0
- data/pkgs/tile-0.8.2/ttkStubLib.o +0 -0
- data/pkgs/tile-0.8.2/widget.o +0 -0
- data/pkgs/tile-0.8.2/win/Tile.dsp +261 -0
- data/pkgs/tile-0.8.2/win/makefile.vc +527 -0
- data/pkgs/tile-0.8.2/win/monitor.c +164 -0
- data/pkgs/tile-0.8.2/win/nmakehlp.c +483 -0
- data/pkgs/tile-0.8.2/win/rules.vc +512 -0
- data/pkgs/tile-0.8.2/win/tile.rc +40 -0
- data/pkgs/tile-0.8.2/win/winTheme.c +734 -0
- data/pkgs/tile-0.8.2/win/xpTheme.c +1029 -0
- data/spec/app_spec.rb +48 -0
- data/spec/customer_spec.rb +31 -0
- data/spec/fixtures/graph.expectation +18 -0
- data/spec/payment_spec.rb +19 -0
- data/spec/pratt_spec.rb +148 -0
- data/spec/project_spec.rb +163 -0
- data/spec/rcov.opts +0 -0
- data/spec/spec.opts +1 -0
- data/spec/spec_helper.rb +21 -0
- data/spec/whence_spec.rb +54 -0
- data/tasks/pratt.rb +84 -0
- data/templates/model.eruby +12 -0
- data/templates/spec.eruby +8 -0
- data/views/env.rb +22 -0
- data/views/graph.eruby +20 -0
- data/views/invoice.eruby +148 -0
- data/views/main.rb +92 -0
- data/views/pid.eruby +3 -0
- data/views/pop.rb +94 -0
- data/views/pop2.rb +75 -0
- data/views/raw.eruby +11 -0
- metadata +390 -0
|
@@ -0,0 +1,1215 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* ttkLayout.c --
|
|
3
|
+
*
|
|
4
|
+
* Generic layout processing.
|
|
5
|
+
*
|
|
6
|
+
* Copyright (c) 2003 Joe English. Freely redistributable.
|
|
7
|
+
*
|
|
8
|
+
* layout.c,v 1.76 2007/12/02 04:34:30 jenglish Exp
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
#include <string.h>
|
|
12
|
+
#include <tk.h>
|
|
13
|
+
#include "tkThemeInt.h"
|
|
14
|
+
|
|
15
|
+
#define MAX(a,b) (a > b ? a : b)
|
|
16
|
+
#define MIN(a,b) (a < b ? a : b)
|
|
17
|
+
|
|
18
|
+
/*------------------------------------------------------------------------
|
|
19
|
+
* +++ Ttk_Box and Ttk_Padding utilities:
|
|
20
|
+
*/
|
|
21
|
+
|
|
22
|
+
Ttk_Box Ttk_MakeBox(int x, int y, int width, int height)
|
|
23
|
+
{
|
|
24
|
+
Ttk_Box b;
|
|
25
|
+
b.x = x; b.y = y; b.width = width; b.height = height;
|
|
26
|
+
return b;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
int Ttk_BoxContains(Ttk_Box box, int x, int y)
|
|
30
|
+
{
|
|
31
|
+
return box.x <= x && x < box.x + box.width
|
|
32
|
+
&& box.y <= y && y < box.y + box.height;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
Tcl_Obj *Ttk_NewBoxObj(Ttk_Box box)
|
|
36
|
+
{
|
|
37
|
+
Tcl_Obj *result[4];
|
|
38
|
+
|
|
39
|
+
result[0] = Tcl_NewIntObj(box.x);
|
|
40
|
+
result[1] = Tcl_NewIntObj(box.y);
|
|
41
|
+
result[2] = Tcl_NewIntObj(box.width);
|
|
42
|
+
result[3] = Tcl_NewIntObj(box.height);
|
|
43
|
+
|
|
44
|
+
return Tcl_NewListObj(4, result);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
/*
|
|
50
|
+
* packTop, packBottom, packLeft, packRight --
|
|
51
|
+
* Carve out a parcel of the specified height (resp width)
|
|
52
|
+
* from the specified cavity.
|
|
53
|
+
*
|
|
54
|
+
* Returns:
|
|
55
|
+
* The new parcel.
|
|
56
|
+
*
|
|
57
|
+
* Side effects:
|
|
58
|
+
* Adjust the cavity.
|
|
59
|
+
*/
|
|
60
|
+
|
|
61
|
+
static Ttk_Box packTop(Ttk_Box *cavity, int height)
|
|
62
|
+
{
|
|
63
|
+
Ttk_Box parcel;
|
|
64
|
+
height = MIN(height, cavity->height);
|
|
65
|
+
parcel = Ttk_MakeBox(cavity->x, cavity->y, cavity->width, height);
|
|
66
|
+
cavity->y += height;
|
|
67
|
+
cavity->height -= height;
|
|
68
|
+
return parcel;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
static Ttk_Box packBottom(Ttk_Box *cavity, int height)
|
|
72
|
+
{
|
|
73
|
+
height = MIN(height, cavity->height);
|
|
74
|
+
cavity->height -= height;
|
|
75
|
+
return Ttk_MakeBox(
|
|
76
|
+
cavity->x, cavity->y + cavity->height,
|
|
77
|
+
cavity->width, height);
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
static Ttk_Box packLeft(Ttk_Box *cavity, int width)
|
|
81
|
+
{
|
|
82
|
+
Ttk_Box parcel;
|
|
83
|
+
width = MIN(width, cavity->width);
|
|
84
|
+
parcel = Ttk_MakeBox(cavity->x, cavity->y, width,cavity->height);
|
|
85
|
+
cavity->x += width;
|
|
86
|
+
cavity->width -= width;
|
|
87
|
+
return parcel;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
static Ttk_Box packRight(Ttk_Box *cavity, int width)
|
|
91
|
+
{
|
|
92
|
+
width = MIN(width, cavity->width);
|
|
93
|
+
cavity->width -= width;
|
|
94
|
+
return Ttk_MakeBox(cavity->x + cavity->width,
|
|
95
|
+
cavity->y, width, cavity->height);
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/*
|
|
99
|
+
* Ttk_PackBox --
|
|
100
|
+
* Carve out a parcel of the specified size on the specified side
|
|
101
|
+
* in the specified cavity.
|
|
102
|
+
*
|
|
103
|
+
* Returns:
|
|
104
|
+
* The new parcel.
|
|
105
|
+
*
|
|
106
|
+
* Side effects:
|
|
107
|
+
* Adjust the cavity.
|
|
108
|
+
*/
|
|
109
|
+
|
|
110
|
+
Ttk_Box Ttk_PackBox(Ttk_Box *cavity, int width, int height, Ttk_Side side)
|
|
111
|
+
{
|
|
112
|
+
switch (side) {
|
|
113
|
+
default:
|
|
114
|
+
case TTK_SIDE_TOP: return packTop(cavity, height);
|
|
115
|
+
case TTK_SIDE_BOTTOM: return packBottom(cavity, height);
|
|
116
|
+
case TTK_SIDE_LEFT: return packLeft(cavity, width);
|
|
117
|
+
case TTK_SIDE_RIGHT: return packRight(cavity, width);
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
/*
|
|
122
|
+
* Ttk_PadBox --
|
|
123
|
+
* Shrink a box by the specified padding amount.
|
|
124
|
+
*/
|
|
125
|
+
Ttk_Box Ttk_PadBox(Ttk_Box b, Ttk_Padding p)
|
|
126
|
+
{
|
|
127
|
+
b.x += p.left;
|
|
128
|
+
b.y += p.top;
|
|
129
|
+
b.width -= (p.left + p.right);
|
|
130
|
+
b.height -= (p.top + p.bottom);
|
|
131
|
+
if (b.width <= 0) b.width = 1;
|
|
132
|
+
if (b.height <= 0) b.height = 1;
|
|
133
|
+
return b;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
/*
|
|
137
|
+
* Ttk_ExpandBox --
|
|
138
|
+
* Grow a box by the specified padding amount.
|
|
139
|
+
*/
|
|
140
|
+
Ttk_Box Ttk_ExpandBox(Ttk_Box b, Ttk_Padding p)
|
|
141
|
+
{
|
|
142
|
+
b.x -= p.left;
|
|
143
|
+
b.y -= p.top;
|
|
144
|
+
b.width += (p.left + p.right);
|
|
145
|
+
b.height += (p.top + p.bottom);
|
|
146
|
+
return b;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
/*
|
|
150
|
+
* Ttk_StickBox --
|
|
151
|
+
* Place a box of size w * h in the specified parcel,
|
|
152
|
+
* according to the specified sticky bits.
|
|
153
|
+
*/
|
|
154
|
+
Ttk_Box Ttk_StickBox(Ttk_Box parcel, int width, int height, unsigned sticky)
|
|
155
|
+
{
|
|
156
|
+
int dx, dy;
|
|
157
|
+
|
|
158
|
+
if (width > parcel.width) width = parcel.width;
|
|
159
|
+
if (height > parcel.height) height = parcel.height;
|
|
160
|
+
|
|
161
|
+
dx = parcel.width - width;
|
|
162
|
+
dy = parcel.height - height;
|
|
163
|
+
|
|
164
|
+
/*
|
|
165
|
+
* X coordinate adjustment:
|
|
166
|
+
*/
|
|
167
|
+
switch (sticky & (TTK_STICK_W | TTK_STICK_E))
|
|
168
|
+
{
|
|
169
|
+
case TTK_STICK_W | TTK_STICK_E:
|
|
170
|
+
/* no-op -- use entire parcel width */
|
|
171
|
+
break;
|
|
172
|
+
case TTK_STICK_W:
|
|
173
|
+
parcel.width = width;
|
|
174
|
+
break;
|
|
175
|
+
case TTK_STICK_E:
|
|
176
|
+
parcel.x += dx;
|
|
177
|
+
parcel.width = width;
|
|
178
|
+
break;
|
|
179
|
+
default :
|
|
180
|
+
parcel.x += dx / 2;
|
|
181
|
+
parcel.width = width;
|
|
182
|
+
break;
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
/*
|
|
186
|
+
* Y coordinate adjustment:
|
|
187
|
+
*/
|
|
188
|
+
switch (sticky & (TTK_STICK_N | TTK_STICK_S))
|
|
189
|
+
{
|
|
190
|
+
case TTK_STICK_N | TTK_STICK_S:
|
|
191
|
+
/* use entire parcel height */
|
|
192
|
+
break;
|
|
193
|
+
case TTK_STICK_N:
|
|
194
|
+
parcel.height = height;
|
|
195
|
+
break;
|
|
196
|
+
case TTK_STICK_S:
|
|
197
|
+
parcel.y += dy;
|
|
198
|
+
parcel.height = height;
|
|
199
|
+
break;
|
|
200
|
+
default :
|
|
201
|
+
parcel.y += dy / 2;
|
|
202
|
+
parcel.height = height;
|
|
203
|
+
break;
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
return parcel;
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
/*
|
|
210
|
+
* AnchorToSticky --
|
|
211
|
+
* Convert a Tk_Anchor enum to a TTK_STICKY bitmask.
|
|
212
|
+
*/
|
|
213
|
+
static Ttk_Sticky AnchorToSticky(Tk_Anchor anchor)
|
|
214
|
+
{
|
|
215
|
+
switch (anchor)
|
|
216
|
+
{
|
|
217
|
+
case TK_ANCHOR_N: return TTK_STICK_N;
|
|
218
|
+
case TK_ANCHOR_NE: return TTK_STICK_N | TTK_STICK_E;
|
|
219
|
+
case TK_ANCHOR_E: return TTK_STICK_E;
|
|
220
|
+
case TK_ANCHOR_SE: return TTK_STICK_S | TTK_STICK_E;
|
|
221
|
+
case TK_ANCHOR_S: return TTK_STICK_S;
|
|
222
|
+
case TK_ANCHOR_SW: return TTK_STICK_S | TTK_STICK_W;
|
|
223
|
+
case TK_ANCHOR_W: return TTK_STICK_W;
|
|
224
|
+
case TK_ANCHOR_NW: return TTK_STICK_N | TTK_STICK_W;
|
|
225
|
+
default:
|
|
226
|
+
case TK_ANCHOR_CENTER: return 0;
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
/*
|
|
231
|
+
* Ttk_AnchorBox --
|
|
232
|
+
* Place a box of size w * h in the specified parcel,
|
|
233
|
+
* according to the specified anchor.
|
|
234
|
+
*/
|
|
235
|
+
Ttk_Box Ttk_AnchorBox(Ttk_Box parcel, int width, int height, Tk_Anchor anchor)
|
|
236
|
+
{
|
|
237
|
+
return Ttk_StickBox(parcel, width, height, AnchorToSticky(anchor));
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
/*
|
|
241
|
+
* Ttk_PlaceBox --
|
|
242
|
+
* Combine Ttk_PackBox() and Ttk_StickBox().
|
|
243
|
+
*/
|
|
244
|
+
Ttk_Box Ttk_PlaceBox(
|
|
245
|
+
Ttk_Box *cavity, int width, int height, Ttk_Side side, unsigned sticky)
|
|
246
|
+
{
|
|
247
|
+
return Ttk_StickBox(
|
|
248
|
+
Ttk_PackBox(cavity, width, height, side), width, height, sticky);
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
/*
|
|
252
|
+
* Ttk_PositionBox --
|
|
253
|
+
* Pack and stick a box according to PositionSpec flags.
|
|
254
|
+
*/
|
|
255
|
+
TTKAPI Ttk_Box
|
|
256
|
+
Ttk_PositionBox(Ttk_Box *cavity, int width, int height, Ttk_PositionSpec flags)
|
|
257
|
+
{
|
|
258
|
+
Ttk_Box parcel;
|
|
259
|
+
|
|
260
|
+
if (flags & TTK_EXPAND) parcel = *cavity;
|
|
261
|
+
else if (flags & TTK_PACK_TOP) parcel = packTop(cavity, height);
|
|
262
|
+
else if (flags & TTK_PACK_LEFT) parcel = packLeft(cavity, width);
|
|
263
|
+
else if (flags & TTK_PACK_BOTTOM) parcel = packBottom(cavity, height);
|
|
264
|
+
else if (flags & TTK_PACK_RIGHT) parcel = packRight(cavity, width);
|
|
265
|
+
else parcel = *cavity;
|
|
266
|
+
|
|
267
|
+
return Ttk_StickBox(parcel, width, height, flags);
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
/*
|
|
271
|
+
* TTKInitPadding --
|
|
272
|
+
* Common factor of Ttk_GetPaddingFromObj and Ttk_GetBorderFromObj.
|
|
273
|
+
* Initializes Ttk_Padding record, supplying default values
|
|
274
|
+
* for missing entries.
|
|
275
|
+
*/
|
|
276
|
+
static void TTKInitPadding(int padc, int pixels[4], Ttk_Padding *pad)
|
|
277
|
+
{
|
|
278
|
+
switch (padc)
|
|
279
|
+
{
|
|
280
|
+
case 0: pixels[0] = 0; /*FALLTHRU*/
|
|
281
|
+
case 1: pixels[1] = pixels[0]; /*FALLTHRU*/
|
|
282
|
+
case 2: pixels[2] = pixels[0]; /*FALLTHRU*/
|
|
283
|
+
case 3: pixels[3] = pixels[1]; /*FALLTHRU*/
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
pad->left = (short)pixels[0];
|
|
287
|
+
pad->top = (short)pixels[1];
|
|
288
|
+
pad->right = (short)pixels[2];
|
|
289
|
+
pad->bottom = (short)pixels[3];
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
/*
|
|
293
|
+
* Ttk_GetPaddingFromObj --
|
|
294
|
+
*
|
|
295
|
+
* Extract a padding specification from a Tcl_Obj * scaled
|
|
296
|
+
* to work with a particular Tk_Window.
|
|
297
|
+
*
|
|
298
|
+
* The string representation of a Ttk_Padding is a list
|
|
299
|
+
* of one to four Tk_Pixel specifications, corresponding
|
|
300
|
+
* to the left, top, right, and bottom padding.
|
|
301
|
+
*
|
|
302
|
+
* If the 'bottom' (fourth) element is missing, it defaults to 'top'.
|
|
303
|
+
* If the 'right' (third) element is missing, it defaults to 'left'.
|
|
304
|
+
* If the 'top' (second) element is missing, it defaults to 'left'.
|
|
305
|
+
*
|
|
306
|
+
* The internal representation is a Tcl_ListObj containing
|
|
307
|
+
* one to four Tk_PixelObj objects.
|
|
308
|
+
*
|
|
309
|
+
* Returns:
|
|
310
|
+
* TCL_OK or TCL_ERROR. In the latter case an error message is
|
|
311
|
+
* left in 'interp' and '*paddingPtr' is set to all-zeros.
|
|
312
|
+
* Otherwise, *paddingPtr is filled in with the padding specification.
|
|
313
|
+
*
|
|
314
|
+
*/
|
|
315
|
+
int Ttk_GetPaddingFromObj(
|
|
316
|
+
Tcl_Interp *interp,
|
|
317
|
+
Tk_Window tkwin,
|
|
318
|
+
Tcl_Obj *objPtr,
|
|
319
|
+
Ttk_Padding *pad)
|
|
320
|
+
{
|
|
321
|
+
Tcl_Obj **padv;
|
|
322
|
+
int i, padc, pixels[4];
|
|
323
|
+
|
|
324
|
+
if (TCL_OK != Tcl_ListObjGetElements(interp, objPtr, &padc, &padv)) {
|
|
325
|
+
goto error;
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
if (padc > 4) {
|
|
329
|
+
if (interp) {
|
|
330
|
+
Tcl_ResetResult(interp);
|
|
331
|
+
Tcl_AppendResult(interp, "Wrong #elements in padding spec", NULL);
|
|
332
|
+
}
|
|
333
|
+
goto error;
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
for (i=0; i < padc; ++i) {
|
|
337
|
+
if (Tk_GetPixelsFromObj(interp, tkwin, padv[i], &pixels[i]) != TCL_OK) {
|
|
338
|
+
goto error;
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
TTKInitPadding(padc, pixels, pad);
|
|
343
|
+
return TCL_OK;
|
|
344
|
+
|
|
345
|
+
error:
|
|
346
|
+
pad->left = pad->top = pad->right = pad->bottom = 0;
|
|
347
|
+
return TCL_ERROR;
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
/* Ttk_GetBorderFromObj --
|
|
351
|
+
* Same as Ttk_GetPaddingFromObj, except padding is a list of integers
|
|
352
|
+
* instead of Tk_Pixel specifications. Does not require a Tk_Window
|
|
353
|
+
* parameter.
|
|
354
|
+
*
|
|
355
|
+
*/
|
|
356
|
+
int Ttk_GetBorderFromObj(Tcl_Interp *interp, Tcl_Obj *objPtr, Ttk_Padding *pad)
|
|
357
|
+
{
|
|
358
|
+
Tcl_Obj **padv;
|
|
359
|
+
int i, padc, pixels[4];
|
|
360
|
+
|
|
361
|
+
if (TCL_OK != Tcl_ListObjGetElements(interp, objPtr, &padc, &padv)) {
|
|
362
|
+
goto error;
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
if (padc > 4) {
|
|
366
|
+
if (interp) {
|
|
367
|
+
Tcl_ResetResult(interp);
|
|
368
|
+
Tcl_AppendResult(interp, "Wrong #elements in border spec", NULL);
|
|
369
|
+
}
|
|
370
|
+
goto error;
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
for (i=0; i < padc; ++i) {
|
|
374
|
+
if (Tcl_GetIntFromObj(interp, padv[i], &pixels[i]) != TCL_OK) {
|
|
375
|
+
goto error;
|
|
376
|
+
}
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
TTKInitPadding(padc, pixels, pad);
|
|
380
|
+
return TCL_OK;
|
|
381
|
+
|
|
382
|
+
error:
|
|
383
|
+
pad->left = pad->top = pad->right = pad->bottom = 0;
|
|
384
|
+
return TCL_ERROR;
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
/*
|
|
388
|
+
* Ttk_MakePadding --
|
|
389
|
+
* Return an initialized Ttk_Padding structure.
|
|
390
|
+
*/
|
|
391
|
+
Ttk_Padding Ttk_MakePadding(short left, short top, short right, short bottom)
|
|
392
|
+
{
|
|
393
|
+
Ttk_Padding pad;
|
|
394
|
+
pad.left = left;
|
|
395
|
+
pad.top = top;
|
|
396
|
+
pad.right = right;
|
|
397
|
+
pad.bottom = bottom;
|
|
398
|
+
return pad;
|
|
399
|
+
}
|
|
400
|
+
|
|
401
|
+
/*
|
|
402
|
+
* Ttk_UniformPadding --
|
|
403
|
+
* Returns a uniform Ttk_Padding structure, with the same
|
|
404
|
+
* border width on all sides.
|
|
405
|
+
*/
|
|
406
|
+
Ttk_Padding Ttk_UniformPadding(short borderWidth)
|
|
407
|
+
{
|
|
408
|
+
Ttk_Padding pad;
|
|
409
|
+
pad.left = pad.top = pad.right = pad.bottom = borderWidth;
|
|
410
|
+
return pad;
|
|
411
|
+
}
|
|
412
|
+
|
|
413
|
+
/*
|
|
414
|
+
* Ttk_AddPadding --
|
|
415
|
+
* Combine two padding records.
|
|
416
|
+
*/
|
|
417
|
+
Ttk_Padding Ttk_AddPadding(Ttk_Padding p1, Ttk_Padding p2)
|
|
418
|
+
{
|
|
419
|
+
p1.left += p2.left;
|
|
420
|
+
p1.top += p2.top;
|
|
421
|
+
p1.right += p2.right;
|
|
422
|
+
p1.bottom += p2.bottom;
|
|
423
|
+
return p1;
|
|
424
|
+
}
|
|
425
|
+
|
|
426
|
+
/* Ttk_RelievePadding --
|
|
427
|
+
* Add an extra n pixels of padding according to specified relief.
|
|
428
|
+
* This may be used in element geometry procedures to simulate
|
|
429
|
+
* a "pressed-in" look for pushbuttons.
|
|
430
|
+
*/
|
|
431
|
+
Ttk_Padding Ttk_RelievePadding(Ttk_Padding padding, int relief, int n)
|
|
432
|
+
{
|
|
433
|
+
switch (relief)
|
|
434
|
+
{
|
|
435
|
+
case TK_RELIEF_RAISED:
|
|
436
|
+
padding.right += n;
|
|
437
|
+
padding.bottom += n;
|
|
438
|
+
break;
|
|
439
|
+
case TK_RELIEF_SUNKEN: /* shift */
|
|
440
|
+
padding.left += n;
|
|
441
|
+
padding.top += n;
|
|
442
|
+
break;
|
|
443
|
+
default:
|
|
444
|
+
{
|
|
445
|
+
int h1 = n/2, h2 = h1 + n % 2;
|
|
446
|
+
padding.left += h1;
|
|
447
|
+
padding.top += h1;
|
|
448
|
+
padding.right += h2;
|
|
449
|
+
padding.bottom += h2;
|
|
450
|
+
break;
|
|
451
|
+
}
|
|
452
|
+
}
|
|
453
|
+
return padding;
|
|
454
|
+
}
|
|
455
|
+
|
|
456
|
+
/*
|
|
457
|
+
* Ttk_GetStickyFromObj --
|
|
458
|
+
* Returns a stickiness specification from the specified Tcl_Obj*,
|
|
459
|
+
* consisting of any combination of n, s, e, and w.
|
|
460
|
+
*
|
|
461
|
+
* Returns: TCL_OK if objPtr holds a valid stickiness specification,
|
|
462
|
+
* otherwise TCL_ERROR. interp is used for error reporting if non-NULL.
|
|
463
|
+
*
|
|
464
|
+
*/
|
|
465
|
+
int Ttk_GetStickyFromObj(
|
|
466
|
+
Tcl_Interp *interp, Tcl_Obj *objPtr, Ttk_Sticky *result)
|
|
467
|
+
{
|
|
468
|
+
const char *string = Tcl_GetString(objPtr);
|
|
469
|
+
Ttk_Sticky sticky = 0;
|
|
470
|
+
char c;
|
|
471
|
+
|
|
472
|
+
while ((c = *string++) != '\0') {
|
|
473
|
+
switch (c) {
|
|
474
|
+
case 'w': case 'W': sticky |= TTK_STICK_W; break;
|
|
475
|
+
case 'e': case 'E': sticky |= TTK_STICK_E; break;
|
|
476
|
+
case 'n': case 'N': sticky |= TTK_STICK_N; break;
|
|
477
|
+
case 's': case 'S': sticky |= TTK_STICK_S; break;
|
|
478
|
+
default:
|
|
479
|
+
if (interp) {
|
|
480
|
+
Tcl_ResetResult(interp);
|
|
481
|
+
Tcl_AppendResult(interp,
|
|
482
|
+
"Bad -sticky specification ",
|
|
483
|
+
Tcl_GetString(objPtr),
|
|
484
|
+
NULL);
|
|
485
|
+
}
|
|
486
|
+
return TCL_ERROR;
|
|
487
|
+
}
|
|
488
|
+
}
|
|
489
|
+
|
|
490
|
+
*result = sticky;
|
|
491
|
+
return TCL_OK;
|
|
492
|
+
}
|
|
493
|
+
|
|
494
|
+
/* Ttk_NewStickyObj --
|
|
495
|
+
* Construct a new Tcl_Obj * containing a stickiness specification.
|
|
496
|
+
*/
|
|
497
|
+
Tcl_Obj *Ttk_NewStickyObj(Ttk_Sticky sticky)
|
|
498
|
+
{
|
|
499
|
+
char buf[5];
|
|
500
|
+
char *p = buf;
|
|
501
|
+
|
|
502
|
+
if (sticky & TTK_STICK_N) *p++ = 'n';
|
|
503
|
+
if (sticky & TTK_STICK_S) *p++ = 's';
|
|
504
|
+
if (sticky & TTK_STICK_W) *p++ = 'w';
|
|
505
|
+
if (sticky & TTK_STICK_E) *p++ = 'e';
|
|
506
|
+
|
|
507
|
+
*p = '\0';
|
|
508
|
+
return Tcl_NewStringObj(buf, p - buf);
|
|
509
|
+
}
|
|
510
|
+
|
|
511
|
+
/*------------------------------------------------------------------------
|
|
512
|
+
* +++ Layout nodes.
|
|
513
|
+
*/
|
|
514
|
+
struct Ttk_LayoutNode_
|
|
515
|
+
{
|
|
516
|
+
unsigned flags; /* Packing and sticky flags */
|
|
517
|
+
Ttk_ElementImpl element; /* Element implementation */
|
|
518
|
+
Ttk_State state; /* Current state */
|
|
519
|
+
Ttk_Box parcel; /* allocated parcel */
|
|
520
|
+
Ttk_LayoutNode *next, *child;
|
|
521
|
+
};
|
|
522
|
+
|
|
523
|
+
static Ttk_LayoutNode *Ttk_NewLayoutNode(unsigned flags, Ttk_ElementImpl element)
|
|
524
|
+
{
|
|
525
|
+
Ttk_LayoutNode *node = (Ttk_LayoutNode*)ckalloc(sizeof(Ttk_LayoutNode));
|
|
526
|
+
|
|
527
|
+
node->flags = flags;
|
|
528
|
+
node->element = element;
|
|
529
|
+
node->state = 0u;
|
|
530
|
+
node->next = node->child = 0;
|
|
531
|
+
/* parcel uninitialized */
|
|
532
|
+
|
|
533
|
+
return node;
|
|
534
|
+
}
|
|
535
|
+
|
|
536
|
+
static void Ttk_FreeLayoutNode(Ttk_LayoutNode *node)
|
|
537
|
+
{
|
|
538
|
+
while (node) {
|
|
539
|
+
Ttk_LayoutNode *next = node->next;
|
|
540
|
+
Ttk_FreeLayoutNode(node->child);
|
|
541
|
+
ckfree((ClientData)node);
|
|
542
|
+
node = next;
|
|
543
|
+
}
|
|
544
|
+
}
|
|
545
|
+
|
|
546
|
+
/*------------------------------------------------------------------------
|
|
547
|
+
* +++ Layout templates.
|
|
548
|
+
*/
|
|
549
|
+
|
|
550
|
+
struct Ttk_TemplateNode_ {
|
|
551
|
+
char *name;
|
|
552
|
+
unsigned flags;
|
|
553
|
+
struct Ttk_TemplateNode_ *next, *child;
|
|
554
|
+
};
|
|
555
|
+
|
|
556
|
+
static Ttk_TemplateNode *Ttk_NewTemplateNode(const char *name, unsigned flags)
|
|
557
|
+
{
|
|
558
|
+
Ttk_TemplateNode *op = (Ttk_TemplateNode*)ckalloc(sizeof(*op));
|
|
559
|
+
op->name = ckalloc(strlen(name) + 1); strcpy(op->name, name);
|
|
560
|
+
op->flags = flags;
|
|
561
|
+
op->next = op->child = 0;
|
|
562
|
+
return op;
|
|
563
|
+
}
|
|
564
|
+
|
|
565
|
+
void Ttk_FreeLayoutTemplate(Ttk_LayoutTemplate op)
|
|
566
|
+
{
|
|
567
|
+
while (op) {
|
|
568
|
+
Ttk_LayoutTemplate next = op->next;
|
|
569
|
+
Ttk_FreeLayoutTemplate(op->child);
|
|
570
|
+
ckfree(op->name);
|
|
571
|
+
ckfree((ClientData)op);
|
|
572
|
+
op = next;
|
|
573
|
+
}
|
|
574
|
+
}
|
|
575
|
+
|
|
576
|
+
/* InstantiateLayout --
|
|
577
|
+
* Create a layout tree from a template.
|
|
578
|
+
*/
|
|
579
|
+
static Ttk_LayoutNode *
|
|
580
|
+
Ttk_InstantiateLayout(Ttk_Theme theme, Ttk_TemplateNode *op)
|
|
581
|
+
{
|
|
582
|
+
Ttk_ElementImpl elementImpl = Ttk_GetElement(theme, op->name);
|
|
583
|
+
Ttk_LayoutNode *node = Ttk_NewLayoutNode(op->flags, elementImpl);
|
|
584
|
+
|
|
585
|
+
if (op->next) {
|
|
586
|
+
node->next = Ttk_InstantiateLayout(theme,op->next);
|
|
587
|
+
}
|
|
588
|
+
if (op->child) {
|
|
589
|
+
node->child = Ttk_InstantiateLayout(theme,op->child);
|
|
590
|
+
}
|
|
591
|
+
|
|
592
|
+
return node;
|
|
593
|
+
}
|
|
594
|
+
|
|
595
|
+
/*
|
|
596
|
+
* Ttk_ParseLayoutTemplate --
|
|
597
|
+
* Convert a Tcl list into a layout template.
|
|
598
|
+
*
|
|
599
|
+
* Syntax:
|
|
600
|
+
* layoutSpec ::= { elementName ?-option value ...? }+
|
|
601
|
+
*/
|
|
602
|
+
|
|
603
|
+
/* NB: This must match bit definitions TTK_PACK_LEFT etc. */
|
|
604
|
+
static const char *packSideStrings[] =
|
|
605
|
+
{ "left", "right", "top", "bottom", NULL };
|
|
606
|
+
|
|
607
|
+
Ttk_LayoutTemplate Ttk_ParseLayoutTemplate(Tcl_Interp *interp, Tcl_Obj *objPtr)
|
|
608
|
+
{
|
|
609
|
+
enum { OP_SIDE, OP_STICKY, OP_EXPAND, OP_BORDER, OP_UNIT, OP_CHILDREN };
|
|
610
|
+
static const char *optStrings[] = {
|
|
611
|
+
"-side", "-sticky", "-expand", "-border", "-unit", "-children", 0 };
|
|
612
|
+
|
|
613
|
+
int i = 0, objc;
|
|
614
|
+
Tcl_Obj **objv;
|
|
615
|
+
Ttk_TemplateNode *head = 0, *tail = 0;
|
|
616
|
+
|
|
617
|
+
if (Tcl_ListObjGetElements(interp, objPtr, &objc, &objv) != TCL_OK)
|
|
618
|
+
return 0;
|
|
619
|
+
|
|
620
|
+
while (i < objc) {
|
|
621
|
+
char *elementName = Tcl_GetString(objv[i]);
|
|
622
|
+
unsigned flags = 0x0, sticky = TTK_FILL_BOTH;
|
|
623
|
+
Tcl_Obj *childSpec = 0;
|
|
624
|
+
|
|
625
|
+
/*
|
|
626
|
+
* Parse options:
|
|
627
|
+
*/
|
|
628
|
+
++i;
|
|
629
|
+
while (i < objc) {
|
|
630
|
+
const char *optName = Tcl_GetString(objv[i]);
|
|
631
|
+
int option, value;
|
|
632
|
+
|
|
633
|
+
if (optName[0] != '-')
|
|
634
|
+
break;
|
|
635
|
+
|
|
636
|
+
if (Tcl_GetIndexFromObj(
|
|
637
|
+
interp, objv[i], optStrings, "option", 0, &option)
|
|
638
|
+
!= TCL_OK)
|
|
639
|
+
{
|
|
640
|
+
goto error;
|
|
641
|
+
}
|
|
642
|
+
|
|
643
|
+
if (++i >= objc) {
|
|
644
|
+
Tcl_ResetResult(interp);
|
|
645
|
+
Tcl_AppendResult(interp,
|
|
646
|
+
"Missing value for option ",Tcl_GetString(objv[i-1]),
|
|
647
|
+
NULL);
|
|
648
|
+
goto error;
|
|
649
|
+
}
|
|
650
|
+
|
|
651
|
+
switch (option) {
|
|
652
|
+
case OP_SIDE: /* <<NOTE-PACKSIDE>> */
|
|
653
|
+
if (Tcl_GetIndexFromObj(interp, objv[i], packSideStrings,
|
|
654
|
+
"side", 0, &value) != TCL_OK)
|
|
655
|
+
{
|
|
656
|
+
goto error;
|
|
657
|
+
}
|
|
658
|
+
flags |= (TTK_PACK_LEFT << value);
|
|
659
|
+
|
|
660
|
+
break;
|
|
661
|
+
case OP_STICKY:
|
|
662
|
+
if (Ttk_GetStickyFromObj(interp,objv[i],&sticky) != TCL_OK)
|
|
663
|
+
goto error;
|
|
664
|
+
break;
|
|
665
|
+
case OP_EXPAND:
|
|
666
|
+
if (Tcl_GetBooleanFromObj(interp,objv[i],&value) != TCL_OK)
|
|
667
|
+
goto error;
|
|
668
|
+
if (value)
|
|
669
|
+
flags |= TTK_EXPAND;
|
|
670
|
+
break;
|
|
671
|
+
case OP_BORDER:
|
|
672
|
+
if (Tcl_GetBooleanFromObj(interp,objv[i],&value) != TCL_OK)
|
|
673
|
+
goto error;
|
|
674
|
+
if (value)
|
|
675
|
+
flags |= TTK_BORDER;
|
|
676
|
+
break;
|
|
677
|
+
case OP_UNIT:
|
|
678
|
+
if (Tcl_GetBooleanFromObj(interp,objv[i],&value) != TCL_OK)
|
|
679
|
+
goto error;
|
|
680
|
+
if (value)
|
|
681
|
+
flags |= TTK_UNIT;
|
|
682
|
+
break;
|
|
683
|
+
case OP_CHILDREN:
|
|
684
|
+
childSpec = objv[i];
|
|
685
|
+
break;
|
|
686
|
+
}
|
|
687
|
+
++i;
|
|
688
|
+
}
|
|
689
|
+
|
|
690
|
+
/*
|
|
691
|
+
* Build new node:
|
|
692
|
+
*/
|
|
693
|
+
if (tail) {
|
|
694
|
+
tail->next = Ttk_NewTemplateNode(elementName, flags | sticky);
|
|
695
|
+
tail = tail->next;
|
|
696
|
+
} else {
|
|
697
|
+
head = tail = Ttk_NewTemplateNode(elementName, flags | sticky);
|
|
698
|
+
}
|
|
699
|
+
if (childSpec) {
|
|
700
|
+
tail->child = Ttk_ParseLayoutTemplate(interp, childSpec);
|
|
701
|
+
if (!tail->child) {
|
|
702
|
+
goto error;
|
|
703
|
+
}
|
|
704
|
+
}
|
|
705
|
+
}
|
|
706
|
+
|
|
707
|
+
return head;
|
|
708
|
+
|
|
709
|
+
error:
|
|
710
|
+
Ttk_FreeLayoutTemplate(head);
|
|
711
|
+
return 0;
|
|
712
|
+
}
|
|
713
|
+
|
|
714
|
+
/* Ttk_BuildLayoutTemplate --
|
|
715
|
+
* Build a layout template tree from a statically defined
|
|
716
|
+
* Ttk_LayoutSpec array.
|
|
717
|
+
*/
|
|
718
|
+
Ttk_LayoutTemplate Ttk_BuildLayoutTemplate(Ttk_LayoutSpec spec)
|
|
719
|
+
{
|
|
720
|
+
Ttk_TemplateNode *first = 0, *last = 0;
|
|
721
|
+
|
|
722
|
+
for ( ; !(spec->opcode & _TTK_LAYOUT_END) ; ++spec) {
|
|
723
|
+
if (spec->elementName) {
|
|
724
|
+
Ttk_TemplateNode *node =
|
|
725
|
+
Ttk_NewTemplateNode(spec->elementName, spec->opcode);
|
|
726
|
+
|
|
727
|
+
if (last) {
|
|
728
|
+
last->next = node;
|
|
729
|
+
} else {
|
|
730
|
+
first = node;
|
|
731
|
+
}
|
|
732
|
+
last = node;
|
|
733
|
+
}
|
|
734
|
+
|
|
735
|
+
if (spec->opcode & _TTK_CHILDREN) {
|
|
736
|
+
int depth = 1;
|
|
737
|
+
last->child = Ttk_BuildLayoutTemplate(spec+1);
|
|
738
|
+
|
|
739
|
+
/* Skip to end of group:
|
|
740
|
+
*/
|
|
741
|
+
while (depth) {
|
|
742
|
+
++spec;
|
|
743
|
+
if (spec->opcode & _TTK_CHILDREN) {
|
|
744
|
+
++depth;
|
|
745
|
+
}
|
|
746
|
+
if (spec->opcode & _TTK_LAYOUT_END) {
|
|
747
|
+
--depth;
|
|
748
|
+
}
|
|
749
|
+
}
|
|
750
|
+
}
|
|
751
|
+
|
|
752
|
+
} /* for */
|
|
753
|
+
|
|
754
|
+
return first;
|
|
755
|
+
}
|
|
756
|
+
|
|
757
|
+
void Ttk_RegisterLayouts(Ttk_Theme theme, Ttk_LayoutSpec spec)
|
|
758
|
+
{
|
|
759
|
+
while (!(spec->opcode & _TTK_LAYOUT_END)) {
|
|
760
|
+
Ttk_LayoutTemplate layoutTemplate = Ttk_BuildLayoutTemplate(spec+1);
|
|
761
|
+
Ttk_RegisterLayoutTemplate(theme, spec->elementName, layoutTemplate);
|
|
762
|
+
do {
|
|
763
|
+
++spec;
|
|
764
|
+
} while (!(spec->opcode & _TTK_LAYOUT));
|
|
765
|
+
}
|
|
766
|
+
}
|
|
767
|
+
|
|
768
|
+
Tcl_Obj *Ttk_UnparseLayoutTemplate(Ttk_TemplateNode *node)
|
|
769
|
+
{
|
|
770
|
+
Tcl_Obj *result = Tcl_NewListObj(0,0);
|
|
771
|
+
|
|
772
|
+
# define APPENDOBJ(obj) Tcl_ListObjAppendElement(NULL, result, obj)
|
|
773
|
+
# define APPENDSTR(str) APPENDOBJ(Tcl_NewStringObj(str,-1))
|
|
774
|
+
|
|
775
|
+
while (node) {
|
|
776
|
+
unsigned flags = node->flags;
|
|
777
|
+
|
|
778
|
+
APPENDSTR(node->name);
|
|
779
|
+
|
|
780
|
+
/* Back-compute -side. <<NOTE-PACKSIDE>>
|
|
781
|
+
* @@@ NOTES: Ick.
|
|
782
|
+
*/
|
|
783
|
+
if (flags & TTK_EXPAND) {
|
|
784
|
+
APPENDSTR("-expand");
|
|
785
|
+
APPENDSTR("1");
|
|
786
|
+
} else {
|
|
787
|
+
if (flags & _TTK_MASK_PACK) {
|
|
788
|
+
int side = 0;
|
|
789
|
+
unsigned sideFlags = flags & _TTK_MASK_PACK;
|
|
790
|
+
|
|
791
|
+
while ((sideFlags & TTK_PACK_LEFT) == 0) {
|
|
792
|
+
++side;
|
|
793
|
+
sideFlags >>= 1;
|
|
794
|
+
}
|
|
795
|
+
APPENDSTR("-side");
|
|
796
|
+
APPENDSTR(packSideStrings[side]);
|
|
797
|
+
}
|
|
798
|
+
}
|
|
799
|
+
|
|
800
|
+
/* In Ttk_ParseLayoutTemplate, default -sticky is "nsew",
|
|
801
|
+
* so always include this even if no sticky bits are set.
|
|
802
|
+
*/
|
|
803
|
+
APPENDSTR("-sticky");
|
|
804
|
+
APPENDOBJ(Ttk_NewStickyObj(flags & _TTK_MASK_STICK));
|
|
805
|
+
|
|
806
|
+
/* @@@ Check again: are these necessary? */
|
|
807
|
+
if (flags & TTK_BORDER) { APPENDSTR("-border"); APPENDSTR("1"); }
|
|
808
|
+
if (flags & TTK_UNIT) { APPENDSTR("-unit"); APPENDSTR("1"); }
|
|
809
|
+
|
|
810
|
+
if (node->child) {
|
|
811
|
+
APPENDSTR("-children");
|
|
812
|
+
APPENDOBJ(Ttk_UnparseLayoutTemplate(node->child));
|
|
813
|
+
}
|
|
814
|
+
node = node->next;
|
|
815
|
+
}
|
|
816
|
+
|
|
817
|
+
# undef APPENDOBJ
|
|
818
|
+
# undef APPENDSTR
|
|
819
|
+
|
|
820
|
+
return result;
|
|
821
|
+
}
|
|
822
|
+
|
|
823
|
+
/*------------------------------------------------------------------------
|
|
824
|
+
* +++ Layouts.
|
|
825
|
+
*/
|
|
826
|
+
struct Ttk_Layout_
|
|
827
|
+
{
|
|
828
|
+
Ttk_Style style;
|
|
829
|
+
void *recordPtr;
|
|
830
|
+
Tk_OptionTable optionTable;
|
|
831
|
+
Tk_Window tkwin;
|
|
832
|
+
Ttk_LayoutNode *root;
|
|
833
|
+
};
|
|
834
|
+
|
|
835
|
+
static Ttk_Layout TTKNewLayout(
|
|
836
|
+
Ttk_Style style,
|
|
837
|
+
void *recordPtr,Tk_OptionTable optionTable, Tk_Window tkwin,
|
|
838
|
+
Ttk_LayoutNode *root)
|
|
839
|
+
{
|
|
840
|
+
Ttk_Layout layout = (Ttk_Layout)ckalloc(sizeof(*layout));
|
|
841
|
+
layout->style = style;
|
|
842
|
+
layout->recordPtr = recordPtr;
|
|
843
|
+
layout->optionTable = optionTable;
|
|
844
|
+
layout->tkwin = tkwin;
|
|
845
|
+
layout->root = root;
|
|
846
|
+
return layout;
|
|
847
|
+
}
|
|
848
|
+
|
|
849
|
+
void Ttk_FreeLayout(Ttk_Layout layout)
|
|
850
|
+
{
|
|
851
|
+
Ttk_FreeLayoutNode(layout->root);
|
|
852
|
+
ckfree((ClientData)layout);
|
|
853
|
+
}
|
|
854
|
+
|
|
855
|
+
/*
|
|
856
|
+
* Ttk_CreateLayout --
|
|
857
|
+
* Create a layout from the specified theme and style name.
|
|
858
|
+
* Returns: New layout, 0 on error.
|
|
859
|
+
* Leaves an error message in interp's result if there is an error.
|
|
860
|
+
*/
|
|
861
|
+
Ttk_Layout Ttk_CreateLayout(
|
|
862
|
+
Tcl_Interp *interp, /* where to leave error messages */
|
|
863
|
+
Ttk_Theme themePtr,
|
|
864
|
+
const char *styleName,
|
|
865
|
+
void *recordPtr,
|
|
866
|
+
Tk_OptionTable optionTable,
|
|
867
|
+
Tk_Window tkwin)
|
|
868
|
+
{
|
|
869
|
+
Ttk_Style style = Ttk_GetStyle(themePtr, styleName);
|
|
870
|
+
Ttk_LayoutTemplate layoutTemplate =
|
|
871
|
+
Ttk_FindLayoutTemplate(themePtr,styleName);
|
|
872
|
+
Ttk_ElementImpl bgelement = Ttk_GetElement(themePtr, "background");
|
|
873
|
+
Ttk_LayoutNode *bgnode;
|
|
874
|
+
|
|
875
|
+
if (!layoutTemplate) {
|
|
876
|
+
Tcl_ResetResult(interp);
|
|
877
|
+
Tcl_AppendResult(interp, "Layout ", styleName, " not found", NULL);
|
|
878
|
+
return 0;
|
|
879
|
+
}
|
|
880
|
+
|
|
881
|
+
bgnode = Ttk_NewLayoutNode(TTK_FILL_BOTH, bgelement);
|
|
882
|
+
bgnode->next = Ttk_InstantiateLayout(themePtr, layoutTemplate);
|
|
883
|
+
|
|
884
|
+
return TTKNewLayout(style, recordPtr, optionTable, tkwin, bgnode);
|
|
885
|
+
}
|
|
886
|
+
|
|
887
|
+
/* Ttk_CreateSublayout --
|
|
888
|
+
* Creates a new sublayout.
|
|
889
|
+
*
|
|
890
|
+
* Sublayouts are used to draw subparts of a compound widget.
|
|
891
|
+
* They use the same Tk_Window, but a different option table
|
|
892
|
+
* and data record.
|
|
893
|
+
*/
|
|
894
|
+
Ttk_Layout
|
|
895
|
+
Ttk_CreateSublayout(
|
|
896
|
+
Tcl_Interp *interp,
|
|
897
|
+
Ttk_Theme themePtr,
|
|
898
|
+
Ttk_Layout parentLayout,
|
|
899
|
+
const char *baseName,
|
|
900
|
+
Tk_OptionTable optionTable)
|
|
901
|
+
{
|
|
902
|
+
Tcl_DString buf;
|
|
903
|
+
const char *styleName;
|
|
904
|
+
Ttk_Style style;
|
|
905
|
+
Ttk_LayoutTemplate layoutTemplate;
|
|
906
|
+
|
|
907
|
+
Tcl_DStringInit(&buf);
|
|
908
|
+
Tcl_DStringAppend(&buf, Ttk_StyleName(parentLayout->style), -1);
|
|
909
|
+
Tcl_DStringAppend(&buf, baseName, -1);
|
|
910
|
+
styleName = Tcl_DStringValue(&buf);
|
|
911
|
+
|
|
912
|
+
style = Ttk_GetStyle(themePtr, styleName);
|
|
913
|
+
layoutTemplate = Ttk_FindLayoutTemplate(themePtr, styleName);
|
|
914
|
+
|
|
915
|
+
if (!layoutTemplate) {
|
|
916
|
+
Tcl_ResetResult(interp);
|
|
917
|
+
Tcl_AppendResult(interp, "Layout ", styleName, " not found", NULL);
|
|
918
|
+
return 0;
|
|
919
|
+
}
|
|
920
|
+
|
|
921
|
+
Tcl_DStringFree(&buf);
|
|
922
|
+
|
|
923
|
+
return TTKNewLayout(
|
|
924
|
+
style, 0, optionTable, parentLayout->tkwin,
|
|
925
|
+
Ttk_InstantiateLayout(themePtr, layoutTemplate));
|
|
926
|
+
}
|
|
927
|
+
|
|
928
|
+
/* Ttk_RebindSublayout --
|
|
929
|
+
* Bind sublayout to new data source.
|
|
930
|
+
*/
|
|
931
|
+
void Ttk_RebindSublayout(Ttk_Layout layout, void *recordPtr)
|
|
932
|
+
{
|
|
933
|
+
layout->recordPtr = recordPtr;
|
|
934
|
+
}
|
|
935
|
+
|
|
936
|
+
/*
|
|
937
|
+
* Ttk_QueryOption --
|
|
938
|
+
* Look up an option from a layout's associated option.
|
|
939
|
+
*/
|
|
940
|
+
Tcl_Obj *Ttk_QueryOption(
|
|
941
|
+
Ttk_Layout layout, const char *optionName, Ttk_State state)
|
|
942
|
+
{
|
|
943
|
+
return Ttk_QueryStyle(
|
|
944
|
+
layout->style,layout->recordPtr,layout->optionTable,optionName,state);
|
|
945
|
+
}
|
|
946
|
+
|
|
947
|
+
/*------------------------------------------------------------------------
|
|
948
|
+
* +++ Size computation.
|
|
949
|
+
*/
|
|
950
|
+
static void Ttk_NodeListSize(
|
|
951
|
+
Ttk_Layout layout, Ttk_LayoutNode *node,
|
|
952
|
+
Ttk_State state, int *widthPtr, int *heightPtr); /* Forward */
|
|
953
|
+
|
|
954
|
+
static void Ttk_NodeSize(
|
|
955
|
+
Ttk_Layout layout, Ttk_LayoutNode *node, Ttk_State state,
|
|
956
|
+
int *widthPtr, int *heightPtr, Ttk_Padding *paddingPtr)
|
|
957
|
+
{
|
|
958
|
+
int elementWidth, elementHeight, subWidth, subHeight;
|
|
959
|
+
Ttk_Padding elementPadding;
|
|
960
|
+
|
|
961
|
+
Ttk_ElementSize(node->element,
|
|
962
|
+
layout->style, layout->recordPtr,layout->optionTable, layout->tkwin,
|
|
963
|
+
state|node->state,
|
|
964
|
+
&elementWidth, &elementHeight, &elementPadding);
|
|
965
|
+
|
|
966
|
+
Ttk_NodeListSize(layout,node->child,state,&subWidth,&subHeight);
|
|
967
|
+
subWidth += Ttk_PaddingWidth(elementPadding);
|
|
968
|
+
subHeight += Ttk_PaddingHeight(elementPadding);
|
|
969
|
+
|
|
970
|
+
*widthPtr = MAX(elementWidth, subWidth);
|
|
971
|
+
*heightPtr = MAX(elementHeight, subHeight);
|
|
972
|
+
*paddingPtr = elementPadding;
|
|
973
|
+
}
|
|
974
|
+
|
|
975
|
+
static void Ttk_NodeListSize(
|
|
976
|
+
Ttk_Layout layout, Ttk_LayoutNode *node,
|
|
977
|
+
Ttk_State state, int *widthPtr, int *heightPtr)
|
|
978
|
+
{
|
|
979
|
+
if (!node) {
|
|
980
|
+
*widthPtr = *heightPtr = 0;
|
|
981
|
+
} else {
|
|
982
|
+
int width, height, restWidth, restHeight;
|
|
983
|
+
Ttk_Padding unused;
|
|
984
|
+
|
|
985
|
+
Ttk_NodeSize(layout, node, state, &width, &height, &unused);
|
|
986
|
+
Ttk_NodeListSize(layout, node->next, state, &restWidth, &restHeight);
|
|
987
|
+
|
|
988
|
+
if (node->flags & (TTK_PACK_LEFT|TTK_PACK_RIGHT)) {
|
|
989
|
+
*widthPtr = width + restWidth;
|
|
990
|
+
} else {
|
|
991
|
+
*widthPtr = MAX(width, restWidth);
|
|
992
|
+
}
|
|
993
|
+
|
|
994
|
+
if (node->flags & (TTK_PACK_TOP|TTK_PACK_BOTTOM)) {
|
|
995
|
+
*heightPtr = height + restHeight;
|
|
996
|
+
} else {
|
|
997
|
+
*heightPtr = MAX(height, restHeight);
|
|
998
|
+
}
|
|
999
|
+
}
|
|
1000
|
+
}
|
|
1001
|
+
|
|
1002
|
+
/*
|
|
1003
|
+
* Ttk_LayoutNodeInternalPadding --
|
|
1004
|
+
* Returns the internal padding of a layout node.
|
|
1005
|
+
*/
|
|
1006
|
+
Ttk_Padding Ttk_LayoutNodeInternalPadding(
|
|
1007
|
+
Ttk_Layout layout, Ttk_LayoutNode *node)
|
|
1008
|
+
{
|
|
1009
|
+
int unused;
|
|
1010
|
+
Ttk_Padding padding;
|
|
1011
|
+
Ttk_ElementSize(node->element,
|
|
1012
|
+
layout->style, layout->recordPtr, layout->optionTable, layout->tkwin,
|
|
1013
|
+
0/*state*/, &unused, &unused, &padding);
|
|
1014
|
+
return padding;
|
|
1015
|
+
}
|
|
1016
|
+
|
|
1017
|
+
/*
|
|
1018
|
+
* Ttk_LayoutNodeInternalParcel --
|
|
1019
|
+
* Returns the inner area of a specified layout node,
|
|
1020
|
+
* based on current parcel and element's internal padding.
|
|
1021
|
+
*/
|
|
1022
|
+
Ttk_Box Ttk_LayoutNodeInternalParcel(Ttk_Layout layout, Ttk_LayoutNode *node)
|
|
1023
|
+
{
|
|
1024
|
+
Ttk_Padding padding = Ttk_LayoutNodeInternalPadding(layout, node);
|
|
1025
|
+
return Ttk_PadBox(node->parcel, padding);
|
|
1026
|
+
}
|
|
1027
|
+
|
|
1028
|
+
/* Ttk_LayoutSize --
|
|
1029
|
+
* Compute requested size of a layout.
|
|
1030
|
+
*/
|
|
1031
|
+
void Ttk_LayoutSize(
|
|
1032
|
+
Ttk_Layout layout, Ttk_State state, int *widthPtr, int *heightPtr)
|
|
1033
|
+
{
|
|
1034
|
+
Ttk_NodeListSize(layout, layout->root, state, widthPtr, heightPtr);
|
|
1035
|
+
}
|
|
1036
|
+
|
|
1037
|
+
void Ttk_LayoutNodeReqSize( /* @@@ Rename this */
|
|
1038
|
+
Ttk_Layout layout, Ttk_LayoutNode *node, int *widthPtr, int *heightPtr)
|
|
1039
|
+
{
|
|
1040
|
+
Ttk_Padding unused;
|
|
1041
|
+
Ttk_NodeSize(layout, node, 0/*state*/, widthPtr, heightPtr, &unused);
|
|
1042
|
+
}
|
|
1043
|
+
|
|
1044
|
+
/*------------------------------------------------------------------------
|
|
1045
|
+
* +++ Layout placement.
|
|
1046
|
+
*/
|
|
1047
|
+
|
|
1048
|
+
/* Ttk_PlaceNodeList --
|
|
1049
|
+
* Compute parcel for each node in a layout tree
|
|
1050
|
+
* according to position specification and overall size.
|
|
1051
|
+
*/
|
|
1052
|
+
static void Ttk_PlaceNodeList(
|
|
1053
|
+
Ttk_Layout layout, Ttk_LayoutNode *node, Ttk_State state, Ttk_Box cavity)
|
|
1054
|
+
{
|
|
1055
|
+
for (; node; node = node->next)
|
|
1056
|
+
{
|
|
1057
|
+
int width, height;
|
|
1058
|
+
Ttk_Padding padding;
|
|
1059
|
+
|
|
1060
|
+
/* Compute node size: (@@@ cache this instead?)
|
|
1061
|
+
*/
|
|
1062
|
+
Ttk_NodeSize(layout, node, state, &width, &height, &padding);
|
|
1063
|
+
|
|
1064
|
+
/* Compute parcel:
|
|
1065
|
+
*/
|
|
1066
|
+
node->parcel = Ttk_PositionBox(&cavity, width, height, node->flags);
|
|
1067
|
+
|
|
1068
|
+
/* Place child nodes:
|
|
1069
|
+
*/
|
|
1070
|
+
if (node->child) {
|
|
1071
|
+
Ttk_Box childBox = Ttk_PadBox(node->parcel, padding);
|
|
1072
|
+
Ttk_PlaceNodeList(layout,node->child, state, childBox);
|
|
1073
|
+
}
|
|
1074
|
+
}
|
|
1075
|
+
}
|
|
1076
|
+
|
|
1077
|
+
void Ttk_PlaceLayout(Ttk_Layout layout, Ttk_State state, Ttk_Box b)
|
|
1078
|
+
{
|
|
1079
|
+
Ttk_PlaceNodeList(layout, layout->root, state, b);
|
|
1080
|
+
}
|
|
1081
|
+
|
|
1082
|
+
/*------------------------------------------------------------------------
|
|
1083
|
+
* +++ Layout drawing.
|
|
1084
|
+
*/
|
|
1085
|
+
|
|
1086
|
+
/*
|
|
1087
|
+
* Ttk_DrawLayout --
|
|
1088
|
+
* Draw a layout tree.
|
|
1089
|
+
*/
|
|
1090
|
+
static void Ttk_DrawNodeList(
|
|
1091
|
+
Ttk_Layout layout, Ttk_State state, Ttk_LayoutNode *node, Drawable d)
|
|
1092
|
+
{
|
|
1093
|
+
for (; node; node = node->next)
|
|
1094
|
+
{
|
|
1095
|
+
int border = node->flags & TTK_BORDER;
|
|
1096
|
+
int substate = state;
|
|
1097
|
+
|
|
1098
|
+
if (node->flags & TTK_UNIT)
|
|
1099
|
+
substate |= node->state;
|
|
1100
|
+
|
|
1101
|
+
if (node->child && border)
|
|
1102
|
+
Ttk_DrawNodeList(layout, substate, node->child, d);
|
|
1103
|
+
|
|
1104
|
+
Ttk_DrawElement(
|
|
1105
|
+
node->element,
|
|
1106
|
+
layout->style,layout->recordPtr,layout->optionTable,layout->tkwin,
|
|
1107
|
+
d, node->parcel, state | node->state);
|
|
1108
|
+
|
|
1109
|
+
if (node->child && !border)
|
|
1110
|
+
Ttk_DrawNodeList(layout, substate, node->child, d);
|
|
1111
|
+
}
|
|
1112
|
+
}
|
|
1113
|
+
|
|
1114
|
+
void Ttk_DrawLayout(Ttk_Layout layout, Ttk_State state, Drawable d)
|
|
1115
|
+
{
|
|
1116
|
+
Ttk_DrawNodeList(layout, state, layout->root, d);
|
|
1117
|
+
}
|
|
1118
|
+
|
|
1119
|
+
/*------------------------------------------------------------------------
|
|
1120
|
+
* +++ Inquiry and modification.
|
|
1121
|
+
*/
|
|
1122
|
+
|
|
1123
|
+
/*
|
|
1124
|
+
* Ttk_LayoutIdentify --
|
|
1125
|
+
* Find the layout node at the specified x,y coordinate.
|
|
1126
|
+
*/
|
|
1127
|
+
static Ttk_LayoutNode *
|
|
1128
|
+
Ttk_LayoutNodeIdentify(Ttk_LayoutNode *node, int x, int y)
|
|
1129
|
+
{
|
|
1130
|
+
Ttk_LayoutNode *closest = NULL;
|
|
1131
|
+
|
|
1132
|
+
for (; node; node = node->next) {
|
|
1133
|
+
if (Ttk_BoxContains(node->parcel, x, y)) {
|
|
1134
|
+
closest = node;
|
|
1135
|
+
if (node->child && !(node->flags & TTK_UNIT)) {
|
|
1136
|
+
Ttk_LayoutNode *childNode =
|
|
1137
|
+
Ttk_LayoutNodeIdentify(node->child, x,y);
|
|
1138
|
+
if (childNode) {
|
|
1139
|
+
closest = childNode;
|
|
1140
|
+
}
|
|
1141
|
+
}
|
|
1142
|
+
}
|
|
1143
|
+
}
|
|
1144
|
+
return closest;
|
|
1145
|
+
}
|
|
1146
|
+
|
|
1147
|
+
Ttk_LayoutNode *Ttk_LayoutIdentify(Ttk_Layout layout, int x, int y)
|
|
1148
|
+
{
|
|
1149
|
+
return Ttk_LayoutNodeIdentify(layout->root, x, y);
|
|
1150
|
+
}
|
|
1151
|
+
|
|
1152
|
+
/*
|
|
1153
|
+
* tail --
|
|
1154
|
+
* Return the last component of an element name, e.g.,
|
|
1155
|
+
* "Scrollbar.thumb" => "thumb"
|
|
1156
|
+
*/
|
|
1157
|
+
static const char *tail(const char *elementName)
|
|
1158
|
+
{
|
|
1159
|
+
const char *dot;
|
|
1160
|
+
while ((dot=strchr(elementName,'.')) != NULL)
|
|
1161
|
+
elementName = dot + 1;
|
|
1162
|
+
return elementName;
|
|
1163
|
+
}
|
|
1164
|
+
|
|
1165
|
+
/*
|
|
1166
|
+
* Ttk_LayoutFindNode --
|
|
1167
|
+
* Look up a layout node by name.
|
|
1168
|
+
*/
|
|
1169
|
+
static Ttk_LayoutNode *
|
|
1170
|
+
Ttk_LayoutNodeFind(Ttk_LayoutNode *node, const char *nodeName)
|
|
1171
|
+
{
|
|
1172
|
+
for (; node ; node = node->next) {
|
|
1173
|
+
if (!strcmp(tail(Ttk_LayoutNodeName(node)), nodeName))
|
|
1174
|
+
return node;
|
|
1175
|
+
|
|
1176
|
+
if (node->child) {
|
|
1177
|
+
Ttk_LayoutNode *childNode =
|
|
1178
|
+
Ttk_LayoutNodeFind(node->child, nodeName);
|
|
1179
|
+
if (childNode)
|
|
1180
|
+
return childNode;
|
|
1181
|
+
}
|
|
1182
|
+
}
|
|
1183
|
+
return 0;
|
|
1184
|
+
}
|
|
1185
|
+
|
|
1186
|
+
Ttk_LayoutNode *Ttk_LayoutFindNode(Ttk_Layout layout, const char *nodeName)
|
|
1187
|
+
{
|
|
1188
|
+
return Ttk_LayoutNodeFind(layout->root, nodeName);
|
|
1189
|
+
}
|
|
1190
|
+
|
|
1191
|
+
const char *Ttk_LayoutNodeName(Ttk_LayoutNode *node)
|
|
1192
|
+
{
|
|
1193
|
+
return Ttk_ElementName(node->element);
|
|
1194
|
+
}
|
|
1195
|
+
|
|
1196
|
+
Ttk_Box Ttk_LayoutNodeParcel(Ttk_LayoutNode *node)
|
|
1197
|
+
{
|
|
1198
|
+
return node->parcel;
|
|
1199
|
+
}
|
|
1200
|
+
|
|
1201
|
+
void Ttk_PlaceLayoutNode(Ttk_Layout layout, Ttk_LayoutNode *node, Ttk_Box b)
|
|
1202
|
+
{
|
|
1203
|
+
node->parcel = b;
|
|
1204
|
+
if (node->child) {
|
|
1205
|
+
Ttk_PlaceNodeList(layout, node->child, 0,
|
|
1206
|
+
Ttk_PadBox(b, Ttk_LayoutNodeInternalPadding(layout, node)));
|
|
1207
|
+
}
|
|
1208
|
+
}
|
|
1209
|
+
|
|
1210
|
+
void Ttk_ChangeElementState(Ttk_LayoutNode *node,unsigned set,unsigned clr)
|
|
1211
|
+
{
|
|
1212
|
+
node->state = (node->state | set) & ~clr;
|
|
1213
|
+
}
|
|
1214
|
+
|
|
1215
|
+
/*EOF*/
|