From 534ca653e54f417f413a65a9eacd71eb12c51326 Mon Sep 17 00:00:00 2001 From: Jaakko Keränen Date: Sat, 25 Jul 2020 08:25:16 +0300 Subject: Basic navigation history; Back and Forward are working --- src/app.c | 106 ++++++++++++++++++++++++++++++++++++++++++++++-- src/gmdocument.c | 34 ++++++++-------- src/ui/documentwidget.c | 2 +- src/ui/scrollwidget.c | 2 +- src/ui/widget.c | 2 + src/ui/window.c | 2 +- 6 files changed, 125 insertions(+), 23 deletions(-) (limited to 'src') diff --git a/src/app.c b/src/app.c index 05038a4b..4c9a3477 100644 --- a/src/app.c +++ b/src/app.c @@ -28,6 +28,21 @@ #endif iDeclareType(App) +iDeclareType(HistoryItem) + +struct Impl_HistoryItem { + iTime when; + iString url; +}; + +void init_HistoryItem(iHistoryItem *d) { + initCurrent_Time(&d->when); + init_String(&d->url); +} + +void deinit_HistoryItem(iHistoryItem *d) { + deinit_String(&d->url); +} #if defined (iPlatformApple) static const char *dataDir_App_ = "~/Library/Application Support/fi.skyjake.Lagrange"; @@ -40,12 +55,16 @@ static const char *dataDir_App_ = "~/.config/lagrange"; #endif static const char *prefsFileName_App_ = "prefs.cfg"; +static const int HISTORY_MAX = 100; + struct Impl_App { iCommandLine args; iBool running; iWindow * window; iSortedArray tickers; iBool pendingRefresh; + iArray history; + size_t historyPos; /* zero at the latest item */ /* Preferences: */ iBool retainWindowSize; float uiScale; @@ -131,9 +150,18 @@ static void savePrefs_App_(const iApp *d) { delete_String(cfg); } +static void clearHistory_App_(iApp *d) { + iForEach(Array, i, &d->history) { + deinit_HistoryItem(i.value); + } + clear_Array(&d->history); +} + static void init_App_(iApp *d, int argc, char **argv) { init_CommandLine(&d->args, argc, argv); init_SortedArray(&d->tickers, sizeof(iTicker), cmp_Ticker_); + init_Array(&d->history, sizeof(iHistoryItem)); + d->historyPos = 0; d->running = iFalse; d->window = NULL; d->retainWindowSize = iTrue; @@ -152,10 +180,12 @@ static void init_App_(iApp *d, int argc, char **argv) { static void deinit_App(iApp *d) { savePrefs_App_(d); + clearHistory_App_(d); + deinit_Array(&d->history); deinit_SortedArray(&d->tickers); delete_Window(d->window); d->window = NULL; - deinit_CommandLine(&d->args); + deinit_CommandLine(&d->args); } const iString *execPath_App(void) { @@ -302,12 +332,62 @@ static iBool handlePrefsCommands_(iWidget *d, const char *cmd) { return iFalse; } +static iHistoryItem *historyItem_App_(iApp *d, size_t pos) { + if (isEmpty_Array(&d->history)) return NULL; + return &value_Array(&d->history, size_Array(&d->history) - 1 - pos, iHistoryItem); +} + +static const iString *historyUrl_App_(iApp *d, size_t pos) { + const iHistoryItem *item = historyItem_App_(d, pos); + if (item) { + return &item->url; + } + return collectNew_String(); +} + +static void printHistory_App_(const iApp *d) { + iConstForEach(Array, i, &d->history) { + const size_t idx = index_ArrayConstIterator(&i); + printf("%s[%zu]: %s\n", + d->historyPos == size_Array(&d->history) - idx - 1 ? "->" : " ", + idx, + cstr_String(&((const iHistoryItem *) i.value)->url)); + } + fflush(stdout); +} + iBool handleCommand_App(const char *cmd) { iApp *d = &app_; iWidget *root = d->window->root; if (equal_Command(cmd, "open")) { - setUrl_DocumentWidget(findChild_Widget(root, "document"), - collect_String(newCStr_String(valuePtr_Command(cmd, "url")))); + const iString *url = collect_String(newCStr_String(valuePtr_Command(cmd, "url"))); + if (!argLabel_Command(cmd, "history")) { + if (argLabel_Command(cmd, "redirect")) { + /* Update in the history. */ + iHistoryItem *item = historyItem_App_(d, d->historyPos); + if (item) { + set_String(&item->url, url); + } + } + else { + /* Cut the trailing history items. */ + if (d->historyPos > 0) { + for (size_t i = 0; i < d->historyPos - 1; i++) { + deinit_HistoryItem(historyItem_App_(d, i)); + } + removeN_Array( + &d->history, size_Array(&d->history) - d->historyPos, iInvalidSize); + d->historyPos = 0; + } + /* Insert new item. */ + iHistoryItem item; + init_HistoryItem(&item); + set_String(&item.url, url); + pushBack_Array(&d->history, &item); + } + } + printHistory_App_(d); + setUrl_DocumentWidget(findChild_Widget(root, "document"), url); } else if (equal_Command(cmd, "quit")) { SDL_Event ev; @@ -328,6 +408,26 @@ iBool handleCommand_App(const char *cmd) { const iInt2 pos = coord_Command(cmd); SDL_SetWindowPosition(d->window->win, pos.x, pos.y); } + else if (equal_Command(cmd, "document.changed")) { + /* TODO: Update current history item with this actual/redirected URL. */ + return iFalse; + } + else if (equal_Command(cmd, "navigate.back")) { + if (d->historyPos < size_Array(&d->history) - 1) { + d->historyPos++; + postCommandf_App("open history:1 url:%s", + cstr_String(historyUrl_App_(d, d->historyPos))); + } + return iTrue; + } + else if (equal_Command(cmd, "navigate.forward")) { + if (d->historyPos > 0) { + d->historyPos--; + postCommandf_App("open history:1 url:%s", + cstr_String(historyUrl_App_(d, d->historyPos))); + } + return iTrue; + } else { return iFalse; } diff --git a/src/gmdocument.c b/src/gmdocument.c index 6fde864a..eb147925 100644 --- a/src/gmdocument.c +++ b/src/gmdocument.c @@ -133,15 +133,6 @@ static void clearLinks_GmDocument_(iGmDocument *d) { } static void doLayout_GmDocument_(iGmDocument *d) { - clear_Array(&d->layout); - clearLinks_GmDocument_(d); - if (d->size.x <= 0 || isEmpty_String(&d->source)) { - return; - } - iBool isPreformat = iFalse; - iInt2 pos = zero_I2(); - const iRangecc content = range_String(&d->source); - iRangecc line = iNullRange; /* TODO: Collect these parameters into a GmTheme. */ static const int fonts[max_GmLineType] = { paragraph_FontId, @@ -152,17 +143,17 @@ static void doLayout_GmDocument_(iGmDocument *d) { header2_FontId, header3_FontId, regular_FontId, - }; + }; static const int colors[max_GmLineType] = { gray75_ColorId, gray75_ColorId, - orange_ColorId, - orange_ColorId, + cyan_ColorId, + gray75_ColorId, white_ColorId, white_ColorId, white_ColorId, white_ColorId, - }; + }; static const int indents[max_GmLineType] = { 4, 10, 4, 10, 0, 0, 0, 0 }; @@ -173,10 +164,19 @@ static void doLayout_GmDocument_(iGmDocument *d) { 0.0f, 0.5f, 1.0f, 0.5f, 1.0f, 1.0f, 1.0f, 1.0f }; static const char *bullet = "\u2022"; - iRangecc preAltText = iNullRange; - enum iGmLineType prevType = text_GmLineType; - iBool isFirstText = iTrue; - int preFont = preformatted_FontId; + clear_Array(&d->layout); + clearLinks_GmDocument_(d); + if (d->size.x <= 0 || isEmpty_String(&d->source)) { + return; + } + const iRangecc content = range_String(&d->source); + iInt2 pos = zero_I2(); + iRangecc line = iNullRange; + iRangecc preAltText = iNullRange; + enum iGmLineType prevType = text_GmLineType; + iBool isPreformat = iFalse; + iBool isFirstText = iTrue; + int preFont = preformatted_FontId; while (nextSplit_Rangecc(&content, "\n", &line)) { iGmRun run; run.color = white_ColorId; diff --git a/src/ui/documentwidget.c b/src/ui/documentwidget.c index 3bb66be6..4cd0ac18 100644 --- a/src/ui/documentwidget.c +++ b/src/ui/documentwidget.c @@ -247,7 +247,7 @@ static void checkResponseCode_DocumentWidget_(iDocumentWidget *d) { switch (status_GmRequest(d->request)) { case redirectTemporary_GmStatusCode: case redirectPermanent_GmStatusCode: - postCommandf_App("open url:%s", cstr_String(meta_GmRequest(d->request))); + postCommandf_App("open redirect:1 url:%s", cstr_String(meta_GmRequest(d->request))); iReleasePtr(&d->request); break; default: diff --git a/src/ui/scrollwidget.c b/src/ui/scrollwidget.c index 1961677b..65b20a28 100644 --- a/src/ui/scrollwidget.c +++ b/src/ui/scrollwidget.c @@ -115,7 +115,7 @@ static void draw_ScrollWidget_(const iScrollWidget *d) { iPaint p; init_Paint(&p); drawRect_Paint(&p, bounds, black_ColorId); - fillRect_Paint(&p, shrunk_Rect(thumbRect_ScrollWidget_(d), one_I2()), + fillRect_Paint(&p, shrunk_Rect(thumbRect_ScrollWidget_(d), init1_I2(gap_UI / 2)), isPressed ? orange_ColorId : gray50_ColorId); } } diff --git a/src/ui/widget.c b/src/ui/widget.c index 86d2e195..69509e33 100644 --- a/src/ui/widget.c +++ b/src/ui/widget.c @@ -74,6 +74,7 @@ void destroy_Widget(iWidget *d) { rootData_.pendingDestruction = new_PtrSet(); } insert_PtrSet(rootData_.pendingDestruction, d); + postRefresh_App(); } void setId_Widget(iWidget *d, const char *id) { @@ -449,6 +450,7 @@ iAny *removeChild_Widget(iWidget *d, iAnyObject *child) { } iAssert(found); ((iWidget *) child)->parent = NULL; + postRefresh_App(); return child; } diff --git a/src/ui/window.c b/src/ui/window.c index 2d030dcc..896b1e66 100644 --- a/src/ui/window.c +++ b/src/ui/window.c @@ -86,7 +86,7 @@ static iBool handleNavBarCommands_(iWidget *navBar, const char *cmd) { iInputWidget *url = findWidget_App("url"); setTextCStr_InputWidget(url, valuePtr_Command(cmd, "url")); setTitle_Window(get_Window(), text_InputWidget(url)); - return iTrue; + return iFalse; } return iFalse; } -- cgit v1.2.3