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,91 @@
|
|
|
1
|
+
/* manager.h,v 1.11 2007/11/25 17:17:09 jenglish Exp
|
|
2
|
+
*
|
|
3
|
+
* Copyright (c) 2005, Joe English. Freely redistributable.
|
|
4
|
+
*
|
|
5
|
+
* Geometry manager utilities.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
#ifndef _TTKMANAGER
|
|
9
|
+
#define _TTKMANAGER
|
|
10
|
+
|
|
11
|
+
typedef struct TtkManager_ Ttk_Manager;
|
|
12
|
+
|
|
13
|
+
/*
|
|
14
|
+
* Geometry manager specification record:
|
|
15
|
+
*
|
|
16
|
+
* RequestedSize computes the requested size of the master window.
|
|
17
|
+
*
|
|
18
|
+
* PlaceSlaves sets the position and size of all managed slaves
|
|
19
|
+
* by calling Ttk_PlaceSlave().
|
|
20
|
+
*
|
|
21
|
+
* SlaveRemoved() is called immediately before a slave is removed.
|
|
22
|
+
* NB: the associated slave window may have been destroyed when this
|
|
23
|
+
* routine is called.
|
|
24
|
+
*
|
|
25
|
+
* SlaveRequest() is called when a slave requests a size change.
|
|
26
|
+
* It should return 1 if the request should propagate, 0 otherwise.
|
|
27
|
+
*/
|
|
28
|
+
typedef struct { /* Manager hooks */
|
|
29
|
+
Tk_GeomMgr tkGeomMgr; /* "real" Tk Geometry Manager */
|
|
30
|
+
|
|
31
|
+
int (*RequestedSize)(void *managerData, int *widthPtr, int *heightPtr);
|
|
32
|
+
void (*PlaceSlaves)(void *managerData);
|
|
33
|
+
int (*SlaveRequest)(void *managerData, int slaveIndex, int w, int h);
|
|
34
|
+
void (*SlaveRemoved)(void *managerData, int slaveIndex);
|
|
35
|
+
} Ttk_ManagerSpec;
|
|
36
|
+
|
|
37
|
+
/*
|
|
38
|
+
* Default implementations for Tk_GeomMgr hooks:
|
|
39
|
+
*/
|
|
40
|
+
extern void Ttk_GeometryRequestProc(ClientData, Tk_Window slave);
|
|
41
|
+
extern void Ttk_LostSlaveProc(ClientData, Tk_Window slave);
|
|
42
|
+
|
|
43
|
+
/*
|
|
44
|
+
* Public API:
|
|
45
|
+
*/
|
|
46
|
+
extern Ttk_Manager *Ttk_CreateManager(
|
|
47
|
+
Ttk_ManagerSpec *, void *managerData, Tk_Window masterWindow);
|
|
48
|
+
extern void Ttk_DeleteManager(Ttk_Manager *);
|
|
49
|
+
|
|
50
|
+
extern void Ttk_InsertSlave(
|
|
51
|
+
Ttk_Manager *, int position, Tk_Window, void *slaveData);
|
|
52
|
+
|
|
53
|
+
extern void Ttk_ForgetSlave(Ttk_Manager *, int slaveIndex);
|
|
54
|
+
|
|
55
|
+
extern void Ttk_ReorderSlave(Ttk_Manager *, int fromIndex, int toIndex);
|
|
56
|
+
/* Rearrange slave positions */
|
|
57
|
+
|
|
58
|
+
extern void Ttk_PlaceSlave(
|
|
59
|
+
Ttk_Manager *, int slaveIndex, int x, int y, int width, int height);
|
|
60
|
+
/* Position and map the slave */
|
|
61
|
+
|
|
62
|
+
extern void Ttk_UnmapSlave(Ttk_Manager *, int slaveIndex);
|
|
63
|
+
/* Unmap the slave */
|
|
64
|
+
|
|
65
|
+
extern void Ttk_ManagerSizeChanged(Ttk_Manager *);
|
|
66
|
+
extern void Ttk_ManagerLayoutChanged(Ttk_Manager *);
|
|
67
|
+
/* Notify manager that size (resp. layout) needs to be recomputed */
|
|
68
|
+
|
|
69
|
+
/* Utilities:
|
|
70
|
+
*/
|
|
71
|
+
extern int Ttk_SlaveIndex(Ttk_Manager *, Tk_Window);
|
|
72
|
+
/* Returns: index in slave array of specified window, -1 if not found */
|
|
73
|
+
|
|
74
|
+
extern int Ttk_GetSlaveIndexFromObj(
|
|
75
|
+
Tcl_Interp *, Ttk_Manager *, Tcl_Obj *, int *indexPtr);
|
|
76
|
+
|
|
77
|
+
/* Accessor functions:
|
|
78
|
+
*/
|
|
79
|
+
extern int Ttk_NumberSlaves(Ttk_Manager *);
|
|
80
|
+
/* Returns: number of managed slaves */
|
|
81
|
+
|
|
82
|
+
extern void *Ttk_SlaveData(Ttk_Manager *, int slaveIndex);
|
|
83
|
+
/* Returns: client data associated with slave */
|
|
84
|
+
|
|
85
|
+
extern Tk_Window Ttk_SlaveWindow(Ttk_Manager *, int slaveIndex);
|
|
86
|
+
/* Returns: slave window */
|
|
87
|
+
|
|
88
|
+
extern int Ttk_Maintainable(Tcl_Interp *, Tk_Window slave, Tk_Window master);
|
|
89
|
+
/* Returns: 1 if master can manage slave; 0 otherwise leaving error msg */
|
|
90
|
+
|
|
91
|
+
#endif /* _TTKMANAGER */
|
|
@@ -0,0 +1,1380 @@
|
|
|
1
|
+
/* notebook.c,v 1.97 2007/11/25 18:09:51 jenglish Exp
|
|
2
|
+
* Copyright (c) 2004, Joe English
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
#include <string.h>
|
|
6
|
+
#include <ctype.h>
|
|
7
|
+
#include <stdio.h>
|
|
8
|
+
#include <tk.h>
|
|
9
|
+
|
|
10
|
+
#include "tkTheme.h"
|
|
11
|
+
#include "widget.h"
|
|
12
|
+
#include "manager.h"
|
|
13
|
+
|
|
14
|
+
#define MIN(a,b) ((a) < (b) ? (a) : (b))
|
|
15
|
+
#define MAX(a,b) ((a) > (b) ? (a) : (b))
|
|
16
|
+
|
|
17
|
+
/*------------------------------------------------------------------------
|
|
18
|
+
* +++ Tab resources.
|
|
19
|
+
*/
|
|
20
|
+
|
|
21
|
+
#define DEFAULT_MIN_TAB_WIDTH 24
|
|
22
|
+
|
|
23
|
+
static const char *TabStateStrings[] = { "normal", "disabled", "hidden", 0 };
|
|
24
|
+
typedef enum {
|
|
25
|
+
TAB_STATE_NORMAL, TAB_STATE_DISABLED, TAB_STATE_HIDDEN
|
|
26
|
+
} TAB_STATE;
|
|
27
|
+
|
|
28
|
+
typedef struct
|
|
29
|
+
{
|
|
30
|
+
/* Internal data:
|
|
31
|
+
*/
|
|
32
|
+
int width, height; /* Requested size of tab */
|
|
33
|
+
Ttk_Box parcel; /* Tab position */
|
|
34
|
+
|
|
35
|
+
/* Tab options:
|
|
36
|
+
*/
|
|
37
|
+
TAB_STATE state;
|
|
38
|
+
|
|
39
|
+
/* Child window options:
|
|
40
|
+
*/
|
|
41
|
+
Tcl_Obj *paddingObj; /* Padding inside pane */
|
|
42
|
+
Ttk_Padding padding;
|
|
43
|
+
Tcl_Obj *stickyObj;
|
|
44
|
+
Ttk_Sticky sticky;
|
|
45
|
+
|
|
46
|
+
/* Label options:
|
|
47
|
+
*/
|
|
48
|
+
Tcl_Obj *textObj;
|
|
49
|
+
Tcl_Obj *imageObj;
|
|
50
|
+
Tcl_Obj *compoundObj;
|
|
51
|
+
Tcl_Obj *underlineObj;
|
|
52
|
+
|
|
53
|
+
} Tab;
|
|
54
|
+
|
|
55
|
+
/* Two different option tables are used for tabs:
|
|
56
|
+
* TabOptionSpecs is used to draw the tab, and only includes resources
|
|
57
|
+
* relevant to the tab.
|
|
58
|
+
*
|
|
59
|
+
* PaneOptionSpecs includes additional options for child window placement
|
|
60
|
+
* and is used to configure the slave.
|
|
61
|
+
*/
|
|
62
|
+
static Tk_OptionSpec TabOptionSpecs[] =
|
|
63
|
+
{
|
|
64
|
+
{TK_OPTION_STRING_TABLE, "-state", "", "",
|
|
65
|
+
"normal", -1,Tk_Offset(Tab,state),
|
|
66
|
+
0,(ClientData)TabStateStrings,0 },
|
|
67
|
+
{TK_OPTION_STRING, "-text", "text", "Text", "",
|
|
68
|
+
Tk_Offset(Tab,textObj), -1, 0,0,GEOMETRY_CHANGED },
|
|
69
|
+
{TK_OPTION_STRING, "-image", "image", "Image", NULL/*default*/,
|
|
70
|
+
Tk_Offset(Tab,imageObj), -1, TK_OPTION_NULL_OK,0,GEOMETRY_CHANGED },
|
|
71
|
+
{TK_OPTION_STRING_TABLE, "-compound", "compound", "Compound",
|
|
72
|
+
"none", Tk_Offset(Tab,compoundObj), -1,
|
|
73
|
+
0,(ClientData)ttkCompoundStrings,GEOMETRY_CHANGED },
|
|
74
|
+
{TK_OPTION_INT, "-underline", "underline", "Underline", "-1",
|
|
75
|
+
Tk_Offset(Tab,underlineObj), -1, 0,0,GEOMETRY_CHANGED },
|
|
76
|
+
{TK_OPTION_END}
|
|
77
|
+
};
|
|
78
|
+
|
|
79
|
+
static Tk_OptionSpec PaneOptionSpecs[] =
|
|
80
|
+
{
|
|
81
|
+
{TK_OPTION_STRING, "-padding", "padding", "Padding", "0",
|
|
82
|
+
Tk_Offset(Tab,paddingObj), -1, 0,0,GEOMETRY_CHANGED },
|
|
83
|
+
{TK_OPTION_STRING, "-sticky", "sticky", "Sticky", "nsew",
|
|
84
|
+
Tk_Offset(Tab,stickyObj), -1, 0,0,GEOMETRY_CHANGED },
|
|
85
|
+
|
|
86
|
+
WIDGET_INHERIT_OPTIONS(TabOptionSpecs)
|
|
87
|
+
};
|
|
88
|
+
|
|
89
|
+
/*------------------------------------------------------------------------
|
|
90
|
+
* +++ Notebook resources.
|
|
91
|
+
*/
|
|
92
|
+
typedef struct
|
|
93
|
+
{
|
|
94
|
+
Tcl_Obj *widthObj; /* Default width */
|
|
95
|
+
Tcl_Obj *heightObj; /* Default height */
|
|
96
|
+
Tcl_Obj *paddingObj; /* Padding around notebook */
|
|
97
|
+
|
|
98
|
+
Ttk_Manager *mgr; /* Geometry manager */
|
|
99
|
+
Tk_OptionTable tabOptionTable; /* Tab options */
|
|
100
|
+
Tk_OptionTable paneOptionTable; /* Tab+pane options */
|
|
101
|
+
int currentIndex; /* index of currently selected tab */
|
|
102
|
+
int activeIndex; /* index of currently active tab */
|
|
103
|
+
Ttk_Layout tabLayout; /* Sublayout for tabs */
|
|
104
|
+
|
|
105
|
+
Ttk_Box clientArea; /* Where to pack slave widgets */
|
|
106
|
+
} NotebookPart;
|
|
107
|
+
|
|
108
|
+
typedef struct
|
|
109
|
+
{
|
|
110
|
+
WidgetCore core;
|
|
111
|
+
NotebookPart notebook;
|
|
112
|
+
} Notebook;
|
|
113
|
+
|
|
114
|
+
static Tk_OptionSpec NotebookOptionSpecs[] =
|
|
115
|
+
{
|
|
116
|
+
WIDGET_TAKES_FOCUS,
|
|
117
|
+
|
|
118
|
+
{TK_OPTION_INT, "-width", "width", "Width", "0",
|
|
119
|
+
Tk_Offset(Notebook,notebook.widthObj),-1,
|
|
120
|
+
0,0,GEOMETRY_CHANGED },
|
|
121
|
+
{TK_OPTION_INT, "-height", "height", "Height", "0",
|
|
122
|
+
Tk_Offset(Notebook,notebook.heightObj),-1,
|
|
123
|
+
0,0,GEOMETRY_CHANGED },
|
|
124
|
+
{TK_OPTION_STRING, "-padding", "padding", "Padding", NULL,
|
|
125
|
+
Tk_Offset(Notebook,notebook.paddingObj),-1,
|
|
126
|
+
TK_OPTION_NULL_OK,0,GEOMETRY_CHANGED },
|
|
127
|
+
|
|
128
|
+
WIDGET_INHERIT_OPTIONS(ttkCoreOptionSpecs)
|
|
129
|
+
};
|
|
130
|
+
|
|
131
|
+
/* Notebook style options:
|
|
132
|
+
*/
|
|
133
|
+
typedef struct
|
|
134
|
+
{
|
|
135
|
+
Ttk_PositionSpec tabPosition; /* Where to place tabs */
|
|
136
|
+
Ttk_Padding tabMargins; /* Margins around tab row */
|
|
137
|
+
Ttk_PositionSpec tabPlacement; /* How to pack tabs within tab row */
|
|
138
|
+
Ttk_Orient tabOrient; /* ... */
|
|
139
|
+
int minTabWidth; /* Minimum tab width */
|
|
140
|
+
Ttk_Padding padding; /* External padding */
|
|
141
|
+
} NotebookStyle;
|
|
142
|
+
|
|
143
|
+
static void NotebookStyleOptions(Notebook *nb, NotebookStyle *nbstyle)
|
|
144
|
+
{
|
|
145
|
+
Tcl_Obj *objPtr;
|
|
146
|
+
|
|
147
|
+
nbstyle->tabPosition = TTK_PACK_TOP | TTK_STICK_W;
|
|
148
|
+
if ((objPtr = Ttk_QueryOption(nb->core.layout, "-tabposition", 0)) != 0) {
|
|
149
|
+
TtkGetLabelAnchorFromObj(NULL, objPtr, &nbstyle->tabPosition);
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
/* compute tabPlacement and tabOrient as function of tabPosition:
|
|
153
|
+
*/
|
|
154
|
+
if (nbstyle->tabPosition & TTK_PACK_LEFT) {
|
|
155
|
+
nbstyle->tabPlacement = TTK_PACK_TOP | TTK_STICK_E;
|
|
156
|
+
nbstyle->tabOrient = TTK_ORIENT_VERTICAL;
|
|
157
|
+
} else if (nbstyle->tabPosition & TTK_PACK_RIGHT) {
|
|
158
|
+
nbstyle->tabPlacement = TTK_PACK_TOP | TTK_STICK_W;
|
|
159
|
+
nbstyle->tabOrient = TTK_ORIENT_VERTICAL;
|
|
160
|
+
} else if (nbstyle->tabPosition & TTK_PACK_BOTTOM) {
|
|
161
|
+
nbstyle->tabPlacement = TTK_PACK_LEFT | TTK_STICK_N;
|
|
162
|
+
nbstyle->tabOrient = TTK_ORIENT_HORIZONTAL;
|
|
163
|
+
} else { /* Assume TTK_PACK_TOP */
|
|
164
|
+
nbstyle->tabPlacement = TTK_PACK_LEFT | TTK_STICK_S;
|
|
165
|
+
nbstyle->tabOrient = TTK_ORIENT_HORIZONTAL;
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
nbstyle->tabMargins = Ttk_UniformPadding(0);
|
|
169
|
+
if ((objPtr = Ttk_QueryOption(nb->core.layout, "-tabmargins", 0)) != 0) {
|
|
170
|
+
Ttk_GetBorderFromObj(NULL, objPtr, &nbstyle->tabMargins);
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
nbstyle->padding = Ttk_UniformPadding(0);
|
|
174
|
+
if ((objPtr = Ttk_QueryOption(nb->core.layout, "-padding", 0)) != 0) {
|
|
175
|
+
Ttk_GetPaddingFromObj(NULL,nb->core.tkwin,objPtr,&nbstyle->padding);
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
nbstyle->minTabWidth = DEFAULT_MIN_TAB_WIDTH;
|
|
179
|
+
if ((objPtr = Ttk_QueryOption(nb->core.layout, "-mintabwidth", 0)) != 0) {
|
|
180
|
+
Tcl_GetIntFromObj(NULL, objPtr, &nbstyle->minTabWidth);
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
/*------------------------------------------------------------------------
|
|
185
|
+
* +++ Tab management.
|
|
186
|
+
*/
|
|
187
|
+
|
|
188
|
+
static Tab *CreateTab(Tcl_Interp *interp, Notebook *nb, Tk_Window slaveWindow)
|
|
189
|
+
{
|
|
190
|
+
Tk_OptionTable optionTable = nb->notebook.paneOptionTable;
|
|
191
|
+
void *record = ckalloc(sizeof(Tab));
|
|
192
|
+
memset(record, 0, sizeof(Tab));
|
|
193
|
+
|
|
194
|
+
if (Tk_InitOptions(interp, record, optionTable, slaveWindow) != TCL_OK) {
|
|
195
|
+
ckfree(record);
|
|
196
|
+
return NULL;
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
return record;
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
static void DestroyTab(Notebook *nb, Tab *tab)
|
|
203
|
+
{
|
|
204
|
+
void *record = tab;
|
|
205
|
+
Tk_FreeConfigOptions(record, nb->notebook.paneOptionTable, nb->core.tkwin);
|
|
206
|
+
ckfree(record);
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
static int ConfigureTab(
|
|
210
|
+
Tcl_Interp *interp, Notebook *nb, Tab *tab, Tk_Window slaveWindow,
|
|
211
|
+
int objc, Tcl_Obj *CONST objv[])
|
|
212
|
+
{
|
|
213
|
+
Ttk_Sticky sticky = tab->sticky;
|
|
214
|
+
Ttk_Padding padding = tab->padding;
|
|
215
|
+
Tk_SavedOptions savedOptions;
|
|
216
|
+
int mask = 0;
|
|
217
|
+
|
|
218
|
+
if (Tk_SetOptions(interp, (ClientData)tab, nb->notebook.paneOptionTable,
|
|
219
|
+
objc, objv, slaveWindow, &savedOptions, &mask) != TCL_OK)
|
|
220
|
+
{
|
|
221
|
+
return TCL_ERROR;
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
/* Check options:
|
|
225
|
+
* @@@ TODO: validate -image option.
|
|
226
|
+
*/
|
|
227
|
+
if (Ttk_GetStickyFromObj(interp, tab->stickyObj, &sticky) != TCL_OK)
|
|
228
|
+
{
|
|
229
|
+
goto error;
|
|
230
|
+
}
|
|
231
|
+
if (Ttk_GetPaddingFromObj(interp, slaveWindow, tab->paddingObj, &padding)
|
|
232
|
+
!= TCL_OK)
|
|
233
|
+
{
|
|
234
|
+
goto error;
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
tab->sticky = sticky;
|
|
238
|
+
tab->padding = padding;
|
|
239
|
+
|
|
240
|
+
Tk_FreeSavedOptions(&savedOptions);
|
|
241
|
+
Ttk_ManagerSizeChanged(nb->notebook.mgr);
|
|
242
|
+
|
|
243
|
+
return TCL_OK;
|
|
244
|
+
error:
|
|
245
|
+
Tk_RestoreSavedOptions(&savedOptions);
|
|
246
|
+
return TCL_ERROR;
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
/*
|
|
250
|
+
* IdentifyTab --
|
|
251
|
+
* Return the index of the tab at point x,y,
|
|
252
|
+
* or -1 if no tab at that point.
|
|
253
|
+
*/
|
|
254
|
+
static int IdentifyTab(Notebook *nb, int x, int y)
|
|
255
|
+
{
|
|
256
|
+
int index;
|
|
257
|
+
for (index = 0; index < Ttk_NumberSlaves(nb->notebook.mgr); ++index) {
|
|
258
|
+
Tab *tab = Ttk_SlaveData(nb->notebook.mgr,index);
|
|
259
|
+
if ( tab->state != TAB_STATE_HIDDEN
|
|
260
|
+
&& Ttk_BoxContains(tab->parcel, x,y))
|
|
261
|
+
{
|
|
262
|
+
return index;
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
return -1;
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
/*
|
|
269
|
+
* ActivateTab --
|
|
270
|
+
* Set the active tab index, redisplay if necessary.
|
|
271
|
+
*/
|
|
272
|
+
static void ActivateTab(Notebook *nb, int index)
|
|
273
|
+
{
|
|
274
|
+
if (index != nb->notebook.activeIndex) {
|
|
275
|
+
nb->notebook.activeIndex = index;
|
|
276
|
+
TtkRedisplayWidget(&nb->core);
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
/*
|
|
281
|
+
* TabState --
|
|
282
|
+
* Return the state of the specified tab, based on
|
|
283
|
+
* notebook state, currentIndex, activeIndex, and user-specified tab state.
|
|
284
|
+
* The USER1 bit is set for the leftmost tab, and USER2
|
|
285
|
+
* is set for the rightmost tab.
|
|
286
|
+
*/
|
|
287
|
+
static Ttk_State TabState(Notebook *nb, int index)
|
|
288
|
+
{
|
|
289
|
+
Ttk_State state = nb->core.state;
|
|
290
|
+
Tab *tab = Ttk_SlaveData(nb->notebook.mgr, index);
|
|
291
|
+
|
|
292
|
+
if (index == nb->notebook.currentIndex) {
|
|
293
|
+
state |= TTK_STATE_SELECTED;
|
|
294
|
+
} else {
|
|
295
|
+
state &= ~TTK_STATE_FOCUS;
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
if (index == nb->notebook.activeIndex) {
|
|
299
|
+
state |= TTK_STATE_ACTIVE;
|
|
300
|
+
}
|
|
301
|
+
if (index == 0) {
|
|
302
|
+
state |= TTK_STATE_USER1;
|
|
303
|
+
}
|
|
304
|
+
if (index == Ttk_NumberSlaves(nb->notebook.mgr) - 1) {
|
|
305
|
+
state |= TTK_STATE_USER2;
|
|
306
|
+
}
|
|
307
|
+
if (tab->state == TAB_STATE_DISABLED) {
|
|
308
|
+
state |= TTK_STATE_DISABLED;
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
return state;
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
/*------------------------------------------------------------------------
|
|
315
|
+
* +++ Geometry management - size computation.
|
|
316
|
+
*/
|
|
317
|
+
|
|
318
|
+
/* TabrowSize --
|
|
319
|
+
* Compute max height and total width of all tabs (horizontal layouts)
|
|
320
|
+
* or total height and max width (vertical layouts).
|
|
321
|
+
*
|
|
322
|
+
* Side effects:
|
|
323
|
+
* Sets width and height fields for all tabs.
|
|
324
|
+
*
|
|
325
|
+
* Notes:
|
|
326
|
+
* Hidden tabs are included in the perpendicular computation
|
|
327
|
+
* (max height/width) but not parallel (total width/height).
|
|
328
|
+
*/
|
|
329
|
+
static void TabrowSize(
|
|
330
|
+
Notebook *nb, Ttk_Orient orient, int *widthPtr, int *heightPtr)
|
|
331
|
+
{
|
|
332
|
+
Ttk_Layout tabLayout = nb->notebook.tabLayout;
|
|
333
|
+
int tabrowWidth = 0, tabrowHeight = 0;
|
|
334
|
+
int i;
|
|
335
|
+
|
|
336
|
+
for (i = 0; i < Ttk_NumberSlaves(nb->notebook.mgr); ++i) {
|
|
337
|
+
Tab *tab = Ttk_SlaveData(nb->notebook.mgr, i);
|
|
338
|
+
Ttk_State tabState = TabState(nb,i);
|
|
339
|
+
|
|
340
|
+
Ttk_RebindSublayout(tabLayout, tab);
|
|
341
|
+
Ttk_LayoutSize(tabLayout,tabState,&tab->width,&tab->height);
|
|
342
|
+
|
|
343
|
+
if (orient == TTK_ORIENT_HORIZONTAL) {
|
|
344
|
+
tabrowHeight = MAX(tabrowHeight, tab->height);
|
|
345
|
+
if (tab->state != TAB_STATE_HIDDEN) { tabrowWidth += tab->width; }
|
|
346
|
+
} else {
|
|
347
|
+
tabrowWidth = MAX(tabrowWidth, tab->width);
|
|
348
|
+
if (tab->state != TAB_STATE_HIDDEN) { tabrowHeight += tab->height; }
|
|
349
|
+
}
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
*widthPtr = tabrowWidth;
|
|
353
|
+
*heightPtr = tabrowHeight;
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
/* NotebookSize -- GM and widget size hook.
|
|
357
|
+
*
|
|
358
|
+
* Total height is tab height + client area height + pane internal padding
|
|
359
|
+
* Total width is max(client width, tab width) + pane internal padding
|
|
360
|
+
* Client area size determined by max size of slaves,
|
|
361
|
+
* overridden by -width and/or -height if nonzero.
|
|
362
|
+
*/
|
|
363
|
+
|
|
364
|
+
static int NotebookSize(void *clientData, int *widthPtr, int *heightPtr)
|
|
365
|
+
{
|
|
366
|
+
Notebook *nb = clientData;
|
|
367
|
+
NotebookStyle nbstyle;
|
|
368
|
+
Ttk_Padding padding;
|
|
369
|
+
Ttk_LayoutNode *clientNode = Ttk_LayoutFindNode(nb->core.layout, "client");
|
|
370
|
+
int clientWidth = 0, clientHeight = 0,
|
|
371
|
+
reqWidth = 0, reqHeight = 0,
|
|
372
|
+
tabrowWidth = 0, tabrowHeight = 0;
|
|
373
|
+
int i;
|
|
374
|
+
|
|
375
|
+
NotebookStyleOptions(nb, &nbstyle);
|
|
376
|
+
|
|
377
|
+
/* Compute max requested size of all slaves:
|
|
378
|
+
*/
|
|
379
|
+
for (i = 0; i < Ttk_NumberSlaves(nb->notebook.mgr); ++i) {
|
|
380
|
+
Tk_Window slaveWindow = Ttk_SlaveWindow(nb->notebook.mgr, i);
|
|
381
|
+
Tab *tab = Ttk_SlaveData(nb->notebook.mgr, i);
|
|
382
|
+
int slaveWidth
|
|
383
|
+
= Tk_ReqWidth(slaveWindow) + Ttk_PaddingWidth(tab->padding);
|
|
384
|
+
int slaveHeight
|
|
385
|
+
= Tk_ReqHeight(slaveWindow) + Ttk_PaddingHeight(tab->padding);
|
|
386
|
+
|
|
387
|
+
clientWidth = MAX(clientWidth, slaveWidth);
|
|
388
|
+
clientHeight = MAX(clientHeight, slaveHeight);
|
|
389
|
+
}
|
|
390
|
+
|
|
391
|
+
/* Client width/height overridable by widget options:
|
|
392
|
+
*/
|
|
393
|
+
Tcl_GetIntFromObj(NULL, nb->notebook.widthObj,&reqWidth);
|
|
394
|
+
Tcl_GetIntFromObj(NULL, nb->notebook.heightObj,&reqHeight);
|
|
395
|
+
if (reqWidth > 0)
|
|
396
|
+
clientWidth = reqWidth;
|
|
397
|
+
if (reqHeight > 0)
|
|
398
|
+
clientHeight = reqHeight;
|
|
399
|
+
|
|
400
|
+
/* Tab row:
|
|
401
|
+
*/
|
|
402
|
+
TabrowSize(nb, nbstyle.tabOrient, &tabrowWidth, &tabrowHeight);
|
|
403
|
+
tabrowHeight += Ttk_PaddingHeight(nbstyle.tabMargins);
|
|
404
|
+
tabrowWidth += Ttk_PaddingWidth(nbstyle.tabMargins);
|
|
405
|
+
|
|
406
|
+
/* Account for exterior and interior padding:
|
|
407
|
+
*/
|
|
408
|
+
padding = nbstyle.padding;
|
|
409
|
+
if (clientNode) {
|
|
410
|
+
Ttk_Padding ipad =
|
|
411
|
+
Ttk_LayoutNodeInternalPadding(nb->core.layout, clientNode);
|
|
412
|
+
padding = Ttk_AddPadding(padding, ipad);
|
|
413
|
+
}
|
|
414
|
+
|
|
415
|
+
*widthPtr = MAX(tabrowWidth, clientWidth) + Ttk_PaddingWidth(padding);
|
|
416
|
+
*heightPtr = tabrowHeight + clientHeight + Ttk_PaddingHeight(padding);
|
|
417
|
+
|
|
418
|
+
return 1;
|
|
419
|
+
}
|
|
420
|
+
|
|
421
|
+
/*------------------------------------------------------------------------
|
|
422
|
+
* +++ Geometry management - layout.
|
|
423
|
+
*/
|
|
424
|
+
|
|
425
|
+
/* SqueezeTabs --
|
|
426
|
+
* If the notebook is not wide enough to display all tabs,
|
|
427
|
+
* attempt to decrease tab widths to fit.
|
|
428
|
+
*
|
|
429
|
+
* All tabs are shrunk by an equal amount, but will not be made
|
|
430
|
+
* smaller than the minimum width. (If all the tabs still do
|
|
431
|
+
* not fit in the available space, the rightmost tabs are truncated).
|
|
432
|
+
*
|
|
433
|
+
* The algorithm does not always yield an optimal layout, but does
|
|
434
|
+
* have the important property that decreasing the available width
|
|
435
|
+
* by one pixel will cause at most one tab to shrink by one pixel;
|
|
436
|
+
* this means that tabs resize "smoothly" when the window shrinks
|
|
437
|
+
* and grows.
|
|
438
|
+
*
|
|
439
|
+
* @@@ <<NOTE-TABPOSITION>> bug: only works for horizontal orientations
|
|
440
|
+
*/
|
|
441
|
+
|
|
442
|
+
static void SqueezeTabs(
|
|
443
|
+
Notebook *nb, int desiredWidth, int availableWidth, int minTabWidth)
|
|
444
|
+
{
|
|
445
|
+
int nTabs = Ttk_NumberSlaves(nb->notebook.mgr);
|
|
446
|
+
int shrinkage = desiredWidth - availableWidth;
|
|
447
|
+
int extra = 0;
|
|
448
|
+
int i;
|
|
449
|
+
|
|
450
|
+
for (i = 0; i < nTabs; ++i) {
|
|
451
|
+
Tab *tab = Ttk_SlaveData(nb->notebook.mgr,i);
|
|
452
|
+
int shrink = (shrinkage/nTabs) + (i < (shrinkage%nTabs)) + extra;
|
|
453
|
+
int shrinkability = MAX(0, tab->width - minTabWidth);
|
|
454
|
+
int delta = MIN(shrinkability, shrink);
|
|
455
|
+
tab->width -= delta;
|
|
456
|
+
extra = shrink - delta;
|
|
457
|
+
}
|
|
458
|
+
}
|
|
459
|
+
|
|
460
|
+
/* PlaceTabs --
|
|
461
|
+
* Compute all tab parcels.
|
|
462
|
+
*/
|
|
463
|
+
static void PlaceTabs(
|
|
464
|
+
Notebook *nb, Ttk_Box tabrowBox, Ttk_PositionSpec tabPlacement)
|
|
465
|
+
{
|
|
466
|
+
Ttk_Layout tabLayout = nb->notebook.tabLayout;
|
|
467
|
+
int nTabs = Ttk_NumberSlaves(nb->notebook.mgr);
|
|
468
|
+
int i;
|
|
469
|
+
|
|
470
|
+
for (i = 0; i < nTabs; ++i) {
|
|
471
|
+
Tab *tab = Ttk_SlaveData(nb->notebook.mgr, i);
|
|
472
|
+
Ttk_State tabState = TabState(nb, i);
|
|
473
|
+
|
|
474
|
+
if (tab->state != TAB_STATE_HIDDEN) {
|
|
475
|
+
Ttk_Padding expand = Ttk_UniformPadding(0);
|
|
476
|
+
Tcl_Obj *expandObj = Ttk_QueryOption(tabLayout,"-expand",tabState);
|
|
477
|
+
|
|
478
|
+
if (expandObj) {
|
|
479
|
+
Ttk_GetBorderFromObj(NULL, expandObj, &expand);
|
|
480
|
+
}
|
|
481
|
+
|
|
482
|
+
tab->parcel =
|
|
483
|
+
Ttk_ExpandBox(
|
|
484
|
+
Ttk_PositionBox(&tabrowBox,
|
|
485
|
+
tab->width, tab->height, tabPlacement),
|
|
486
|
+
expand);
|
|
487
|
+
}
|
|
488
|
+
}
|
|
489
|
+
}
|
|
490
|
+
|
|
491
|
+
/* NotebookDoLayout --
|
|
492
|
+
* Computes notebook layout and places tabs.
|
|
493
|
+
*
|
|
494
|
+
* Side effects:
|
|
495
|
+
* Sets clientArea, used to place slave panes.
|
|
496
|
+
*/
|
|
497
|
+
static void NotebookDoLayout(void *recordPtr)
|
|
498
|
+
{
|
|
499
|
+
Notebook *nb = recordPtr;
|
|
500
|
+
Tk_Window nbwin = nb->core.tkwin;
|
|
501
|
+
Ttk_Box cavity = Ttk_WinBox(nbwin);
|
|
502
|
+
int tabrowWidth = 0, tabrowHeight = 0;
|
|
503
|
+
Ttk_LayoutNode *clientNode = Ttk_LayoutFindNode(nb->core.layout, "client");
|
|
504
|
+
Ttk_Box tabrowBox;
|
|
505
|
+
NotebookStyle nbstyle;
|
|
506
|
+
|
|
507
|
+
NotebookStyleOptions(nb, &nbstyle);
|
|
508
|
+
|
|
509
|
+
/* Notebook internal padding:
|
|
510
|
+
*/
|
|
511
|
+
cavity = Ttk_PadBox(cavity, nbstyle.padding);
|
|
512
|
+
|
|
513
|
+
/* Layout for notebook background (base layout):
|
|
514
|
+
*/
|
|
515
|
+
Ttk_PlaceLayout(nb->core.layout, nb->core.state, Ttk_WinBox(nbwin));
|
|
516
|
+
|
|
517
|
+
/* Place tabs:
|
|
518
|
+
*/
|
|
519
|
+
TabrowSize(nb, nbstyle.tabOrient, &tabrowWidth, &tabrowHeight);
|
|
520
|
+
tabrowBox = Ttk_PadBox(
|
|
521
|
+
Ttk_PositionBox(&cavity,
|
|
522
|
+
tabrowWidth + Ttk_PaddingWidth(nbstyle.tabMargins),
|
|
523
|
+
tabrowHeight + Ttk_PaddingHeight(nbstyle.tabMargins),
|
|
524
|
+
nbstyle.tabPosition),
|
|
525
|
+
nbstyle.tabMargins);
|
|
526
|
+
|
|
527
|
+
if (tabrowWidth > tabrowBox.width) {
|
|
528
|
+
SqueezeTabs(nb, tabrowWidth, tabrowBox.width, nbstyle.minTabWidth);
|
|
529
|
+
}
|
|
530
|
+
PlaceTabs(nb, tabrowBox, nbstyle.tabPlacement);
|
|
531
|
+
|
|
532
|
+
/* Layout for client area frame:
|
|
533
|
+
*/
|
|
534
|
+
if (clientNode) {
|
|
535
|
+
Ttk_PlaceLayoutNode(nb->core.layout, clientNode, cavity);
|
|
536
|
+
cavity = Ttk_LayoutNodeInternalParcel(nb->core.layout, clientNode);
|
|
537
|
+
}
|
|
538
|
+
|
|
539
|
+
if (cavity.height <= 0) cavity.height = 1;
|
|
540
|
+
if (cavity.width <= 0) cavity.width = 1;
|
|
541
|
+
|
|
542
|
+
nb->notebook.clientArea = cavity;
|
|
543
|
+
}
|
|
544
|
+
|
|
545
|
+
/*
|
|
546
|
+
* NotebookPlaceSlave --
|
|
547
|
+
* Set the position and size of a child widget
|
|
548
|
+
* based on the current client area and slave options:
|
|
549
|
+
*/
|
|
550
|
+
static void NotebookPlaceSlave(Notebook *nb, int slaveIndex)
|
|
551
|
+
{
|
|
552
|
+
Tab *tab = Ttk_SlaveData(nb->notebook.mgr, slaveIndex);
|
|
553
|
+
Tk_Window slaveWindow = Ttk_SlaveWindow(nb->notebook.mgr, slaveIndex);
|
|
554
|
+
Ttk_Box slaveBox =
|
|
555
|
+
Ttk_StickBox(Ttk_PadBox(nb->notebook.clientArea, tab->padding),
|
|
556
|
+
Tk_ReqWidth(slaveWindow), Tk_ReqHeight(slaveWindow),tab->sticky);
|
|
557
|
+
|
|
558
|
+
Ttk_PlaceSlave(nb->notebook.mgr, slaveIndex,
|
|
559
|
+
slaveBox.x, slaveBox.y, slaveBox.width, slaveBox.height);
|
|
560
|
+
}
|
|
561
|
+
|
|
562
|
+
/* NotebookPlaceSlaves --
|
|
563
|
+
* Geometry manager hook.
|
|
564
|
+
*/
|
|
565
|
+
static void NotebookPlaceSlaves(void *recordPtr)
|
|
566
|
+
{
|
|
567
|
+
Notebook *nb = recordPtr;
|
|
568
|
+
int currentIndex = nb->notebook.currentIndex;
|
|
569
|
+
if (currentIndex >= 0) {
|
|
570
|
+
NotebookDoLayout(nb);
|
|
571
|
+
NotebookPlaceSlave(nb, currentIndex);
|
|
572
|
+
}
|
|
573
|
+
}
|
|
574
|
+
|
|
575
|
+
/*
|
|
576
|
+
* SelectTab(nb, index) --
|
|
577
|
+
* Change the currently-selected tab.
|
|
578
|
+
*/
|
|
579
|
+
static void SelectTab(Notebook *nb, int index)
|
|
580
|
+
{
|
|
581
|
+
Tab *tab = Ttk_SlaveData(nb->notebook.mgr,index);
|
|
582
|
+
int currentIndex = nb->notebook.currentIndex;
|
|
583
|
+
|
|
584
|
+
if (index == currentIndex) {
|
|
585
|
+
return;
|
|
586
|
+
}
|
|
587
|
+
|
|
588
|
+
if (TabState(nb, index) & TTK_STATE_DISABLED) {
|
|
589
|
+
return;
|
|
590
|
+
}
|
|
591
|
+
|
|
592
|
+
/* Unhide the tab if it is currently hidden and being selected.
|
|
593
|
+
*/
|
|
594
|
+
if (tab->state == TAB_STATE_HIDDEN) {
|
|
595
|
+
tab->state = TAB_STATE_NORMAL;
|
|
596
|
+
}
|
|
597
|
+
|
|
598
|
+
if (currentIndex >= 0) {
|
|
599
|
+
Ttk_UnmapSlave(nb->notebook.mgr, currentIndex);
|
|
600
|
+
}
|
|
601
|
+
|
|
602
|
+
NotebookPlaceSlave(nb, index);
|
|
603
|
+
|
|
604
|
+
nb->notebook.currentIndex = index;
|
|
605
|
+
TtkRedisplayWidget(&nb->core);
|
|
606
|
+
|
|
607
|
+
TtkSendVirtualEvent(nb->core.tkwin, "NotebookTabChanged");
|
|
608
|
+
}
|
|
609
|
+
|
|
610
|
+
/* NextTab --
|
|
611
|
+
* Returns the index of the next tab after the specified tab
|
|
612
|
+
* in the normal state (e.g., not hidden or disabled),
|
|
613
|
+
* or -1 if all tabs are disabled or hidden.
|
|
614
|
+
*/
|
|
615
|
+
static int NextTab(Notebook *nb, int index)
|
|
616
|
+
{
|
|
617
|
+
int nTabs = Ttk_NumberSlaves(nb->notebook.mgr);
|
|
618
|
+
int nextIndex;
|
|
619
|
+
|
|
620
|
+
/* Scan forward for following usable tab:
|
|
621
|
+
*/
|
|
622
|
+
for (nextIndex = index + 1; nextIndex < nTabs; ++nextIndex) {
|
|
623
|
+
Tab *tab = Ttk_SlaveData(nb->notebook.mgr, nextIndex);
|
|
624
|
+
if (tab->state == TAB_STATE_NORMAL) {
|
|
625
|
+
return nextIndex;
|
|
626
|
+
}
|
|
627
|
+
}
|
|
628
|
+
|
|
629
|
+
/* Not found -- scan backwards.
|
|
630
|
+
*/
|
|
631
|
+
for (nextIndex = index - 1; nextIndex >= 0; --nextIndex) {
|
|
632
|
+
Tab *tab = Ttk_SlaveData(nb->notebook.mgr, nextIndex);
|
|
633
|
+
if (tab->state == TAB_STATE_NORMAL) {
|
|
634
|
+
return nextIndex;
|
|
635
|
+
}
|
|
636
|
+
}
|
|
637
|
+
|
|
638
|
+
/* Still nothing. Give up.
|
|
639
|
+
*/
|
|
640
|
+
return -1;
|
|
641
|
+
}
|
|
642
|
+
|
|
643
|
+
/* SelectNearestTab --
|
|
644
|
+
* Handles the case where the current tab is forgotten, hidden,
|
|
645
|
+
* or destroyed.
|
|
646
|
+
*
|
|
647
|
+
* Unmap the current tab and schedule the next available one
|
|
648
|
+
* to be mapped at the next GM update.
|
|
649
|
+
*/
|
|
650
|
+
static void SelectNearestTab(Notebook *nb)
|
|
651
|
+
{
|
|
652
|
+
int currentIndex = nb->notebook.currentIndex;
|
|
653
|
+
int nextIndex = NextTab(nb, currentIndex);
|
|
654
|
+
|
|
655
|
+
if (currentIndex >= 0) {
|
|
656
|
+
Ttk_UnmapSlave(nb->notebook.mgr, currentIndex);
|
|
657
|
+
}
|
|
658
|
+
if (currentIndex != nextIndex) {
|
|
659
|
+
TtkSendVirtualEvent(nb->core.tkwin, "NotebookTabChanged");
|
|
660
|
+
}
|
|
661
|
+
|
|
662
|
+
nb->notebook.currentIndex = nextIndex;
|
|
663
|
+
Ttk_ManagerLayoutChanged(nb->notebook.mgr);
|
|
664
|
+
TtkRedisplayWidget(&nb->core);
|
|
665
|
+
}
|
|
666
|
+
|
|
667
|
+
/* TabRemoved -- GM SlaveRemoved hook.
|
|
668
|
+
* Select the next tab if the current one is being removed.
|
|
669
|
+
* Adjust currentIndex to account for removed slave.
|
|
670
|
+
*/
|
|
671
|
+
static void TabRemoved(void *managerData, int index)
|
|
672
|
+
{
|
|
673
|
+
Notebook *nb = managerData;
|
|
674
|
+
Tab *tab = Ttk_SlaveData(nb->notebook.mgr, index);
|
|
675
|
+
|
|
676
|
+
if (index == nb->notebook.currentIndex) {
|
|
677
|
+
SelectNearestTab(nb);
|
|
678
|
+
}
|
|
679
|
+
|
|
680
|
+
if (index < nb->notebook.currentIndex) {
|
|
681
|
+
--nb->notebook.currentIndex;
|
|
682
|
+
}
|
|
683
|
+
|
|
684
|
+
DestroyTab(nb, tab);
|
|
685
|
+
|
|
686
|
+
TtkRedisplayWidget(&nb->core);
|
|
687
|
+
}
|
|
688
|
+
|
|
689
|
+
static int TabRequest(void *managerData, int index, int width, int height)
|
|
690
|
+
{
|
|
691
|
+
return 1;
|
|
692
|
+
}
|
|
693
|
+
|
|
694
|
+
/* AddTab --
|
|
695
|
+
* Add new tab at specified index.
|
|
696
|
+
*/
|
|
697
|
+
static int AddTab(
|
|
698
|
+
Tcl_Interp *interp, Notebook *nb,
|
|
699
|
+
int destIndex, Tk_Window slaveWindow,
|
|
700
|
+
int objc, Tcl_Obj *const objv[])
|
|
701
|
+
{
|
|
702
|
+
Tab *tab;
|
|
703
|
+
if (!Ttk_Maintainable(interp, slaveWindow, nb->core.tkwin)) {
|
|
704
|
+
return TCL_ERROR;
|
|
705
|
+
}
|
|
706
|
+
#if 0 /* can't happen */
|
|
707
|
+
if (Ttk_SlaveIndex(nb->notebook.mgr, slaveWindow) >= 0) {
|
|
708
|
+
Tcl_AppendResult(interp,
|
|
709
|
+
Tk_PathName(slaveWindow), " already added",
|
|
710
|
+
NULL);
|
|
711
|
+
return TCL_ERROR;
|
|
712
|
+
}
|
|
713
|
+
#endif
|
|
714
|
+
|
|
715
|
+
/* Create and insert tab.
|
|
716
|
+
*/
|
|
717
|
+
tab = CreateTab(interp, nb, slaveWindow);
|
|
718
|
+
if (!tab) {
|
|
719
|
+
return TCL_ERROR;
|
|
720
|
+
}
|
|
721
|
+
if (ConfigureTab(interp, nb, tab, slaveWindow, objc, objv) != TCL_OK) {
|
|
722
|
+
DestroyTab(nb, tab);
|
|
723
|
+
return TCL_ERROR;
|
|
724
|
+
}
|
|
725
|
+
|
|
726
|
+
Ttk_InsertSlave(nb->notebook.mgr, destIndex, slaveWindow, tab);
|
|
727
|
+
|
|
728
|
+
/* Adjust indices and/or autoselect first tab:
|
|
729
|
+
*/
|
|
730
|
+
if (nb->notebook.currentIndex < 0) {
|
|
731
|
+
SelectTab(nb, destIndex);
|
|
732
|
+
} else if (nb->notebook.currentIndex >= destIndex) {
|
|
733
|
+
++nb->notebook.currentIndex;
|
|
734
|
+
}
|
|
735
|
+
|
|
736
|
+
return TCL_OK;
|
|
737
|
+
}
|
|
738
|
+
|
|
739
|
+
static Ttk_ManagerSpec NotebookManagerSpec = {
|
|
740
|
+
{ "notebook", Ttk_GeometryRequestProc, Ttk_LostSlaveProc },
|
|
741
|
+
NotebookSize,
|
|
742
|
+
NotebookPlaceSlaves,
|
|
743
|
+
TabRequest,
|
|
744
|
+
TabRemoved
|
|
745
|
+
};
|
|
746
|
+
|
|
747
|
+
/*------------------------------------------------------------------------
|
|
748
|
+
* +++ Event handlers.
|
|
749
|
+
*/
|
|
750
|
+
|
|
751
|
+
/* NotebookEventHandler --
|
|
752
|
+
* Tracks the active tab.
|
|
753
|
+
*/
|
|
754
|
+
static const int NotebookEventMask
|
|
755
|
+
= StructureNotifyMask
|
|
756
|
+
| PointerMotionMask
|
|
757
|
+
| LeaveWindowMask
|
|
758
|
+
;
|
|
759
|
+
static void NotebookEventHandler(ClientData clientData, XEvent *eventPtr)
|
|
760
|
+
{
|
|
761
|
+
Notebook *nb = clientData;
|
|
762
|
+
|
|
763
|
+
if (eventPtr->type == DestroyNotify) { /* Remove self */
|
|
764
|
+
Tk_DeleteEventHandler(nb->core.tkwin,
|
|
765
|
+
NotebookEventMask, NotebookEventHandler, clientData);
|
|
766
|
+
} else if (eventPtr->type == MotionNotify) {
|
|
767
|
+
int index = IdentifyTab(nb, eventPtr->xmotion.x, eventPtr->xmotion.y);
|
|
768
|
+
ActivateTab(nb, index);
|
|
769
|
+
} else if (eventPtr->type == LeaveNotify) {
|
|
770
|
+
ActivateTab(nb, -1);
|
|
771
|
+
}
|
|
772
|
+
}
|
|
773
|
+
|
|
774
|
+
/*------------------------------------------------------------------------
|
|
775
|
+
* +++ Utilities.
|
|
776
|
+
*/
|
|
777
|
+
|
|
778
|
+
/* FindTabIndex --
|
|
779
|
+
* Find the index of the specified tab.
|
|
780
|
+
* Tab identifiers are one of:
|
|
781
|
+
*
|
|
782
|
+
* + positional specifications @x,y,
|
|
783
|
+
* + "current",
|
|
784
|
+
* + numeric indices [0..nTabs],
|
|
785
|
+
* + slave window names
|
|
786
|
+
*
|
|
787
|
+
* Stores index of specified tab in *index_rtn, -1 if not found.
|
|
788
|
+
*
|
|
789
|
+
* Returns TCL_ERROR and leaves an error message in interp->result
|
|
790
|
+
* if the tab identifier was incorrect.
|
|
791
|
+
*
|
|
792
|
+
* See also: GetTabIndex.
|
|
793
|
+
*/
|
|
794
|
+
static int FindTabIndex(
|
|
795
|
+
Tcl_Interp *interp, Notebook *nb, Tcl_Obj *objPtr, int *index_rtn)
|
|
796
|
+
{
|
|
797
|
+
const char *string = Tcl_GetString(objPtr);
|
|
798
|
+
int x, y;
|
|
799
|
+
|
|
800
|
+
*index_rtn = -1;
|
|
801
|
+
|
|
802
|
+
/* Check for @x,y ...
|
|
803
|
+
*/
|
|
804
|
+
if (string[0] == '@' && sscanf(string, "@%d,%d",&x,&y) == 2) {
|
|
805
|
+
*index_rtn = IdentifyTab(nb, x, y);
|
|
806
|
+
return TCL_OK;
|
|
807
|
+
}
|
|
808
|
+
|
|
809
|
+
/* ... or "current" ...
|
|
810
|
+
*/
|
|
811
|
+
if (!strcmp(string, "current")) {
|
|
812
|
+
*index_rtn = nb->notebook.currentIndex;
|
|
813
|
+
return TCL_OK;
|
|
814
|
+
}
|
|
815
|
+
|
|
816
|
+
/* ... or integer index or slave window name:
|
|
817
|
+
*/
|
|
818
|
+
if (Ttk_GetSlaveIndexFromObj(
|
|
819
|
+
interp, nb->notebook.mgr, objPtr, index_rtn) == TCL_OK)
|
|
820
|
+
{
|
|
821
|
+
return TCL_OK;
|
|
822
|
+
}
|
|
823
|
+
|
|
824
|
+
/* Nothing matched; Ttk_GetSlaveIndexFromObj will have left error message.
|
|
825
|
+
*/
|
|
826
|
+
return TCL_ERROR;
|
|
827
|
+
}
|
|
828
|
+
|
|
829
|
+
/* GetTabIndex --
|
|
830
|
+
* Get the index of an existing tab.
|
|
831
|
+
* Tab identifiers are as per FindTabIndex.
|
|
832
|
+
* Returns TCL_ERROR if the tab does not exist.
|
|
833
|
+
*/
|
|
834
|
+
static int GetTabIndex(
|
|
835
|
+
Tcl_Interp *interp, Notebook *nb, Tcl_Obj *objPtr, int *index_rtn)
|
|
836
|
+
{
|
|
837
|
+
int status = FindTabIndex(interp, nb, objPtr, index_rtn);
|
|
838
|
+
|
|
839
|
+
if (status == TCL_OK && *index_rtn < 0) {
|
|
840
|
+
Tcl_ResetResult(interp);
|
|
841
|
+
Tcl_AppendResult(interp,
|
|
842
|
+
"tab '", Tcl_GetString(objPtr), "' not found",
|
|
843
|
+
NULL);
|
|
844
|
+
status = TCL_ERROR;
|
|
845
|
+
}
|
|
846
|
+
return status;
|
|
847
|
+
}
|
|
848
|
+
|
|
849
|
+
/*------------------------------------------------------------------------
|
|
850
|
+
* +++ Widget command routines.
|
|
851
|
+
*/
|
|
852
|
+
|
|
853
|
+
/* $nb add window ?options ... ?
|
|
854
|
+
*/
|
|
855
|
+
static int NotebookAddCommand(
|
|
856
|
+
Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[], void *recordPtr)
|
|
857
|
+
{
|
|
858
|
+
Notebook *nb = recordPtr;
|
|
859
|
+
int index = Ttk_NumberSlaves(nb->notebook.mgr);
|
|
860
|
+
Tk_Window slaveWindow;
|
|
861
|
+
int slaveIndex;
|
|
862
|
+
Tab *tab;
|
|
863
|
+
|
|
864
|
+
if (objc <= 2 || objc % 2 != 1) {
|
|
865
|
+
Tcl_WrongNumArgs(interp, 2, objv, "window ?options...?");
|
|
866
|
+
return TCL_ERROR;
|
|
867
|
+
}
|
|
868
|
+
|
|
869
|
+
slaveWindow = Tk_NameToWindow(interp,Tcl_GetString(objv[2]),nb->core.tkwin);
|
|
870
|
+
if (!slaveWindow) {
|
|
871
|
+
return TCL_ERROR;
|
|
872
|
+
}
|
|
873
|
+
slaveIndex = Ttk_SlaveIndex(nb->notebook.mgr, slaveWindow);
|
|
874
|
+
|
|
875
|
+
if (slaveIndex < 0) { /* New tab */
|
|
876
|
+
return AddTab(interp, nb, index, slaveWindow, objc-3,objv+3);
|
|
877
|
+
}
|
|
878
|
+
|
|
879
|
+
tab = Ttk_SlaveData(nb->notebook.mgr, slaveIndex);
|
|
880
|
+
if (tab->state == TAB_STATE_HIDDEN) {
|
|
881
|
+
tab->state = TAB_STATE_NORMAL;
|
|
882
|
+
}
|
|
883
|
+
if (ConfigureTab(interp, nb, tab, slaveWindow, objc-4,objv+4) != TCL_OK) {
|
|
884
|
+
return TCL_ERROR;
|
|
885
|
+
}
|
|
886
|
+
|
|
887
|
+
TtkRedisplayWidget(&nb->core);
|
|
888
|
+
|
|
889
|
+
return TCL_OK;
|
|
890
|
+
}
|
|
891
|
+
|
|
892
|
+
/* $nb insert $index $tab ?options...?
|
|
893
|
+
* Insert new tab, or move existing one.
|
|
894
|
+
*/
|
|
895
|
+
static int NotebookInsertCommand(
|
|
896
|
+
Tcl_Interp *interp, int objc, Tcl_Obj *const objv[], void *recordPtr)
|
|
897
|
+
{
|
|
898
|
+
Notebook *nb = recordPtr;
|
|
899
|
+
int current = nb->notebook.currentIndex;
|
|
900
|
+
int nSlaves = Ttk_NumberSlaves(nb->notebook.mgr);
|
|
901
|
+
int srcIndex, destIndex;
|
|
902
|
+
|
|
903
|
+
if (objc < 4) {
|
|
904
|
+
Tcl_WrongNumArgs(interp, 2,objv, "index slave ?options...?");
|
|
905
|
+
return TCL_ERROR;
|
|
906
|
+
}
|
|
907
|
+
|
|
908
|
+
if (!strcmp(Tcl_GetString(objv[2]), "end")) {
|
|
909
|
+
destIndex = Ttk_NumberSlaves(nb->notebook.mgr);
|
|
910
|
+
} else if (TCL_OK != Ttk_GetSlaveIndexFromObj(
|
|
911
|
+
interp, nb->notebook.mgr, objv[2], &destIndex)) {
|
|
912
|
+
return TCL_ERROR;
|
|
913
|
+
}
|
|
914
|
+
|
|
915
|
+
if (Tcl_GetString(objv[3])[0] == '.') {
|
|
916
|
+
/* Window name -- could be new or existing slave.
|
|
917
|
+
*/
|
|
918
|
+
Tk_Window slaveWindow =
|
|
919
|
+
Tk_NameToWindow(interp,Tcl_GetString(objv[3]),nb->core.tkwin);
|
|
920
|
+
|
|
921
|
+
if (!slaveWindow) {
|
|
922
|
+
return TCL_ERROR;
|
|
923
|
+
}
|
|
924
|
+
|
|
925
|
+
srcIndex = Ttk_SlaveIndex(nb->notebook.mgr, slaveWindow);
|
|
926
|
+
if (srcIndex < 0) { /* New slave */
|
|
927
|
+
return AddTab(interp, nb, destIndex, slaveWindow, objc-4,objv+4);
|
|
928
|
+
}
|
|
929
|
+
} else if (Ttk_GetSlaveIndexFromObj(
|
|
930
|
+
interp, nb->notebook.mgr, objv[3], &srcIndex) != TCL_OK)
|
|
931
|
+
{
|
|
932
|
+
return TCL_ERROR;
|
|
933
|
+
}
|
|
934
|
+
|
|
935
|
+
/* Move existing slave:
|
|
936
|
+
*/
|
|
937
|
+
if (ConfigureTab(interp, nb,
|
|
938
|
+
Ttk_SlaveData(nb->notebook.mgr,srcIndex),
|
|
939
|
+
Ttk_SlaveWindow(nb->notebook.mgr,srcIndex),
|
|
940
|
+
objc-4,objv+4) != TCL_OK)
|
|
941
|
+
{
|
|
942
|
+
return TCL_ERROR;
|
|
943
|
+
}
|
|
944
|
+
|
|
945
|
+
if (destIndex >= nSlaves) {
|
|
946
|
+
destIndex = nSlaves - 1;
|
|
947
|
+
}
|
|
948
|
+
Ttk_ReorderSlave(nb->notebook.mgr, srcIndex, destIndex);
|
|
949
|
+
|
|
950
|
+
/* Adjust internal indexes:
|
|
951
|
+
*/
|
|
952
|
+
nb->notebook.activeIndex = -1;
|
|
953
|
+
if (current == srcIndex) {
|
|
954
|
+
nb->notebook.currentIndex = destIndex;
|
|
955
|
+
} else if (destIndex <= current && current < srcIndex) {
|
|
956
|
+
++nb->notebook.currentIndex;
|
|
957
|
+
} else if (srcIndex < current && current <= destIndex) {
|
|
958
|
+
--nb->notebook.currentIndex;
|
|
959
|
+
}
|
|
960
|
+
|
|
961
|
+
TtkRedisplayWidget(&nb->core);
|
|
962
|
+
|
|
963
|
+
return TCL_OK;
|
|
964
|
+
}
|
|
965
|
+
|
|
966
|
+
/* $nb forget $tab --
|
|
967
|
+
* Removes the specified tab.
|
|
968
|
+
*/
|
|
969
|
+
static int NotebookForgetCommand(
|
|
970
|
+
Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[], void *recordPtr)
|
|
971
|
+
{
|
|
972
|
+
Notebook *nb = recordPtr;
|
|
973
|
+
int index;
|
|
974
|
+
|
|
975
|
+
if (objc != 3) {
|
|
976
|
+
Tcl_WrongNumArgs(interp, 2, objv, "tab");
|
|
977
|
+
return TCL_ERROR;
|
|
978
|
+
}
|
|
979
|
+
|
|
980
|
+
if (GetTabIndex(interp, nb, objv[2], &index) != TCL_OK) {
|
|
981
|
+
return TCL_ERROR;
|
|
982
|
+
}
|
|
983
|
+
|
|
984
|
+
Ttk_ForgetSlave(nb->notebook.mgr, index);
|
|
985
|
+
|
|
986
|
+
return TCL_OK;
|
|
987
|
+
}
|
|
988
|
+
|
|
989
|
+
/* $nb hide $tab --
|
|
990
|
+
* Hides the specified tab.
|
|
991
|
+
*/
|
|
992
|
+
static int NotebookHideCommand(
|
|
993
|
+
Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[], void *recordPtr)
|
|
994
|
+
{
|
|
995
|
+
Notebook *nb = recordPtr;
|
|
996
|
+
int index;
|
|
997
|
+
Tab *tab;
|
|
998
|
+
|
|
999
|
+
if (objc != 3) {
|
|
1000
|
+
Tcl_WrongNumArgs(interp, 2, objv, "tab");
|
|
1001
|
+
return TCL_ERROR;
|
|
1002
|
+
}
|
|
1003
|
+
|
|
1004
|
+
if (GetTabIndex(interp, nb, objv[2], &index) != TCL_OK) {
|
|
1005
|
+
return TCL_ERROR;
|
|
1006
|
+
}
|
|
1007
|
+
|
|
1008
|
+
tab = Ttk_SlaveData(nb->notebook.mgr, index);
|
|
1009
|
+
tab->state = TAB_STATE_HIDDEN;
|
|
1010
|
+
if (index == nb->notebook.currentIndex) {
|
|
1011
|
+
SelectNearestTab(nb);
|
|
1012
|
+
}
|
|
1013
|
+
|
|
1014
|
+
return TCL_OK;
|
|
1015
|
+
}
|
|
1016
|
+
|
|
1017
|
+
/* $nb identify $x $y --
|
|
1018
|
+
* Returns name of tab element at $x,$y; empty string if none.
|
|
1019
|
+
*/
|
|
1020
|
+
static int NotebookIdentifyCommand(
|
|
1021
|
+
Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[], void *recordPtr)
|
|
1022
|
+
{
|
|
1023
|
+
Notebook *nb = recordPtr;
|
|
1024
|
+
Ttk_LayoutNode *node = NULL;
|
|
1025
|
+
int x, y, tabIndex;
|
|
1026
|
+
|
|
1027
|
+
if (objc != 4) {
|
|
1028
|
+
Tcl_WrongNumArgs(interp, 2, objv, "x y");
|
|
1029
|
+
return TCL_ERROR;
|
|
1030
|
+
}
|
|
1031
|
+
|
|
1032
|
+
if ( Tcl_GetIntFromObj(interp, objv[2], &x) != TCL_OK
|
|
1033
|
+
|| Tcl_GetIntFromObj(interp, objv[3], &y) != TCL_OK)
|
|
1034
|
+
{
|
|
1035
|
+
return TCL_ERROR;
|
|
1036
|
+
}
|
|
1037
|
+
|
|
1038
|
+
tabIndex = IdentifyTab(nb, x, y);
|
|
1039
|
+
if (tabIndex >= 0) {
|
|
1040
|
+
Tab *tab = Ttk_SlaveData(nb->notebook.mgr, tabIndex);
|
|
1041
|
+
Ttk_State state = TabState(nb, tabIndex);
|
|
1042
|
+
Ttk_Layout tabLayout = nb->notebook.tabLayout;
|
|
1043
|
+
|
|
1044
|
+
Ttk_RebindSublayout(tabLayout, tab);
|
|
1045
|
+
Ttk_PlaceLayout(tabLayout, state, tab->parcel);
|
|
1046
|
+
|
|
1047
|
+
node = Ttk_LayoutIdentify(tabLayout, x, y);
|
|
1048
|
+
}
|
|
1049
|
+
|
|
1050
|
+
if (node) {
|
|
1051
|
+
const char *elementName = Ttk_LayoutNodeName(node);
|
|
1052
|
+
Tcl_SetObjResult(interp,Tcl_NewStringObj(elementName,-1));
|
|
1053
|
+
}
|
|
1054
|
+
|
|
1055
|
+
return TCL_OK;
|
|
1056
|
+
}
|
|
1057
|
+
|
|
1058
|
+
/* $nb index $item --
|
|
1059
|
+
* Returns the integer index of the tab specified by $item,
|
|
1060
|
+
* the empty string if $item does not identify a tab.
|
|
1061
|
+
* See above for valid item formats.
|
|
1062
|
+
*/
|
|
1063
|
+
static int NotebookIndexCommand(
|
|
1064
|
+
Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[], void *recordPtr)
|
|
1065
|
+
{
|
|
1066
|
+
Notebook *nb = recordPtr;
|
|
1067
|
+
int index, status;
|
|
1068
|
+
|
|
1069
|
+
if (objc != 3) {
|
|
1070
|
+
Tcl_WrongNumArgs(interp, 2, objv, "tab");
|
|
1071
|
+
return TCL_ERROR;
|
|
1072
|
+
}
|
|
1073
|
+
|
|
1074
|
+
/*
|
|
1075
|
+
* Special-case for "end":
|
|
1076
|
+
*/
|
|
1077
|
+
if (!strcmp("end", Tcl_GetString(objv[2]))) {
|
|
1078
|
+
int nSlaves = Ttk_NumberSlaves(nb->notebook.mgr);
|
|
1079
|
+
Tcl_SetObjResult(interp, Tcl_NewIntObj(nSlaves));
|
|
1080
|
+
return TCL_OK;
|
|
1081
|
+
}
|
|
1082
|
+
|
|
1083
|
+
status = FindTabIndex(interp, nb, objv[2], &index);
|
|
1084
|
+
if (status == TCL_OK && index >= 0) {
|
|
1085
|
+
Tcl_SetObjResult(interp, Tcl_NewIntObj(index));
|
|
1086
|
+
}
|
|
1087
|
+
|
|
1088
|
+
return status;
|
|
1089
|
+
}
|
|
1090
|
+
|
|
1091
|
+
/* $nb select ?$item? --
|
|
1092
|
+
* Select the specified tab, or return the widget path of
|
|
1093
|
+
* the currently-selected pane.
|
|
1094
|
+
*/
|
|
1095
|
+
static int NotebookSelectCommand(
|
|
1096
|
+
Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[], void *recordPtr)
|
|
1097
|
+
{
|
|
1098
|
+
Notebook *nb = recordPtr;
|
|
1099
|
+
|
|
1100
|
+
if (objc == 2) {
|
|
1101
|
+
if (nb->notebook.currentIndex >= 0) {
|
|
1102
|
+
Tk_Window pane = Ttk_SlaveWindow(
|
|
1103
|
+
nb->notebook.mgr, nb->notebook.currentIndex);
|
|
1104
|
+
Tcl_SetObjResult(interp, Tcl_NewStringObj(Tk_PathName(pane), -1));
|
|
1105
|
+
}
|
|
1106
|
+
return TCL_OK;
|
|
1107
|
+
} else if (objc == 3) {
|
|
1108
|
+
int index, status = GetTabIndex(interp, nb, objv[2], &index);
|
|
1109
|
+
if (status == TCL_OK) {
|
|
1110
|
+
SelectTab(nb, index);
|
|
1111
|
+
}
|
|
1112
|
+
return status;
|
|
1113
|
+
} /*else*/
|
|
1114
|
+
Tcl_WrongNumArgs(interp, 2, objv, "?tab?");
|
|
1115
|
+
return TCL_ERROR;
|
|
1116
|
+
}
|
|
1117
|
+
|
|
1118
|
+
/* $nb tabs --
|
|
1119
|
+
* Return list of tabs.
|
|
1120
|
+
*/
|
|
1121
|
+
static int NotebookTabsCommand(
|
|
1122
|
+
Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[], void *recordPtr)
|
|
1123
|
+
{
|
|
1124
|
+
Notebook *nb = recordPtr;
|
|
1125
|
+
Ttk_Manager *mgr = nb->notebook.mgr;
|
|
1126
|
+
Tcl_Obj *result;
|
|
1127
|
+
int i;
|
|
1128
|
+
|
|
1129
|
+
if (objc != 2) {
|
|
1130
|
+
Tcl_WrongNumArgs(interp, 2, objv, "");
|
|
1131
|
+
return TCL_ERROR;
|
|
1132
|
+
}
|
|
1133
|
+
|
|
1134
|
+
result = Tcl_NewListObj(0, NULL);
|
|
1135
|
+
for (i = 0; i < Ttk_NumberSlaves(mgr); ++i) {
|
|
1136
|
+
const char *pathName = Tk_PathName(Ttk_SlaveWindow(mgr,i));
|
|
1137
|
+
Tcl_ListObjAppendElement(interp, result, Tcl_NewStringObj(pathName,-1));
|
|
1138
|
+
}
|
|
1139
|
+
Tcl_SetObjResult(interp, result);
|
|
1140
|
+
|
|
1141
|
+
return TCL_OK;
|
|
1142
|
+
}
|
|
1143
|
+
|
|
1144
|
+
/* $nb tab $tab ?-option ?value -option value...??
|
|
1145
|
+
*/
|
|
1146
|
+
static int NotebookTabCommand(
|
|
1147
|
+
Tcl_Interp *interp, int objc, Tcl_Obj * CONST objv[], void *recordPtr)
|
|
1148
|
+
{
|
|
1149
|
+
Notebook *nb = recordPtr;
|
|
1150
|
+
Ttk_Manager *mgr = nb->notebook.mgr;
|
|
1151
|
+
int index;
|
|
1152
|
+
Tk_Window slaveWindow;
|
|
1153
|
+
Tab *tab;
|
|
1154
|
+
|
|
1155
|
+
if (objc < 3) {
|
|
1156
|
+
Tcl_WrongNumArgs(interp, 2, objv, "tab ?-option ?value??...");
|
|
1157
|
+
return TCL_ERROR;
|
|
1158
|
+
}
|
|
1159
|
+
|
|
1160
|
+
if (GetTabIndex(interp, nb, objv[2], &index) != TCL_OK) {
|
|
1161
|
+
return TCL_ERROR;
|
|
1162
|
+
}
|
|
1163
|
+
|
|
1164
|
+
tab = Ttk_SlaveData(mgr, index);
|
|
1165
|
+
slaveWindow = Ttk_SlaveWindow(mgr, index);
|
|
1166
|
+
|
|
1167
|
+
if (objc == 3) {
|
|
1168
|
+
return TtkEnumerateOptions(interp, tab,
|
|
1169
|
+
PaneOptionSpecs, nb->notebook.paneOptionTable, slaveWindow);
|
|
1170
|
+
} else if (objc == 4) {
|
|
1171
|
+
return TtkGetOptionValue(interp, tab, objv[3],
|
|
1172
|
+
nb->notebook.paneOptionTable, slaveWindow);
|
|
1173
|
+
} /* else */
|
|
1174
|
+
|
|
1175
|
+
if (ConfigureTab(interp, nb, tab, slaveWindow, objc-3,objv+3) != TCL_OK) {
|
|
1176
|
+
return TCL_ERROR;
|
|
1177
|
+
}
|
|
1178
|
+
|
|
1179
|
+
/* If the current tab has become disabled or hidden,
|
|
1180
|
+
* select the next nondisabled, unhidden one:
|
|
1181
|
+
*/
|
|
1182
|
+
if (index == nb->notebook.currentIndex && tab->state != TAB_STATE_NORMAL) {
|
|
1183
|
+
SelectNearestTab(nb);
|
|
1184
|
+
}
|
|
1185
|
+
|
|
1186
|
+
TtkResizeWidget(&nb->core);
|
|
1187
|
+
return TCL_OK;
|
|
1188
|
+
}
|
|
1189
|
+
|
|
1190
|
+
/* Subcommand table:
|
|
1191
|
+
*/
|
|
1192
|
+
static WidgetCommandSpec NotebookCommands[] =
|
|
1193
|
+
{
|
|
1194
|
+
{ "add", NotebookAddCommand },
|
|
1195
|
+
{ "configure", TtkWidgetConfigureCommand },
|
|
1196
|
+
{ "cget", TtkWidgetCgetCommand },
|
|
1197
|
+
{ "forget", NotebookForgetCommand },
|
|
1198
|
+
{ "hide", NotebookHideCommand },
|
|
1199
|
+
{ "identify", NotebookIdentifyCommand },
|
|
1200
|
+
{ "index", NotebookIndexCommand },
|
|
1201
|
+
{ "insert", NotebookInsertCommand },
|
|
1202
|
+
{ "instate", TtkWidgetInstateCommand },
|
|
1203
|
+
{ "select", NotebookSelectCommand },
|
|
1204
|
+
{ "state", TtkWidgetStateCommand },
|
|
1205
|
+
{ "tab", NotebookTabCommand },
|
|
1206
|
+
{ "tabs", NotebookTabsCommand },
|
|
1207
|
+
{ 0,0 }
|
|
1208
|
+
};
|
|
1209
|
+
|
|
1210
|
+
/*------------------------------------------------------------------------
|
|
1211
|
+
* +++ Widget class hooks.
|
|
1212
|
+
*/
|
|
1213
|
+
|
|
1214
|
+
static int NotebookInitialize(Tcl_Interp *interp, void *recordPtr)
|
|
1215
|
+
{
|
|
1216
|
+
Notebook *nb = recordPtr;
|
|
1217
|
+
|
|
1218
|
+
nb->notebook.mgr = Ttk_CreateManager(
|
|
1219
|
+
&NotebookManagerSpec, recordPtr, nb->core.tkwin);
|
|
1220
|
+
|
|
1221
|
+
nb->notebook.tabOptionTable = Tk_CreateOptionTable(interp,TabOptionSpecs);
|
|
1222
|
+
nb->notebook.paneOptionTable = Tk_CreateOptionTable(interp,PaneOptionSpecs);
|
|
1223
|
+
|
|
1224
|
+
nb->notebook.currentIndex = -1;
|
|
1225
|
+
nb->notebook.activeIndex = -1;
|
|
1226
|
+
nb->notebook.tabLayout = 0;
|
|
1227
|
+
|
|
1228
|
+
nb->notebook.clientArea = Ttk_MakeBox(0,0,1,1);
|
|
1229
|
+
|
|
1230
|
+
Tk_CreateEventHandler(
|
|
1231
|
+
nb->core.tkwin, NotebookEventMask, NotebookEventHandler, recordPtr);
|
|
1232
|
+
|
|
1233
|
+
return TCL_OK;
|
|
1234
|
+
}
|
|
1235
|
+
|
|
1236
|
+
static void NotebookCleanup(void *recordPtr)
|
|
1237
|
+
{
|
|
1238
|
+
Notebook *nb = recordPtr;
|
|
1239
|
+
|
|
1240
|
+
Ttk_DeleteManager(nb->notebook.mgr);
|
|
1241
|
+
Tk_DeleteOptionTable(nb->notebook.tabOptionTable);
|
|
1242
|
+
Tk_DeleteOptionTable(nb->notebook.paneOptionTable);
|
|
1243
|
+
|
|
1244
|
+
if (nb->notebook.tabLayout)
|
|
1245
|
+
Ttk_FreeLayout(nb->notebook.tabLayout);
|
|
1246
|
+
}
|
|
1247
|
+
|
|
1248
|
+
static int NotebookConfigure(Tcl_Interp *interp, void *clientData, int mask)
|
|
1249
|
+
{
|
|
1250
|
+
Notebook *nb = clientData;
|
|
1251
|
+
|
|
1252
|
+
/*
|
|
1253
|
+
* Error-checks:
|
|
1254
|
+
*/
|
|
1255
|
+
if (nb->notebook.paddingObj) {
|
|
1256
|
+
/* Check for valid -padding: */
|
|
1257
|
+
Ttk_Padding unused;
|
|
1258
|
+
if (Ttk_GetPaddingFromObj(
|
|
1259
|
+
interp, nb->core.tkwin, nb->notebook.paddingObj, &unused)
|
|
1260
|
+
!= TCL_OK) {
|
|
1261
|
+
return TCL_ERROR;
|
|
1262
|
+
}
|
|
1263
|
+
}
|
|
1264
|
+
|
|
1265
|
+
return TtkCoreConfigure(interp, clientData, mask);
|
|
1266
|
+
}
|
|
1267
|
+
|
|
1268
|
+
/* NotebookGetLayout --
|
|
1269
|
+
* GetLayout widget hook.
|
|
1270
|
+
*/
|
|
1271
|
+
static Ttk_Layout NotebookGetLayout(
|
|
1272
|
+
Tcl_Interp *interp, Ttk_Theme theme, void *recordPtr)
|
|
1273
|
+
{
|
|
1274
|
+
Notebook *nb = recordPtr;
|
|
1275
|
+
Ttk_Layout notebookLayout = TtkWidgetGetLayout(interp, theme, recordPtr);
|
|
1276
|
+
Ttk_Layout tabLayout;
|
|
1277
|
+
|
|
1278
|
+
if (!notebookLayout) {
|
|
1279
|
+
return NULL;
|
|
1280
|
+
}
|
|
1281
|
+
|
|
1282
|
+
tabLayout = Ttk_CreateSublayout(
|
|
1283
|
+
interp, theme, notebookLayout, ".Tab", nb->notebook.tabOptionTable);
|
|
1284
|
+
|
|
1285
|
+
if (tabLayout) {
|
|
1286
|
+
if (nb->notebook.tabLayout) {
|
|
1287
|
+
Ttk_FreeLayout(nb->notebook.tabLayout);
|
|
1288
|
+
}
|
|
1289
|
+
nb->notebook.tabLayout = tabLayout;
|
|
1290
|
+
}
|
|
1291
|
+
|
|
1292
|
+
return notebookLayout;
|
|
1293
|
+
}
|
|
1294
|
+
|
|
1295
|
+
/*------------------------------------------------------------------------
|
|
1296
|
+
* +++ Display routines.
|
|
1297
|
+
*/
|
|
1298
|
+
|
|
1299
|
+
static void DisplayTab(Notebook *nb, int index, Drawable d)
|
|
1300
|
+
{
|
|
1301
|
+
Ttk_Layout tabLayout = nb->notebook.tabLayout;
|
|
1302
|
+
Tab *tab = Ttk_SlaveData(nb->notebook.mgr, index);
|
|
1303
|
+
Ttk_State state = TabState(nb, index);
|
|
1304
|
+
|
|
1305
|
+
if (tab->state != TAB_STATE_HIDDEN) {
|
|
1306
|
+
Ttk_RebindSublayout(tabLayout, tab);
|
|
1307
|
+
Ttk_PlaceLayout(tabLayout, state, tab->parcel);
|
|
1308
|
+
Ttk_DrawLayout(tabLayout, state, d);
|
|
1309
|
+
}
|
|
1310
|
+
}
|
|
1311
|
+
|
|
1312
|
+
static void NotebookDisplay(void *clientData, Drawable d)
|
|
1313
|
+
{
|
|
1314
|
+
Notebook *nb = clientData;
|
|
1315
|
+
int nSlaves = Ttk_NumberSlaves(nb->notebook.mgr);
|
|
1316
|
+
int index;
|
|
1317
|
+
|
|
1318
|
+
/* Draw notebook background (base layout):
|
|
1319
|
+
*/
|
|
1320
|
+
Ttk_DrawLayout(nb->core.layout, nb->core.state, d);
|
|
1321
|
+
|
|
1322
|
+
/* Draw tabs from left to right, but draw the current tab last
|
|
1323
|
+
* so it will overwrite its neighbors.
|
|
1324
|
+
*/
|
|
1325
|
+
for (index = 0; index < nSlaves; ++index) {
|
|
1326
|
+
if (index != nb->notebook.currentIndex) {
|
|
1327
|
+
DisplayTab(nb, index, d);
|
|
1328
|
+
}
|
|
1329
|
+
}
|
|
1330
|
+
if (nb->notebook.currentIndex >= 0) {
|
|
1331
|
+
DisplayTab(nb, nb->notebook.currentIndex, d);
|
|
1332
|
+
}
|
|
1333
|
+
}
|
|
1334
|
+
|
|
1335
|
+
/*------------------------------------------------------------------------
|
|
1336
|
+
* +++ Widget specification and layout definitions.
|
|
1337
|
+
*/
|
|
1338
|
+
|
|
1339
|
+
static WidgetSpec NotebookWidgetSpec =
|
|
1340
|
+
{
|
|
1341
|
+
"TNotebook", /* className */
|
|
1342
|
+
sizeof(Notebook), /* recordSize */
|
|
1343
|
+
NotebookOptionSpecs, /* optionSpecs */
|
|
1344
|
+
NotebookCommands, /* subcommands */
|
|
1345
|
+
NotebookInitialize, /* initializeProc */
|
|
1346
|
+
NotebookCleanup, /* cleanupProc */
|
|
1347
|
+
NotebookConfigure, /* configureProc */
|
|
1348
|
+
TtkNullPostConfigure, /* postConfigureProc */
|
|
1349
|
+
NotebookGetLayout, /* getLayoutProc */
|
|
1350
|
+
NotebookSize, /* geometryProc */
|
|
1351
|
+
NotebookDoLayout, /* layoutProc */
|
|
1352
|
+
NotebookDisplay /* displayProc */
|
|
1353
|
+
};
|
|
1354
|
+
|
|
1355
|
+
TTK_BEGIN_LAYOUT(NotebookLayout)
|
|
1356
|
+
TTK_NODE("Notebook.client", TTK_FILL_BOTH)
|
|
1357
|
+
TTK_END_LAYOUT
|
|
1358
|
+
|
|
1359
|
+
TTK_BEGIN_LAYOUT(TabLayout)
|
|
1360
|
+
TTK_GROUP("Notebook.tab", TTK_FILL_BOTH,
|
|
1361
|
+
TTK_GROUP("Notebook.padding", TTK_PACK_TOP|TTK_FILL_BOTH,
|
|
1362
|
+
TTK_GROUP("Notebook.focus", TTK_PACK_TOP|TTK_FILL_BOTH,
|
|
1363
|
+
TTK_NODE("Notebook.label", TTK_PACK_TOP))))
|
|
1364
|
+
TTK_END_LAYOUT
|
|
1365
|
+
|
|
1366
|
+
/*------------------------------------------------------------------------
|
|
1367
|
+
* +++ Initialization.
|
|
1368
|
+
*/
|
|
1369
|
+
|
|
1370
|
+
void TtkNotebook_Init(Tcl_Interp *interp)
|
|
1371
|
+
{
|
|
1372
|
+
Ttk_Theme themePtr = Ttk_GetDefaultTheme(interp);
|
|
1373
|
+
|
|
1374
|
+
Ttk_RegisterLayout(themePtr, "Tab", TabLayout);
|
|
1375
|
+
Ttk_RegisterLayout(themePtr, "TNotebook", NotebookLayout);
|
|
1376
|
+
|
|
1377
|
+
RegisterWidget(interp, "ttk::notebook", &NotebookWidgetSpec);
|
|
1378
|
+
}
|
|
1379
|
+
|
|
1380
|
+
/*EOF*/
|