diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/app.c | 33 | ||||
-rw-r--r-- | src/history.c | 19 | ||||
-rw-r--r-- | src/history.h | 2 | ||||
-rw-r--r-- | src/ui/documentwidget.c | 29 | ||||
-rw-r--r-- | src/ui/documentwidget.h | 9 | ||||
-rw-r--r-- | src/ui/util.c | 8 | ||||
-rw-r--r-- | src/ui/util.h | 23 | ||||
-rw-r--r-- | src/ui/widget.c | 11 | ||||
-rw-r--r-- | src/ui/widget.h | 1 | ||||
-rw-r--r-- | src/ui/window.c | 171 |
10 files changed, 132 insertions, 174 deletions
@@ -396,20 +396,47 @@ iBool handleCommand_App(const char *cmd) { | |||
396 | iWidget *tabs = findWidget_App("doctabs"); | 396 | iWidget *tabs = findWidget_App("doctabs"); |
397 | iWidget *newTabButton = findChild_Widget(tabs, "newtab"); | 397 | iWidget *newTabButton = findChild_Widget(tabs, "newtab"); |
398 | removeChild_Widget(newTabButton->parent, newTabButton); | 398 | removeChild_Widget(newTabButton->parent, newTabButton); |
399 | iDocumentWidget *newDoc = new_DocumentWidget(); | 399 | iDocumentWidget *newDoc; |
400 | const iBool isDuplicate = (argLabel_Command(cmd, "duplicate") != 0); | ||
401 | if (isDuplicate) { | ||
402 | newDoc = duplicate_DocumentWidget(document_App()); | ||
403 | } | ||
404 | else { | ||
405 | newDoc = new_DocumentWidget(); | ||
406 | } | ||
400 | setId_Widget(as_Widget(newDoc), format_CStr("document%03d", tabCount_Widget(tabs))); | 407 | setId_Widget(as_Widget(newDoc), format_CStr("document%03d", tabCount_Widget(tabs))); |
401 | appendTabPage_Widget(tabs, iClob(newDoc), "", 0, 0); | 408 | appendTabPage_Widget(tabs, iClob(newDoc), "", 0, 0); |
402 | addChild_Widget(findChild_Widget(tabs, "tabs.buttons"), iClob(newTabButton)); | 409 | addChild_Widget(findChild_Widget(tabs, "tabs.buttons"), iClob(newTabButton)); |
403 | postCommandf_App("tabs.switch page:%p", newDoc); | 410 | postCommandf_App("tabs.switch page:%p", newDoc); |
404 | postCommand_App("navigate.home"); | 411 | if (!isDuplicate) { |
412 | postCommand_App("navigate.home"); | ||
413 | } | ||
405 | arrange_Widget(tabs); | 414 | arrange_Widget(tabs); |
406 | refresh_Widget(tabs); | 415 | refresh_Widget(tabs); |
407 | return iTrue; | 416 | return iTrue; |
408 | } | 417 | } |
409 | else if (equal_Command(cmd, "tabs.close")) { | 418 | else if (equal_Command(cmd, "tabs.close")) { |
410 | iWidget *tabs = findWidget_App("doctabs"); | 419 | iWidget *tabs = findWidget_App("doctabs"); |
420 | size_t index = tabPageIndex_Widget(tabs, document_App()); | ||
421 | iBool wasClosed = iFalse; | ||
422 | if (argLabel_Command(cmd, "toright")) { | ||
423 | while (tabCount_Widget(tabs) > index + 1) { | ||
424 | destroy_Widget(removeTabPage_Widget(tabs, index + 1)); | ||
425 | } | ||
426 | wasClosed = iTrue; | ||
427 | } | ||
428 | if (argLabel_Command(cmd, "toleft")) { | ||
429 | while (index-- > 0) { | ||
430 | destroy_Widget(removeTabPage_Widget(tabs, 0)); | ||
431 | } | ||
432 | postCommandf_App("tabs.switch page:%p", tabPage_Widget(tabs, 0)); | ||
433 | wasClosed = iTrue; | ||
434 | } | ||
435 | if (wasClosed) { | ||
436 | arrange_Widget(tabs); | ||
437 | return iTrue; | ||
438 | } | ||
411 | if (tabCount_Widget(tabs) > 1) { | 439 | if (tabCount_Widget(tabs) > 1) { |
412 | size_t index = tabPageIndex_Widget(tabs, document_App()); | ||
413 | iWidget *closed = removeTabPage_Widget(tabs, index); | 440 | iWidget *closed = removeTabPage_Widget(tabs, index); |
414 | destroy_Widget(closed); /* released later */ | 441 | destroy_Widget(closed); /* released later */ |
415 | if (index == tabCount_Widget(tabs)) { | 442 | if (index == tabCount_Widget(tabs)) { |
diff --git a/src/history.c b/src/history.c index c009f484..5be24608 100644 --- a/src/history.c +++ b/src/history.c | |||
@@ -17,6 +17,16 @@ void deinit_RecentUrl(iRecentUrl *d) { | |||
17 | delete_GmResponse(d->cachedResponse); | 17 | delete_GmResponse(d->cachedResponse); |
18 | } | 18 | } |
19 | 19 | ||
20 | iDefineTypeConstruction(RecentUrl) | ||
21 | |||
22 | iRecentUrl *copy_RecentUrl(const iRecentUrl *d) { | ||
23 | iRecentUrl *copy = new_RecentUrl(); | ||
24 | set_String(©->url, &d->url); | ||
25 | copy->scrollY = d->scrollY; | ||
26 | copy->cachedResponse = d->cachedResponse ? copy_GmResponse(d->cachedResponse) : NULL; | ||
27 | return copy; | ||
28 | } | ||
29 | |||
20 | /*----------------------------------------------------------------------------------------------*/ | 30 | /*----------------------------------------------------------------------------------------------*/ |
21 | 31 | ||
22 | struct Impl_History { | 32 | struct Impl_History { |
@@ -36,6 +46,15 @@ void deinit_History(iHistory *d) { | |||
36 | deinit_Array(&d->recent); | 46 | deinit_Array(&d->recent); |
37 | } | 47 | } |
38 | 48 | ||
49 | iHistory *copy_History(const iHistory *d) { | ||
50 | iHistory *copy = new_History(); | ||
51 | iConstForEach(Array, i, &d->recent) { | ||
52 | pushBack_Array(©->recent, copy_RecentUrl(i.value)); | ||
53 | } | ||
54 | copy->recentPos = d->recentPos; | ||
55 | return copy; | ||
56 | } | ||
57 | |||
39 | void save_History(const iHistory *d, const char *dirPath) { | 58 | void save_History(const iHistory *d, const char *dirPath) { |
40 | iString *line = new_String(); | 59 | iString *line = new_String(); |
41 | iFile *f = newCStr_File(concatPath_CStr(dirPath, "recent.txt")); | 60 | iFile *f = newCStr_File(concatPath_CStr(dirPath, "recent.txt")); |
diff --git a/src/history.h b/src/history.h index bb7f5c88..9deae8ea 100644 --- a/src/history.h +++ b/src/history.h | |||
@@ -20,6 +20,8 @@ struct Impl_RecentUrl { | |||
20 | iDeclareType(History) | 20 | iDeclareType(History) |
21 | iDeclareTypeConstruction(History) | 21 | iDeclareTypeConstruction(History) |
22 | 22 | ||
23 | iHistory * copy_History (const iHistory *); | ||
24 | |||
23 | void clear_History (iHistory *); | 25 | void clear_History (iHistory *); |
24 | void load_History (iHistory *, const char *dirPath); | 26 | void load_History (iHistory *, const char *dirPath); |
25 | void add_History (iHistory *, const iString *url); | 27 | void add_History (iHistory *, const iString *url); |
diff --git a/src/ui/documentwidget.c b/src/ui/documentwidget.c index 9a97c39e..6313e6df 100644 --- a/src/ui/documentwidget.c +++ b/src/ui/documentwidget.c | |||
@@ -280,6 +280,11 @@ static void updateVisible_DocumentWidget_(iDocumentWidget *d) { | |||
280 | } | 280 | } |
281 | 281 | ||
282 | static void updateWindowTitle_DocumentWidget_(const iDocumentWidget *d) { | 282 | static void updateWindowTitle_DocumentWidget_(const iDocumentWidget *d) { |
283 | iLabelWidget *tabButton = tabPageButton_Widget(findWidget_App("doctabs"), d); | ||
284 | if (!tabButton) { | ||
285 | /* Not part of the UI at the moment. */ | ||
286 | return; | ||
287 | } | ||
283 | iStringArray *title = iClob(new_StringArray()); | 288 | iStringArray *title = iClob(new_StringArray()); |
284 | if (!isEmpty_String(title_GmDocument(d->doc))) { | 289 | if (!isEmpty_String(title_GmDocument(d->doc))) { |
285 | pushBack_StringArray(title, title_GmDocument(d->doc)); | 290 | pushBack_StringArray(title, title_GmDocument(d->doc)); |
@@ -298,7 +303,6 @@ static void updateWindowTitle_DocumentWidget_(const iDocumentWidget *d) { | |||
298 | pushBackCStr_StringArray(title, "Lagrange"); | 303 | pushBackCStr_StringArray(title, "Lagrange"); |
299 | } | 304 | } |
300 | /* Take away parts if it doesn't fit. */ | 305 | /* Take away parts if it doesn't fit. */ |
301 | iLabelWidget *tabButton = tabPageButton_Widget(findWidget_App("doctabs"), d); | ||
302 | const int avail = bounds_Widget(as_Widget(tabButton)).size.x - 3 * gap_UI; | 306 | const int avail = bounds_Widget(as_Widget(tabButton)).size.x - 3 * gap_UI; |
303 | iBool setWindow = (document_App() == d); | 307 | iBool setWindow = (document_App() == d); |
304 | for (;;) { | 308 | for (;;) { |
@@ -455,9 +459,11 @@ static void fetch_DocumentWidget_(iDocumentWidget *d) { | |||
455 | static void updateTrust_DocumentWidget_(iDocumentWidget *d, const iGmResponse *response) { | 459 | static void updateTrust_DocumentWidget_(iDocumentWidget *d, const iGmResponse *response) { |
456 | #define openLock_CStr "\U0001f513" | 460 | #define openLock_CStr "\U0001f513" |
457 | #define closedLock_CStr "\U0001f512" | 461 | #define closedLock_CStr "\U0001f512" |
458 | d->certFlags = response->certFlags; | 462 | if (response) { |
459 | d->certExpiry = response->certValidUntil; | 463 | d->certFlags = response->certFlags; |
460 | set_String(d->certSubject, &response->certSubject); | 464 | d->certExpiry = response->certValidUntil; |
465 | set_String(d->certSubject, &response->certSubject); | ||
466 | } | ||
461 | iLabelWidget *lock = findWidget_App("navbar.lock"); | 467 | iLabelWidget *lock = findWidget_App("navbar.lock"); |
462 | if (~d->certFlags & available_GmCertFlag) { | 468 | if (~d->certFlags & available_GmCertFlag) { |
463 | setFlags_Widget(as_Widget(lock), disabled_WidgetFlag, iTrue); | 469 | setFlags_Widget(as_Widget(lock), disabled_WidgetFlag, iTrue); |
@@ -516,6 +522,16 @@ void setUrlFromCache_DocumentWidget(iDocumentWidget *d, const iString *url, iBoo | |||
516 | } | 522 | } |
517 | } | 523 | } |
518 | 524 | ||
525 | iDocumentWidget *duplicate_DocumentWidget(iDocumentWidget *orig) { | ||
526 | iDocumentWidget *d = new_DocumentWidget(); | ||
527 | delete_History(d->history); | ||
528 | d->textSizePercent = orig->textSizePercent; | ||
529 | d->initialScrollY = orig->scrollY; | ||
530 | d->history = copy_History(orig->history); | ||
531 | setUrlFromCache_DocumentWidget(d, orig->url, iTrue); | ||
532 | return d; | ||
533 | } | ||
534 | |||
519 | void setUrl_DocumentWidget(iDocumentWidget *d, const iString *url) { | 535 | void setUrl_DocumentWidget(iDocumentWidget *d, const iString *url) { |
520 | setUrlFromCache_DocumentWidget(d, url, iFalse); | 536 | setUrlFromCache_DocumentWidget(d, url, iFalse); |
521 | } | 537 | } |
@@ -754,11 +770,14 @@ static iBool handleCommand_DocumentWidget_(iDocumentWidget *d, const char *cmd) | |||
754 | if (cmp_String(id_Widget(w), suffixPtr_Command(cmd, "id")) == 0) { | 770 | if (cmp_String(id_Widget(w), suffixPtr_Command(cmd, "id")) == 0) { |
755 | /* Set palette for our document. */ | 771 | /* Set palette for our document. */ |
756 | updateTheme_DocumentWidget_(d); | 772 | updateTheme_DocumentWidget_(d); |
773 | updateTrust_DocumentWidget_(d, NULL); | ||
774 | setWidth_GmDocument(d->doc, documentWidth_DocumentWidget_(d)); | ||
775 | updateVisible_DocumentWidget_(d); | ||
757 | } | 776 | } |
758 | updateWindowTitle_DocumentWidget_(d); | 777 | updateWindowTitle_DocumentWidget_(d); |
759 | return iFalse; | 778 | return iFalse; |
760 | } | 779 | } |
761 | else if (equal_Command(cmd, "server.showcert")) { | 780 | else if (equal_Command(cmd, "server.showcert") && d == document_App()) { |
762 | const char *unchecked = red_ColorEscape "\u2610"; | 781 | const char *unchecked = red_ColorEscape "\u2610"; |
763 | const char *checked = green_ColorEscape "\u2611"; | 782 | const char *checked = green_ColorEscape "\u2611"; |
764 | makeMessage_Widget( | 783 | makeMessage_Widget( |
diff --git a/src/ui/documentwidget.h b/src/ui/documentwidget.h index 38fcf8e3..5e7c3f2c 100644 --- a/src/ui/documentwidget.h +++ b/src/ui/documentwidget.h | |||
@@ -7,11 +7,12 @@ iDeclareType(History) | |||
7 | iDeclareWidgetClass(DocumentWidget) | 7 | iDeclareWidgetClass(DocumentWidget) |
8 | iDeclareObjectConstruction(DocumentWidget) | 8 | iDeclareObjectConstruction(DocumentWidget) |
9 | 9 | ||
10 | iHistory * history_DocumentWidget (iDocumentWidget *); | 10 | iDocumentWidget *duplicate_DocumentWidget (iDocumentWidget *); |
11 | iHistory * history_DocumentWidget (iDocumentWidget *); | ||
12 | |||
13 | const iString * url_DocumentWidget (const iDocumentWidget *); | ||
14 | iBool isRequestOngoing_DocumentWidget (const iDocumentWidget *); | ||
11 | 15 | ||
12 | void setUrl_DocumentWidget (iDocumentWidget *, const iString *url); | 16 | void setUrl_DocumentWidget (iDocumentWidget *, const iString *url); |
13 | void setUrlFromCache_DocumentWidget (iDocumentWidget *d, const iString *url, iBool isFromCache); | 17 | void setUrlFromCache_DocumentWidget (iDocumentWidget *d, const iString *url, iBool isFromCache); |
14 | void setInitialScroll_DocumentWidget (iDocumentWidget *, int scrollY); /* set after content received */ | 18 | void setInitialScroll_DocumentWidget (iDocumentWidget *, int scrollY); /* set after content received */ |
15 | |||
16 | const iString * url_DocumentWidget (const iDocumentWidget *); | ||
17 | iBool isRequestOngoing_DocumentWidget (const iDocumentWidget *); | ||
diff --git a/src/ui/util.c b/src/ui/util.c index 9ac1913d..5868e9d7 100644 --- a/src/ui/util.c +++ b/src/ui/util.c | |||
@@ -195,6 +195,8 @@ iWidget *makeMenu_Widget(iWidget *parent, const iMenuItem *items, size_t n) { | |||
195 | 195 | ||
196 | void openMenu_Widget(iWidget *d, iInt2 coord) { | 196 | void openMenu_Widget(iWidget *d, iInt2 coord) { |
197 | /* Menu closes when commands are emitted, so handle any pending ones beforehand. */ | 197 | /* Menu closes when commands are emitted, so handle any pending ones beforehand. */ |
198 | postCommand_App("cancel"); /* dismiss any other menus */ | ||
199 | processEvents_App(postedEventsOnly_AppEventMode); | ||
198 | setFlags_Widget(d, hidden_WidgetFlag, iFalse); | 200 | setFlags_Widget(d, hidden_WidgetFlag, iFalse); |
199 | arrange_Widget(d); | 201 | arrange_Widget(d); |
200 | d->rect.pos = coord; | 202 | d->rect.pos = coord; |
@@ -318,7 +320,7 @@ static void addTabPage_Widget_(iWidget *tabs, enum iWidgetAddPos addPos, iWidget | |||
318 | iClob(new_LabelWidget(label, key, kmods, format_CStr("tabs.switch page:%p", page))), | 320 | iClob(new_LabelWidget(label, key, kmods, format_CStr("tabs.switch page:%p", page))), |
319 | addPos); | 321 | addPos); |
320 | setFlags_Widget(button, selected_WidgetFlag, isSel); | 322 | setFlags_Widget(button, selected_WidgetFlag, isSel); |
321 | setFlags_Widget(button, expand_WidgetFlag, iTrue); | 323 | setFlags_Widget(button, commandOnClick_WidgetFlag | expand_WidgetFlag, iTrue); |
322 | addChildPos_Widget(pages, page, addPos); | 324 | addChildPos_Widget(pages, page, addPos); |
323 | setFlags_Widget(page, hidden_WidgetFlag | disabled_WidgetFlag, !isSel); | 325 | setFlags_Widget(page, hidden_WidgetFlag | disabled_WidgetFlag, !isSel); |
324 | } | 326 | } |
@@ -388,6 +390,10 @@ iLabelWidget *tabPageButton_Widget(iWidget *tabs, const iAnyObject *page) { | |||
388 | return tabButtonForPage_Widget_(tabs, page); | 390 | return tabButtonForPage_Widget_(tabs, page); |
389 | } | 391 | } |
390 | 392 | ||
393 | iBool isTabButton_Widget(const iWidget *d) { | ||
394 | return d->parent && cmp_String(id_Widget(d->parent), "tabs.buttons") == 0; | ||
395 | } | ||
396 | |||
391 | void setTabPageLabel_Widget(iWidget *tabs, const iAnyObject *page, const iString *label) { | 397 | void setTabPageLabel_Widget(iWidget *tabs, const iAnyObject *page, const iString *label) { |
392 | iLabelWidget *button = tabButtonForPage_Widget_(tabs, page); | 398 | iLabelWidget *button = tabButtonForPage_Widget_(tabs, page); |
393 | setText_LabelWidget(button, label); | 399 | setText_LabelWidget(button, label); |
diff --git a/src/ui/util.h b/src/ui/util.h index 6e210422..26066e53 100644 --- a/src/ui/util.h +++ b/src/ui/util.h | |||
@@ -94,17 +94,18 @@ iLabelWidget * makeMenuButton_LabelWidget (const char *label, const iMenuItem | |||
94 | 94 | ||
95 | /*-----------------------------------------------------------------------------------------------*/ | 95 | /*-----------------------------------------------------------------------------------------------*/ |
96 | 96 | ||
97 | iWidget * makeTabs_Widget (iWidget *parent); | 97 | iWidget * makeTabs_Widget (iWidget *parent); |
98 | void appendTabPage_Widget (iWidget *tabs, iWidget *page, const char *label, int key, int kmods); | 98 | void appendTabPage_Widget (iWidget *tabs, iWidget *page, const char *label, int key, int kmods); |
99 | void prependTabPage_Widget (iWidget *tabs, iWidget *page, const char *label, int key, int kmods); | 99 | void prependTabPage_Widget (iWidget *tabs, iWidget *page, const char *label, int key, int kmods); |
100 | iWidget * tabPage_Widget (iWidget *tabs, size_t index); | 100 | iWidget * removeTabPage_Widget (iWidget *tabs, size_t index); /* returns the page */ |
101 | iLabelWidget *tabPageButton_Widget (iWidget *tabs, const iAnyObject *page); | 101 | void showTabPage_Widget (iWidget *tabs, const iWidget *page); |
102 | iWidget * removeTabPage_Widget (iWidget *tabs, size_t index); /* returns the page */ | 102 | void setTabPageLabel_Widget (iWidget *tabs, const iAnyObject *page, const iString *label); |
103 | void showTabPage_Widget (iWidget *tabs, const iWidget *page); | 103 | iWidget * tabPage_Widget (iWidget *tabs, size_t index); |
104 | void setTabPageLabel_Widget (iWidget *tabs, const iAnyObject *page, const iString *label); | 104 | iLabelWidget * tabPageButton_Widget (iWidget *tabs, const iAnyObject *page); |
105 | size_t tabPageIndex_Widget (const iWidget *tabs, const iAnyObject *page); | 105 | iBool isTabButton_Widget (const iWidget *); |
106 | const iWidget *currentTabPage_Widget(const iWidget *tabs); | 106 | size_t tabPageIndex_Widget (const iWidget *tabs, const iAnyObject *page); |
107 | size_t tabCount_Widget (const iWidget *tabs); | 107 | const iWidget * currentTabPage_Widget (const iWidget *tabs); |
108 | size_t tabCount_Widget (const iWidget *tabs); | ||
108 | 109 | ||
109 | /*-----------------------------------------------------------------------------------------------*/ | 110 | /*-----------------------------------------------------------------------------------------------*/ |
110 | 111 | ||
diff --git a/src/ui/widget.c b/src/ui/widget.c index 56b05aa6..51841d64 100644 --- a/src/ui/widget.c +++ b/src/ui/widget.c | |||
@@ -419,6 +419,17 @@ iBool processEvent_Widget(iWidget *d, const SDL_Event *ev) { | |||
419 | return iTrue; | 419 | return iTrue; |
420 | } | 420 | } |
421 | } | 421 | } |
422 | else if (d->flags & commandOnClick_WidgetFlag && (ev->type == SDL_MOUSEBUTTONDOWN || | ||
423 | ev->type == SDL_MOUSEBUTTONUP) && | ||
424 | contains_Widget(d, init_I2(ev->button.x, ev->button.y))) { | ||
425 | postCommand_Widget(d, | ||
426 | "mouse.clicked arg:%d button:%d coord:%d %d", | ||
427 | ev->type == SDL_MOUSEBUTTONDOWN ? 1 : 0, | ||
428 | ev->button.button, | ||
429 | ev->button.x, | ||
430 | ev->button.y); | ||
431 | return iTrue; | ||
432 | } | ||
422 | switch (ev->type) { | 433 | switch (ev->type) { |
423 | case SDL_USEREVENT: { | 434 | case SDL_USEREVENT: { |
424 | if (ev->user.code == command_UserEventCode && d->commandHandler && | 435 | if (ev->user.code == command_UserEventCode && d->commandHandler && |
diff --git a/src/ui/widget.h b/src/ui/widget.h index 8277b4ba..1cea7147 100644 --- a/src/ui/widget.h +++ b/src/ui/widget.h | |||
@@ -30,6 +30,7 @@ enum iWidgetFlag { | |||
30 | alignLeft_WidgetFlag = iBit(6), | 30 | alignLeft_WidgetFlag = iBit(6), |
31 | alignRight_WidgetFlag = iBit(7), | 31 | alignRight_WidgetFlag = iBit(7), |
32 | frameless_WidgetFlag = iBit(8), | 32 | frameless_WidgetFlag = iBit(8), |
33 | commandOnClick_WidgetFlag = iBit(9), | ||
33 | drawKey_WidgetFlag = iBit(10), | 34 | drawKey_WidgetFlag = iBit(10), |
34 | focusable_WidgetFlag = iBit(11), | 35 | focusable_WidgetFlag = iBit(11), |
35 | tight_WidgetFlag = iBit(31), /* smaller padding */ | 36 | tight_WidgetFlag = iBit(31), /* smaller padding */ |
diff --git a/src/ui/window.c b/src/ui/window.c index bc690426..296b8d05 100644 --- a/src/ui/window.c +++ b/src/ui/window.c | |||
@@ -140,6 +140,16 @@ static iBool handleNavBarCommands_(iWidget *navBar, const char *cmd) { | |||
140 | updateTextCStr_LabelWidget(findChild_Widget(navBar, "reload"), | 140 | updateTextCStr_LabelWidget(findChild_Widget(navBar, "reload"), |
141 | isRequestOngoing_DocumentWidget(doc) ? stopCStr_ : reloadCStr_); | 141 | isRequestOngoing_DocumentWidget(doc) ? stopCStr_ : reloadCStr_); |
142 | } | 142 | } |
143 | else if (equal_Command(cmd, "mouse.clicked")) { | ||
144 | iWidget *widget = pointer_Command(cmd); | ||
145 | iWidget *menu = findWidget_App("doctabs.menu"); | ||
146 | if (isTabButton_Widget(widget)) { | ||
147 | iWidget *tabs = findWidget_App("doctabs"); | ||
148 | showTabPage_Widget(tabs, | ||
149 | tabPage_Widget(tabs, childIndex_Widget(widget->parent, widget))); | ||
150 | openMenu_Widget(menu, coord_Command(cmd)); | ||
151 | } | ||
152 | } | ||
143 | else if (equal_Command(cmd, "navigate.reload")) { | 153 | else if (equal_Command(cmd, "navigate.reload")) { |
144 | iDocumentWidget *doc = document_Command(cmd); | 154 | iDocumentWidget *doc = document_Command(cmd); |
145 | if (isRequestOngoing_DocumentWidget(doc)) { | 155 | if (isRequestOngoing_DocumentWidget(doc)) { |
@@ -265,156 +275,17 @@ static void setupUserInterface_Window(iWindow *d) { | |||
265 | addChild_Widget(searchBar, iClob(newIcon_LabelWidget(" \u2b9d ", 'g', KMOD_PRIMARY | KMOD_SHIFT, "find.prev"))); | 275 | addChild_Widget(searchBar, iClob(newIcon_LabelWidget(" \u2b9d ", 'g', KMOD_PRIMARY | KMOD_SHIFT, "find.prev"))); |
266 | addChild_Widget(searchBar, iClob(newIcon_LabelWidget("\u2a2f", SDLK_ESCAPE, 0, "find.close"))); | 276 | addChild_Widget(searchBar, iClob(newIcon_LabelWidget("\u2a2f", SDLK_ESCAPE, 0, "find.close"))); |
267 | } | 277 | } |
268 | 278 | iWidget *tabsMenu = makeMenu_Widget(d->root, | |
269 | #if 0 | 279 | (iMenuItem[]){ |
270 | iWidget *mainDiv = makeHDiv_Widget(); | 280 | { "Close Tab", 0, 0, "tabs.close" }, |
271 | setId_Widget(mainDiv, "maindiv"); | 281 | { "Duplicate Tab", 0, 0, "tabs.new duplicate:1" }, |
272 | addChild_Widget(d->root, iClob(mainDiv)); | 282 | { "---", 0, 0, NULL }, |
273 | 283 | { "Close Other Tabs", 0, 0, "tabs.close toleft:1 toright:1" }, | |
274 | iWidget *sidebar = makeVDiv_Widget(); | 284 | { "Close Tabs To Left", 0, 0, "tabs.close toleft:1" }, |
275 | setFlags_Widget(sidebar, arrangeWidth_WidgetFlag, iTrue); | 285 | { "Close Tabs To Right", 0, 0, "tabs.close toright:1" }, |
276 | setId_Widget(sidebar, "sidebar"); | 286 | }, |
277 | addChild_Widget(mainDiv, iClob(sidebar)); | 287 | 6); |
278 | 288 | setId_Widget(tabsMenu, "doctabs.menu"); | |
279 | /* Menus. */ { | ||
280 | #if defined (iPlatformApple) && !defined (iPlatformIOS) | ||
281 | /* Use the native menus. */ | ||
282 | insertMenuItems_MacOS("File", fileMenuItems, iElemCount(fileMenuItems)); | ||
283 | insertMenuItems_MacOS("Edit", editMenuItems, iElemCount(editMenuItems)); | ||
284 | insertMenuItems_MacOS("View", viewMenuItems, iElemCount(viewMenuItems)); | ||
285 | #else | ||
286 | iWidget *menubar = new_Widget(); | ||
287 | setBackgroundColor_Widget(menubar, gray25_ColorId); | ||
288 | setFlags_Widget(menubar, arrangeHorizontal_WidgetFlag | arrangeHeight_WidgetFlag, iTrue); | ||
289 | addChild_Widget(menubar, iClob(makeMenuButton_LabelWidget("File", fileMenuItems, iElemCount(fileMenuItems)))); | ||
290 | addChild_Widget(menubar, iClob(makeMenuButton_LabelWidget("Edit", editMenuItems, iElemCount(editMenuItems)))); | ||
291 | addChild_Widget(menubar, iClob(makeMenuButton_LabelWidget("View", viewMenuItems, iElemCount(viewMenuItems)))); | ||
292 | addChild_Widget(sidebar, iClob(menubar)); | ||
293 | #endif | ||
294 | } | ||
295 | /* Tracker info. */ { | ||
296 | iWidget *trackerInfo = addChild_Widget(sidebar, iClob(new_Widget())); | ||
297 | setId_Widget(trackerInfo, "trackerinfo"); | ||
298 | trackerInfo->rect.size.y = lineHeight_Text(default_FontId) + 2 * gap_UI; | ||
299 | setFlags_Widget(trackerInfo, arrangeHorizontal_WidgetFlag | resizeChildren_WidgetFlag, iTrue); | ||
300 | setId_Widget( | ||
301 | addChild_Widget(trackerInfo, iClob(new_LabelWidget("", 'p', KMOD_PRIMARY, "pattern.goto arg:-1"))), | ||
302 | "trackerinfo.current"); | ||
303 | iLabelWidget *dims = new_LabelWidget("", 'r', KMOD_PRIMARY | KMOD_ALT, "pattern.resize"); | ||
304 | setId_Widget(addChild_Widget(trackerInfo, iClob(dims)), "trackerinfo.dims"); | ||
305 | } | ||
306 | |||
307 | iLibraryWidget *lib = new_LibraryWidget(); | ||
308 | setId_Widget(as_Widget(lib), "library"); | ||
309 | addChildFlags_Widget(sidebar, iClob(lib), expand_WidgetFlag); | ||
310 | |||
311 | iPlaybackWidget *play = new_PlaybackWidget(); | ||
312 | setId_Widget(as_Widget(play), "playback"); | ||
313 | addChild_Widget(sidebar, iClob(play)); | ||
314 | |||
315 | iWidget *mainTabs = makeTabs_Widget(mainDiv); | ||
316 | setId_Widget(mainTabs, "maintabs"); | ||
317 | setFlags_Widget(mainTabs, expand_WidgetFlag, iTrue); | ||
318 | |||
319 | /* Optional sidebar on the right. */ | ||
320 | iWidget *sidebar2 = new_Widget(); | ||
321 | setId_Widget(addChild_Widget(mainDiv, iClob(sidebar2)), "sidebar2"); | ||
322 | setFlags_Widget( | ||
323 | sidebar2, fixedWidth_WidgetFlag | frameless_WidgetFlag | resizeChildren_WidgetFlag, iTrue); | ||
324 | |||
325 | /* Pattern sequence. */ { | ||
326 | iSequenceWidget *seq = new_SequenceWidget(); | ||
327 | appendTabPage_Widget(mainTabs, iClob(seq), "SEQUENCE", 0, 0); | ||
328 | } | ||
329 | /* Tracker. */ { | ||
330 | iTrackerWidget *tracker = new_TrackerWidget(); | ||
331 | appendTabPage_Widget(mainTabs, as_Widget(tracker), "PATTERN", 0, 0); | ||
332 | } | ||
333 | /* Voice editor. */ { | ||
334 | iWidget *voice = as_Widget(new_VoiceWidget()); | ||
335 | setId_Widget(voice, "voicelayers"); | ||
336 | appendTabPage_Widget(mainTabs, iClob(voice), "VOICE", '3', KMOD_PRIMARY); | ||
337 | } | ||
338 | /* Song information. */ { | ||
339 | iWidget *songPage = new_Widget(); | ||
340 | setId_Widget(songPage, "songinfo"); | ||
341 | setFlags_Widget(songPage, arrangeHorizontal_WidgetFlag, iTrue); | ||
342 | iWidget *headings = | ||
343 | addChildFlags_Widget(songPage, | ||
344 | iClob(new_Widget()), | ||
345 | resizeToParentHeight_WidgetFlag | resizeChildren_WidgetFlag | | ||
346 | arrangeVertical_WidgetFlag | arrangeWidth_WidgetFlag); | ||
347 | iWidget *values = addChildFlags_Widget( | ||
348 | songPage, iClob(new_Widget()), arrangeVertical_WidgetFlag | arrangeSize_WidgetFlag); | ||
349 | |||
350 | setId_Widget(addChild_Widget(headings, iClob(makePadding_Widget(2 * gap_UI))), "headings.padding"); | ||
351 | setId_Widget(addChild_Widget(values, iClob(makePadding_Widget(2 * gap_UI))), "values.padding"); | ||
352 | |||
353 | addChild_Widget(headings, iClob(makeHeading_Widget(cyan_ColorEscape "SONG PROPERTIES"))); | ||
354 | addChild_Widget(values, iClob(makeHeading_Widget(""))); | ||
355 | |||
356 | const int fieldWidth = advance_Text(monospace_FontId, "A").x * 40; | ||
357 | iWidget *field; | ||
358 | |||
359 | addChild_Widget(headings, iClob(makeHeading_Widget("Title:"))); | ||
360 | setId_Widget(field = addChild_Widget(values, iClob(new_InputWidget(0))), "info.title"); | ||
361 | field->rect.size.x = fieldWidth; | ||
362 | |||
363 | addChild_Widget(headings, iClob(makeHeading_Widget("Author:"))); | ||
364 | setId_Widget(field = addChild_Widget(values, iClob(new_InputWidget(0))), "info.author"); | ||
365 | field->rect.size.x = fieldWidth; | ||
366 | |||
367 | addChild_Widget(headings, iClob(makeHeading_Widget("Tempo:"))); | ||
368 | setId_Widget(addChild_Widget(values, iClob(new_InputWidget(3))), "info.tempo"); | ||
369 | |||
370 | addChild_Widget(headings, iClob(makeHeading_Widget("Events per Beat:"))); | ||
371 | setId_Widget(addChild_Widget(values, iClob(new_InputWidget(2))), "info.eventsperbeat"); | ||
372 | |||
373 | addChild_Widget(headings, iClob(makeHeading_Widget("Num of Tracks:"))); | ||
374 | setId_Widget(addChild_Widget(values, iClob(new_InputWidget(2))), "info.numtracks"); | ||
375 | |||
376 | addChild_Widget(headings, iClob(makePadding_Widget(2 * gap_UI))); | ||
377 | addChild_Widget(values, iClob(makePadding_Widget(2 * gap_UI))); | ||
378 | |||
379 | addChild_Widget(headings, iClob(makeHeading_Widget(cyan_ColorEscape "SONG METADATA"))); | ||
380 | addChild_Widget(values, iClob(makeHeading_Widget(""))); | ||
381 | |||
382 | addChild_Widget(headings, iClob(makeHeading_Widget("Duration:"))); | ||
383 | setId_Widget(addChildFlags_Widget(values, iClob(newEmpty_LabelWidget()), | ||
384 | alignLeft_WidgetFlag | frameless_WidgetFlag), | ||
385 | "info.duration"); | ||
386 | addChild_Widget(headings, iClob(makeHeading_Widget("Statistics:\n\n "))); | ||
387 | setId_Widget(addChildFlags_Widget(values, | ||
388 | iClob(newEmpty_LabelWidget()), | ||
389 | alignLeft_WidgetFlag | frameless_WidgetFlag), | ||
390 | "info.statistics"); | ||
391 | addChild_Widget(headings, iClob(makeHeading_Widget("Created on:"))); | ||
392 | setId_Widget(addChildFlags_Widget(values, | ||
393 | iClob(newEmpty_LabelWidget()), | ||
394 | alignLeft_WidgetFlag | frameless_WidgetFlag), | ||
395 | "info.created"); | ||
396 | |||
397 | addChild_Widget(headings, iClob(makeHeading_Widget("Last Modified on:"))); | ||
398 | setId_Widget(addChildFlags_Widget(values, | ||
399 | iClob(newEmpty_LabelWidget()), | ||
400 | alignLeft_WidgetFlag | frameless_WidgetFlag), | ||
401 | "info.lastmodified"); | ||
402 | /* App info in the bottom. */ { | ||
403 | addChildFlags_Widget(headings, iClob(new_Widget()), expand_WidgetFlag); | ||
404 | addChildFlags_Widget( | ||
405 | headings, | ||
406 | iClob(new_LabelWidget(gray50_ColorEscape "Version " BWH_APP_VERSION, 0, 0, NULL)), | ||
407 | frameless_WidgetFlag | alignLeft_WidgetFlag); | ||
408 | } | ||
409 | appendTabPage_Widget(mainTabs, iClob(songPage), "INFO", '4', KMOD_PRIMARY); | ||
410 | } | ||
411 | /* Application status. */ { | ||
412 | iWidget *status = addChildFlags_Widget(d->root, iClob(newEmpty_LabelWidget()), 0); | ||
413 | setFont_LabelWidget((iLabelWidget *) status, monospace_FontId); | ||
414 | setFlags_Widget(status, frameless_WidgetFlag | alignRight_WidgetFlag, iTrue); | ||
415 | setId_Widget(status, "status"); | ||
416 | } | ||
417 | #endif | ||
418 | /* Glboal keyboard shortcuts. */ { | 289 | /* Glboal keyboard shortcuts. */ { |
419 | addAction_Widget(d->root, SDLK_LEFTBRACKET, KMOD_SHIFT | KMOD_PRIMARY, "tabs.prev"); | 290 | addAction_Widget(d->root, SDLK_LEFTBRACKET, KMOD_SHIFT | KMOD_PRIMARY, "tabs.prev"); |
420 | addAction_Widget(d->root, SDLK_RIGHTBRACKET, KMOD_SHIFT | KMOD_PRIMARY, "tabs.next"); | 291 | addAction_Widget(d->root, SDLK_RIGHTBRACKET, KMOD_SHIFT | KMOD_PRIMARY, "tabs.next"); |