diff options
Diffstat (limited to 'src/ui/window.c')
-rw-r--r-- | src/ui/window.c | 91 |
1 files changed, 77 insertions, 14 deletions
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 | ||
164 | static int numRoots_Window(const iWindow *d) { | 164 | int 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 | ||
186 | static void windowSizeChanged_Window_(iWindow *d) { | 185 | static 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 | ||
1039 | void resize_Window(iWindow *d, int w, int h) { | 1052 | void 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 | ||
1044 | void setTitle_Window(iWindow *d, const iString *title) { | 1062 | void setTitle_Window(iWindow *d, const iString *title) { |
@@ -1126,6 +1144,51 @@ void setKeyboardHeight_Window(iWindow *d, int height) { | |||
1126 | } | 1144 | } |
1127 | } | 1145 | } |
1128 | 1146 | ||
1147 | void 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 | |||
1129 | void setSnap_Window(iWindow *d, int snapMode) { | 1192 | void 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) { |