diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/app.c | 62 | ||||
-rw-r--r-- | src/defs.h | 3 |
2 files changed, 47 insertions, 18 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); |
@@ -28,8 +28,9 @@ enum iFileVersion { | |||
28 | initial_FileVersion = 0, | 28 | initial_FileVersion = 0, |
29 | addedResponseTimestamps_FileVersion = 1, | 29 | addedResponseTimestamps_FileVersion = 1, |
30 | multipleRoots_FileVersion = 2, | 30 | multipleRoots_FileVersion = 2, |
31 | serializedSidebarState_FileVersion = 3, | ||
31 | /* meta */ | 32 | /* meta */ |
32 | latest_FileVersion = 2 | 33 | latest_FileVersion = 3 |
33 | }; | 34 | }; |
34 | 35 | ||
35 | /* Icons */ | 36 | /* Icons */ |