diff options
author | Jaakko Keränen <jaakko.keranen@iki.fi> | 2020-07-25 08:25:16 +0300 |
---|---|---|
committer | Jaakko Keränen <jaakko.keranen@iki.fi> | 2020-07-25 08:25:16 +0300 |
commit | 534ca653e54f417f413a65a9eacd71eb12c51326 (patch) | |
tree | 8167ec4b72968cd03f88bdb464952ce048aef08e /src/app.c | |
parent | 62852e380d732402c10c80c77442f3079f66e16d (diff) |
Basic navigation history; Back and Forward are working
Diffstat (limited to 'src/app.c')
-rw-r--r-- | src/app.c | 106 |
1 files changed, 103 insertions, 3 deletions
@@ -28,6 +28,21 @@ | |||
28 | #endif | 28 | #endif |
29 | 29 | ||
30 | iDeclareType(App) | 30 | iDeclareType(App) |
31 | iDeclareType(HistoryItem) | ||
32 | |||
33 | struct Impl_HistoryItem { | ||
34 | iTime when; | ||
35 | iString url; | ||
36 | }; | ||
37 | |||
38 | void init_HistoryItem(iHistoryItem *d) { | ||
39 | initCurrent_Time(&d->when); | ||
40 | init_String(&d->url); | ||
41 | } | ||
42 | |||
43 | void deinit_HistoryItem(iHistoryItem *d) { | ||
44 | deinit_String(&d->url); | ||
45 | } | ||
31 | 46 | ||
32 | #if defined (iPlatformApple) | 47 | #if defined (iPlatformApple) |
33 | static const char *dataDir_App_ = "~/Library/Application Support/fi.skyjake.Lagrange"; | 48 | static const char *dataDir_App_ = "~/Library/Application Support/fi.skyjake.Lagrange"; |
@@ -40,12 +55,16 @@ static const char *dataDir_App_ = "~/.config/lagrange"; | |||
40 | #endif | 55 | #endif |
41 | static const char *prefsFileName_App_ = "prefs.cfg"; | 56 | static const char *prefsFileName_App_ = "prefs.cfg"; |
42 | 57 | ||
58 | static const int HISTORY_MAX = 100; | ||
59 | |||
43 | struct Impl_App { | 60 | struct Impl_App { |
44 | iCommandLine args; | 61 | iCommandLine args; |
45 | iBool running; | 62 | iBool running; |
46 | iWindow * window; | 63 | iWindow * window; |
47 | iSortedArray tickers; | 64 | iSortedArray tickers; |
48 | iBool pendingRefresh; | 65 | iBool pendingRefresh; |
66 | iArray history; | ||
67 | size_t historyPos; /* zero at the latest item */ | ||
49 | /* Preferences: */ | 68 | /* Preferences: */ |
50 | iBool retainWindowSize; | 69 | iBool retainWindowSize; |
51 | float uiScale; | 70 | float uiScale; |
@@ -131,9 +150,18 @@ static void savePrefs_App_(const iApp *d) { | |||
131 | delete_String(cfg); | 150 | delete_String(cfg); |
132 | } | 151 | } |
133 | 152 | ||
153 | static void clearHistory_App_(iApp *d) { | ||
154 | iForEach(Array, i, &d->history) { | ||
155 | deinit_HistoryItem(i.value); | ||
156 | } | ||
157 | clear_Array(&d->history); | ||
158 | } | ||
159 | |||
134 | static void init_App_(iApp *d, int argc, char **argv) { | 160 | static void init_App_(iApp *d, int argc, char **argv) { |
135 | init_CommandLine(&d->args, argc, argv); | 161 | init_CommandLine(&d->args, argc, argv); |
136 | init_SortedArray(&d->tickers, sizeof(iTicker), cmp_Ticker_); | 162 | init_SortedArray(&d->tickers, sizeof(iTicker), cmp_Ticker_); |
163 | init_Array(&d->history, sizeof(iHistoryItem)); | ||
164 | d->historyPos = 0; | ||
137 | d->running = iFalse; | 165 | d->running = iFalse; |
138 | d->window = NULL; | 166 | d->window = NULL; |
139 | d->retainWindowSize = iTrue; | 167 | d->retainWindowSize = iTrue; |
@@ -152,10 +180,12 @@ static void init_App_(iApp *d, int argc, char **argv) { | |||
152 | 180 | ||
153 | static void deinit_App(iApp *d) { | 181 | static void deinit_App(iApp *d) { |
154 | savePrefs_App_(d); | 182 | savePrefs_App_(d); |
183 | clearHistory_App_(d); | ||
184 | deinit_Array(&d->history); | ||
155 | deinit_SortedArray(&d->tickers); | 185 | deinit_SortedArray(&d->tickers); |
156 | delete_Window(d->window); | 186 | delete_Window(d->window); |
157 | d->window = NULL; | 187 | d->window = NULL; |
158 | deinit_CommandLine(&d->args); | 188 | deinit_CommandLine(&d->args); |
159 | } | 189 | } |
160 | 190 | ||
161 | const iString *execPath_App(void) { | 191 | const iString *execPath_App(void) { |
@@ -302,12 +332,62 @@ static iBool handlePrefsCommands_(iWidget *d, const char *cmd) { | |||
302 | return iFalse; | 332 | return iFalse; |
303 | } | 333 | } |
304 | 334 | ||
335 | static iHistoryItem *historyItem_App_(iApp *d, size_t pos) { | ||
336 | if (isEmpty_Array(&d->history)) return NULL; | ||
337 | return &value_Array(&d->history, size_Array(&d->history) - 1 - pos, iHistoryItem); | ||
338 | } | ||
339 | |||
340 | static const iString *historyUrl_App_(iApp *d, size_t pos) { | ||
341 | const iHistoryItem *item = historyItem_App_(d, pos); | ||
342 | if (item) { | ||
343 | return &item->url; | ||
344 | } | ||
345 | return collectNew_String(); | ||
346 | } | ||
347 | |||
348 | static void printHistory_App_(const iApp *d) { | ||
349 | iConstForEach(Array, i, &d->history) { | ||
350 | const size_t idx = index_ArrayConstIterator(&i); | ||
351 | printf("%s[%zu]: %s\n", | ||
352 | d->historyPos == size_Array(&d->history) - idx - 1 ? "->" : " ", | ||
353 | idx, | ||
354 | cstr_String(&((const iHistoryItem *) i.value)->url)); | ||
355 | } | ||
356 | fflush(stdout); | ||
357 | } | ||
358 | |||
305 | iBool handleCommand_App(const char *cmd) { | 359 | iBool handleCommand_App(const char *cmd) { |
306 | iApp *d = &app_; | 360 | iApp *d = &app_; |
307 | iWidget *root = d->window->root; | 361 | iWidget *root = d->window->root; |
308 | if (equal_Command(cmd, "open")) { | 362 | if (equal_Command(cmd, "open")) { |
309 | setUrl_DocumentWidget(findChild_Widget(root, "document"), | 363 | const iString *url = collect_String(newCStr_String(valuePtr_Command(cmd, "url"))); |
310 | collect_String(newCStr_String(valuePtr_Command(cmd, "url")))); | 364 | if (!argLabel_Command(cmd, "history")) { |
365 | if (argLabel_Command(cmd, "redirect")) { | ||
366 | /* Update in the history. */ | ||
367 | iHistoryItem *item = historyItem_App_(d, d->historyPos); | ||
368 | if (item) { | ||
369 | set_String(&item->url, url); | ||
370 | } | ||
371 | } | ||
372 | else { | ||
373 | /* Cut the trailing history items. */ | ||
374 | if (d->historyPos > 0) { | ||
375 | for (size_t i = 0; i < d->historyPos - 1; i++) { | ||
376 | deinit_HistoryItem(historyItem_App_(d, i)); | ||
377 | } | ||
378 | removeN_Array( | ||
379 | &d->history, size_Array(&d->history) - d->historyPos, iInvalidSize); | ||
380 | d->historyPos = 0; | ||
381 | } | ||
382 | /* Insert new item. */ | ||
383 | iHistoryItem item; | ||
384 | init_HistoryItem(&item); | ||
385 | set_String(&item.url, url); | ||
386 | pushBack_Array(&d->history, &item); | ||
387 | } | ||
388 | } | ||
389 | printHistory_App_(d); | ||
390 | setUrl_DocumentWidget(findChild_Widget(root, "document"), url); | ||
311 | } | 391 | } |
312 | else if (equal_Command(cmd, "quit")) { | 392 | else if (equal_Command(cmd, "quit")) { |
313 | SDL_Event ev; | 393 | SDL_Event ev; |
@@ -328,6 +408,26 @@ iBool handleCommand_App(const char *cmd) { | |||
328 | const iInt2 pos = coord_Command(cmd); | 408 | const iInt2 pos = coord_Command(cmd); |
329 | SDL_SetWindowPosition(d->window->win, pos.x, pos.y); | 409 | SDL_SetWindowPosition(d->window->win, pos.x, pos.y); |
330 | } | 410 | } |
411 | else if (equal_Command(cmd, "document.changed")) { | ||
412 | /* TODO: Update current history item with this actual/redirected URL. */ | ||
413 | return iFalse; | ||
414 | } | ||
415 | else if (equal_Command(cmd, "navigate.back")) { | ||
416 | if (d->historyPos < size_Array(&d->history) - 1) { | ||
417 | d->historyPos++; | ||
418 | postCommandf_App("open history:1 url:%s", | ||
419 | cstr_String(historyUrl_App_(d, d->historyPos))); | ||
420 | } | ||
421 | return iTrue; | ||
422 | } | ||
423 | else if (equal_Command(cmd, "navigate.forward")) { | ||
424 | if (d->historyPos > 0) { | ||
425 | d->historyPos--; | ||
426 | postCommandf_App("open history:1 url:%s", | ||
427 | cstr_String(historyUrl_App_(d, d->historyPos))); | ||
428 | } | ||
429 | return iTrue; | ||
430 | } | ||
331 | else { | 431 | else { |
332 | return iFalse; | 432 | return iFalse; |
333 | } | 433 | } |