summaryrefslogtreecommitdiff
path: root/src/ui
diff options
context:
space:
mode:
authorJaakko Keränen <jaakko.keranen@iki.fi>2021-04-29 16:53:39 +0300
committerJaakko Keränen <jaakko.keranen@iki.fi>2021-04-29 16:53:39 +0300
commit5039199857ed0b1644a319d3cc514d63c3e3db45 (patch)
treee57e58592229e4bfed50ce12aa859ee07ee864c2 /src/ui
parent190684240e303ad708e0522432849332011964f3 (diff)
Working on multiple UI roots
Added a menu for changing the split mode.
Diffstat (limited to 'src/ui')
-rw-r--r--src/ui/documentwidget.c5
-rw-r--r--src/ui/root.c22
-rw-r--r--src/ui/util.c8
-rw-r--r--src/ui/util.h1
-rw-r--r--src/ui/widget.c10
-rw-r--r--src/ui/widget.h2
-rw-r--r--src/ui/window.c91
-rw-r--r--src/ui/window.h15
8 files changed, 138 insertions, 16 deletions
diff --git a/src/ui/documentwidget.c b/src/ui/documentwidget.c
index 21c0aa23..410b793e 100644
--- a/src/ui/documentwidget.c
+++ b/src/ui/documentwidget.c
@@ -3969,6 +3969,11 @@ static iBool render_DocumentWidget_(const iDocumentWidget *d, iDrawContext *ctx,
3969} 3969}
3970 3970
3971static void prerender_DocumentWidget_(iAny *context) { 3971static void prerender_DocumentWidget_(iAny *context) {
3972 if (current_Root() == NULL) {
3973 /* The widget has probably been removed from the widget tree, pending destruction.
3974 Tickers are not cancelled until the widget is actually destroyed. */
3975 return;
3976 }
3972 const iDocumentWidget *d = context; 3977 const iDocumentWidget *d = context;
3973 iDrawContext ctx = { 3978 iDrawContext ctx = {
3974 .widget = d, 3979 .widget = d,
diff --git a/src/ui/root.c b/src/ui/root.c
index 247faf38..2eca982c 100644
--- a/src/ui/root.c
+++ b/src/ui/root.c
@@ -304,6 +304,12 @@ static iBool handleRootCommands_(iWidget *root, const char *cmd) {
304 } 304 }
305 return iTrue; 305 return iTrue;
306 } 306 }
307 else if (equal_Command(cmd, "splitmenu.open")) {
308 iWidget *menu = findWidget_Root("splitmenu");
309 openMenu_Widget(menu, zero_I2());
310 setPos_Widget(menu, sub_I2(divi_I2(size_Root(get_Root()), 2), divi_I2(menu->rect.size, 2)));
311 return iTrue;
312 }
307 else if (equal_Command(cmd, "contextclick")) { 313 else if (equal_Command(cmd, "contextclick")) {
308 iBool showBarMenu = iFalse; 314 iBool showBarMenu = iFalse;
309 if (equal_Rangecc(range_Command(cmd, "id"), "buttons")) { 315 if (equal_Rangecc(range_Command(cmd, "id"), "buttons")) {
@@ -879,7 +885,7 @@ void updateMetrics_Root(iRoot *d) {
879} 885}
880 886
881void createUserInterface_Root(iRoot *d) { 887void createUserInterface_Root(iRoot *d) {
882 iWidget *root = d->widget = new_Widget(); 888 iWidget *root = d->widget = new_Widget();
883 iAssert(root->root == d); 889 iAssert(root->root == d);
884 setId_Widget(root, "root"); 890 setId_Widget(root, "root");
885 /* Children of root cover the entire window. */ 891 /* Children of root cover the entire window. */
@@ -1231,9 +1237,22 @@ void createUserInterface_Root(iRoot *d) {
1231 { clipboard_Icon " ${menu.paste}", 0, 0, "input.paste" }, 1237 { clipboard_Icon " ${menu.paste}", 0, 0, "input.paste" },
1232 }, 1238 },
1233 4); 1239 4);
1240 iWidget *splitMenu = makeMenu_Widget(root, (iMenuItem[]){
1241 { "Single Frame", '1', 0, "ui.frames arg:0" },
1242 { "---", 0, 0, NULL },
1243 { "Horizontal", '2', 0, "ui.frames arg:3 axis:0" },
1244 { "Horizontal 1:2", SDLK_d, 0, "ui.frames arg:1 axis:0" },
1245 { "Horizontal 2:1", SDLK_e, 0, "ui.frames arg:2 axis:0" },
1246 { "---", 0, 0, NULL },
1247 { "Vertical", '3', 0, "ui.frames arg:3 axis:1" },
1248 { "Vertical 1:2", SDLK_f, 0, "ui.frames arg:1 axis:1" },
1249 { "Vertical 2:1", SDLK_r, 0, "ui.frames arg:2 axis:1" },
1250 }, 9);
1251 setFlags_Widget(splitMenu, disabledWhenHidden_WidgetFlag, iTrue); /* enabled when open */
1234 setId_Widget(tabsMenu, "doctabs.menu"); 1252 setId_Widget(tabsMenu, "doctabs.menu");
1235 setId_Widget(barMenu, "barmenu"); 1253 setId_Widget(barMenu, "barmenu");
1236 setId_Widget(clipMenu, "clipmenu"); 1254 setId_Widget(clipMenu, "clipmenu");
1255 setId_Widget(splitMenu, "splitmenu");
1237 } 1256 }
1238 /* Global keyboard shortcuts. */ { 1257 /* Global keyboard shortcuts. */ {
1239 addAction_Widget(root, 'l', KMOD_PRIMARY, "navigate.focus"); 1258 addAction_Widget(root, 'l', KMOD_PRIMARY, "navigate.focus");
@@ -1248,6 +1267,7 @@ void createUserInterface_Root(iRoot *d) {
1248 addAction_Widget(root, '3', rightSidebar_KeyModifier, "sidebar2.mode arg:2 toggle:1"); 1267 addAction_Widget(root, '3', rightSidebar_KeyModifier, "sidebar2.mode arg:2 toggle:1");
1249 addAction_Widget(root, '4', rightSidebar_KeyModifier, "sidebar2.mode arg:3 toggle:1"); 1268 addAction_Widget(root, '4', rightSidebar_KeyModifier, "sidebar2.mode arg:3 toggle:1");
1250 addAction_Widget(root, '5', rightSidebar_KeyModifier, "sidebar2.mode arg:4 toggle:1"); 1269 addAction_Widget(root, '5', rightSidebar_KeyModifier, "sidebar2.mode arg:4 toggle:1");
1270 addAction_Widget(root, SDLK_j, KMOD_PRIMARY, "splitmenu.open");
1251 } 1271 }
1252 updateMetrics_Root(d); 1272 updateMetrics_Root(d);
1253} 1273}
diff --git a/src/ui/util.c b/src/ui/util.c
index a1d76709..fd8740b4 100644
--- a/src/ui/util.c
+++ b/src/ui/util.c
@@ -984,6 +984,14 @@ void prependTabPage_Widget(iWidget *tabs, iWidget *page, const char *label, int
984 addTabPage_Widget_(tabs, front_WidgetAddPos, page, label, key, kmods); 984 addTabPage_Widget_(tabs, front_WidgetAddPos, page, label, key, kmods);
985} 985}
986 986
987void moveTabButtonToEnd_Widget(iWidget *tabButton) {
988 iWidget *buttons = tabButton->parent;
989 iWidget *tabs = buttons->parent;
990 removeChild_Widget(buttons, tabButton);
991 addChild_Widget(buttons, iClob(tabButton));
992 arrange_Widget(tabs);
993}
994
987iWidget *tabPage_Widget(iWidget *tabs, size_t index) { 995iWidget *tabPage_Widget(iWidget *tabs, size_t index) {
988 iWidget *pages = findChild_Widget(tabs, "tabs.pages"); 996 iWidget *pages = findChild_Widget(tabs, "tabs.pages");
989 return child_Widget(pages, index); 997 return child_Widget(pages, index);
diff --git a/src/ui/util.h b/src/ui/util.h
index 8dd16a7f..cbedefaa 100644
--- a/src/ui/util.h
+++ b/src/ui/util.h
@@ -246,6 +246,7 @@ void setTabPageLabel_Widget (iWidget *tabs, const iAnyObject *page,
246iWidget * tabPage_Widget (iWidget *tabs, size_t index); 246iWidget * tabPage_Widget (iWidget *tabs, size_t index);
247iLabelWidget * tabPageButton_Widget (iWidget *tabs, const iAnyObject *page); 247iLabelWidget * tabPageButton_Widget (iWidget *tabs, const iAnyObject *page);
248iBool isTabButton_Widget (const iWidget *); 248iBool isTabButton_Widget (const iWidget *);
249void moveTabButtonToEnd_Widget(iWidget *tabButton);
249size_t tabPageIndex_Widget (const iWidget *tabs, const iAnyObject *page); 250size_t tabPageIndex_Widget (const iWidget *tabs, const iAnyObject *page);
250const iWidget * currentTabPage_Widget (const iWidget *tabs); 251const iWidget * currentTabPage_Widget (const iWidget *tabs);
251size_t tabCount_Widget (const iWidget *tabs); 252size_t tabCount_Widget (const iWidget *tabs);
diff --git a/src/ui/widget.c b/src/ui/widget.c
index 590dbe70..e4d92b35 100644
--- a/src/ui/widget.c
+++ b/src/ui/widget.c
@@ -225,6 +225,13 @@ void setCommandHandler_Widget(iWidget *d, iBool (*handler)(iWidget *, const char
225 d->commandHandler = handler; 225 d->commandHandler = handler;
226} 226}
227 227
228void setRoot_Widget(iWidget *d, iRoot *root) {
229 d->root = root;
230 iForEach(ObjectList, i, d->children) {
231 setRoot_Widget(i.object, root);
232 }
233}
234
228static int numExpandingChildren_Widget_(const iWidget *d) { 235static int numExpandingChildren_Widget_(const iWidget *d) {
229 int count = 0; 236 int count = 0;
230 iConstForEach(ObjectList, i, d->children) { 237 iConstForEach(ObjectList, i, d->children) {
@@ -749,7 +756,8 @@ iLocalDef iBool isMouseEvent_(const SDL_Event *ev) {
749static iBool filterEvent_Widget_(const iWidget *d, const SDL_Event *ev) { 756static iBool filterEvent_Widget_(const iWidget *d, const SDL_Event *ev) {
750 const iBool isKey = isKeyboardEvent_(ev); 757 const iBool isKey = isKeyboardEvent_(ev);
751 const iBool isMouse = isMouseEvent_(ev); 758 const iBool isMouse = isMouseEvent_(ev);
752 if (d->flags & disabled_WidgetFlag) { 759 if ((d->flags & disabled_WidgetFlag) || (d->flags & hidden_WidgetFlag &&
760 d->flags & disabledWhenHidden_WidgetFlag)) {
753 if (isKey || isMouse) return iFalse; 761 if (isKey || isMouse) return iFalse;
754 } 762 }
755 if (d->flags & hidden_WidgetFlag) { 763 if (d->flags & hidden_WidgetFlag) {
diff --git a/src/ui/widget.h b/src/ui/widget.h
index 2ef035b6..c3c9609e 100644
--- a/src/ui/widget.h
+++ b/src/ui/widget.h
@@ -116,6 +116,7 @@ enum iWidgetFlag {
116#define parentCannotResizeHeight_WidgetFlag iBit64(58) 116#define parentCannotResizeHeight_WidgetFlag iBit64(58)
117#define ignoreForParentWidth_WidgetFlag iBit64(59) 117#define ignoreForParentWidth_WidgetFlag iBit64(59)
118#define noFadeBackground_WidgetFlag iBit64(60) 118#define noFadeBackground_WidgetFlag iBit64(60)
119#define disabledWhenHidden_WidgetFlag iBit64(61)
119 120
120enum iWidgetAddPos { 121enum iWidgetAddPos {
121 back_WidgetAddPos, 122 back_WidgetAddPos,
@@ -247,6 +248,7 @@ void showCollapsed_Widget (iWidget *, iBool show); /* takes care of re
247void setBackgroundColor_Widget (iWidget *, int bgColor); 248void setBackgroundColor_Widget (iWidget *, int bgColor);
248void setFrameColor_Widget (iWidget *, int frameColor); 249void setFrameColor_Widget (iWidget *, int frameColor);
249void setCommandHandler_Widget (iWidget *, iBool (*handler)(iWidget *, const char *)); 250void setCommandHandler_Widget (iWidget *, iBool (*handler)(iWidget *, const char *));
251void setRoot_Widget (iWidget *, iRoot *root); /* updates the entire tree */
250iAny * addChild_Widget (iWidget *, iAnyObject *child); /* holds a ref */ 252iAny * addChild_Widget (iWidget *, iAnyObject *child); /* holds a ref */
251iAny * addChildPos_Widget (iWidget *, iAnyObject *child, enum iWidgetAddPos addPos); 253iAny * addChildPos_Widget (iWidget *, iAnyObject *child, enum iWidgetAddPos addPos);
252iAny * addChildPosFlags_Widget (iWidget *, iAnyObject *child, enum iWidgetAddPos addPos, int64_t childFlags); 254iAny * addChildPosFlags_Widget (iWidget *, iAnyObject *child, enum iWidgetAddPos addPos, int64_t childFlags);
diff --git a/src/ui/window.c b/src/ui/window.c
index 54f05a20..da1db514 100644
--- a/src/ui/window.c
+++ b/src/ui/window.c
@@ -161,7 +161,7 @@ static void removeMacMenus_(void) {
161} 161}
162#endif 162#endif
163 163
164static int numRoots_Window(const iWindow *d) { 164int numRoots_Window(const iWindow *d) {
165 int num = 0; 165 int num = 0;
166 iForIndices(i, d->roots) { 166 iForIndices(i, d->roots) {
167 if (d->roots[i]) num++; 167 if (d->roots[i]) num++;
@@ -173,27 +173,38 @@ static void setupUserInterface_Window(iWindow *d) {
173#if defined (iPlatformAppleDesktop) 173#if defined (iPlatformAppleDesktop)
174 insertMacMenus_(); 174 insertMacMenus_();
175#endif 175#endif
176 iForIndices(i, d->roots) { 176 /* One root is created by default. */
177 d->roots[i] = new_Root(); 177 d->roots[0] = new_Root();
178 setCurrent_Root(d->roots[i]); 178 setCurrent_Root(d->roots[0]);
179 createUserInterface_Root(d->roots[i]); 179 createUserInterface_Root(d->roots[0]);
180 setCurrent_Root(NULL); 180 setCurrent_Root(NULL);
181 }
182 /* One of the roots always has keyboard input focus. */ 181 /* One of the roots always has keyboard input focus. */
183 d->keyRoot = d->roots[0]; 182 d->keyRoot = d->roots[0];
184} 183}
185 184
186static void windowSizeChanged_Window_(iWindow *d) { 185static void windowSizeChanged_Window_(iWindow *d) {
187 const int numRoots = numRoots_Window(d); 186 const int numRoots = numRoots_Window(d);
188 /* Horizontal split frame. */
189 const iInt2 rootSize = d->size; 187 const iInt2 rootSize = d->size;
188 const int weights[2] = {
189 d->roots[0] ? (d->splitMode & twoToOne_WindowSplit ? 2 : 1) : 0,
190 d->roots[1] ? (d->splitMode & oneToTwo_WindowSplit ? 2 : 1) : 0,
191 };
192 const int totalWeight = weights[0] + weights[1];
193 int w = 0;
190 iForIndices(i, d->roots) { 194 iForIndices(i, d->roots) {
191 iRoot *root = d->roots[i]; 195 iRoot *root = d->roots[i];
192 if (root) { 196 if (root) {
193 iRect *rect = &root->widget->rect; 197 iRect *rect = &root->widget->rect;
194 /* Horizontal split frame. */ 198 /* Horizontal split frame. */
195 rect->pos = init_I2(rootSize.x * i / numRoots, 0); 199 if (d->splitMode & vertical_WindowSplit) {
196 rect->size = init_I2(rootSize.x * (i + 1) / numRoots - rect->pos.x, rootSize.y); 200 rect->pos = init_I2(0, rootSize.y * w / totalWeight);
201 rect->size = init_I2(rootSize.x, rootSize.y * (w + weights[i]) / totalWeight - rect->pos.y);
202 }
203 else {
204 rect->pos = init_I2(rootSize.x * w / totalWeight, 0);
205 rect->size = init_I2(rootSize.x * (w + weights[i]) / totalWeight - rect->pos.x, rootSize.y);
206 }
207 w += weights[i];
197 root->widget->minSize = rect->size; 208 root->widget->minSize = rect->size;
198 updatePadding_Root(root); 209 updatePadding_Root(root);
199 arrange_Widget(root->widget); 210 arrange_Widget(root->widget);
@@ -378,6 +389,7 @@ void init_Window(iWindow *d, iRect rect) {
378 d->win = NULL; 389 d->win = NULL;
379 d->size = zero_I2(); /* will be updated below */ 390 d->size = zero_I2(); /* will be updated below */
380 iZap(d->roots); 391 iZap(d->roots);
392 d->splitMode = d->pendingSplitMode = 0;
381 d->hover = NULL; 393 d->hover = NULL;
382 d->mouseGrab = NULL; 394 d->mouseGrab = NULL;
383 d->focus = NULL; 395 d->focus = NULL;
@@ -1004,7 +1016,8 @@ void draw_Window(iWindow *d) {
1004 &(SDL_Rect){ left_Rect(rect) + gap_UI * 1.25f, mid.y - size / 2, size, size }); 1016 &(SDL_Rect){ left_Rect(rect) + gap_UI * 1.25f, mid.y - size / 2, size, size });
1005 } 1017 }
1006#endif 1018#endif
1007 /* Root separator and keyboard focus indicator. */ { 1019 /* Root separator and keyboard focus indicator. */
1020 if (numRoots_Window(d) > 1){
1008 iPaint p; 1021 iPaint p;
1009 init_Paint(&p); 1022 init_Paint(&p);
1010 const iRect bounds = bounds_Widget(root->widget); 1023 const iRect bounds = bounds_Widget(root->widget);
@@ -1017,7 +1030,7 @@ void draw_Window(iWindow *d) {
1017 if (root == d->keyRoot) { 1030 if (root == d->keyRoot) {
1018 fillRect_Paint(&p, (iRect){ 1031 fillRect_Paint(&p, (iRect){
1019 topLeft_Rect(bounds), 1032 topLeft_Rect(bounds),
1020 init_I2(width_Rect(bounds), gap_UI / 2) 1033 init_I2(width_Rect(bounds), gap_UI / 2)
1021 }, uiBackgroundSelected_ColorId); 1034 }, uiBackgroundSelected_ColorId);
1022 } 1035 }
1023 } 1036 }
@@ -1037,8 +1050,13 @@ void draw_Window(iWindow *d) {
1037} 1050}
1038 1051
1039void resize_Window(iWindow *d, int w, int h) { 1052void resize_Window(iWindow *d, int w, int h) {
1040 SDL_SetWindowSize(d->win, w, h); 1053 if (w > 0 && h > 0) {
1041 updateSize_Window_(d, iFalse); 1054 SDL_SetWindowSize(d->win, w, h);
1055 updateSize_Window_(d, iFalse);
1056 }
1057 else {
1058 updateSize_Window_(d, iTrue); /* notify always */
1059 }
1042} 1060}
1043 1061
1044void setTitle_Window(iWindow *d, const iString *title) { 1062void setTitle_Window(iWindow *d, const iString *title) {
@@ -1126,6 +1144,51 @@ void setKeyboardHeight_Window(iWindow *d, int height) {
1126 } 1144 }
1127} 1145}
1128 1146
1147void setSplitMode_Window(iWindow *d, int splitMode) {
1148 iAssert(current_Root() == NULL);
1149 if (d->splitMode != splitMode) {
1150 int oldCount = numRoots_Window(d);
1151 setFreezeDraw_Window(d, iTrue);
1152 if (oldCount == 2 && splitMode == 0) {
1153 /* Keep references to the tabs of the second root. */
1154 iObjectList *tabs = listDocuments_App(d->roots[1]);
1155 iForEach(ObjectList, i, tabs) {
1156 setRoot_Widget(i.object, d->roots[0]);
1157 }
1158 delete_Root(d->roots[1]);
1159 d->roots[1] = NULL;
1160 d->keyRoot = d->roots[0];
1161 /* Move the deleted root's tabs to the first root. */
1162 setCurrent_Root(d->roots[0]);
1163 iWidget *docTabs = findWidget_Root("doctabs");
1164 iForEach(ObjectList, j, tabs) {
1165 appendTabPage_Widget(docTabs, j.object, "", 0, 0);
1166 }
1167 /* The last child is the [+] button for adding a tab. */
1168 moveTabButtonToEnd_Widget(findChild_Widget(docTabs, "newtab"));
1169 iRelease(tabs);
1170 }
1171 else if ((splitMode & mask_WindowSplit) && oldCount == 1) {
1172 /* Add a second root. */
1173 iAssert(d->roots[1] == NULL);
1174 d->roots[1] = new_Root();
1175 setCurrent_Root(d->roots[1]);
1176 createUserInterface_Root(d->roots[1]);
1177 /* If the old root has multiple tabs, move the current one to the new split. */
1178
1179 postCommand_Root(d->roots[1], "navigate.home");
1180 setCurrent_Root(NULL);
1181 }
1182 d->splitMode = splitMode;
1183// windowSizeChanged_Window_(d);
1184 updateSize_Window_(d, iTrue);
1185// postCommand_App("window.resized");
1186 // postCommand_App("metrics.resized");
1187// postCommand_App("window.updatelayout");
1188 postCommand_App("window.unfreeze");
1189 }
1190}
1191
1129void setSnap_Window(iWindow *d, int snapMode) { 1192void setSnap_Window(iWindow *d, int snapMode) {
1130 if (!prefs_App()->customFrame) { 1193 if (!prefs_App()->customFrame) {
1131 if (snapMode == maximized_WindowSnap) { 1194 if (snapMode == maximized_WindowSnap) {
diff --git a/src/ui/window.h b/src/ui/window.h
index b2b22e90..ad577ce4 100644
--- a/src/ui/window.h
+++ b/src/ui/window.h
@@ -56,6 +56,17 @@ struct Impl_WindowPlacement {
56 int lastHit; 56 int lastHit;
57}; 57};
58 58
59enum iWindowSplit {
60 vertical_WindowSplit = iBit(1),
61 oneToTwo_WindowSplit = iBit(2),
62 twoToOne_WindowSplit = iBit(3),
63 equal_WindowSplit = oneToTwo_WindowSplit | twoToOne_WindowSplit,
64 /* meta */
65 mode_WindowSplit = vertical_WindowSplit | equal_WindowSplit,
66 mask_WindowSplit = equal_WindowSplit,
67 merge_WindowSplit = iBit(10),
68};
69
59struct Impl_Window { 70struct Impl_Window {
60 SDL_Window * win; 71 SDL_Window * win;
61 iWindowPlacement place; 72 iWindowPlacement place;
@@ -67,6 +78,8 @@ struct Impl_Window {
67 uint32_t focusGainedAt; 78 uint32_t focusGainedAt;
68 SDL_Renderer *render; 79 SDL_Renderer *render;
69 iInt2 size; 80 iInt2 size;
81 int splitMode;
82 int pendingSplitMode;
70 iRoot * roots[2]; /* root widget and UI state; second one is for split mode */ 83 iRoot * roots[2]; /* root widget and UI state; second one is for split mode */
71 iRoot * keyRoot; /* root that has the current keyboard input focus */ 84 iRoot * keyRoot; /* root that has the current keyboard input focus */
72 iWidget * hover; 85 iWidget * hover;
@@ -98,6 +111,7 @@ iBool setKeyRoot_Window (iWindow *, iRoot *root);
98void setCursor_Window (iWindow *, int cursor); 111void setCursor_Window (iWindow *, int cursor);
99void setSnap_Window (iWindow *, int snapMode); 112void setSnap_Window (iWindow *, int snapMode);
100void setKeyboardHeight_Window(iWindow *, int height); 113void setKeyboardHeight_Window(iWindow *, int height);
114void setSplitMode_Window (iWindow *, int splitMode);
101void showToolbars_Window (iWindow *, iBool show); 115void showToolbars_Window (iWindow *, iBool show);
102iBool postContextClick_Window (iWindow *, const SDL_MouseButtonEvent *); 116iBool postContextClick_Window (iWindow *, const SDL_MouseButtonEvent *);
103 117
@@ -112,6 +126,7 @@ uint32_t frameTime_Window (const iWindow *);
112SDL_Renderer *renderer_Window (const iWindow *); 126SDL_Renderer *renderer_Window (const iWindow *);
113int snap_Window (const iWindow *); 127int snap_Window (const iWindow *);
114iBool isFullscreen_Window (const iWindow *); 128iBool isFullscreen_Window (const iWindow *);
129int numRoots_Window (const iWindow *);
115iRoot * findRoot_Window (const iWindow *, const iWidget *widget); 130iRoot * findRoot_Window (const iWindow *, const iWidget *widget);
116iRoot * otherRoot_Window (const iWindow *, iRoot *root); 131iRoot * otherRoot_Window (const iWindow *, iRoot *root);
117 132