summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/app.c26
-rw-r--r--src/app.h6
-rw-r--r--src/gmdocument.c58
-rw-r--r--src/ui/color.c140
-rw-r--r--src/ui/color.h89
-rw-r--r--src/ui/documentwidget.c21
-rw-r--r--src/ui/inputwidget.c32
-rw-r--r--src/ui/labelwidget.c99
-rw-r--r--src/ui/scrollwidget.c5
-rw-r--r--src/ui/sidebarwidget.c52
-rw-r--r--src/ui/util.c37
-rw-r--r--src/ui/window.c10
12 files changed, 434 insertions, 141 deletions
diff --git a/src/app.c b/src/app.c
index 5543db11..919a17fa 100644
--- a/src/app.c
+++ b/src/app.c
@@ -69,6 +69,7 @@ struct Impl_App {
69 iRect initialWindowRect; 69 iRect initialWindowRect;
70 float uiScale; 70 float uiScale;
71 int zoomPercent; 71 int zoomPercent;
72 enum iColorTheme theme;
72}; 73};
73 74
74static iApp app_; 75static iApp app_;
@@ -112,6 +113,7 @@ static iString *serializePrefs_App_(const iApp *d) {
112 appendFormat_String(str, "sidebar.mode arg:%d\n", mode_SidebarWidget(sidebar)); 113 appendFormat_String(str, "sidebar.mode arg:%d\n", mode_SidebarWidget(sidebar));
113 appendFormat_String(str, "uiscale arg:%f\n", uiScale_Window(d->window)); 114 appendFormat_String(str, "uiscale arg:%f\n", uiScale_Window(d->window));
114 appendFormat_String(str, "zoom.set arg:%d\n", d->zoomPercent); 115 appendFormat_String(str, "zoom.set arg:%d\n", d->zoomPercent);
116 appendFormat_String(str, "theme.set arg:%d\n", d->theme);
115 return str; 117 return str;
116} 118}
117 119
@@ -231,6 +233,7 @@ static void init_App_(iApp *d, int argc, char **argv) {
231 init_SortedArray(&d->tickers, sizeof(iTicker), cmp_Ticker_); 233 init_SortedArray(&d->tickers, sizeof(iTicker), cmp_Ticker_);
232 d->commandEcho = checkArgument_CommandLine(&d->args, "echo") != NULL; 234 d->commandEcho = checkArgument_CommandLine(&d->args, "echo") != NULL;
233 d->initialWindowRect = init_Rect(-1, -1, 800, 500); 235 d->initialWindowRect = init_Rect(-1, -1, 800, 500);
236 d->theme = dark_ColorTheme;
234 d->running = iFalse; 237 d->running = iFalse;
235 d->window = NULL; 238 d->window = NULL;
236 d->retainWindowSize = iTrue; 239 d->retainWindowSize = iTrue;
@@ -240,6 +243,7 @@ static void init_App_(iApp *d, int argc, char **argv) {
240 d->visited = new_Visited(); 243 d->visited = new_Visited();
241 d->bookmarks = new_Bookmarks(); 244 d->bookmarks = new_Bookmarks();
242 d->tabEnum = 0; /* generates unique IDs for tab pages */ 245 d->tabEnum = 0; /* generates unique IDs for tab pages */
246 setThemePalette_Color(d->theme);
243 loadPrefs_App_(d); 247 loadPrefs_App_(d);
244 load_Visited(d->visited, dataDir_App_); 248 load_Visited(d->visited, dataDir_App_);
245 load_Bookmarks(d->bookmarks, dataDir_App_); 249 load_Bookmarks(d->bookmarks, dataDir_App_);
@@ -364,6 +368,10 @@ int zoom_App(void) {
364 return app_.zoomPercent; 368 return app_.zoomPercent;
365} 369}
366 370
371enum iColorTheme colorTheme_App(void) {
372 return app_.theme;
373}
374
367int run_App(int argc, char **argv) { 375int run_App(int argc, char **argv) {
368 init_App_(&app_, argc, argv); 376 init_App_(&app_, argc, argv);
369 const int rc = run_App_(&app_); 377 const int rc = run_App_(&app_);
@@ -430,6 +438,14 @@ iBookmarks *bookmarks_App(void) {
430 return app_.bookmarks; 438 return app_.bookmarks;
431} 439}
432 440
441static void updatePrefsThemeButtons_(iWidget *d) {
442 for (size_t i = 0; i < max_ColorTheme; i++) {
443 setFlags_Widget(findChild_Widget(d, format_CStr("prefs.theme.%u", i)),
444 selected_WidgetFlag,
445 colorTheme_App() == i);
446 }
447}
448
433static iBool handlePrefsCommands_(iWidget *d, const char *cmd) { 449static iBool handlePrefsCommands_(iWidget *d, const char *cmd) {
434 if (equal_Command(cmd, "prefs.dismiss") || equal_Command(cmd, "preferences")) { 450 if (equal_Command(cmd, "prefs.dismiss") || equal_Command(cmd, "preferences")) {
435 setUiScale_Window(get_Window(), 451 setUiScale_Window(get_Window(),
@@ -439,6 +455,9 @@ static iBool handlePrefsCommands_(iWidget *d, const char *cmd) {
439 destroy_Widget(d); 455 destroy_Widget(d);
440 return iTrue; 456 return iTrue;
441 } 457 }
458 else if (equal_Command(cmd, "theme.changed")) {
459 updatePrefsThemeButtons_(d);
460 }
442 return iFalse; 461 return iFalse;
443} 462}
444 463
@@ -581,6 +600,7 @@ iBool handleCommand_App(const char *cmd) {
581 } 600 }
582 else if (equal_Command(cmd, "preferences")) { 601 else if (equal_Command(cmd, "preferences")) {
583 iWidget *dlg = makePreferences_Widget(); 602 iWidget *dlg = makePreferences_Widget();
603 updatePrefsThemeButtons_(dlg);
584 setToggle_Widget(findChild_Widget(dlg, "prefs.retainwindow"), d->retainWindowSize); 604 setToggle_Widget(findChild_Widget(dlg, "prefs.retainwindow"), d->retainWindowSize);
585 setText_InputWidget(findChild_Widget(dlg, "prefs.uiscale"), 605 setText_InputWidget(findChild_Widget(dlg, "prefs.uiscale"),
586 collectNewFormat_String("%g", uiScale_Window(d->window))); 606 collectNewFormat_String("%g", uiScale_Window(d->window)));
@@ -618,6 +638,12 @@ iBool handleCommand_App(const char *cmd) {
618 postCommand_App("bookmarks.changed"); 638 postCommand_App("bookmarks.changed");
619 return iTrue; 639 return iTrue;
620 } 640 }
641 else if (equal_Command(cmd, "theme.set")) {
642 d->theme = arg_Command(cmd);
643 setThemePalette_Color(d->theme);
644 postCommand_App("theme.changed");
645 return iTrue;
646 }
621 else { 647 else {
622 return iFalse; 648 return iFalse;
623 } 649 }
diff --git a/src/app.h b/src/app.h
index 9a6306b9..11c8c4a3 100644
--- a/src/app.h
+++ b/src/app.h
@@ -5,6 +5,8 @@
5#include <the_Foundation/string.h> 5#include <the_Foundation/string.h>
6#include <the_Foundation/time.h> 6#include <the_Foundation/time.h>
7 7
8#include "ui/color.h"
9
8iDeclareType(Bookmarks) 10iDeclareType(Bookmarks)
9iDeclareType(DocumentWidget) 11iDeclareType(DocumentWidget)
10iDeclareType(GmCerts) 12iDeclareType(GmCerts)
@@ -29,7 +31,9 @@ void processEvents_App (enum iAppEventMode mode);
29iBool handleCommand_App (const char *cmd); 31iBool handleCommand_App (const char *cmd);
30void refresh_App (void); 32void refresh_App (void);
31iBool isRefreshPending_App(void); 33iBool isRefreshPending_App(void);
32int zoom_App (void); 34
35int zoom_App (void);
36enum iColorTheme colorTheme_App (void);
33 37
34iGmCerts * certs_App (void); 38iGmCerts * certs_App (void);
35iVisited * visited_App (void); 39iVisited * visited_App (void);
diff --git a/src/gmdocument.c b/src/gmdocument.c
index 52ff1654..c943dfe9 100644
--- a/src/gmdocument.c
+++ b/src/gmdocument.c
@@ -574,6 +574,7 @@ void reset_GmDocument(iGmDocument *d) {
574} 574}
575 575
576void setThemeSeed_GmDocument(iGmDocument *d, const iBlock *seed) { 576void setThemeSeed_GmDocument(iGmDocument *d, const iBlock *seed) {
577 const iBool isLightMode = (colorTheme_App() == light_ColorTheme);
577 static const iChar siteIcons[] = { 578 static const iChar siteIcons[] = {
578 0x203b, 0x2042, 0x205c, 0x2182, 0x25ed, 0x2600, 0x2601, 0x2604, 0x2605, 0x2606, 579 0x203b, 0x2042, 0x205c, 0x2182, 0x25ed, 0x2600, 0x2601, 0x2604, 0x2605, 0x2606,
579 0x265c, 0x265e, 0x2690, 0x2691, 0x2693, 0x2698, 0x2699, 0x26f0, 0x270e, 0x2728, 580 0x265c, 0x265e, 0x2690, 0x2691, 0x2693, 0x2698, 0x2699, 0x26f0, 0x270e, 0x2728,
@@ -585,19 +586,36 @@ void setThemeSeed_GmDocument(iGmDocument *d, const iBlock *seed) {
585 d->themeSeed = 0; 586 d->themeSeed = 0;
586 d->siteIcon = 0; 587 d->siteIcon = 0;
587 /* Default colors. */ { 588 /* Default colors. */ {
588 const iHSLColor base = { 0, 0, 0.15f, 1.0f }; 589 if (!isLightMode) {
589 setHsl_Color(tmBackground_ColorId, base); 590 const iHSLColor base = { 0, 0, 0.15f, 1.0f };
590 set_Color(tmParagraph_ColorId, get_Color(gray75_ColorId)); 591 setHsl_Color(tmBackground_ColorId, base);
591 setHsl_Color(tmFirstParagraph_ColorId, addSatLum_HSLColor(base, 0, 0.75f)); 592 set_Color(tmParagraph_ColorId, get_Color(gray75_ColorId));
592 set_Color(tmQuote_ColorId, get_Color(cyan_ColorId)); 593 setHsl_Color(tmFirstParagraph_ColorId, addSatLum_HSLColor(base, 0, 0.75f));
593 set_Color(tmPreformatted_ColorId, get_Color(cyan_ColorId)); 594 set_Color(tmQuote_ColorId, get_Color(cyan_ColorId));
594 set_Color(tmHeading1_ColorId, get_Color(white_ColorId)); 595 set_Color(tmPreformatted_ColorId, get_Color(cyan_ColorId));
595 setHsl_Color(tmHeading2_ColorId, addSatLum_HSLColor(base, 0, 0.7f)); 596 set_Color(tmHeading1_ColorId, get_Color(white_ColorId));
596 setHsl_Color(tmHeading3_ColorId, addSatLum_HSLColor(base, 0, 0.6f)); 597 setHsl_Color(tmHeading2_ColorId, addSatLum_HSLColor(base, 0, 0.7f));
597 set_Color(tmBannerBackground_ColorId, get_Color(black_ColorId)); 598 setHsl_Color(tmHeading3_ColorId, addSatLum_HSLColor(base, 0, 0.6f));
598 set_Color(tmBannerTitle_ColorId, get_Color(white_ColorId)); 599 set_Color(tmBannerBackground_ColorId, get_Color(black_ColorId));
599 set_Color(tmBannerIcon_ColorId, get_Color(orange_ColorId)); 600 set_Color(tmBannerTitle_ColorId, get_Color(white_ColorId));
600 set_Color(tmInlineContentMetadata_ColorId, get_Color(cyan_ColorId)); 601 set_Color(tmBannerIcon_ColorId, get_Color(orange_ColorId));
602 set_Color(tmInlineContentMetadata_ColorId, get_Color(cyan_ColorId));
603 }
604 else {
605 const iHSLColor base = { 0, 0, 1.0f, 1.0f };
606 setHsl_Color(tmBackground_ColorId, base);
607 set_Color(tmParagraph_ColorId, get_Color(gray25_ColorId));
608 set_Color(tmFirstParagraph_ColorId, get_Color(black_ColorId));
609 set_Color(tmQuote_ColorId, get_Color(brown_ColorId));
610 set_Color(tmPreformatted_ColorId, get_Color(brown_ColorId));
611 set_Color(tmHeading1_ColorId, get_Color(black_ColorId));
612 setHsl_Color(tmHeading2_ColorId, addSatLum_HSLColor(base, 0, -0.7f));
613 setHsl_Color(tmHeading3_ColorId, addSatLum_HSLColor(base, 0, -0.6f));
614 set_Color(tmBannerBackground_ColorId, get_Color(white_ColorId));
615 set_Color(tmBannerTitle_ColorId, get_Color(gray50_ColorId));
616 set_Color(tmBannerIcon_ColorId, get_Color(teal_ColorId));
617 set_Color(tmInlineContentMetadata_ColorId, get_Color(brown_ColorId));
618 }
601 set_Color(tmBadLink_ColorId, get_Color(red_ColorId)); 619 set_Color(tmBadLink_ColorId, get_Color(red_ColorId));
602 set_Color(tmLinkText_ColorId, get_Color(white_ColorId)); 620 set_Color(tmLinkText_ColorId, get_Color(white_ColorId));
603 set_Color(tmLinkIcon_ColorId, get_Color(cyan_ColorId)); 621 set_Color(tmLinkIcon_ColorId, get_Color(cyan_ColorId));
@@ -639,17 +657,17 @@ void setThemeSeed_GmDocument(iGmDocument *d, const iBlock *seed) {
639 { 8, 9 }, /* violet */ 657 { 8, 9 }, /* violet */
640 { 7, 8 }, /* pink */ 658 { 7, 8 }, /* pink */
641 }; 659 };
642 const float saturationLevel = 1.0f; /* TODO: user setting */ 660 const float saturationLevel = 1.0f; /* TODO: user setting */
643 const iBool isLightMode = iFalse; /* TODO: user setting */ 661 const iBool isBannerLighter = (d->themeSeed & 0x4000) != 0;
644 const iBool isBannerLighter = (d->themeSeed & 0x4000) != 0;
645 const size_t primIndex = (d->themeSeed & 0xff) % iElemCount(hues); 662 const size_t primIndex = (d->themeSeed & 0xff) % iElemCount(hues);
646 const iBool isDarkBgSat = (d->themeSeed & 0x200000) != 0 && (primIndex < 1 || primIndex > 4); 663 const iBool isDarkBgSat =
647 iHSLColor base = { hues[primIndex], 664 (d->themeSeed & 0x200000) != 0 && (primIndex < 1 || primIndex > 4);
665 iHSLColor base = { hues[primIndex],
648 0.8f * (d->themeSeed >> 24) / 255.0f, 666 0.8f * (d->themeSeed >> 24) / 255.0f,
649 0.06f + 0.09f * ((d->themeSeed >> 5) & 0x7) / 7.0f, 667 0.06f + 0.09f * ((d->themeSeed >> 5) & 0x7) / 7.0f,
650 1.0f }; 668 1.0f };
651// printf("background: %d %f %f\n", (int) base.hue, base.sat, base.lum); 669 // printf("background: %d %f %f\n", (int) base.hue, base.sat, base.lum);
652// printf("isDarkBgSat: %d\n", isDarkBgSat); 670 // printf("isDarkBgSat: %d\n", isDarkBgSat);
653 setHsl_Color(tmBackground_ColorId, base); 671 setHsl_Color(tmBackground_ColorId, base);
654 672
655 setHsl_Color(tmBannerBackground_ColorId, addSatLum_HSLColor(base, 0.1f, 0.04f * (isBannerLighter ? 1 : -1))); 673 setHsl_Color(tmBannerBackground_ColorId, addSatLum_HSLColor(base, 0.1f, 0.04f * (isBannerLighter ? 1 : -1)));
diff --git a/src/ui/color.c b/src/ui/color.c
index a2ff6e27..b9470084 100644
--- a/src/ui/color.c
+++ b/src/ui/color.c
@@ -4,24 +4,134 @@
4 4
5static const iColor transparent_; 5static const iColor transparent_;
6 6
7static iColor palette_[max_ColorId] = { 7static const iColor darkPalette_[] = {
8 { 0, 0, 0, 255 }, 8 { 0, 0, 0, 255 },
9 { 40, 40, 40, 255 }, 9 { 40, 40, 40, 255 },
10 { 80, 80, 80, 255 }, 10 { 80, 80, 80, 255 },
11 { 160, 160, 160, 255 }, 11 { 160, 160, 160, 255 },
12 { 255, 255, 255, 255 }, 12 { 255, 255, 255, 255 },
13
13 { 106, 80, 0, 255 }, 14 { 106, 80, 0, 255 },
14 { 255, 192, 0, 255 }, 15 { 255, 192, 0, 255 },
15 { 0, 96, 128, 255 }, 16 { 0, 96, 128, 255 },
16 { 0, 192, 255, 255 }, 17 { 0, 192, 255, 255 },
18
17 { 255, 255, 32, 255 }, 19 { 255, 255, 32, 255 },
18 { 255, 64, 64, 255 }, 20 { 255, 64, 64, 255 },
19 { 255, 0, 255, 255 }, 21 { 255, 0, 255, 255 },
20 { 132, 132, 255, 255 }, 22 { 132, 132, 255, 255 },
21 { 0, 200, 0, 255 }, 23 { 0, 200, 0, 255 },
22 /* theme colors left black until theme is seeded */
23}; 24};
24 25
26static const iColor lightPalette_[] = {
27 { 0, 0, 0, 255 },
28 { 75, 75, 75, 255 },
29 { 150, 150, 150, 255 },
30 { 235, 235, 235, 255 },
31 { 255, 255, 255, 255 },
32
33 { 170, 128, 0, 255 },
34 { 255, 213, 86, 255 },
35 { 0, 96, 128, 255 },
36 { 86, 213, 255, 255 },
37
38 { 255, 255, 32, 255 },
39 { 255, 64, 64, 255 },
40 { 255, 0, 255, 255 },
41 { 132, 132, 255, 255 },
42 { 0, 150, 0, 255 },
43};
44
45static iColor palette_[max_ColorId];
46
47iLocalDef void copy_(enum iColorId dst, enum iColorId src) {
48 set_Color(dst, get_Color(src));
49}
50
51void setThemePalette_Color(enum iColorTheme theme) {
52 memcpy(palette_, theme == dark_ColorTheme ? darkPalette_ : lightPalette_, sizeof(darkPalette_));
53 switch (theme) {
54 default:
55 case dark_ColorTheme:
56 copy_(uiBackground_ColorId, gray25_ColorId);
57 copy_(uiBackgroundHover_ColorId, gray25_ColorId);
58 copy_(uiBackgroundPressed_ColorId, orange_ColorId);
59 copy_(uiBackgroundSelected_ColorId, teal_ColorId);
60 copy_(uiBackgroundFramelessHover_ColorId, teal_ColorId);
61 copy_(uiText_ColorId, gray75_ColorId);
62 copy_(uiTextPressed_ColorId, black_ColorId);
63 copy_(uiTextStrong_ColorId, white_ColorId);
64 copy_(uiTextSelected_ColorId, white_ColorId);
65 copy_(uiTextFramelessHover_ColorId, white_ColorId);
66 copy_(uiTextShortcut_ColorId, cyan_ColorId);
67 copy_(uiTextAction_ColorId, cyan_ColorId);
68 copy_(uiTextCaution_ColorId, orange_ColorId);
69 copy_(uiFrame_ColorId, gray25_ColorId);
70 copy_(uiEmboss1_ColorId, gray50_ColorId);
71 copy_(uiEmboss2_ColorId, black_ColorId);
72 copy_(uiEmbossHover1_ColorId, cyan_ColorId);
73 copy_(uiEmbossHover2_ColorId, teal_ColorId);
74 copy_(uiEmbossPressed1_ColorId, brown_ColorId);
75 copy_(uiEmbossPressed2_ColorId, white_ColorId);
76 copy_(uiEmbossSelected1_ColorId, cyan_ColorId);
77 copy_(uiEmbossSelected2_ColorId, black_ColorId);
78 copy_(uiEmbossSelectedHover1_ColorId, white_ColorId);
79 copy_(uiEmbossSelectedHover2_ColorId, cyan_ColorId);
80 copy_(uiInputBackground_ColorId, black_ColorId);
81 copy_(uiInputBackgroundFocused_ColorId, black_ColorId);
82 copy_(uiInputText_ColorId, gray75_ColorId);
83 copy_(uiInputTextFocused_ColorId, white_ColorId);
84 copy_(uiInputFrame_ColorId, gray50_ColorId);
85 copy_(uiInputFrameHover_ColorId, cyan_ColorId);
86 copy_(uiInputFrameFocused_ColorId, orange_ColorId);
87 copy_(uiInputCursor_ColorId, orange_ColorId);
88 copy_(uiInputCursorText_ColorId, black_ColorId);
89 copy_(uiHeading_ColorId, cyan_ColorId);
90 copy_(uiIcon_ColorId, cyan_ColorId);
91 copy_(uiSeparator_ColorId, black_ColorId);
92 break;
93 case light_ColorTheme:
94 copy_(uiBackground_ColorId, white_ColorId);
95 copy_(uiBackgroundHover_ColorId, gray75_ColorId);
96 copy_(uiBackgroundSelected_ColorId, orange_ColorId);
97 copy_(uiBackgroundPressed_ColorId, cyan_ColorId);
98 copy_(uiBackgroundFramelessHover_ColorId, orange_ColorId);
99 copy_(uiText_ColorId, gray25_ColorId);
100 copy_(uiTextStrong_ColorId, black_ColorId);
101 copy_(uiTextPressed_ColorId, black_ColorId);
102 copy_(uiTextStrong_ColorId, black_ColorId);
103 copy_(uiTextSelected_ColorId, black_ColorId);
104 copy_(uiTextFramelessHover_ColorId, black_ColorId);
105 copy_(uiTextShortcut_ColorId, brown_ColorId);
106 copy_(uiTextAction_ColorId, brown_ColorId);
107 copy_(uiTextCaution_ColorId, teal_ColorId);
108 copy_(uiFrame_ColorId, gray75_ColorId);
109 copy_(uiEmboss1_ColorId, white_ColorId);
110 copy_(uiEmboss2_ColorId, white_ColorId);
111 copy_(uiEmbossHover1_ColorId, gray25_ColorId);
112 copy_(uiEmbossHover2_ColorId, gray25_ColorId);
113 copy_(uiEmbossPressed1_ColorId, black_ColorId);
114 copy_(uiEmbossPressed2_ColorId, teal_ColorId);
115 copy_(uiEmbossSelected1_ColorId, white_ColorId);
116 copy_(uiEmbossSelected2_ColorId, brown_ColorId);
117 copy_(uiEmbossSelectedHover1_ColorId, gray50_ColorId);
118 copy_(uiEmbossSelectedHover2_ColorId, gray50_ColorId);
119 copy_(uiInputBackground_ColorId, white_ColorId);
120 copy_(uiInputBackgroundFocused_ColorId, white_ColorId);
121 copy_(uiInputText_ColorId, gray25_ColorId);
122 copy_(uiInputTextFocused_ColorId, black_ColorId);
123 copy_(uiInputFrame_ColorId, gray50_ColorId);
124 copy_(uiInputFrameHover_ColorId, brown_ColorId);
125 copy_(uiInputFrameFocused_ColorId, teal_ColorId);
126 copy_(uiInputCursor_ColorId, teal_ColorId);
127 copy_(uiInputCursorText_ColorId, white_ColorId);
128 copy_(uiHeading_ColorId, brown_ColorId);
129 copy_(uiIcon_ColorId, brown_ColorId);
130 copy_(uiSeparator_ColorId, gray50_ColorId);
131 break;
132 }
133}
134
25iColor get_Color(int color) { 135iColor get_Color(int color) {
26 const iColor *rgba = &transparent_; 136 const iColor *rgba = &transparent_;
27 if (color >= 0 && color < max_ColorId) { 137 if (color >= 0 && color < max_ColorId) {
@@ -31,11 +141,35 @@ iColor get_Color(int color) {
31} 141}
32 142
33void set_Color(int color, iColor rgba) { 143void set_Color(int color, iColor rgba) {
34 if (color >= tmFirst_ColorId && color < max_ColorId) { 144 if (color >= uiBackground_ColorId && color < max_ColorId) {
35 palette_[color] = rgba; 145 palette_[color] = rgba;
36 } 146 }
37} 147}
38 148
149iLocalDef iBool equal_Color_(const iColor *x, const iColor *y) {
150 return memcmp(x, y, sizeof(iColor)) == 0;
151}
152
153int darker_Color(int color) {
154 const iColor rgb = get_Color(color);
155 for (int i = 0; i < uiFirst_ColorId; i++) {
156 if (equal_Color_(&rgb, &palette_[i])) {
157 return i > 0 ? i - 1 : i;
158 }
159 }
160 return color;
161}
162
163int lighter_Color(int color) {
164 const iColor rgb = get_Color(color);
165 for (int i = 0; i < uiFirst_ColorId; i++) {
166 if (equal_Color_(&rgb, &palette_[i])) {
167 return i < uiFirst_ColorId - 1 ? i + 1 : i;
168 }
169 }
170 return color;
171}
172
39iLocalDef iFloat4 normalize_(iColor d) { 173iLocalDef iFloat4 normalize_(iColor d) {
40 return divf_F4(init_F4(d.r, d.g, d.b, d.a), 255.0f); 174 return divf_F4(init_F4(d.r, d.g, d.b, d.a), 255.0f);
41} 175}
diff --git a/src/ui/color.h b/src/ui/color.h
index 6444ad03..77cbac09 100644
--- a/src/ui/color.h
+++ b/src/ui/color.h
@@ -3,8 +3,15 @@
3#include <the_Foundation/range.h> 3#include <the_Foundation/range.h>
4#include <the_Foundation/math.h> 4#include <the_Foundation/math.h>
5 5
6enum iColorTheme {
7 dark_ColorTheme,
8 light_ColorTheme,
9 max_ColorTheme
10};
11
6enum iColorId { 12enum iColorId {
7 none_ColorId = -1, 13 none_ColorId = -1,
14
8 black_ColorId, 15 black_ColorId,
9 gray25_ColorId, 16 gray25_ColorId,
10 gray50_ColorId, 17 gray50_ColorId,
@@ -20,6 +27,46 @@ enum iColorId {
20 blue_ColorId, 27 blue_ColorId,
21 green_ColorId, 28 green_ColorId,
22 29
30 /* user interface colors for semantic use */
31 uiFirst_ColorId,
32 uiBackground_ColorId = uiFirst_ColorId,
33 uiBackgroundHover_ColorId,
34 uiBackgroundPressed_ColorId,
35 uiBackgroundSelected_ColorId,
36 uiBackgroundFramelessHover_ColorId,
37 uiText_ColorId,
38 uiTextPressed_ColorId,
39 uiTextSelected_ColorId,
40 uiTextFramelessHover_ColorId,
41 uiTextFramelessSelected_ColorId,
42 uiTextStrong_ColorId,
43 uiTextShortcut_ColorId,
44 uiTextAction_ColorId,
45 uiTextCaution_ColorId,
46 uiFrame_ColorId,
47 uiEmboss1_ColorId,
48 uiEmboss2_ColorId,
49 uiEmbossHover1_ColorId,
50 uiEmbossHover2_ColorId,
51 uiEmbossPressed1_ColorId,
52 uiEmbossPressed2_ColorId,
53 uiEmbossSelected1_ColorId,
54 uiEmbossSelected2_ColorId,
55 uiEmbossSelectedHover1_ColorId,
56 uiEmbossSelectedHover2_ColorId,
57 uiInputBackground_ColorId,
58 uiInputBackgroundFocused_ColorId,
59 uiInputText_ColorId,
60 uiInputTextFocused_ColorId,
61 uiInputFrame_ColorId,
62 uiInputFrameHover_ColorId,
63 uiInputFrameFocused_ColorId,
64 uiInputCursor_ColorId,
65 uiInputCursorText_ColorId,
66 uiHeading_ColorId,
67 uiIcon_ColorId,
68 uiSeparator_ColorId,
69
23 /* content theme colors */ 70 /* content theme colors */
24 tmFirst_ColorId, 71 tmFirst_ColorId,
25 tmBackground_ColorId = tmFirst_ColorId, 72 tmBackground_ColorId = tmFirst_ColorId,
@@ -77,23 +124,27 @@ iLocalDef iBool isRegularText_ColorId(enum iColorId d) {
77 return isLinkText_ColorId(d) || d == tmParagraph_ColorId || d == tmFirstParagraph_ColorId; 124 return isLinkText_ColorId(d) || d == tmParagraph_ColorId || d == tmFirstParagraph_ColorId;
78} 125}
79 126
80#define mask_ColorId 0x3f 127#define mask_ColorId 0x7f
81#define permanent_ColorId 0x80 /* cannot be changed via escapes */ 128#define permanent_ColorId 0x80 /* cannot be changed via escapes */
82 129
83#define black_ColorEscape "\r0" 130#define black_ColorEscape "\r0"
84#define gray25_ColorEscape "\r1" 131#define gray25_ColorEscape "\r1"
85#define gray50_ColorEscape "\r2" 132#define gray50_ColorEscape "\r2"
86#define gray75_ColorEscape "\r3" 133#define gray75_ColorEscape "\r3"
87#define white_ColorEscape "\r4" 134#define white_ColorEscape "\r4"
88#define brown_ColorEscape "\r5" 135#define brown_ColorEscape "\r5"
89#define orange_ColorEscape "\r6" 136#define orange_ColorEscape "\r6"
90#define teal_ColorEscape "\r7" 137#define teal_ColorEscape "\r7"
91#define cyan_ColorEscape "\r8" 138#define cyan_ColorEscape "\r8"
92#define yellow_ColorEscape "\r9" 139#define yellow_ColorEscape "\r9"
93#define red_ColorEscape "\r:" 140#define red_ColorEscape "\r:"
94#define magenta_ColorEscape "\r;" 141#define magenta_ColorEscape "\r;"
95#define blue_ColorEscape "\r<" 142#define blue_ColorEscape "\r<"
96#define green_ColorEscape "\r=" 143#define green_ColorEscape "\r="
144#define uiText_ColorEscape "\rC"
145#define uiTextAction_ColorEscape "\rJ"
146#define uiTextCaution_ColorEscape "\rK"
147#define uiHeading_ColorEscape "\r`"
97 148
98iDeclareType(Color) 149iDeclareType(Color)
99iDeclareType(HSLColor) 150iDeclareType(HSLColor)
@@ -114,11 +165,15 @@ iHSLColor setLum_HSLColor (iHSLColor, float lum);
114iHSLColor addSatLum_HSLColor (iHSLColor, float sat, float lum); 165iHSLColor addSatLum_HSLColor (iHSLColor, float sat, float lum);
115 166
116iColor get_Color (int color); 167iColor get_Color (int color);
168int darker_Color (int color);
169int lighter_Color (int color);
117void set_Color (int color, iColor rgba); 170void set_Color (int color, iColor rgba);
118 171
119iLocalDef void setHsl_Color(int color, iHSLColor hsl) { 172iLocalDef void setHsl_Color(int color, iHSLColor hsl) {
120 set_Color(color, rgb_HSLColor(hsl)); 173 set_Color(color, rgb_HSLColor(hsl));
121} 174}
122 175
176void setThemePalette_Color (enum iColorTheme theme);
177
123iColor ansi_Color (iRangecc escapeSequence, int fallback); 178iColor ansi_Color (iRangecc escapeSequence, int fallback);
124const char * escape_Color (int color); 179const char * escape_Color (int color);
diff --git a/src/ui/documentwidget.c b/src/ui/documentwidget.c
index 891e7650..ae828367 100644
--- a/src/ui/documentwidget.c
+++ b/src/ui/documentwidget.c
@@ -329,7 +329,7 @@ const iString *bookmarkTitle_DocumentWidget(const iDocumentWidget *d) {
329 if (!isEmpty_String(d->titleUser)) { 329 if (!isEmpty_String(d->titleUser)) {
330 pushBack_StringArray(title, d->titleUser); 330 pushBack_StringArray(title, d->titleUser);
331 } 331 }
332 else { 332 if (isEmpty_StringArray(title)) {
333 iUrl parts; 333 iUrl parts;
334 init_Url(&parts, d->mod.url); 334 init_Url(&parts, d->mod.url);
335 if (!isEmpty_Range(&parts.host)) { 335 if (!isEmpty_Range(&parts.host)) {
@@ -693,11 +693,11 @@ static void checkResponse_DocumentWidget_(iDocumentWidget *d) {
693 iWidget *dlg = makeValueInput_Widget( 693 iWidget *dlg = makeValueInput_Widget(
694 as_Widget(d), 694 as_Widget(d),
695 NULL, 695 NULL,
696 format_CStr(cyan_ColorEscape "%s", cstr_Rangecc(parts.host)), 696 format_CStr(uiHeading_ColorEscape "%s", cstr_Rangecc(parts.host)),
697 isEmpty_String(meta_GmRequest(d->request)) 697 isEmpty_String(meta_GmRequest(d->request))
698 ? format_CStr("Please enter input for %s:", cstr_Rangecc(parts.path)) 698 ? format_CStr("Please enter input for %s:", cstr_Rangecc(parts.path))
699 : cstr_String(meta_GmRequest(d->request)), 699 : cstr_String(meta_GmRequest(d->request)),
700 orange_ColorEscape "Send \u21d2", 700 uiTextCaution_ColorEscape "Send \u21d2",
701 "document.input.submit"); 701 "document.input.submit");
702 setSensitive_InputWidget(findChild_Widget(dlg, "input"), 702 setSensitive_InputWidget(findChild_Widget(dlg, "input"),
703 statusCode == sensitiveInput_GmStatusCode); 703 statusCode == sensitiveInput_GmStatusCode);
@@ -834,7 +834,7 @@ static iBool handleMediaCommand_DocumentWidget_(iDocumentWidget *d, const char *
834 } 834 }
835 else { 835 else {
836 const iGmError *err = get_GmError(code); 836 const iGmError *err = get_GmError(code);
837 makeMessage_Widget(format_CStr(orange_ColorEscape "%s", err->title), err->info); 837 makeMessage_Widget(format_CStr(uiTextCaution_ColorEscape "%s", err->title), err->info);
838 removeMediaRequest_DocumentWidget_(d, req->linkId); 838 removeMediaRequest_DocumentWidget_(d, req->linkId);
839 } 839 }
840 return iTrue; 840 return iTrue;
@@ -864,6 +864,9 @@ static iBool handleCommand_DocumentWidget_(iDocumentWidget *d, const char *cmd)
864 refresh_Widget(w); 864 refresh_Widget(w);
865 updateWindowTitle_DocumentWidget_(d); 865 updateWindowTitle_DocumentWidget_(d);
866 } 866 }
867 else if (equal_Command(cmd, "theme.changed")) {
868 updateTheme_DocumentWidget_(d);
869 }
867 else if (equal_Command(cmd, "tabs.changed")) { 870 else if (equal_Command(cmd, "tabs.changed")) {
868 if (cmp_String(id_Widget(w), suffixPtr_Command(cmd, "id")) == 0) { 871 if (cmp_String(id_Widget(w), suffixPtr_Command(cmd, "id")) == 0) {
869 /* Set palette for our document. */ 872 /* Set palette for our document. */
@@ -879,18 +882,18 @@ static iBool handleCommand_DocumentWidget_(iDocumentWidget *d, const char *cmd)
879 const char *unchecked = red_ColorEscape "\u2610"; 882 const char *unchecked = red_ColorEscape "\u2610";
880 const char *checked = green_ColorEscape "\u2611"; 883 const char *checked = green_ColorEscape "\u2611";
881 makeMessage_Widget( 884 makeMessage_Widget(
882 cyan_ColorEscape "CERTIFICATE STATUS", 885 uiHeading_ColorEscape "CERTIFICATE STATUS",
883 format_CStr("%s%s Domain name %s%s\n" 886 format_CStr("%s%s Domain name %s%s\n"
884 "%s%s %s (%04d-%02d-%02d %02d:%02d:%02d)\n" 887 "%s%s %s (%04d-%02d-%02d %02d:%02d:%02d)\n"
885 "%s%s %s", 888 "%s%s %s",
886 d->certFlags & domainVerified_GmCertFlag ? checked : unchecked, 889 d->certFlags & domainVerified_GmCertFlag ? checked : unchecked,
887 gray75_ColorEscape, 890 uiText_ColorEscape,
888 d->certFlags & domainVerified_GmCertFlag ? "matches" : "mismatch", 891 d->certFlags & domainVerified_GmCertFlag ? "matches" : "mismatch",
889 ~d->certFlags & domainVerified_GmCertFlag 892 ~d->certFlags & domainVerified_GmCertFlag
890 ? format_CStr(" (%s)", cstr_String(d->certSubject)) 893 ? format_CStr(" (%s)", cstr_String(d->certSubject))
891 : "", 894 : "",
892 d->certFlags & timeVerified_GmCertFlag ? checked : unchecked, 895 d->certFlags & timeVerified_GmCertFlag ? checked : unchecked,
893 gray75_ColorEscape, 896 uiText_ColorEscape,
894 d->certFlags & timeVerified_GmCertFlag ? "Not expired" : "Expired", 897 d->certFlags & timeVerified_GmCertFlag ? "Not expired" : "Expired",
895 d->certExpiry.year, 898 d->certExpiry.year,
896 d->certExpiry.month, 899 d->certExpiry.month,
@@ -899,7 +902,7 @@ static iBool handleCommand_DocumentWidget_(iDocumentWidget *d, const char *cmd)
899 d->certExpiry.minute, 902 d->certExpiry.minute,
900 d->certExpiry.second, 903 d->certExpiry.second,
901 d->certFlags & trusted_GmCertFlag ? checked : unchecked, 904 d->certFlags & trusted_GmCertFlag ? checked : unchecked,
902 gray75_ColorEscape, 905 uiText_ColorEscape,
903 d->certFlags & trusted_GmCertFlag ? "Trusted on first use" 906 d->certFlags & trusted_GmCertFlag ? "Trusted on first use"
904 : "Not trusted")); 907 : "Not trusted"));
905 return iTrue; 908 return iTrue;
@@ -1409,7 +1412,7 @@ static void drawRun_DrawContext_(void *context, const iGmRun *run) {
1409 if (tx + textSize.x > right_Rect(d->widgetBounds)) { 1412 if (tx + textSize.x > right_Rect(d->widgetBounds)) {
1410 tx = right_Rect(d->widgetBounds) - textSize.x; 1413 tx = right_Rect(d->widgetBounds) - textSize.x;
1411 fillRect_Paint(&d->paint, (iRect){ init_I2(tx, top_Rect(linkRect)), textSize }, 1414 fillRect_Paint(&d->paint, (iRect){ init_I2(tx, top_Rect(linkRect)), textSize },
1412 black_ColorId); 1415 uiBackground_ColorId);
1413 msg += 4; /* skip the space and dash */ 1416 msg += 4; /* skip the space and dash */
1414 tx += measure_Text(metaFont, " \u2014").x / 2; 1417 tx += measure_Text(metaFont, " \u2014").x / 2;
1415 } 1418 }
diff --git a/src/ui/inputwidget.c b/src/ui/inputwidget.c
index 305b8c9b..66e2af0a 100644
--- a/src/ui/inputwidget.c
+++ b/src/ui/inputwidget.c
@@ -1,6 +1,7 @@
1#include "inputwidget.h" 1#include "inputwidget.h"
2#include "paint.h" 2#include "paint.h"
3#include "util.h" 3#include "util.h"
4#include "app.h"
4 5
5#include <the_Foundation/array.h> 6#include <the_Foundation/array.h>
6#include <SDL_clipboard.h> 7#include <SDL_clipboard.h>
@@ -291,13 +292,13 @@ static iBool processEvent_InputWidget_(iInputWidget *d, const SDL_Event *ev) {
291static const iChar sensitiveChar_ = 0x25cf; /* black circle */ 292static const iChar sensitiveChar_ = 0x25cf; /* black circle */
292 293
293static void draw_InputWidget_(const iInputWidget *d) { 294static void draw_InputWidget_(const iInputWidget *d) {
294 const iWidget *w = constAs_Widget(d); 295 const iWidget *w = constAs_Widget(d);
295 const uint32_t time = frameTime_Window(get_Window()); 296 const uint32_t time = frameTime_Window(get_Window());
296 const iInt2 padding = init_I2(gap_UI / 2, gap_UI / 2); 297 const iInt2 padding = init_I2(gap_UI / 2, gap_UI / 2);
297 iRect bounds = adjusted_Rect(bounds_Widget(w), padding, neg_I2(padding)); 298 iRect bounds = adjusted_Rect(bounds_Widget(w), padding, neg_I2(padding));
298 const iBool isFocused = isFocused_Widget(w); 299 const iBool isFocused = isFocused_Widget(w);
299 const iBool isHover = isHover_Widget(w) && 300 const iBool isHover = isHover_Widget(w) &&
300 contains_Widget(w, mouseCoord_Window(get_Window())); 301 contains_Widget(w, mouseCoord_Window(get_Window()));
301 iPaint p; 302 iPaint p;
302 init_Paint(&p); 303 init_Paint(&p);
303 iString text; 304 iString text;
@@ -310,10 +311,13 @@ static void draw_InputWidget_(const iInputWidget *d) {
310 appendChar_String(&text, sensitiveChar_); 311 appendChar_String(&text, sensitiveChar_);
311 } 312 }
312 } 313 }
313 fillRect_Paint(&p, bounds, black_ColorId); 314 fillRect_Paint(
314 drawRect_Paint(&p, 315 &p, bounds, isFocused ? uiInputBackgroundFocused_ColorId : uiInputBackground_ColorId);
315 adjusted_Rect(bounds, neg_I2(one_I2()), zero_I2()), 316 drawRectThickness_Paint(&p,
316 isFocused ? orange_ColorId : isHover ? cyan_ColorId : gray50_ColorId); 317 adjusted_Rect(bounds, neg_I2(one_I2()), zero_I2()),
318 isFocused ? gap_UI / 4 : 1,
319 isFocused ? uiInputFrameFocused_ColorId
320 : isHover ? uiInputFrameHover_ColorId : uiInputFrame_ColorId);
317 setClip_Paint(&p, bounds); 321 setClip_Paint(&p, bounds);
318 shrink_Rect(&bounds, init_I2(gap_UI * (flags_Widget(w) & tight_WidgetFlag ? 1 : 2), 0)); 322 shrink_Rect(&bounds, init_I2(gap_UI * (flags_Widget(w) & tight_WidgetFlag ? 1 : 2), 0));
319 const iInt2 emSize = advance_Text(d->font, "M"); 323 const iInt2 emSize = advance_Text(d->font, "M");
@@ -332,7 +336,7 @@ static void draw_InputWidget_(const iInputWidget *d) {
332 const int yOff = (height_Rect(bounds) - lineHeight_Text(d->font)) / 2; 336 const int yOff = (height_Rect(bounds) - lineHeight_Text(d->font)) / 2;
333 draw_Text(d->font, 337 draw_Text(d->font,
334 add_I2(topLeft_Rect(bounds), init_I2(xOff, yOff)), 338 add_I2(topLeft_Rect(bounds), init_I2(xOff, yOff)),
335 white_ColorId, 339 isFocused ? uiInputTextFocused_ColorId : uiInputText_ColorId,
336 "%s", 340 "%s",
337 cstr_String(&text)); 341 cstr_String(&text));
338 unsetClip_Paint(&p); 342 unsetClip_Paint(&p);
@@ -354,8 +358,8 @@ static void draw_InputWidget_(const iInputWidget *d) {
354 else { 358 else {
355 initCStr_String(&cur, " "); 359 initCStr_String(&cur, " ");
356 } 360 }
357 fillRect_Paint(&p, curRect, orange_ColorId); 361 fillRect_Paint(&p, curRect, uiInputCursor_ColorId);
358 draw_Text(d->font, curPos, black_ColorId, cstr_String(&cur)); 362 draw_Text(d->font, curPos, uiInputCursorText_ColorId, cstr_String(&cur));
359 deinit_String(&cur); 363 deinit_String(&cur);
360 } 364 }
361 deinit_String(&text); 365 deinit_String(&text);
diff --git a/src/ui/labelwidget.c b/src/ui/labelwidget.c
index 0c9269d1..62eb9853 100644
--- a/src/ui/labelwidget.c
+++ b/src/ui/labelwidget.c
@@ -122,60 +122,79 @@ static void keyStr_LabelWidget_(const iLabelWidget *d, iString *str) {
122 } 122 }
123} 123}
124 124
125static void draw_LabelWidget_(const iLabelWidget *d) { 125static void getColors_LabelWidget_(const iLabelWidget *d, int *bg, int *fg, int *frame1, int *frame2) {
126 const iWidget *w = constAs_Widget(d); 126 const iWidget *w = constAs_Widget(d);
127 draw_Widget(w); 127 const iBool isPress = (flags_Widget(w) & pressed_WidgetFlag) != 0;
128 const iBool isButton = d->click.button != 0; 128 const iBool isSel = (flags_Widget(w) & selected_WidgetFlag) != 0;
129 const int flags = flags_Widget(w); 129 const iBool isFrameless = (flags_Widget(w) & frameless_WidgetFlag) != 0;
130 const iRect bounds = bounds_Widget(w); 130 const iBool isButton = d->click.button != 0;
131 iRect rect = bounds; 131 /* Default color state. */
132 if (isButton) { 132 *bg = isButton ? uiBackground_ColorId : none_ColorId;
133 shrink_Rect(&rect, divi_I2(gap2_UI, 4)); 133 *fg = uiText_ColorId;
134 adjustEdges_Rect(&rect, gap_UI / 8, 0, -gap_UI / 8, 0); 134 *frame1 = isButton ? uiEmboss1_ColorId : uiFrame_ColorId;
135 } 135 *frame2 = isButton ? uiEmboss2_ColorId : *frame1;
136 iPaint p; 136 if (isSel) {
137 init_Paint(&p); 137 *bg = uiBackgroundSelected_ColorId;
138 int bg = 0; 138 *fg = uiTextSelected_ColorId;
139 int fg = gray75_ColorId; 139 if (isButton) {
140 int frame = isButton ? gray50_ColorId : gray25_ColorId; 140 *frame1 = uiEmbossSelected1_ColorId;
141 int frame2 = isButton ? black_ColorId : frame; 141 *frame2 = uiEmbossSelected2_ColorId;
142 if (flags & selected_WidgetFlag) { 142 }
143 bg = teal_ColorId;
144 fg = white_ColorId;
145 frame = isButton ? cyan_ColorId : frame;
146 } 143 }
147 if (isHover_Widget(w)) { 144 if (isHover_Widget(w)) {
148 if (flags & frameless_WidgetFlag) { 145 if (isFrameless) {
149 bg = teal_ColorId; 146 *bg = uiBackgroundFramelessHover_ColorId;
150 fg = white_ColorId; 147 *fg = uiTextFramelessHover_ColorId;
151 if (isButton && flags & selected_WidgetFlag) frame = white_ColorId;
152 } 148 }
153 else { 149 else {
154 if (frame != cyan_ColorId) { 150 /* Frames matching color escaped text. */
155 if (startsWith_String(&d->label, orange_ColorEscape)) { 151 if (startsWith_String(&d->label, "\r")) {
156 frame = orange_ColorId; 152 if (colorTheme_App() == dark_ColorTheme) {
157 frame2 = brown_ColorId; 153 *frame1 = cstr_String(&d->label)[1] - '0';
154 *frame2 = darker_Color(*frame1);
158 } 155 }
159 else { 156 else {
160 frame = cyan_ColorId; 157 *bg = *frame1 = *frame2 = cstr_String(&d->label)[1] - '0';
161 frame2 = teal_ColorId; 158 *fg = uiBackground_ColorId | permanent_ColorId;
162 } 159 }
163 } 160 }
161 else if (isSel) {
162 *frame1 = uiEmbossSelectedHover1_ColorId;
163 *frame2 = uiEmbossSelectedHover2_ColorId;
164 }
164 else { 165 else {
165 frame = white_ColorId; 166 if (isButton) *bg = uiBackgroundHover_ColorId;
166 frame2 = cyan_ColorId; 167 *frame1 = uiEmbossHover1_ColorId;
168 *frame2 = uiEmbossHover2_ColorId;
167 } 169 }
168 } 170 }
169 } 171 }
170 if (flags & pressed_WidgetFlag) { 172 if (isPress) {
171 bg = orange_ColorId | permanent_ColorId; 173 *bg = uiBackgroundPressed_ColorId | permanent_ColorId;
172 if (isButton) { 174 if (isButton) {
173 frame = brown_ColorId; 175 *frame1 = uiEmbossPressed1_ColorId;
174 frame2 = white_ColorId; 176 *frame2 = uiEmbossPressed2_ColorId;
175 } 177 }
176 fg = black_ColorId | permanent_ColorId; 178 *fg = uiTextPressed_ColorId | permanent_ColorId;
177 } 179 }
178 if (bg) { 180}
181
182static void draw_LabelWidget_(const iLabelWidget *d) {
183 const iWidget *w = constAs_Widget(d);
184 draw_Widget(w);
185 const iBool isButton = d->click.button != 0;
186 const int flags = flags_Widget(w);
187 const iRect bounds = bounds_Widget(w);
188 iRect rect = bounds;
189 if (isButton) {
190 shrink_Rect(&rect, divi_I2(gap2_UI, 4));
191 adjustEdges_Rect(&rect, gap_UI / 8, 0, -gap_UI / 8, 0);
192 }
193 iPaint p;
194 init_Paint(&p);
195 int bg, fg, frame, frame2;
196 getColors_LabelWidget_(d, &bg, &fg, &frame, &frame2);
197 if (bg >= 0) {
179 fillRect_Paint(&p, rect, bg); 198 fillRect_Paint(&p, rect, bg);
180 } 199 }
181 if (~flags & frameless_WidgetFlag) { 200 if (~flags & frameless_WidgetFlag) {
@@ -201,7 +220,7 @@ static void draw_LabelWidget_(const iLabelWidget *d) {
201 keyStr_LabelWidget_(d, &str); 220 keyStr_LabelWidget_(d, &str);
202 drawAlign_Text(uiShortcuts_FontId, 221 drawAlign_Text(uiShortcuts_FontId,
203 add_I2(topRight_Rect(bounds), negX_I2(padding_(flags))), 222 add_I2(topRight_Rect(bounds), negX_I2(padding_(flags))),
204 flags & pressed_WidgetFlag ? fg : cyan_ColorId, 223 flags & pressed_WidgetFlag ? fg : uiTextShortcut_ColorId,
205 right_Alignment, 224 right_Alignment,
206 cstr_String(&str)); 225 cstr_String(&str));
207 deinit_String(&str); 226 deinit_String(&str);
diff --git a/src/ui/scrollwidget.c b/src/ui/scrollwidget.c
index d43a1fad..944c9ebe 100644
--- a/src/ui/scrollwidget.c
+++ b/src/ui/scrollwidget.c
@@ -114,9 +114,10 @@ static void draw_ScrollWidget_(const iScrollWidget *d) {
114 if (bounds.size.x > 0) { 114 if (bounds.size.x > 0) {
115 iPaint p; 115 iPaint p;
116 init_Paint(&p); 116 init_Paint(&p);
117 drawRect_Paint(&p, bounds, black_ColorId); 117// drawRect_Paint(&p, bounds, black_ColorId);
118 drawVLine_Paint(&p, topLeft_Rect(bounds), height_Rect(bounds), uiSeparator_ColorId);
118 const iRect thumbRect = shrunk_Rect(thumbRect_ScrollWidget_(d), init_I2(gap_UI, gap_UI / 2)); 119 const iRect thumbRect = shrunk_Rect(thumbRect_ScrollWidget_(d), init_I2(gap_UI, gap_UI / 2));
119 fillRect_Paint(&p, thumbRect, isPressed ? orange_ColorId : tmQuote_ColorId); 120 fillRect_Paint(&p, thumbRect, isPressed ? uiBackgroundPressed_ColorId : tmQuote_ColorId);
120 } 121 }
121} 122}
122 123
diff --git a/src/ui/sidebarwidget.c b/src/ui/sidebarwidget.c
index 7d0e8b42..de3cfd86 100644
--- a/src/ui/sidebarwidget.c
+++ b/src/ui/sidebarwidget.c
@@ -102,6 +102,10 @@ static void updateVisible_SidebarWidget_(iSidebarWidget *d) {
102 : 0); 102 : 0);
103} 103}
104 104
105static int cmpTitle_Bookmark_(const iBookmark **a, const iBookmark **b) {
106 return cmpStringCase_String(&(*a)->title, &(*b)->title);
107}
108
105static void updateItems_SidebarWidget_(iSidebarWidget *d) { 109static void updateItems_SidebarWidget_(iSidebarWidget *d) {
106 clearItems_SidebarWidget_(d); 110 clearItems_SidebarWidget_(d);
107 destroy_Widget(d->menu); 111 destroy_Widget(d->menu);
@@ -122,7 +126,7 @@ static void updateItems_SidebarWidget_(iSidebarWidget *d) {
122 break; 126 break;
123 } 127 }
124 case bookmarks_SidebarMode: { 128 case bookmarks_SidebarMode: {
125 iConstForEach(PtrArray, i, list_Bookmarks(bookmarks_App(), NULL, NULL)) { 129 iConstForEach(PtrArray, i, list_Bookmarks(bookmarks_App(), NULL, cmpTitle_Bookmark_)) {
126 const iBookmark *bm = i.ptr; 130 const iBookmark *bm = i.ptr;
127 iSidebarItem item; 131 iSidebarItem item;
128 init_SidebarItem(&item); 132 init_SidebarItem(&item);
@@ -130,11 +134,12 @@ static void updateItems_SidebarWidget_(iSidebarWidget *d) {
130 item.icon = bm->icon; 134 item.icon = bm->icon;
131 set_String(&item.url, &bm->url); 135 set_String(&item.url, &bm->url);
132 set_String(&item.label, &bm->title); 136 set_String(&item.label, &bm->title);
133 iDate date; 137// iDate date;
134 init_Date(&date, &bm->when); 138// init_Date(&date, &bm->when);
135 iString *ds = format_Date(&date, "%Y %b %d"); 139// iString *ds = format_Date(&date, "%Y %b %d");
136 set_String(&item.meta, ds); 140// set_String(&item.meta, ds);
137 delete_String(ds); 141 set_String(&item.meta, &bm->tags);
142// delete_String(ds);
138 pushBack_Array(&d->items, &item); 143 pushBack_Array(&d->items, &item);
139 } 144 }
140 d->menu = makeMenu_Widget( 145 d->menu = makeMenu_Widget(
@@ -142,7 +147,7 @@ static void updateItems_SidebarWidget_(iSidebarWidget *d) {
142 (iMenuItem[]){ { "Edit Bookmark...", 0, 0, "bookmark.edit" }, 147 (iMenuItem[]){ { "Edit Bookmark...", 0, 0, "bookmark.edit" },
143 { "Copy URL", 0, 0, "bookmark.copy" }, 148 { "Copy URL", 0, 0, "bookmark.copy" },
144 { "---", 0, 0, NULL }, 149 { "---", 0, 0, NULL },
145 { orange_ColorEscape "Delete Bookmark", 0, 0, "bookmark.delete" } }, 150 { uiTextCaution_ColorEscape "Delete Bookmark", 0, 0, "bookmark.delete" } },
146 4); 151 4);
147 break; 152 break;
148 } 153 }
@@ -161,7 +166,7 @@ void setMode_SidebarWidget(iSidebarWidget *d, enum iSidebarMode mode) {
161 for (enum iSidebarMode i = 0; i < max_SidebarMode; i++) { 166 for (enum iSidebarMode i = 0; i < max_SidebarMode; i++) {
162 setFlags_Widget(as_Widget(d->modeButtons[i]), selected_WidgetFlag, i == d->mode); 167 setFlags_Widget(as_Widget(d->modeButtons[i]), selected_WidgetFlag, i == d->mode);
163 } 168 }
164 const float heights[max_SidebarMode] = { 1.2f, 2.4f, 3, 3 }; 169 const float heights[max_SidebarMode] = { 1.2f, 1.5f, 3, 3 };
165 d->itemHeight = heights[mode] * lineHeight_Text(default_FontId); 170 d->itemHeight = heights[mode] * lineHeight_Text(default_FontId);
166} 171}
167 172
@@ -351,7 +356,7 @@ static iBool processEvent_SidebarWidget_(iSidebarWidget *d, const SDL_Event *ev)
351 if (argLabel_Command(cmd, "button") == SDL_BUTTON_LEFT) { 356 if (argLabel_Command(cmd, "button") == SDL_BUTTON_LEFT) {
352 if (arg_Command(cmd)) { 357 if (arg_Command(cmd)) {
353 setFlags_Widget(d->resizer, pressed_WidgetFlag, iTrue); 358 setFlags_Widget(d->resizer, pressed_WidgetFlag, iTrue);
354 setBackgroundColor_Widget(d->resizer, gray75_ColorId); 359 setBackgroundColor_Widget(d->resizer, uiBackgroundFramelessHover_ColorId);
355 setMouseGrab_Widget(d->resizer); 360 setMouseGrab_Widget(d->resizer);
356 refresh_Widget(d->resizer); 361 refresh_Widget(d->resizer);
357 } 362 }
@@ -420,6 +425,7 @@ static iBool processEvent_SidebarWidget_(iSidebarWidget *d, const SDL_Event *ev)
420 setText_InputWidget(findChild_Widget(dlg, "bmed.url"), &bm->url); 425 setText_InputWidget(findChild_Widget(dlg, "bmed.url"), &bm->url);
421 setText_InputWidget(findChild_Widget(dlg, "bmed.tags"), &bm->tags); 426 setText_InputWidget(findChild_Widget(dlg, "bmed.tags"), &bm->tags);
422 setCommandHandler_Widget(dlg, handleBookmarkEditorCommands_SidebarWidget_); 427 setCommandHandler_Widget(dlg, handleBookmarkEditorCommands_SidebarWidget_);
428 setFocus_Widget(findChild_Widget(dlg, "bmed.title"));
423 } 429 }
424 return iTrue; 430 return iTrue;
425 } 431 }
@@ -500,35 +506,41 @@ static void draw_SidebarWidget_(const iSidebarWidget *d) {
500 const iBool isHover = (d->hoverItem == i); 506 const iBool isHover = (d->hoverItem == i);
501 setClip_Paint(&p, intersect_Rect(itemRect, bounds)); 507 setClip_Paint(&p, intersect_Rect(itemRect, bounds));
502 if (isHover) { 508 if (isHover) {
503 fillRect_Paint(&p, itemRect, isPressing ? orange_ColorId : teal_ColorId); 509 fillRect_Paint(&p,
510 itemRect,
511 isPressing ? uiBackgroundPressed_ColorId
512 : uiBackgroundFramelessHover_ColorId);
504 } 513 }
505 if (d->mode == documentOutline_SidebarMode) { 514 if (d->mode == documentOutline_SidebarMode) {
506 const int fg = isHover ? (isPressing ? black_ColorId : white_ColorId) : 515 const int fg =
507 (item->indent == 0 ? white_ColorId : gray75_ColorId); 516 isHover ? (isPressing ? uiTextPressed_ColorId : uiTextFramelessHover_ColorId)
517 : (item->indent == 0 ? uiTextStrong_ColorId : uiText_ColorId);
508 drawRange_Text(font, init_I2(pos.x + 3 * gap_UI + item->indent, 518 drawRange_Text(font, init_I2(pos.x + 3 * gap_UI + item->indent,
509 mid_Rect(itemRect).y - lineHeight_Text(font) / 2), 519 mid_Rect(itemRect).y - lineHeight_Text(font) / 2),
510 fg, range_String(&item->label)); 520 fg, range_String(&item->label));
511 } 521 }
512 else if (d->mode == bookmarks_SidebarMode) { 522 else if (d->mode == bookmarks_SidebarMode) {
513 const int fg = 523 const int fg =
514 isHover ? (isPressing ? black_ColorId : white_ColorId) : gray75_ColorId; 524 isHover ? (isPressing ? uiTextPressed_ColorId : uiTextFramelessHover_ColorId)
525 : uiText_ColorId;
515 iString str; 526 iString str;
516 init_String(&str); 527 init_String(&str);
517 appendChar_String(&str, item->icon ? item->icon : 0x1f588); 528 appendChar_String(&str, item->icon ? item->icon : 0x1f588);
518 const iRect iconArea = { pos, init_I2(10 * gap_UI, d->itemHeight) }; 529 const iRect iconArea = { addX_I2(pos, gap_UI), init_I2(7 * gap_UI, d->itemHeight) };
519 drawCentered_Text(uiBookmarkIcon_FontId, 530 drawCentered_Text(font,
520 iconArea, 531 iconArea,
521 iTrue, 532 iTrue,
522 isHover && isPressing ? black_ColorId : cyan_ColorId, 533 isHover && isPressing ? uiTextPressed_ColorId : uiIcon_ColorId,
523 "%s", 534 "%s",
524 cstr_String(&str)); 535 cstr_String(&str));
525 deinit_String(&str); 536 deinit_String(&str);
526 iInt2 textPos = addY_I2(topRight_Rect(iconArea), 0.2f * lineHeight_Text(font)); 537 iInt2 textPos =
538 addY_I2(topRight_Rect(iconArea), (d->itemHeight - lineHeight_Text(font)) / 2);
527 drawRange_Text(font, textPos, fg, range_String(&item->label)); 539 drawRange_Text(font, textPos, fg, range_String(&item->label));
528 drawRange_Text(font, 540 /*drawRange_Text(font,
529 addY_I2(textPos, lineHeight_Text(font)), 541 addY_I2(textPos, lineHeight_Text(font)),
530 isHover ? (isPressing ? black_ColorId : cyan_ColorId) : teal_ColorId, 542 isHover ? (isPressing ? black_ColorId : cyan_ColorId) : teal_ColorId,
531 range_String(&item->meta)); 543 range_String(&item->meta));*/
532 } 544 }
533 unsetClip_Paint(&p); 545 unsetClip_Paint(&p);
534 pos.y += d->itemHeight; 546 pos.y += d->itemHeight;
@@ -538,7 +550,7 @@ static void draw_SidebarWidget_(const iSidebarWidget *d) {
538 drawVLine_Paint(&p, 550 drawVLine_Paint(&p,
539 addX_I2(topRight_Rect(bounds_Widget(w)), -1), 551 addX_I2(topRight_Rect(bounds_Widget(w)), -1),
540 height_Rect(bounds_Widget(w)), 552 height_Rect(bounds_Widget(w)),
541 black_ColorId); 553 uiSeparator_ColorId);
542} 554}
543 555
544iBeginDefineSubclass(SidebarWidget, Widget) 556iBeginDefineSubclass(SidebarWidget, Widget)
diff --git a/src/ui/util.c b/src/ui/util.c
index 05b3c930..e638e596 100644
--- a/src/ui/util.c
+++ b/src/ui/util.c
@@ -126,6 +126,7 @@ iWidget *makePadding_Widget(int size) {
126iLabelWidget *makeHeading_Widget(const char *text) { 126iLabelWidget *makeHeading_Widget(const char *text) {
127 iLabelWidget *heading = new_LabelWidget(text, 0, 0, NULL); 127 iLabelWidget *heading = new_LabelWidget(text, 0, 0, NULL);
128 setFlags_Widget(as_Widget(heading), frameless_WidgetFlag | fixedSize_WidgetFlag, iTrue); 128 setFlags_Widget(as_Widget(heading), frameless_WidgetFlag | fixedSize_WidgetFlag, iTrue);
129 setBackgroundColor_Widget(as_Widget(heading), none_ColorId);
129 return heading; 130 return heading;
130} 131}
131 132
@@ -166,7 +167,7 @@ static iBool menuHandler_(iWidget *menu, const char *cmd) {
166iWidget *makeMenu_Widget(iWidget *parent, const iMenuItem *items, size_t n) { 167iWidget *makeMenu_Widget(iWidget *parent, const iMenuItem *items, size_t n) {
167 iWidget *menu = new_Widget(); 168 iWidget *menu = new_Widget();
168 setFrameColor_Widget(menu, black_ColorId); 169 setFrameColor_Widget(menu, black_ColorId);
169 setBackgroundColor_Widget(menu, gray25_ColorId); 170 setBackgroundColor_Widget(menu, uiBackground_ColorId);
170 setFlags_Widget(menu, 171 setFlags_Widget(menu,
171 keepOnTop_WidgetFlag | collapse_WidgetFlag | hidden_WidgetFlag | 172 keepOnTop_WidgetFlag | collapse_WidgetFlag | hidden_WidgetFlag |
172 arrangeVertical_WidgetFlag | arrangeSize_WidgetFlag | 173 arrangeVertical_WidgetFlag | arrangeSize_WidgetFlag |
@@ -477,7 +478,7 @@ iWidget *makeSheet_Widget(const char *id) {
477 iWidget *sheet = new_Widget(); 478 iWidget *sheet = new_Widget();
478 setId_Widget(sheet, id); 479 setId_Widget(sheet, id);
479 setFrameColor_Widget(sheet, black_ColorId); 480 setFrameColor_Widget(sheet, black_ColorId);
480 setBackgroundColor_Widget(sheet, gray25_ColorId); 481 setBackgroundColor_Widget(sheet, uiBackground_ColorId);
481 setFlags_Widget( 482 setFlags_Widget(
482 sheet, keepOnTop_WidgetFlag | arrangeVertical_WidgetFlag | arrangeHeight_WidgetFlag, iTrue); 483 sheet, keepOnTop_WidgetFlag | arrangeVertical_WidgetFlag | arrangeHeight_WidgetFlag, iTrue);
483 const iInt2 rootSize = rootSize_Window(get_Window()); 484 const iInt2 rootSize = rootSize_Window(get_Window());
@@ -600,7 +601,7 @@ iWidget *makeValueInput_Widget(iWidget *parent, const iString *initialValue, con
600 setFlags_Widget(div, arrangeHorizontal_WidgetFlag | arrangeSize_WidgetFlag, iTrue); 601 setFlags_Widget(div, arrangeHorizontal_WidgetFlag | arrangeSize_WidgetFlag, iTrue);
601 addChild_Widget(div, iClob(new_LabelWidget("Cancel", SDLK_ESCAPE, 0, "cancel"))); 602 addChild_Widget(div, iClob(new_LabelWidget("Cancel", SDLK_ESCAPE, 0, "cancel")));
602 addChild_Widget(div, 603 addChild_Widget(div,
603 iClob(new_LabelWidget(acceptLabel ? acceptLabel : cyan_ColorEscape "OK", 604 iClob(new_LabelWidget(acceptLabel ? acceptLabel : uiTextAction_ColorEscape "OK",
604 SDLK_RETURN, 605 SDLK_RETURN,
605 0, 606 0,
606 "valueinput.accept"))); 607 "valueinput.accept")));
@@ -641,8 +642,8 @@ iWidget *makeQuestion_Widget(const char *title,
641// processEvents_App(postedEventsOnly_AppEventMode); 642// processEvents_App(postedEventsOnly_AppEventMode);
642 iWidget *dlg = makeSheet_Widget(""); 643 iWidget *dlg = makeSheet_Widget("");
643 setCommandHandler_Widget(dlg, messageHandler_); 644 setCommandHandler_Widget(dlg, messageHandler_);
644 addChild_Widget(dlg, iClob(new_LabelWidget(title, 0, 0, NULL))); 645 addChildFlags_Widget(dlg, iClob(new_LabelWidget(title, 0, 0, NULL)), frameless_WidgetFlag);
645 addChild_Widget(dlg, iClob(new_LabelWidget(msg, 0, 0, NULL))); 646 addChildFlags_Widget(dlg, iClob(new_LabelWidget(msg, 0, 0, NULL)), frameless_WidgetFlag);
646 addChild_Widget(dlg, iClob(makePadding_Widget(gap_UI))); 647 addChild_Widget(dlg, iClob(makePadding_Widget(gap_UI)));
647 iWidget *div = new_Widget(); { 648 iWidget *div = new_Widget(); {
648 setFlags_Widget(div, arrangeHorizontal_WidgetFlag | arrangeSize_WidgetFlag, iTrue); 649 setFlags_Widget(div, arrangeHorizontal_WidgetFlag | arrangeSize_WidgetFlag, iTrue);
@@ -685,14 +686,25 @@ iWidget *makeToggle_Widget(const char *id) {
685 686
686iWidget *makePreferences_Widget(void) { 687iWidget *makePreferences_Widget(void) {
687 iWidget *dlg = makeSheet_Widget("prefs"); 688 iWidget *dlg = makeSheet_Widget("prefs");
688 addChild_Widget(dlg, iClob(new_LabelWidget(cyan_ColorEscape "PREFERENCES", 0, 0, NULL))); 689 addChildFlags_Widget(dlg,
690 iClob(new_LabelWidget(uiHeading_ColorEscape "PREFERENCES", 0, 0, NULL)),
691 frameless_WidgetFlag);
689 iWidget *page = new_Widget(); 692 iWidget *page = new_Widget();
690 addChild_Widget(dlg, iClob(page)); 693 addChild_Widget(dlg, iClob(page));
691 setFlags_Widget(page, arrangeHorizontal_WidgetFlag | arrangeSize_WidgetFlag, iTrue); 694 setFlags_Widget(page, arrangeHorizontal_WidgetFlag | arrangeSize_WidgetFlag, iTrue);
692 iWidget *headings = addChildFlags_Widget( 695 iWidget *headings = addChildFlags_Widget(
693 page, iClob(new_Widget()), arrangeVertical_WidgetFlag | arrangeSize_WidgetFlag); 696 page, iClob(new_Widget()), arrangeVertical_WidgetFlag | arrangeSize_WidgetFlag);
694 iWidget *values = addChildFlags_Widget( 697 iWidget *values = addChildFlags_Widget(
695 page, iClob(new_Widget()), arrangeVertical_WidgetFlag | arrangeSize_WidgetFlag); 698 page, iClob(new_Widget()), arrangeVertical_WidgetFlag | arrangeSize_WidgetFlag);
699// setBackgroundColor_Widget(headings, none_ColorId);
700// setBackgroundColor_Widget(values, none_ColorId);
701 addChild_Widget(headings, iClob(makeHeading_Widget("Theme:")));
702 iWidget *themes = new_Widget();
703 /* Themes. */ {
704 setId_Widget(addChild_Widget(themes, iClob(new_LabelWidget("Dark", 0, 0, "theme.set arg:0"))), "prefs.theme.0");
705 setId_Widget(addChild_Widget(themes, iClob(new_LabelWidget("Light", 0, 0, "theme.set arg:1"))), "prefs.theme.1");
706 }
707 addChildFlags_Widget(values, iClob(themes), arrangeHorizontal_WidgetFlag | arrangeSize_WidgetFlag);
696 addChild_Widget(headings, iClob(makeHeading_Widget("Retain window size:"))); 708 addChild_Widget(headings, iClob(makeHeading_Widget("Retain window size:")));
697 addChild_Widget(values, iClob(makeToggle_Widget("prefs.retainwindow"))); 709 addChild_Widget(values, iClob(makeToggle_Widget("prefs.retainwindow")));
698 addChild_Widget(headings, iClob(makeHeading_Widget("UI scale factor:"))); 710 addChild_Widget(headings, iClob(makeHeading_Widget("UI scale factor:")));
@@ -711,7 +723,9 @@ iWidget *makePreferences_Widget(void) {
711 723
712iWidget *makeBookmarkEditor_Widget(void) { 724iWidget *makeBookmarkEditor_Widget(void) {
713 iWidget *dlg = makeSheet_Widget("bmed"); 725 iWidget *dlg = makeSheet_Widget("bmed");
714 addChild_Widget(dlg, iClob(new_LabelWidget(cyan_ColorEscape "EDIT BOOKMARK", 0, 0, NULL))); 726 addChildFlags_Widget(dlg,
727 iClob(new_LabelWidget(uiHeading_ColorEscape "EDIT BOOKMARK", 0, 0, NULL)),
728 frameless_WidgetFlag);
715 iWidget *page = new_Widget(); 729 iWidget *page = new_Widget();
716 addChild_Widget(dlg, iClob(page)); 730 addChild_Widget(dlg, iClob(page));
717 setFlags_Widget(page, arrangeHorizontal_WidgetFlag | arrangeSize_WidgetFlag, iTrue); 731 setFlags_Widget(page, arrangeHorizontal_WidgetFlag | arrangeSize_WidgetFlag, iTrue);
@@ -720,13 +734,16 @@ iWidget *makeBookmarkEditor_Widget(void) {
720 iWidget *values = addChildFlags_Widget( 734 iWidget *values = addChildFlags_Widget(
721 page, iClob(new_Widget()), arrangeVertical_WidgetFlag | arrangeSize_WidgetFlag); 735 page, iClob(new_Widget()), arrangeVertical_WidgetFlag | arrangeSize_WidgetFlag);
722 iInputWidget *inputs[4]; 736 iInputWidget *inputs[4];
723 addChild_Widget(headings, iClob(makeHeading_Widget("Title:"))); 737 iWidget *hd;
738 addChild_Widget(headings, iClob(hd = makeHeading_Widget("Title:")));
724 setId_Widget(addChild_Widget(values, iClob(inputs[0] = new_InputWidget(0))), "bmed.title"); 739 setId_Widget(addChild_Widget(values, iClob(inputs[0] = new_InputWidget(0))), "bmed.title");
725 addChild_Widget(headings, iClob(makeHeading_Widget("URL:"))); 740 addChild_Widget(headings, iClob(makeHeading_Widget("URL:")));
726 setId_Widget(addChild_Widget(values, iClob(inputs[1] = new_InputWidget(0))), "bmed.url"); 741 setId_Widget(addChild_Widget(values, iClob(inputs[1] = new_InputWidget(0))), "bmed.url");
727 addChild_Widget(headings, iClob(makeHeading_Widget("Tags:"))); 742 addChild_Widget(headings, iClob(makeHeading_Widget("Tags:")));
728 setId_Widget(addChild_Widget(values, iClob(inputs[2] = new_InputWidget(0))), "bmed.tags"); 743 setId_Widget(addChild_Widget(values, iClob(inputs[2] = new_InputWidget(0))), "bmed.tags");
729 arrange_Widget(dlg); 744 arrange_Widget(dlg);
745 /* TODO: Heights don't match here. */
746 printf("hd:%d inp:%d\n", hd->rect.size.y, as_Widget(inputs[0])->rect.size.y); fflush(stdout);
730 for (int i = 0; i < 3; ++i) { 747 for (int i = 0; i < 3; ++i) {
731 as_Widget(inputs[i])->rect.size.x = dlg->rect.size.x - headings->rect.size.x - 3 * gap_UI; 748 as_Widget(inputs[i])->rect.size.x = dlg->rect.size.x - headings->rect.size.x - 3 * gap_UI;
732 } 749 }
@@ -736,7 +753,7 @@ iWidget *makeBookmarkEditor_Widget(void) {
736 addChild_Widget( 753 addChild_Widget(
737 div, 754 div,
738 iClob(new_LabelWidget( 755 iClob(new_LabelWidget(
739 orange_ColorEscape "Save", SDLK_RETURN, KMOD_PRIMARY, "bmed.accept"))); 756 uiTextCaution_ColorEscape "Save", SDLK_RETURN, KMOD_PRIMARY, "bmed.accept")));
740 } 757 }
741 addChild_Widget(dlg, iClob(div)); 758 addChild_Widget(dlg, iClob(div));
742 addChild_Widget(get_Window()->root, iClob(dlg)); 759 addChild_Widget(get_Window()->root, iClob(dlg));
diff --git a/src/ui/window.c b/src/ui/window.c
index 5e1ad9c6..8760d36f 100644
--- a/src/ui/window.c
+++ b/src/ui/window.c
@@ -121,7 +121,7 @@ static const iMenuItem helpMenuItems[] = {
121#endif 121#endif
122 122
123static const char *reloadCStr_ = "\U0001f503"; 123static const char *reloadCStr_ = "\U0001f503";
124static const char *stopCStr_ = orange_ColorEscape "\U0001f310"; 124static const char *stopCStr_ = uiTextCaution_ColorEscape "\U0001f310";
125 125
126static iBool handleNavBarCommands_(iWidget *navBar, const char *cmd) { 126static iBool handleNavBarCommands_(iWidget *navBar, const char *cmd) {
127 if (equal_Command(cmd, "window.resized")) { 127 if (equal_Command(cmd, "window.resized")) {
@@ -266,7 +266,7 @@ static void setupUserInterface_Window(iWindow *d) {
266 arrangeHorizontal_WidgetFlag, 266 arrangeHorizontal_WidgetFlag,
267 iTrue); 267 iTrue);
268 addChild_Widget(div, iClob(navBar)); 268 addChild_Widget(div, iClob(navBar));
269 setBackgroundColor_Widget(navBar, gray25_ColorId); 269 setBackgroundColor_Widget(navBar, uiBackground_ColorId);
270 setCommandHandler_Widget(navBar, handleNavBarCommands_); 270 setCommandHandler_Widget(navBar, handleNavBarCommands_);
271 addChild_Widget(navBar, iClob(newIcon_LabelWidget("\U0001f850", 0, 0, "navigate.back"))); 271 addChild_Widget(navBar, iClob(newIcon_LabelWidget("\U0001f850", 0, 0, "navigate.back")));
272 addChild_Widget(navBar, iClob(newIcon_LabelWidget("\U0001f852", 0, 0, "navigate.forward"))); 272 addChild_Widget(navBar, iClob(newIcon_LabelWidget("\U0001f852", 0, 0, "navigate.forward")));
@@ -303,7 +303,7 @@ static void setupUserInterface_Window(iWindow *d) {
303 iWidget *tabBar = makeTabs_Widget(div); 303 iWidget *tabBar = makeTabs_Widget(div);
304 setId_Widget(tabBar, "doctabs"); 304 setId_Widget(tabBar, "doctabs");
305 setFlags_Widget(tabBar, expand_WidgetFlag, iTrue); 305 setFlags_Widget(tabBar, expand_WidgetFlag, iTrue);
306 setBackgroundColor_Widget(tabBar, gray25_ColorId); 306 setBackgroundColor_Widget(tabBar, uiBackground_ColorId);
307 appendTabPage_Widget(tabBar, iClob(new_DocumentWidget()), "Document", 0, 0); 307 appendTabPage_Widget(tabBar, iClob(new_DocumentWidget()), "Document", 0, 0);
308 iWidget *buttons = findChild_Widget(tabBar, "tabs.buttons"); 308 iWidget *buttons = findChild_Widget(tabBar, "tabs.buttons");
309 setFlags_Widget(buttons, collapse_WidgetFlag | hidden_WidgetFlag, iTrue); 309 setFlags_Widget(buttons, collapse_WidgetFlag | hidden_WidgetFlag, iTrue);
@@ -324,7 +324,7 @@ static void setupUserInterface_Window(iWindow *d) {
324 resizeChildren_WidgetFlag | arrangeHorizontal_WidgetFlag, 324 resizeChildren_WidgetFlag | arrangeHorizontal_WidgetFlag,
325 iTrue); 325 iTrue);
326 addChild_Widget(div, iClob(searchBar)); 326 addChild_Widget(div, iClob(searchBar));
327 setBackgroundColor_Widget(searchBar, gray25_ColorId); 327 setBackgroundColor_Widget(searchBar, uiBackground_ColorId);
328 setCommandHandler_Widget(searchBar, handleSearchBarCommands_); 328 setCommandHandler_Widget(searchBar, handleSearchBarCommands_);
329 addChild_Widget(searchBar, iClob(new_LabelWidget("\U0001f50d Text", 0, 0, NULL))); 329 addChild_Widget(searchBar, iClob(new_LabelWidget("\U0001f50d Text", 0, 0, NULL)));
330 iInputWidget *input = new_InputWidget(0); 330 iInputWidget *input = new_InputWidget(0);
@@ -372,7 +372,7 @@ static float pixelRatio_Window_(const iWindow *d) {
372} 372}
373 373
374static void drawBlank_Window_(iWindow *d) { 374static void drawBlank_Window_(iWindow *d) {
375 const iColor bg = get_Color(gray25_ColorId); 375 const iColor bg = get_Color(uiBackground_ColorId);
376 SDL_SetRenderDrawColor(d->render, bg.r, bg.g, bg.b, 255); 376 SDL_SetRenderDrawColor(d->render, bg.r, bg.g, bg.b, 255);
377 SDL_RenderClear(d->render); 377 SDL_RenderClear(d->render);
378 SDL_RenderPresent(d->render); 378 SDL_RenderPresent(d->render);