diff options
-rw-r--r-- | src/app.c | 21 | ||||
-rw-r--r-- | src/ui/root.c | 3 | ||||
-rw-r--r-- | src/ui/window.c | 59 | ||||
-rw-r--r-- | src/ui/window.h | 6 |
4 files changed, 63 insertions, 26 deletions
@@ -1177,9 +1177,7 @@ static int run_App_(iApp *d) { | |||
1177 | runTickers_App_(d); | 1177 | runTickers_App_(d); |
1178 | refresh_App(); | 1178 | refresh_App(); |
1179 | /* Change the widget tree while we are not iterating through it. */ | 1179 | /* Change the widget tree while we are not iterating through it. */ |
1180 | if (d->window->splitMode != d->window->pendingSplitMode) { | 1180 | checkPendingSplit_Window(d->window); |
1181 | setSplitMode_Window(d->window, d->window->pendingSplitMode); | ||
1182 | } | ||
1183 | recycle_Garbage(); | 1181 | recycle_Garbage(); |
1184 | } | 1182 | } |
1185 | SDL_DelEventWatch(resizeWatcher_, d); | 1183 | SDL_DelEventWatch(resizeWatcher_, d); |
@@ -1691,14 +1689,16 @@ iBool handleCommand_App(const char *cmd) { | |||
1691 | return iTrue; | 1689 | return iTrue; |
1692 | } | 1690 | } |
1693 | else if (equal_Command(cmd, "ui.split")) { | 1691 | else if (equal_Command(cmd, "ui.split")) { |
1692 | if (argLabel_Command(cmd, "swap")) { | ||
1693 | swapRoots_Window(d->window); | ||
1694 | return iTrue; | ||
1695 | } | ||
1694 | d->window->pendingSplitMode = | 1696 | d->window->pendingSplitMode = |
1695 | (argLabel_Command(cmd, "axis") ? vertical_WindowSplit : 0) | (arg_Command(cmd) << 1); | 1697 | (argLabel_Command(cmd, "axis") ? vertical_WindowSplit : 0) | (arg_Command(cmd) << 1); |
1698 | const char *url = suffixPtr_Command(cmd, "url"); | ||
1699 | setCStr_String(get_Window()->pendingSplitUrl, url ? url : ""); | ||
1696 | return iTrue; | 1700 | return iTrue; |
1697 | } | 1701 | } |
1698 | // else if (equal_Command(cmd, "window.updatelayout")) { | ||
1699 | // resize_Window(d->window, -1, -1); | ||
1700 | // return iTrue; | ||
1701 | // } | ||
1702 | else if (equal_Command(cmd, "window.retain")) { | 1702 | else if (equal_Command(cmd, "window.retain")) { |
1703 | d->prefs.retainWindowSize = arg_Command(cmd); | 1703 | d->prefs.retainWindowSize = arg_Command(cmd); |
1704 | return iTrue; | 1704 | return iTrue; |
@@ -1993,6 +1993,13 @@ iBool handleCommand_App(const char *cmd) { | |||
1993 | return iTrue; | 1993 | return iTrue; |
1994 | } | 1994 | } |
1995 | const int newTab = argLabel_Command(cmd, "newtab"); | 1995 | const int newTab = argLabel_Command(cmd, "newtab"); |
1996 | if (newTab & otherRoot_OpenTabFlag && numRoots_Window(get_Window()) == 1) { | ||
1997 | /* Need to split first. */ | ||
1998 | postCommandf_App("ui.split arg:3 newtab:%d url:%s", | ||
1999 | newTab & ~otherRoot_OpenTabFlag, | ||
2000 | cstr_String(url)); | ||
2001 | return iTrue; | ||
2002 | } | ||
1996 | iRoot *root = get_Root(); | 2003 | iRoot *root = get_Root(); |
1997 | iRoot *oldRoot = root; | 2004 | iRoot *oldRoot = root; |
1998 | if (newTab & otherRoot_OpenTabFlag) { | 2005 | if (newTab & otherRoot_OpenTabFlag) { |
diff --git a/src/ui/root.c b/src/ui/root.c index cd6959c4..bec42719 100644 --- a/src/ui/root.c +++ b/src/ui/root.c | |||
@@ -1252,7 +1252,8 @@ void createUserInterface_Root(iRoot *d) { | |||
1252 | }, | 1252 | }, |
1253 | 4); | 1253 | 4); |
1254 | iWidget *splitMenu = makeMenu_Widget(root, (iMenuItem[]){ | 1254 | iWidget *splitMenu = makeMenu_Widget(root, (iMenuItem[]){ |
1255 | { "Single Frame", '1', 0, "ui.split arg:0" }, | 1255 | { "Merge Tabs", '1', 0, "ui.split arg:0" }, |
1256 | { "Swap Sides", SDLK_x, 0, "ui.split swap:1" }, | ||
1256 | { "---", 0, 0, NULL }, | 1257 | { "---", 0, 0, NULL }, |
1257 | { "Horizontal", '2', 0, "ui.split arg:3 axis:0" }, | 1258 | { "Horizontal", '2', 0, "ui.split arg:3 axis:0" }, |
1258 | { "Horizontal 1:2", SDLK_d, 0, "ui.split arg:1 axis:0" }, | 1259 | { "Horizontal 1:2", SDLK_d, 0, "ui.split arg:1 axis:0" }, |
diff --git a/src/ui/window.c b/src/ui/window.c index b3840602..e78bb81e 100644 --- a/src/ui/window.c +++ b/src/ui/window.c | |||
@@ -403,6 +403,7 @@ void init_Window(iWindow *d, iRect rect) { | |||
403 | d->size = zero_I2(); /* will be updated below */ | 403 | d->size = zero_I2(); /* will be updated below */ |
404 | iZap(d->roots); | 404 | iZap(d->roots); |
405 | d->splitMode = d->pendingSplitMode = 0; | 405 | d->splitMode = d->pendingSplitMode = 0; |
406 | d->pendingSplitUrl = new_String(); | ||
406 | d->hover = NULL; | 407 | d->hover = NULL; |
407 | d->mouseGrab = NULL; | 408 | d->mouseGrab = NULL; |
408 | d->focus = NULL; | 409 | d->focus = NULL; |
@@ -414,6 +415,7 @@ void init_Window(iWindow *d, iRect rect) { | |||
414 | d->isDrawFrozen = iTrue; | 415 | d->isDrawFrozen = iTrue; |
415 | d->isExposed = iFalse; | 416 | d->isExposed = iFalse; |
416 | d->isMinimized = iFalse; | 417 | d->isMinimized = iFalse; |
418 | d->isInvalidated = iFalse; /* set when posting event, to avoid repeated events */ | ||
417 | d->isMouseInside = iTrue; | 419 | d->isMouseInside = iTrue; |
418 | d->ignoreClick = iFalse; | 420 | d->ignoreClick = iFalse; |
419 | d->focusGainedAt = 0; | 421 | d->focusGainedAt = 0; |
@@ -521,6 +523,7 @@ void deinit_Window(iWindow *d) { | |||
521 | } | 523 | } |
522 | } | 524 | } |
523 | setCurrent_Root(NULL); | 525 | setCurrent_Root(NULL); |
526 | delete_String(d->pendingSplitUrl); | ||
524 | deinit_Text(); | 527 | deinit_Text(); |
525 | SDL_DestroyRenderer(d->render); | 528 | SDL_DestroyRenderer(d->render); |
526 | SDL_DestroyWindow(d->win); | 529 | SDL_DestroyWindow(d->win); |
@@ -561,10 +564,12 @@ iRoot *otherRoot_Window(const iWindow *d, iRoot *root) { | |||
561 | return root == d->roots[0] && d->roots[1] ? d->roots[1] : d->roots[0]; | 564 | return root == d->roots[0] && d->roots[1] ? d->roots[1] : d->roots[0]; |
562 | } | 565 | } |
563 | 566 | ||
564 | static void invalidate_Window_(iWindow *d) { | 567 | void invalidate_Window(iWindow *d) { |
565 | iUnused(d); | 568 | if (d && !d->isInvalidated) { |
566 | resetFonts_Text(); | 569 | d->isInvalidated = iTrue; |
567 | postCommand_App("theme.changed auto:1"); /* forces UI invalidation */ | 570 | resetFonts_Text(); |
571 | postCommand_App("theme.changed auto:1"); /* forces UI invalidation */ | ||
572 | } | ||
568 | } | 573 | } |
569 | 574 | ||
570 | static iBool isNormalPlacement_Window_(const iWindow *d) { | 575 | static iBool isNormalPlacement_Window_(const iWindow *d) { |
@@ -734,7 +739,7 @@ static iBool handleWindowEvent_Window_(iWindow *d, const SDL_WindowEvent *ev) { | |||
734 | return iTrue; | 739 | return iTrue; |
735 | case SDL_WINDOWEVENT_RESTORED: | 740 | case SDL_WINDOWEVENT_RESTORED: |
736 | updateSize_Window_(d, iTrue); | 741 | updateSize_Window_(d, iTrue); |
737 | invalidate_Window_(d); | 742 | invalidate_Window(d); |
738 | d->isMinimized = iFalse; | 743 | d->isMinimized = iFalse; |
739 | postRefresh_App(); | 744 | postRefresh_App(); |
740 | return iTrue; | 745 | return iTrue; |
@@ -809,7 +814,7 @@ iBool processEvent_Window(iWindow *d, const SDL_Event *ev) { | |||
809 | } | 814 | } |
810 | case SDL_RENDER_TARGETS_RESET: | 815 | case SDL_RENDER_TARGETS_RESET: |
811 | case SDL_RENDER_DEVICE_RESET: { | 816 | case SDL_RENDER_DEVICE_RESET: { |
812 | invalidate_Window_(d); | 817 | invalidate_Window(d); |
813 | break; | 818 | break; |
814 | } | 819 | } |
815 | default: { | 820 | default: { |
@@ -892,7 +897,7 @@ iBool processEvent_Window(iWindow *d, const SDL_Event *ev) { | |||
892 | removeMacMenus_(); | 897 | removeMacMenus_(); |
893 | insertMacMenus_(); | 898 | insertMacMenus_(); |
894 | #endif | 899 | #endif |
895 | invalidate_Window_(d); | 900 | invalidate_Window(d); |
896 | iForIndices(i, d->roots) { | 901 | iForIndices(i, d->roots) { |
897 | if (d->roots[i]) { | 902 | if (d->roots[i]) { |
898 | updatePreferencesLayout_Widget(findChild_Widget(d->roots[i]->widget, "prefs")); | 903 | updatePreferencesLayout_Widget(findChild_Widget(d->roots[i]->widget, "prefs")); |
@@ -1008,6 +1013,7 @@ void draw_Window(iWindow *d) { | |||
1008 | /* Draw widgets. */ | 1013 | /* Draw widgets. */ |
1009 | d->frameTime = SDL_GetTicks(); | 1014 | d->frameTime = SDL_GetTicks(); |
1010 | if (isExposed_Window(d)) { | 1015 | if (isExposed_Window(d)) { |
1016 | d->isInvalidated = iFalse; | ||
1011 | iForIndices(i, d->roots) { | 1017 | iForIndices(i, d->roots) { |
1012 | iRoot *root = d->roots[i]; | 1018 | iRoot *root = d->roots[i]; |
1013 | if (root) { | 1019 | if (root) { |
@@ -1159,7 +1165,25 @@ void setKeyboardHeight_Window(iWindow *d, int height) { | |||
1159 | } | 1165 | } |
1160 | } | 1166 | } |
1161 | 1167 | ||
1162 | void setSplitMode_Window(iWindow *d, int splitMode) { | 1168 | void checkPendingSplit_Window(iWindow *d) { |
1169 | if (d->splitMode != d->pendingSplitMode) { | ||
1170 | setSplitMode_Window(d, d->pendingSplitMode); | ||
1171 | if (!isEmpty_String(d->pendingSplitUrl)) { | ||
1172 | postCommandf_Root(d->keyRoot, "open url:%s", cstr_String(d->pendingSplitUrl)); | ||
1173 | clear_String(d->pendingSplitUrl); | ||
1174 | } | ||
1175 | } | ||
1176 | } | ||
1177 | |||
1178 | void swapRoots_Window(iWindow *d) { | ||
1179 | if (numRoots_Window(d) == 2) { | ||
1180 | iSwap(iRoot *, d->roots[0], d->roots[1]); | ||
1181 | updateSize_Window_(d, iTrue); | ||
1182 | } | ||
1183 | } | ||
1184 | |||
1185 | void setSplitMode_Window(iWindow *d, int splitFlags) { | ||
1186 | const int splitMode = splitFlags & mode_WindowSplit; | ||
1163 | iAssert(current_Root() == NULL); | 1187 | iAssert(current_Root() == NULL); |
1164 | if (d->splitMode != splitMode) { | 1188 | if (d->splitMode != splitMode) { |
1165 | int oldCount = numRoots_Window(d); | 1189 | int oldCount = numRoots_Window(d); |
@@ -1183,7 +1207,7 @@ void setSplitMode_Window(iWindow *d, int splitMode) { | |||
1183 | moveTabButtonToEnd_Widget(findChild_Widget(docTabs, "newtab")); | 1207 | moveTabButtonToEnd_Widget(findChild_Widget(docTabs, "newtab")); |
1184 | iRelease(tabs); | 1208 | iRelease(tabs); |
1185 | } | 1209 | } |
1186 | else if ((splitMode & mask_WindowSplit) && oldCount == 1) { | 1210 | else if (splitMode && oldCount == 1) { |
1187 | /* Add a second root. */ | 1211 | /* Add a second root. */ |
1188 | iDocumentWidget *moved = document_Root(d->roots[0]); | 1212 | iDocumentWidget *moved = document_Root(d->roots[0]); |
1189 | iAssert(d->roots[1] == NULL); | 1213 | iAssert(d->roots[1] == NULL); |
@@ -1201,10 +1225,11 @@ void setSplitMode_Window(iWindow *d, int splitMode) { | |||
1201 | iRelease(removeTabPage_Widget(docTabs1, 0)); /* delete the default tab */ | 1225 | iRelease(removeTabPage_Widget(docTabs1, 0)); /* delete the default tab */ |
1202 | setRoot_Widget(as_Widget(moved), d->roots[1]); | 1226 | setRoot_Widget(as_Widget(moved), d->roots[1]); |
1203 | prependTabPage_Widget(docTabs1, iClob(moved), "", 0, 0); | 1227 | prependTabPage_Widget(docTabs1, iClob(moved), "", 0, 0); |
1204 | //showTabPage_Widget(docTabs1, as_Widget(moved)); | 1228 | if (~splitFlags & noEvents_WindowSplit) { |
1205 | postCommandf_App("tabs.switch page:%p", moved); | 1229 | postCommandf_App("tabs.switch page:%p", moved); |
1230 | } | ||
1206 | } | 1231 | } |
1207 | else { | 1232 | else if (~splitFlags & noEvents_WindowSplit) { |
1208 | postCommand_Root(d->roots[1], "navigate.home"); | 1233 | postCommand_Root(d->roots[1], "navigate.home"); |
1209 | } | 1234 | } |
1210 | } | 1235 | } |
@@ -1232,12 +1257,10 @@ void setSplitMode_Window(iWindow *d, int splitMode) { | |||
1232 | } | 1257 | } |
1233 | } | 1258 | } |
1234 | #endif | 1259 | #endif |
1235 | // windowSizeChanged_Window_(d); | 1260 | if (~splitFlags & noEvents_WindowSplit) { |
1236 | updateSize_Window_(d, iTrue); | 1261 | updateSize_Window_(d, iTrue); |
1237 | // postCommand_App("window.resized"); | 1262 | postCommand_App("window.unfreeze"); |
1238 | // postCommand_App("metrics.resized"); | 1263 | } |
1239 | // postCommand_App("window.updatelayout"); | ||
1240 | postCommand_App("window.unfreeze"); | ||
1241 | } | 1264 | } |
1242 | } | 1265 | } |
1243 | 1266 | ||
diff --git a/src/ui/window.h b/src/ui/window.h index ad577ce4..677001e5 100644 --- a/src/ui/window.h +++ b/src/ui/window.h | |||
@@ -65,6 +65,7 @@ enum iWindowSplit { | |||
65 | mode_WindowSplit = vertical_WindowSplit | equal_WindowSplit, | 65 | mode_WindowSplit = vertical_WindowSplit | equal_WindowSplit, |
66 | mask_WindowSplit = equal_WindowSplit, | 66 | mask_WindowSplit = equal_WindowSplit, |
67 | merge_WindowSplit = iBit(10), | 67 | merge_WindowSplit = iBit(10), |
68 | noEvents_WindowSplit = iBit(11), | ||
68 | }; | 69 | }; |
69 | 70 | ||
70 | struct Impl_Window { | 71 | struct Impl_Window { |
@@ -74,12 +75,14 @@ struct Impl_Window { | |||
74 | iBool isExposed; | 75 | iBool isExposed; |
75 | iBool isMinimized; | 76 | iBool isMinimized; |
76 | iBool isMouseInside; | 77 | iBool isMouseInside; |
78 | iBool isInvalidated; | ||
77 | iBool ignoreClick; | 79 | iBool ignoreClick; |
78 | uint32_t focusGainedAt; | 80 | uint32_t focusGainedAt; |
79 | SDL_Renderer *render; | 81 | SDL_Renderer *render; |
80 | iInt2 size; | 82 | iInt2 size; |
81 | int splitMode; | 83 | int splitMode; |
82 | int pendingSplitMode; | 84 | int pendingSplitMode; |
85 | iString * pendingSplitUrl; /* URL to open in a newly opened split */ | ||
83 | iRoot * roots[2]; /* root widget and UI state; second one is for split mode */ | 86 | iRoot * roots[2]; /* root widget and UI state; second one is for split mode */ |
84 | iRoot * keyRoot; /* root that has the current keyboard input focus */ | 87 | iRoot * keyRoot; /* root that has the current keyboard input focus */ |
85 | iWidget * hover; | 88 | iWidget * hover; |
@@ -101,6 +104,7 @@ struct Impl_Window { | |||
101 | 104 | ||
102 | iBool processEvent_Window (iWindow *, const SDL_Event *); | 105 | iBool processEvent_Window (iWindow *, const SDL_Event *); |
103 | iBool dispatchEvent_Window (iWindow *, const SDL_Event *); | 106 | iBool dispatchEvent_Window (iWindow *, const SDL_Event *); |
107 | void invalidate_Window (iWindow *); /* discard all cached graphics */ | ||
104 | void draw_Window (iWindow *); | 108 | void draw_Window (iWindow *); |
105 | void drawWhileResizing_Window(iWindow *d, int w, int h); /* workaround for SDL bug */ | 109 | void drawWhileResizing_Window(iWindow *d, int w, int h); /* workaround for SDL bug */ |
106 | void resize_Window (iWindow *, int w, int h); | 110 | void resize_Window (iWindow *, int w, int h); |
@@ -114,6 +118,8 @@ void setKeyboardHeight_Window(iWindow *, int height); | |||
114 | void setSplitMode_Window (iWindow *, int splitMode); | 118 | void setSplitMode_Window (iWindow *, int splitMode); |
115 | void showToolbars_Window (iWindow *, iBool show); | 119 | void showToolbars_Window (iWindow *, iBool show); |
116 | iBool postContextClick_Window (iWindow *, const SDL_MouseButtonEvent *); | 120 | iBool postContextClick_Window (iWindow *, const SDL_MouseButtonEvent *); |
121 | void checkPendingSplit_Window(iWindow *); | ||
122 | void swapRoots_Window (iWindow *); | ||
117 | 123 | ||
118 | uint32_t id_Window (const iWindow *); | 124 | uint32_t id_Window (const iWindow *); |
119 | iInt2 size_Window (const iWindow *); | 125 | iInt2 size_Window (const iWindow *); |