summaryrefslogtreecommitdiff
path: root/src/app.c
diff options
context:
space:
mode:
authorJaakko Keränen <jaakko.keranen@iki.fi>2021-05-04 10:08:18 +0300
committerJaakko Keränen <jaakko.keranen@iki.fi>2021-05-04 10:08:18 +0300
commitc8facdf2c0f00f7e1fe8b04ba1cf3fa4ac230b8b (patch)
tree6c59e1e5bf2a325290e4327be1d82afd87e6cf9a /src/app.c
parent32c9c9eda7750422049fa62b35b39838ee4dd679 (diff)
App: Serialize sidebar state in state.lgr
The sidebars of each root are now serialized with the rest of the UI state so they have all the widget roots available.
Diffstat (limited to 'src/app.c')
-rw-r--r--src/app.c62
1 files changed, 45 insertions, 17 deletions
diff --git a/src/app.c b/src/app.c
index 9762961a..f909c251 100644
--- a/src/app.c
+++ b/src/app.c
@@ -169,9 +169,6 @@ const iString *dateStr_(const iDate *date) {
169 169
170static iString *serializePrefs_App_(const iApp *d) { 170static iString *serializePrefs_App_(const iApp *d) {
171 iString *str = new_String(); 171 iString *str = new_String();
172 setCurrent_Root(d->window->roots[0]); /* TODO: How about the other? */
173 const iSidebarWidget *sidebar = findWidget_App("sidebar");
174 const iSidebarWidget *sidebar2 = findWidget_App("sidebar2");
175#if defined (LAGRANGE_ENABLE_CUSTOM_FRAME) 172#if defined (LAGRANGE_ENABLE_CUSTOM_FRAME)
176 appendFormat_String(str, "customframe arg:%d\n", d->prefs.customFrame); 173 appendFormat_String(str, "customframe arg:%d\n", d->prefs.customFrame);
177#endif 174#endif
@@ -183,8 +180,6 @@ static iString *serializePrefs_App_(const iApp *d) {
183 w = d->window->place.normalRect.size.x; 180 w = d->window->place.normalRect.size.x;
184 h = d->window->place.normalRect.size.y; 181 h = d->window->place.normalRect.size.y;
185 appendFormat_String(str, "window.setrect width:%d height:%d coord:%d %d\n", w, h, x, y); 182 appendFormat_String(str, "window.setrect width:%d height:%d coord:%d %d\n", w, h, x, y);
186 appendFormat_String(str, "sidebar.width arg:%f gaps:1\n", width_SidebarWidget(sidebar));
187 appendFormat_String(str, "sidebar2.width arg:%f gaps:1\n", width_SidebarWidget(sidebar2));
188 /* On macOS, maximization should be applied at creation time or the window will take 183 /* On macOS, maximization should be applied at creation time or the window will take
189 a moment to animate to its maximized size. */ 184 a moment to animate to its maximized size. */
190#if defined (LAGRANGE_ENABLE_CUSTOM_FRAME) 185#if defined (LAGRANGE_ENABLE_CUSTOM_FRAME)
@@ -205,16 +200,6 @@ static iString *serializePrefs_App_(const iApp *d) {
205 } 200 }
206#endif 201#endif
207 } 202 }
208 /* Sidebars. */ {
209 if (isVisible_Widget(sidebar) && deviceType_App() != phone_AppDeviceType) {
210 appendCStr_String(str, "sidebar.toggle\n");
211 }
212 appendFormat_String(str, "sidebar.mode arg:%d\n", mode_SidebarWidget(sidebar));
213 if (isVisible_Widget(sidebar2) && deviceType_App() != phone_AppDeviceType) {
214 appendCStr_String(str, "sidebar2.toggle\n");
215 }
216 appendFormat_String(str, "sidebar2.mode arg:%d\n", mode_SidebarWidget(sidebar2));
217 }
218 appendFormat_String(str, "uilang id:%s\n", cstr_String(&d->prefs.uiLanguage)); 203 appendFormat_String(str, "uilang id:%s\n", cstr_String(&d->prefs.uiLanguage));
219 appendFormat_String(str, "uiscale arg:%f\n", uiScale_Window(d->window)); 204 appendFormat_String(str, "uiscale arg:%f\n", uiScale_Window(d->window));
220 appendFormat_String(str, "prefs.dialogtab arg:%d\n", d->prefs.dialogTab); 205 appendFormat_String(str, "prefs.dialogtab arg:%d\n", d->prefs.dialogTab);
@@ -378,6 +363,7 @@ static void savePrefs_App_(const iApp *d) {
378static const char *magicState_App_ = "lgL1"; 363static const char *magicState_App_ = "lgL1";
379static const char *magicWindow_App_ = "wind"; 364static const char *magicWindow_App_ = "wind";
380static const char *magicTabDocument_App_ = "tabd"; 365static const char *magicTabDocument_App_ = "tabd";
366static const char *magicSidebar_App_ = "side";
381 367
382enum iDocumentStateFlag { 368enum iDocumentStateFlag {
383 current_DocumentStateFlag = iBit(1), 369 current_DocumentStateFlag = iBit(1),
@@ -415,9 +401,29 @@ static iBool loadState_App_(iApp *d) {
415 d->window->pendingSplitMode = splitMode; 401 d->window->pendingSplitMode = splitMode;
416 setSplitMode_Window(d->window, splitMode | noEvents_WindowSplit); 402 setSplitMode_Window(d->window, splitMode | noEvents_WindowSplit);
417 d->window->keyRoot = d->window->roots[keyRoot]; 403 d->window->keyRoot = d->window->roots[keyRoot];
418 continue;
419 } 404 }
420 if (!memcmp(magic, magicTabDocument_App_, 4)) { 405 else if (!memcmp(magic, magicSidebar_App_, 4)) {
406 const uint16_t bits = readU16_File(f);
407 const uint8_t modes = readU8_File(f);
408 const float widths[2] = {
409 readf_Stream(stream_File(f)),
410 readf_Stream(stream_File(f))
411 };
412 const uint8_t rootIndex = bits & 0xff;
413 const uint8_t flags = bits >> 8;
414 iRoot *root = d->window->roots[rootIndex];
415 if (root && deviceType_App() != phone_AppDeviceType) {
416 iSidebarWidget *sidebar = findChild_Widget(root->widget, "sidebar");
417 iSidebarWidget *sidebar2 = findChild_Widget(root->widget, "sidebar2");
418 setWidth_SidebarWidget(sidebar, widths[0]);
419 setWidth_SidebarWidget(sidebar2, widths[1]);
420 postCommandf_Root(root, "sidebar.mode arg:%u", modes & 0xf);
421 postCommandf_Root(root, "sidebar2.mode arg:%u", modes >> 4);
422 if (flags & 1) postCommand_Root(root, "sidebar.toggle");
423 if (flags & 2) postCommand_Root(root, "sidebar2.toggle");
424 }
425 }
426 else if (!memcmp(magic, magicTabDocument_App_, 4)) {
421 const int8_t flags = read8_File(f); 427 const int8_t flags = read8_File(f);
422 int rootIndex = flags & rootIndex1_DocumentStateFlag ? 1 : 0; 428 int rootIndex = flags & rootIndex1_DocumentStateFlag ? 1 : 0;
423 if (rootIndex > numRoots_Window(d->window) - 1) { 429 if (rootIndex > numRoots_Window(d->window) - 1) {
@@ -461,6 +467,10 @@ static void saveState_App_(const iApp *d) {
461 iUnused(d); 467 iUnused(d);
462 trimCache_App(); 468 trimCache_App();
463 iWindow *win = d->window; 469 iWindow *win = d->window;
470 /* UI state is saved in binary because it is quite complex (e.g.,
471 navigation history, cached content) and depends closely on the widget
472 tree. The data is largely not reorderable and should not be modified
473 by the user manually. */
464 iFile *f = newCStr_File(concatPath_CStr(dataDir_App_(), stateFileName_App_)); 474 iFile *f = newCStr_File(concatPath_CStr(dataDir_App_(), stateFileName_App_));
465 if (open_File(f, writeOnly_FileMode)) { 475 if (open_File(f, writeOnly_FileMode)) {
466 writeData_File(f, magicState_App_, 4); 476 writeData_File(f, magicState_App_, 4);
@@ -470,6 +480,24 @@ static void saveState_App_(const iApp *d) {
470 writeU32_File(f, win->splitMode); 480 writeU32_File(f, win->splitMode);
471 writeU32_File(f, win->keyRoot == win->roots[0] ? 0 : 1); 481 writeU32_File(f, win->keyRoot == win->roots[0] ? 0 : 1);
472 } 482 }
483 /* State of UI elements. */ {
484 iForIndices(i, win->roots) {
485 const iRoot *root = win->roots[i];
486 if (root) {
487 writeData_File(f, magicSidebar_App_, 4);
488 const iSidebarWidget *sidebar = findChild_Widget(root->widget, "sidebar");
489 const iSidebarWidget *sidebar2 = findChild_Widget(root->widget, "sidebar2");
490 writeU16_File(f, i |
491 (isVisible_Widget(sidebar) ? 0x100 : 0) |
492 (isVisible_Widget(sidebar2) ? 0x200 : 0));
493 writeU8_File(f,
494 mode_SidebarWidget(sidebar) |
495 (mode_SidebarWidget(sidebar2) << 4));
496 writef_Stream(stream_File(f), width_SidebarWidget(sidebar));
497 writef_Stream(stream_File(f), width_SidebarWidget(sidebar2));
498 }
499 }
500 }
473 iConstForEach(ObjectList, i, iClob(listDocuments_App(NULL))) { 501 iConstForEach(ObjectList, i, iClob(listDocuments_App(NULL))) {
474 iAssert(isInstance_Object(i.object, &Class_DocumentWidget)); 502 iAssert(isInstance_Object(i.object, &Class_DocumentWidget));
475 const iWidget *widget = constAs_Widget(i.object); 503 const iWidget *widget = constAs_Widget(i.object);