diff options
author | Jaakko Keränen <jaakko.keranen@iki.fi> | 2021-05-04 10:08:18 +0300 |
---|---|---|
committer | Jaakko Keränen <jaakko.keranen@iki.fi> | 2021-05-04 10:08:18 +0300 |
commit | c8facdf2c0f00f7e1fe8b04ba1cf3fa4ac230b8b (patch) | |
tree | 6c59e1e5bf2a325290e4327be1d82afd87e6cf9a /src/app.c | |
parent | 32c9c9eda7750422049fa62b35b39838ee4dd679 (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.c | 62 |
1 files changed, 45 insertions, 17 deletions
@@ -169,9 +169,6 @@ const iString *dateStr_(const iDate *date) { | |||
169 | 169 | ||
170 | static iString *serializePrefs_App_(const iApp *d) { | 170 | static 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) { | |||
378 | static const char *magicState_App_ = "lgL1"; | 363 | static const char *magicState_App_ = "lgL1"; |
379 | static const char *magicWindow_App_ = "wind"; | 364 | static const char *magicWindow_App_ = "wind"; |
380 | static const char *magicTabDocument_App_ = "tabd"; | 365 | static const char *magicTabDocument_App_ = "tabd"; |
366 | static const char *magicSidebar_App_ = "side"; | ||
381 | 367 | ||
382 | enum iDocumentStateFlag { | 368 | enum 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); |