=> 430525d298e75ae2c24de54af58f6f12c5374437
[1mdiff --git a/po/en.po b/po/en.po[m [1mindex 37dfffed..a4433caa 100644[m [1m--- a/po/en.po[m [1m+++ b/po/en.po[m [36m@@ -1531,6 +1531,9 @@[m [mmsgstr "Fonts"[m msgid "heading.prefs.general"[m msgstr "General"[m [m [32m+[m[32mmsgid "heading.prefs.appearance"[m [32m+[m[32mmsgstr "Appearance"[m [32m+[m # tab button[m msgid "heading.prefs.interface"[m msgstr "UI"[m [36m@@ -1539,6 +1542,12 @@[m [mmsgstr "UI"[m msgid "heading.prefs.keys"[m msgstr "Keys"[m [m [32m+[m[32mmsgid "heading.prefs.layout"[m [32m+[m[32mmsgstr "Page Layout"[m [32m+[m [32m+[m[32mmsgid "heading.prefs.content"[m [32m+[m[32mmsgstr "Content"[m [32m+[m # tab button[m msgid "heading.prefs.network"[m msgstr "Network"[m [36m@@ -1566,7 +1575,7 @@[m [mmsgstr "Wide Layout"[m [m # tab button[m msgid "heading.prefs.style"[m [31m-msgstr "Style"[m [32m+[m[32mmsgstr "Page Style"[m [m # tab button[m msgid "heading.prefs.userinterface"[m [36m@@ -1596,7 +1605,7 @@[m [mmsgstr "Open images in Data URLs:"[m [m # User preference that controls whether index.gmi pages get automatically opened when browsing the contents of a directory inside a compressed archive.[m msgid "prefs.archive.openindex"[m [31m-msgstr "Open archive indices:"[m [32m+[m[32mmsgstr "Open index.gmi in ZIP archives:"[m [m msgid "prefs.markdown.viewsource"[m msgstr "View Markdown as source:"[m [36m@@ -1623,7 +1632,7 @@[m [mmsgid "prefs.scrollspeed.mouse"[m msgstr "Mouse speed:"[m [m msgid "prefs.imageloadscroll"[m [31m-msgstr "Load image on scroll:"[m [32m+[m[32mmsgstr "Load next image on scroll key:"[m [m msgid "prefs.uilayout"[m msgstr "Layout:"[m [36m@@ -1662,7 +1671,7 @@[m [mmsgid "prefs.ostheme"[m msgstr "Use system theme:"[m [m msgid "prefs.theme"[m [31m-msgstr "Theme:"[m [32m+[m[32mmsgstr "UI theme:"[m [m msgid "prefs.theme.black"[m msgstr "Black"[m [36m@@ -1701,7 +1710,7 @@[m [mmsgid "prefs.uilang"[m msgstr "Language:"[m [m msgid "prefs.time.24h"[m [31m-msgstr "24-Hour Time"[m [32m+[m[32mmsgstr "24-hour time:"[m [m msgid "prefs.retaintabs"[m msgstr "Restore tabs at launch:"[m [36m@@ -1728,10 +1737,10 @@[m [mmsgid "prefs.animate"[m msgstr "Animations:"[m [m msgid "prefs.retainwindow"[m [31m-msgstr "Retain placement:"[m [32m+[m[32mmsgstr "Save window placement:"[m [m msgid "prefs.sideicon"[m [31m-msgstr "Capsule icon:"[m [32m+[m[32mmsgstr "Capsule icon on left side:"[m [m msgid "prefs.doctheme.dark"[m msgstr "Dark theme:"[m [36m@@ -1789,7 +1798,7 @@[m [mmsgid "prefs.tui.simple"[m msgstr "Simple characters:"[m [m msgid "prefs.font.ui"[m [31m-msgstr "UI:"[m [32m+[m[32mmsgstr "UI font:"[m [m msgid "prefs.font.heading"[m msgstr "Headings:"[m [36m@@ -1817,7 +1826,7 @@[m [mmsgid "prefs.mono.gopher"[m msgstr "Gopher"[m [m msgid "prefs.gopher.gemstyle"[m [31m-msgstr "Styling on Gopher:"[m [32m+[m[32mmsgstr "Autodetect Gopher menu styling:"[m [m msgid "prefs.boldlink"[m msgstr "Bold links:"[m [36m@@ -1834,7 +1843,7 @@[m [mmsgid "prefs.boldlink.light"[m msgstr "On Light"[m [m msgid "prefs.gemtext.ansi"[m [31m-msgstr "ANSI escapes:"[m [32m+[m[32mmsgstr "Gemtext ANSI escapes:"[m [m # Color of the text foreground, i.e., the characters.[m msgid "prefs.gemtext.ansi.fg"[m [36m@@ -1848,10 +1857,10 @@[m [mmsgid "prefs.gemtext.ansi.fontstyle"[m msgstr "Font Style"[m [m msgid "prefs.font.warnmissing"[m [31m-msgstr "Glyph warnings:"[m [32m+[m[32mmsgstr "Font glyph warnings:"[m [m msgid "prefs.font.smooth"[m [31m-msgstr "Smoothing:"[m [32m+[m[32mmsgstr "Font smoothing:"[m [m msgid "prefs.linewidth"[m msgstr "Line width:"[m [36m@@ -1884,7 +1893,7 @@[m [mmsgid "prefs.justify"[m msgstr "Justify:"[m [m msgid "prefs.plaintext.wrap"[m [31m-msgstr "Wrap plain text:"[m [32m+[m[32mmsgstr "Wrap long plaintext lines:"[m [m msgid "prefs.decodeurls"[m msgstr "Decode URLs:"[m [1mdiff --git a/res/lang/cs.bin b/res/lang/cs.bin[m [1mindex 4e802ba7..8cdbed59 100644[m Binary files a/res/lang/cs.bin and b/res/lang/cs.bin differ [1mdiff --git a/res/lang/de.bin b/res/lang/de.bin[m [1mindex 31715f3e..8a294ca4 100644[m Binary files a/res/lang/de.bin and b/res/lang/de.bin differ [1mdiff --git a/res/lang/en.bin b/res/lang/en.bin[m [1mindex 2e2f9522..9a4029f1 100644[m Binary files a/res/lang/en.bin and b/res/lang/en.bin differ [1mdiff --git a/res/lang/eo.bin b/res/lang/eo.bin[m [1mindex 59151ad9..4daa72a7 100644[m Binary files a/res/lang/eo.bin and b/res/lang/eo.bin differ [1mdiff --git a/res/lang/es.bin b/res/lang/es.bin[m [1mindex 000b46f7..aab45c44 100644[m Binary files a/res/lang/es.bin and b/res/lang/es.bin differ [1mdiff --git a/res/lang/es_MX.bin b/res/lang/es_MX.bin[m [1mindex ed686023..10188964 100644[m Binary files a/res/lang/es_MX.bin and b/res/lang/es_MX.bin differ [1mdiff --git a/res/lang/fi.bin b/res/lang/fi.bin[m [1mindex 5966054d..bccc98b6 100644[m Binary files a/res/lang/fi.bin and b/res/lang/fi.bin differ [1mdiff --git a/res/lang/fr.bin b/res/lang/fr.bin[m [1mindex 4759de0d..c50caa4d 100644[m Binary files a/res/lang/fr.bin and b/res/lang/fr.bin differ [1mdiff --git a/res/lang/gl.bin b/res/lang/gl.bin[m [1mindex 2eda23ee..1ab16b46 100644[m Binary files a/res/lang/gl.bin and b/res/lang/gl.bin differ [1mdiff --git a/res/lang/hu.bin b/res/lang/hu.bin[m [1mindex 81d49de8..4ec109fc 100644[m Binary files a/res/lang/hu.bin and b/res/lang/hu.bin differ [1mdiff --git a/res/lang/ia.bin b/res/lang/ia.bin[m [1mindex dd963eca..e3c34beb 100644[m Binary files a/res/lang/ia.bin and b/res/lang/ia.bin differ [1mdiff --git a/res/lang/ie.bin b/res/lang/ie.bin[m [1mindex 6a79a05b..5570e349 100644[m Binary files a/res/lang/ie.bin and b/res/lang/ie.bin differ [1mdiff --git a/res/lang/isv.bin b/res/lang/isv.bin[m [1mindex d484ea8f..ce6aac3b 100644[m Binary files a/res/lang/isv.bin and b/res/lang/isv.bin differ [1mdiff --git a/res/lang/it.bin b/res/lang/it.bin[m [1mindex 1d907cfa..ce5a10c9 100644[m Binary files a/res/lang/it.bin and b/res/lang/it.bin differ [1mdiff --git a/res/lang/nl.bin b/res/lang/nl.bin[m [1mindex 8c3c7d74..21d1cd3a 100644[m Binary files a/res/lang/nl.bin and b/res/lang/nl.bin differ [1mdiff --git a/res/lang/pl.bin b/res/lang/pl.bin[m [1mindex e309f76e..34d9dcb3 100644[m Binary files a/res/lang/pl.bin and b/res/lang/pl.bin differ [1mdiff --git a/res/lang/ru.bin b/res/lang/ru.bin[m [1mindex 1ac217bd..c0f06c15 100644[m Binary files a/res/lang/ru.bin and b/res/lang/ru.bin differ [1mdiff --git a/res/lang/sk.bin b/res/lang/sk.bin[m [1mindex 5ecef86c..c067b156 100644[m Binary files a/res/lang/sk.bin and b/res/lang/sk.bin differ [1mdiff --git a/res/lang/sr.bin b/res/lang/sr.bin[m [1mindex 4e70b7b4..525b90f3 100644[m Binary files a/res/lang/sr.bin and b/res/lang/sr.bin differ [1mdiff --git a/res/lang/tok.bin b/res/lang/tok.bin[m [1mindex 65cac0c0..461b2ad5 100644[m Binary files a/res/lang/tok.bin and b/res/lang/tok.bin differ [1mdiff --git a/res/lang/tr.bin b/res/lang/tr.bin[m [1mindex 42704ae2..448350b9 100644[m Binary files a/res/lang/tr.bin and b/res/lang/tr.bin differ [1mdiff --git a/res/lang/uk.bin b/res/lang/uk.bin[m [1mindex dd0c6a55..622dc980 100644[m Binary files a/res/lang/uk.bin and b/res/lang/uk.bin differ [1mdiff --git a/res/lang/zh_Hans.bin b/res/lang/zh_Hans.bin[m [1mindex 84cfdb8b..fe0f2b42 100644[m Binary files a/res/lang/zh_Hans.bin and b/res/lang/zh_Hans.bin differ [1mdiff --git a/res/lang/zh_Hant.bin b/res/lang/zh_Hant.bin[m [1mindex 11baf6a0..4668a81f 100644[m Binary files a/res/lang/zh_Hant.bin and b/res/lang/zh_Hant.bin differ [1mdiff --git a/src/app.c b/src/app.c[m [1mindex 564cd9b6..fd000dbd 100644[m [1m--- a/src/app.c[m [1m+++ b/src/app.c[m [36m@@ -2546,6 +2546,8 @@[m [mstatic void updatePrefsThemeButtons_(iWidget *d) {[m selected_WidgetFlag,[m prefs_App()->accent == i);[m }[m [32m+[m[32m updateDropdownSelection_LabelWidget(findChild_Widget(d, "prefs.accent"),[m [32m+[m[32m format_CStr(" arg:%u", prefs_App()->accent));[m }[m [m static void updatePrefsPinSplitButtons_(iWidget *d, int value) {[m [36m@@ -2640,11 +2642,14 @@[m [mstatic iBool handlePrefsCommands_(iWidget *d, const char *cmd) {[m postCommand_App("prefs.changed");[m return iTrue;[m }[m [32m+[m[32m /*[m else if (equal_Command(cmd, "tabs.changed")) {[m setFlags_Widget(findChild_Widget(d, "prefs.aboutfonts"), hidden_WidgetFlag,[m [31m- !equal_Rangecc(range_Command(cmd, "id"), "prefs.page.fonts"));[m [32m+[m[32m !equal_Rangecc(range_Command(cmd, "id"), "prefs.page.style") &&[m [32m+[m[32m !equal_Rangecc(range_Command(cmd, "id"), "prefs.page.appearance"));[m return iFalse;[m }[m [32m+[m[32m */[m else if (equal_Command(cmd, "uilang")) {[m updateDropdownSelection_LabelWidget(findChild_Widget(d, "prefs.uilang"),[m cstr_String(string_Command(cmd, "id")));[m [1mdiff --git a/src/defs.h b/src/defs.h[m [1mindex cf90b27f..2048b744 100644[m [1m--- a/src/defs.h[m [1m+++ b/src/defs.h[m [36m@@ -254,6 +254,12 @@[m [miLocalDef int acceptKeyMod_ReturnKeyBehavior(int behavior) {[m #define toggleYes_Icon check_Icon[m #define toggleNo_Icon bullet_Icon[m #define spartan_Icon "\U0001f4aa"[m [32m+[m[32m#define keyboard_Icon "\u2328"[m [32m+[m[32m#define network_Icon "\U0001f5a7"[m [32m+[m[32m#define computer_Icon "\U0001f5b3"[m [32m+[m[32m#define palette_Icon "\U0001f3a8"[m [32m+[m[32m#define pageLayout_Icon page_Icon //"\u21b9" //"\U0001F5B9"[m [32m+[m[32m#define fonts_Icon "\U0001f5da"[m [m #if defined (iPlatformTerminal)[m # undef page_Icon[m [1mdiff --git a/src/ui/color.c b/src/ui/color.c[m [1mindex 899e3a28..3f392987 100644[m [1m--- a/src/ui/color.c[m [1m+++ b/src/ui/color.c[m [36m@@ -80,7 +80,7 @@[m [miLocalDef void copy_(enum iColorId dst, enum iColorId src) {[m set_Color(dst, get_Color(src));[m }[m [m [31m-static int accentColor_(enum iColorAccent accent, int brightness) {[m [32m+[m[32mint color_ColorAccent(enum iColorAccent accent, iBool isBright) {[m const iBool isMedium = prefs_App()->theme == dark_ColorTheme ||[m prefs_App()->theme == light_ColorTheme;[m const int brightColors[max_ColorAccent] = {[m [36m@@ -99,18 +99,18 @@[m [mstatic int accentColor_(enum iColorAccent accent, int brightness) {[m indigo_ColorId,[m isMedium ? black_ColorId : gray25_ColorId,[m };[m [31m- return brightness ? brightColors[accent] : darkColors[accent];[m [32m+[m[32m return isBright ? brightColors[accent] : darkColors[accent];[m }[m [m int accent_Color(iBool isBright) {[m [31m- return accentColor_(prefs_App()->accent, isBright ? 1 : 0);[m [32m+[m[32m return color_ColorAccent(prefs_App()->accent, isBright);[m }[m [m void setThemePalette_Color(enum iColorTheme theme) {[m const iPrefs *prefs = prefs_App();[m memcpy(uiPalette_, isDark_ColorTheme(theme) ? darkPalette_ : lightPalette_, sizeof(darkPalette_));[m [31m- const int accentHi = accentColor_(prefs->accent, 1);[m [31m- const int accentLo = accentColor_(prefs->accent, 0);[m [32m+[m[32m const int accentHi = color_ColorAccent(prefs->accent, 1);[m [32m+[m[32m const int accentLo = color_ColorAccent(prefs->accent, 0);[m switch (theme) {[m case pureBlack_ColorTheme: {[m copy_(uiBackground_ColorId, black_ColorId);[m [1mdiff --git a/src/ui/color.h b/src/ui/color.h[m [1mindex 356831d2..ea285ca6 100644[m [1m--- a/src/ui/color.h[m [1m+++ b/src/ui/color.h[m [36m@@ -272,3 +272,5 @@[m [menum iColorId parseEscape_Color (const char *cstr, const char **endp);[m [m int accent_Color (iBool isBright);[m iColor systemAccent_Color (void); /* platform-specific impl */[m [32m+[m [32m+[m[32mint color_ColorAccent (enum iColorAccent, iBool isBright);[m [1mdiff --git a/src/ui/labelwidget.c b/src/ui/labelwidget.c[m [1mindex 69b9092a..47f2ccc8 100644[m [1m--- a/src/ui/labelwidget.c[m [1m+++ b/src/ui/labelwidget.c[m [36m@@ -42,6 +42,7 @@[m [mstruct Impl_LabelWidget {[m int kmods;[m iChar icon;[m int forceFg;[m [32m+[m[32m int iconColor;[m iString command;[m iClick click;[m struct {[m [36m@@ -301,6 +302,13 @@[m [mstatic void getColors_LabelWidget_(const iLabelWidget *d, int *bg, int *fg, int[m if (colorEscape == uiTextCaution_ColorId) {[m *icon = *meta = colorEscape;[m }[m [32m+[m[32m if (d->iconColor != none_ColorId) {[m [32m+[m[32m *icon = d->iconColor;[m [32m+[m[32m if ((*icon >= brown_ColorId && *icon <= blue_ColorId) && !isDarkTheme) {[m [32m+[m[32m /* Auto-adjust absolute color IDs to suit the UI theme. */[m [32m+[m[32m (*icon)--; /* make it darker */[m [32m+[m[32m }[m [32m+[m[32m }[m if (isHover) {[m if (isFrameless) {[m if (prefs_App()->accent == gray_ColorAccent && prefs_App()->theme >= light_ColorTheme) {[m [36m@@ -601,6 +609,7 @@[m [mvoid init_LabelWidget(iLabelWidget *d, const char *label, const char *cmd) {[m iZap(d->flags);[m d->font = uiLabel_FontId;[m d->forceFg = none_ColorId;[m [32m+[m[32m d->iconColor = none_ColorId;[m d->icon = 0;[m d->labelOffset = zero_I2();[m initCStr_String(&d->srcLabel, label);[m [36m@@ -751,6 +760,10 @@[m [mvoid setIcon_LabelWidget(iLabelWidget *d, iChar icon) {[m }[m }[m [m [32m+[m[32mvoid setIconColor_LabelWidget(iLabelWidget *d, int color) {[m [32m+[m[32m d->iconColor = color;[m [32m+[m[32m}[m [32m+[m iBool checkIcon_LabelWidget(iLabelWidget *d) {[m if (isEmpty_String(&d->label)) {[m d->icon = 0;[m [1mdiff --git a/src/ui/labelwidget.h b/src/ui/labelwidget.h[m [1mindex fbc83d2d..3dbc70d9 100644[m [1m--- a/src/ui/labelwidget.h[m [1m+++ b/src/ui/labelwidget.h[m [36m@@ -47,6 +47,7 @@[m [mvoid setText_LabelWidget (iLabelWidget *, const iString *text); /* re[m void setTextCStr_LabelWidget (iLabelWidget *, const char *text);[m void setCommand_LabelWidget (iLabelWidget *, const iString *command);[m void setIcon_LabelWidget (iLabelWidget *, iChar icon);[m [32m+[m[32mvoid setIconColor_LabelWidget (iLabelWidget *, int color);[m [m iBool checkIcon_LabelWidget (iLabelWidget *);[m void updateSize_LabelWidget (iLabelWidget *);[m [1mdiff --git a/src/ui/uploadwidget.c b/src/ui/uploadwidget.c[m [1mindex bf840d7b..ea605c85 100644[m [1m--- a/src/ui/uploadwidget.c[m [1m+++ b/src/ui/uploadwidget.c[m [36m@@ -329,10 +329,10 @@[m [mvoid init_UploadWidget(iUploadWidget *d, enum iUploadProtocol protocol) {[m setId_Widget(as_Widget(d->input), "upload.text");[m setFixedSize_Widget(as_Widget(d->input), init_I2(120 * gap_UI * aspectRatio, -1));[m addChild_Widget(page, iClob(d->input));[m [31m- appendFramelessTabPage_Widget(tabs, iClob(page), "${heading.upload.text}", '1', 0);[m [32m+[m[32m appendFramelessTabPage_Widget(tabs, iClob(page), "${heading.upload.text}", none_ColorId, '1', 0);[m }[m /* File content. */ {[m [31m- iWidget *page = appendTwoColumnTabPage_Widget(tabs, "${heading.upload.file}", '2', &headings, &values);[m [32m+[m[32m iWidget *page = appendTwoColumnTabPage_Widget(tabs, "${heading.upload.file}", none_ColorId, '2', &headings, &values);[m setBackgroundColor_Widget(page, uiBackgroundSidebar_ColorId);[m addChildFlags_Widget(headings, iClob(new_LabelWidget("${upload.file.name}", NULL)), frameless_WidgetFlag);[m d->filePathLabel = addChildFlags_Widget(values, iClob(new_LabelWidget(uiTextAction_ColorEscape "${upload.file.drophere}", NULL)), frameless_WidgetFlag);[m [1mdiff --git a/src/ui/util.c b/src/ui/util.c[m [1mindex 56300a66..87a8ec0b 100644[m [1m--- a/src/ui/util.c[m [1m+++ b/src/ui/util.c[m [36m@@ -1695,8 +1695,27 @@[m [mvoid setTabBarPosition_Widget(iWidget *tabs, iBool atBottom) {[m iRelease(buttons);[m }[m [m [32m+[m[32mvoid setVerticalTabBar_Widget(iWidget *tabs) {[m [32m+[m[32m iWidget *buttons = findChild_Widget(tabs, "tabs.buttons");[m [32m+[m[32m iWidget *content = findChild_Widget(tabs, "tabs.content");[m [32m+[m[32m setFlags_Widget(tabs, arrangeVertical_WidgetFlag, iFalse);[m [32m+[m[32m setFlags_Widget(tabs, arrangeHorizontal_WidgetFlag, iTrue);[m [32m+[m[32m setFlags_Widget(buttons, arrangeHorizontal_WidgetFlag | arrangeHeight_WidgetFlag |[m [32m+[m[32m resizeWidthOfChildren_WidgetFlag, iFalse);[m [32m+[m[32m setFlags_Widget(buttons, arrangeVertical_WidgetFlag | arrangeWidth_WidgetFlag |[m [32m+[m[32m resizeChildrenToWidestChild_WidgetFlag, iTrue);[m [32m+[m[32m buttons->flags2 |= centerChildrenVertical_WidgetFlag2;[m [32m+[m[32m setFlags_Widget(content, arrangeHorizontal_WidgetFlag, iFalse);[m [32m+[m[32m setFlags_Widget(content, arrangeVertical_WidgetFlag, iTrue);[m [32m+[m[32m}[m [32m+[m [32m+[m[32miBool isVerticalTabBar_Widget(const iWidget *tabs) {[m [32m+[m[32m return (tabs->flags & arrangeVertical_WidgetFlag) == 0;[m [32m+[m[32m}[m [32m+[m static void addTabPage_Widget_(iWidget *tabs, enum iWidgetAddPos addPos, iWidget *page,[m const char *label, int key, int kmods) {[m [32m+[m[32m const iBool isVerticalTabs = isVerticalTabBar_Widget(tabs);[m iWidget * pages = findChild_Widget(tabs, "tabs.pages");[m const iBool isSel = childCount_Widget(pages) == 0;[m iWidget * buttons = findChild_Widget(tabs, "tabs.buttons");[m [36m@@ -1704,8 +1723,10 @@[m [mstatic void addTabPage_Widget_(iWidget *tabs, enum iWidgetAddPos addPos, iWidget[m buttons,[m iClob(newKeyMods_LabelWidget(label, key, kmods, format_CStr("tabs.switch page:%p", page))),[m addPos);[m [32m+[m[32m checkIcon_LabelWidget((iLabelWidget *) button);[m setFlags_Widget(button, selected_WidgetFlag, isSel);[m [31m- setFlags_Widget(button, commandOnClick_WidgetFlag | expand_WidgetFlag, iTrue);[m [32m+[m[32m setFlags_Widget(button, commandOnClick_WidgetFlag |[m [32m+[m[32m (isVerticalTabs ? alignLeft_WidgetFlag : expand_WidgetFlag), iTrue);[m if (prefs_App()->bottomTabBar) {[m setNoBottomFrame_LabelWidget((iLabelWidget *) button, iTrue);[m }[m [36m@@ -1772,7 +1793,10 @@[m [mvoid resizeToLargestPage_Widget(iWidget *tabs) {[m iForEach(ObjectList, k, children_Widget(pages)) {[m setMinSize_Widget(k.object, largest);[m }[m [31m- setFixedSize_Widget(tabs, addY_I2(largest, height_Widget(findChild_Widget(tabs, "tabs.buttons"))));[m [32m+[m[32m const iWidget *buttons = findChild_Widget(tabs, "tabs.buttons");[m [32m+[m[32m setFixedSize_Widget(tabs,[m [32m+[m[32m isVerticalTabBar_Widget(tabs) ? addX_I2(largest, width_Widget(buttons))[m [32m+[m[32m : addY_I2(largest, height_Widget(buttons)));[m // puts("... DONE WITH RESIZE TO LARGEST PAGE");[m }[m [m [36m@@ -2394,13 +2418,16 @@[m [miWidget *makeToggle_Widget(const char *id) {[m return toggle;[m }[m [m [31m-void appendFramelessTabPage_Widget(iWidget *tabs, iWidget *page, const char *title, int shortcut,[m [31m- int kmods) {[m [32m+[m[32mvoid appendFramelessTabPage_Widget(iWidget *tabs, iWidget *page, const char *title, int iconColor,[m [32m+[m[32m int shortcut, int kmods) {[m appendTabPage_Widget(tabs, page, title, shortcut, kmods);[m setFlags_Widget([m (iWidget *) back_ObjectList(children_Widget(findChild_Widget(tabs, "tabs.buttons"))),[m frameless_WidgetFlag | noBackground_WidgetFlag,[m iTrue);[m [32m+[m[32m if (iconColor != none_ColorId) {[m [32m+[m[32m setIconColor_LabelWidget(tabPageButton_Widget(tabs, page), iconColor);[m [32m+[m[32m }[m }[m [m iWidget *makeTwoColumns_Widget(iWidget **headings, iWidget **values) {[m [36m@@ -2422,8 +2449,8 @@[m [miLabelWidget *dialogAcceptButton_Widget(const iWidget *d) {[m return (iLabelWidget *) lastChild_Widget(buttonParent);[m }[m [m [31m-iWidget *appendTwoColumnTabPage_Widget(iWidget *tabs, const char *title, int shortcut, iWidget **headings,[m [31m- iWidget **values) {[m [32m+[m[32miWidget *appendTwoColumnTabPage_Widget(iWidget *tabs, const char *title, int iconColor,[m [32m+[m[32m int shortcut, iWidget **headings, iWidget **values) {[m /* TODO: Use `makeTwoColumnWidget_()`, see above. */[m iWidget *page = new_Widget();[m setFlags_Widget(page, arrangeVertical_WidgetFlag | arrangeSize_WidgetFlag, iTrue);[m [36m@@ -2436,20 +2463,26 @@[m [miWidget *appendTwoColumnTabPage_Widget(iWidget *tabs, const char *title, int sho[m *values = addChildFlags_Widget([m columns, iClob(new_Widget()), arrangeVertical_WidgetFlag | arrangeSize_WidgetFlag);[m addChildFlags_Widget(page, iClob(new_Widget()), expand_WidgetFlag);[m [31m- appendFramelessTabPage_Widget(tabs, iClob(page), title, shortcut, shortcut ? KMOD_PRIMARY : 0);[m [32m+[m[32m appendFramelessTabPage_Widget(tabs, iClob(page), title, iconColor, shortcut, shortcut ? KMOD_PRIMARY : 0);[m return page;[m }[m [m [32m+[m[32mstatic void addDialogPaddingSize_(iWidget *headings, iWidget *values, int size) {[m [32m+[m[32m addChild_Widget(headings, iClob(makePadding_Widget(size)));[m [32m+[m[32m addChild_Widget(values, iClob(makePadding_Widget(size)));[m[41m [m [32m+[m[32m}[m [32m+[m static void addDialogPadding_(iWidget *headings, iWidget *values) {[m [31m- const int bigGap = iMaxi(1, lineHeight_Text(uiLabel_FontId) * 3 / 4);[m [31m- addChild_Widget(headings, iClob(makePadding_Widget(bigGap)));[m [31m- addChild_Widget(values, iClob(makePadding_Widget(bigGap))); [m [32m+[m[32m addDialogPaddingSize_(headings, values, iMaxi(1, lineHeight_Text(uiLabel_FontId) * 3 / 4));[m }[m [m static void makeTwoColumnHeading_(const char *title, iWidget *headings, iWidget *values) {[m if (isTerminal_Platform()) {[m addDialogPadding_(headings, values);[m }[m [32m+[m[32m else {[m [32m+[m[32m addDialogPaddingSize_(headings, values, 2 * gap_UI);[m [32m+[m[32m }[m setFont_LabelWidget(addChildFlags_Widget(headings,[m iClob(makeHeading_Widget([m format_CStr(uiHeading_ColorEscape "%s", title))),[m [36m@@ -2534,6 +2567,7 @@[m [mvoid updatePreferencesLayout_Widget(iWidget *prefs) {[m "prefs.proxy.http"[m };[m iWidget *tabs = findChild_Widget(prefs, "prefs.tabs");[m [32m+[m[32m tabs->rect.size = zero_I2();[m /* Input fields expand to the right edge. */[m /* TODO: Add an arrangement flag for this. */[m iForIndices(i, inputIds) {[m [36m@@ -2609,6 +2643,17 @@[m [mstatic void addDialogToggleGroup_(iWidget *headings, iWidget *values, const char[m values, iClob(group), arrangeHorizontal_WidgetFlag | arrangeSize_WidgetFlag);[m }[m [m [32m+[m[32mstatic iLabelWidget *addDialogDropMenu_(iWidget *headings, iWidget *values, const char *title,[m [32m+[m[32m const iMenuItem *items, size_t numItems, const char *id) {[m [32m+[m[32m addChild_Widget(headings, iClob(makeHeading_Widget(title)));[m [32m+[m[32m iLabelWidget *button = makeMenuButton_LabelWidget([m [32m+[m[32m items[findWidestLabel_MenuItem(items, numItems)].label, items, numItems);[m [32m+[m[32m setBackgroundColor_Widget(findChild_Widget(as_Widget(button), "menu"),[m [32m+[m[32m uiBackgroundMenu_ColorId);[m [32m+[m[32m setId_Widget(addChildFlags_Widget(values, iClob(button), alignLeft_WidgetFlag), id);[m [32m+[m[32m return button;[m [32m+[m[32m}[m [32m+[m size_t findWidestLabel_MenuItem(const iMenuItem *items, size_t num) {[m int widest = 0;[m size_t widestPos = iInvalidPos;[m [36m@@ -2757,6 +2802,14 @@[m [miWidget *makePreferences_Widget(void) {[m };[m memcpy(docThemes[i], items, sizeof(items));[m }[m [32m+[m[32m const iMenuItem accentItems[max_ColorAccent] = {[m [32m+[m[32m { circle_Icon " ${prefs.accent.teal}", 0, 0, "accent.set arg:0" },[m [32m+[m[32m { circle_Icon " ${prefs.accent.orange}", 0, 0, "accent.set arg:1" },[m [32m+[m[32m { circle_Icon " ${prefs.accent.red}", 0, 0, "accent.set arg:2" },[m [32m+[m[32m { circle_Icon " ${prefs.accent.green}", 0, 0, "accent.set arg:3" },[m [32m+[m[32m { circle_Icon " ${prefs.accent.blue}", 0, 0, "accent.set arg:4" },[m [32m+[m[32m { circle_Icon " ${prefs.accent.gray}", 0, 0, "accent.set arg:5" }[m [32m+[m[32m };[m const iMenuItem imgStyles[] = {[m { "${prefs.imagestyle.original}", 0, 0, format_CStr("imagestyle.set arg:%d", original_ImageStyle) },[m { "${prefs.imagestyle.grayscale}", 0, 0, format_CStr("imagestyle.set arg:%d", grayscale_ImageStyle) },[m [36m@@ -3001,11 +3054,17 @@[m [miWidget *makePreferences_Widget(void) {[m iWidget *dlg = makeSheet_Widget("prefs");[m addDialogTitle_(dlg, "${heading.prefs}", NULL);[m iWidget *tabs = makeTabs_Widget(dlg);[m [32m+[m[32m setVerticalTabBar_Widget(tabs);[m setBackgroundColor_Widget(findChild_Widget(tabs, "tabs.buttons"), uiBackgroundSidebar_ColorId);[m setId_Widget(tabs, "prefs.tabs");[m iWidget *headings, *values;[m [31m- /* General preferences. */ {[m [31m- setId_Widget(appendTwoColumnTabPage_Widget(tabs, "${heading.prefs.general}", '1', &headings, &values),[m [32m+[m[32m /* General settings. */ {[m [32m+[m[32m setId_Widget(appendTwoColumnTabPage_Widget(tabs,[m [32m+[m[32m gear_Icon " ${heading.prefs.general}",[m [32m+[m[32m uiIcon_ColorId,[m [32m+[m[32m '1',[m [32m+[m[32m &headings,[m [32m+[m[32m &values),[m "prefs.page.general");[m #if defined (LAGRANGE_ENABLE_DOWNLOAD_EDIT)[m addPrefsInputWithHeading_(headings, values, "prefs.downloads", iClob(new_InputWidget(0)));[m [36m@@ -3014,7 +3073,6 @@[m [miWidget *makePreferences_Widget(void) {[m addPrefsInputWithHeading_(headings, values, "prefs.searchurl", iClob(searchUrl = new_InputWidget(0)));[m setUrlContent_InputWidget(searchUrl, iTrue);[m addDialogPadding_(headings, values);[m [31m- addDialogToggle_(headings, values, "${prefs.hoverlink}", "prefs.hoverlink");[m addDialogToggle_(headings, values, "${prefs.retaintabs}", "prefs.retaintabs");[m if (deviceType_App() != phone_AppDeviceType) {[m addChild_Widget(headings, iClob(makeHeading_Widget("${prefs.pinsplit}")));[m [36m@@ -3026,15 +3084,12 @@[m [miWidget *makePreferences_Widget(void) {[m }[m addChildFlags_Widget(values, iClob(pinSplit), arrangeHorizontal_WidgetFlag | arrangeSize_WidgetFlag);[m }[m [31m- addDialogToggle_(headings, values, "${prefs.markdown.viewsource}", "prefs.markdown.viewsource");[m [31m- addDialogToggle_(headings, values, "${prefs.bookmarks.addbottom}", "prefs.bookmarks.addbottom");[m [31m- addDialogToggle_(headings, values, "${prefs.archive.openindex}", "prefs.archive.openindex");[m [31m- addDialogToggle_(headings, values, "${prefs.dataurl.openimages}", "prefs.dataurl.openimages");[m addDialogPadding_(headings, values);[m /* UI languages. */ {[m iArray *uiLangs = collectNew_Array(sizeof(iMenuItem));[m pushBackN_Array(uiLangs, langItems, iElemCount(langItems) - 1);[m /* TODO: Add an arrange flag for resizing parent to widest child. */[m [32m+[m[32m /*[m size_t widestPos = findWidestLabel_MenuItem(data_Array(uiLangs), size_Array(uiLangs));[m addChild_Widget(headings, iClob(makeHeading_Widget("${prefs.uilang}")));[m setId_Widget(addChildFlags_Widget(values,[m [36m@@ -3042,87 +3097,17 @@[m [miWidget *makePreferences_Widget(void) {[m value_Array(uiLangs, widestPos, iMenuItem).label,[m data_Array(uiLangs),[m size_Array(uiLangs))),[m [31m- alignLeft_WidgetFlag),[m [31m- "prefs.uilang");[m [31m- }[m [31m- addDialogToggle_(headings, values, "${prefs.time.24h}", "prefs.time.24h");[m [31m- }[m [31m- /* User Interface. */ {[m [31m- setId_Widget(appendTwoColumnTabPage_Widget(tabs, "${heading.prefs.interface}", '2', &headings, &values),[m [31m- "prefs.page.ui");[m [31m- addDialogToggle_(headings, values, "${prefs.animate}", "prefs.animate");[m [31m- if (!isTerminal_Platform()) {[m [31m- addDialogToggle_(headings, values, "${prefs.blink}", "prefs.blink");[m [31m- }[m [31m- addDialogToggleGroup_([m [31m- headings,[m [31m- values,[m [31m- "${prefs.uilayout}",[m [31m- (const char *[]) {[m [31m-#if defined (LAGRANGE_MAC_MENUBAR)[m [31m- "prefs.bottomnavbar", "prefs.bottomtabbar", NULL[m [31m-#else[m [31m- "prefs.bottomnavbar", "prefs.bottomtabbar", "prefs.menubar", NULL[m [31m-#endif[m [31m- },[m [31m- iInvalidSize);[m [31m- addDialogToggle_(headings, values, "${prefs.evensplit}", "prefs.evensplit");[m [31m- addChild_Widget(headings, iClob(makeHeading_Widget("${prefs.returnkey}")));[m [31m- /* Return key behaviors. */ {[m [31m- iLabelWidget *returnKey = makeMenuButton_LabelWidget([m [31m- returnKeyBehaviors[findWidestLabel_MenuItem(returnKeyBehaviors,[m [31m- iElemCount(returnKeyBehaviors) - 1)][m [31m- .label,[m [31m- returnKeyBehaviors,[m [31m- iElemCount(returnKeyBehaviors) - 1);[m [31m- setBackgroundColor_Widget(findChild_Widget(as_Widget(returnKey), "menu"),[m [31m- uiBackgroundMenu_ColorId);[m [31m- setId_Widget(addChildFlags_Widget(values, iClob(returnKey), alignLeft_WidgetFlag),[m [31m- "prefs.returnkey");[m [31m- }[m [31m-#if defined (LAGRANGE_ENABLE_CUSTOM_FRAME)[m [31m- addDialogToggle_(headings, values, "${prefs.customframe}", "prefs.customframe");[m [31m-#endif[m [31m- makeTwoColumnHeading_("${heading.prefs.scrolling}", headings, values);[m [31m- addDialogToggle_(headings, values, "${prefs.smoothscroll}", "prefs.smoothscroll");[m [31m- /* Scroll speeds. */ {[m [31m- for (int type = 0; type < max_ScrollType; type++) {[m [31m- const char *typeStr = (type == mouse_ScrollType ? "mouse" : "keyboard");[m [31m- addChild_Widget(headings,[m [31m- iClob(makeHeading_Widget(type == mouse_ScrollType[m [31m- ? "${prefs.scrollspeed.mouse}"[m [31m- : "${prefs.scrollspeed.keyboard}")));[m [31m- /* TODO: Make a SliderWidget. */[m [31m- iWidget *scrollSpeed = new_Widget(); [m [31m- addRadioButton_(scrollSpeed, format_CStr("prefs.scrollspeed.%s.7", typeStr), "0", format_CStr("scrollspeed arg:7 type:%d", type));[m [31m- addRadioButton_(scrollSpeed, format_CStr("prefs.scrollspeed.%s.10", typeStr), "1", format_CStr("scrollspeed arg:10 type:%d", type));[m [31m- addRadioButton_(scrollSpeed, format_CStr("prefs.scrollspeed.%s.13", typeStr), "2", format_CStr("scrollspeed arg:13 type:%d", type));[m [31m- addRadioButton_(scrollSpeed, format_CStr("prefs.scrollspeed.%s.17", typeStr), "3", format_CStr("scrollspeed arg:17 type:%d", type));[m [31m- addRadioButton_(scrollSpeed, format_CStr("prefs.scrollspeed.%s.23", typeStr), "4", format_CStr("scrollspeed arg:23 type:%d", type));[m [31m- addRadioButton_(scrollSpeed, format_CStr("prefs.scrollspeed.%s.30", typeStr), "5", format_CStr("scrollspeed arg:30 type:%d", type));[m [31m- addRadioButton_(scrollSpeed, format_CStr("prefs.scrollspeed.%s.40", typeStr), "6", format_CStr("scrollspeed arg:40 type:%d", type));[m [31m- addChildFlags_Widget([m [31m- values, iClob(scrollSpeed), arrangeHorizontal_WidgetFlag | arrangeSize_WidgetFlag);[m [31m- }[m [31m- }[m [31m- if (!isTerminal_Platform()) {[m [31m- addDialogToggle_(headings, values, "${prefs.imageloadscroll}", "prefs.imageloadscroll");[m [31m- }[m [31m- if (deviceType_App() == phone_AppDeviceType) {[m [31m- addDialogToggle_(headings, values, "${prefs.hidetoolbarscroll}", "prefs.hidetoolbarscroll");[m [31m- }[m [31m- if (!isTerminal_Platform()) {[m [31m- makeTwoColumnHeading_("${heading.prefs.sizing}", headings, values);[m [31m- addPrefsInputWithHeading_(headings, values, "prefs.uiscale", iClob(new_InputWidget(5)));[m [31m- if (deviceType_App() == desktop_AppDeviceType) {[m [31m- addDialogToggle_(headings, values, "${prefs.retainwindow}", "prefs.retainwindow");[m [31m- }[m [32m+[m[32m algnLeft_WidgetFlag),[m [32m+[m[32m "prefs.uilang");*/[m [32m+[m[32m addDialogDropMenu_(headings, values, "${prefs.uilang}",[m [32m+[m[32m constData_Array(uiLangs), size_Array(uiLangs),[m [32m+[m[32m "prefs.uilang");[m }[m }[m [31m- /* Colors. */ {[m [31m- setId_Widget(appendTwoColumnTabPage_Widget(tabs, "${heading.prefs.colors}", '3', &headings, &values),[m [31m- "prefs.page.color");[m [31m- makeTwoColumnHeading_("${heading.prefs.uitheme}", headings, values);[m [32m+[m[32m /* Appearance. */ {[m [32m+[m[32m setId_Widget(appendTwoColumnTabPage_Widget(tabs, palette_Icon " ${heading.prefs.appearance}", red_ColorId, '2', &headings, &values),[m [32m+[m[32m "prefs.page.appearance");[m [32m+[m[32m// makeTwoColumnHeading_("${heading.prefs.uitheme}", headings, values);[m #if (defined (iPlatformApple) || defined (iPlatformMSys)) && !defined (iPlatformTerminal)[m addDialogToggle_(headings, values, "${prefs.ostheme}", "prefs.ostheme");[m #endif[m [36m@@ -3135,7 +3120,23 @@[m [miWidget *makePreferences_Widget(void) {[m setId_Widget(addChild_Widget(themes, iClob(new_LabelWidget("${prefs.theme.white}", "theme.set arg:3"))), "prefs.theme.3");[m }[m addChildFlags_Widget(values, iClob(themes), arrangeHorizontal_WidgetFlag | arrangeSize_WidgetFlag);[m [31m- /* Accents. */[m [32m+[m[32m /* Accents. */ {[m [32m+[m[32m iLabelWidget *accentMenu = addDialogDropMenu_(headings,[m [32m+[m[32m values,[m [32m+[m[32m "${prefs.accent}",[m [32m+[m[32m accentItems,[m [32m+[m[32m iElemCount(accentItems),[m [32m+[m[32m "prefs.accent");[m [32m+[m[32m int accentId = 0;[m [32m+[m[32m iForEach(ObjectList,[m [32m+[m[32m i,[m [32m+[m[32m children_Widget(findChild_Widget(constAs_Widget(accentMenu), "menu"))) {[m [32m+[m[32m if (isInstance_Object(i.object, &Class_LabelWidget)) {[m [32m+[m[32m setIconColor_LabelWidget(i.object, color_ColorAccent(accentId++, iTrue));[m [32m+[m[32m }[m [32m+[m[32m }[m [32m+[m[32m }[m [32m+[m[32m#if 0[m iWidget *accent = new_Widget(); {[m setId_Widget(addChild_Widget(accent, iClob(new_LabelWidget("${prefs.accent.teal}", "accent.set arg:0"))), "prefs.accent.0");[m setId_Widget(addChild_Widget(accent, iClob(new_LabelWidget("${prefs.accent.orange}", "accent.set arg:1"))), "prefs.accent.1");[m [36m@@ -3143,15 +3144,53 @@[m [miWidget *makePreferences_Widget(void) {[m setId_Widget(addChild_Widget(accent, iClob(new_LabelWidget("${prefs.accent.green}", "accent.set arg:3"))), "prefs.accent.3");[m setId_Widget(addChild_Widget(accent, iClob(new_LabelWidget("${prefs.accent.blue}", "accent.set arg:4"))), "prefs.accent.4");[m setId_Widget(addChild_Widget(accent, iClob(new_LabelWidget("${prefs.accent.gray}", "accent.set arg:5"))), "prefs.accent.5");[m [31m-#if defined (iPlatformApple)[m [32m+[m[32m# if defined (iPlatformApple)[m /* TODO: Re-enable this! Accent colors should now be applied in a way that suits [m the system accents, as long as there are light and dark variants. */[m // setId_Widget(addChild_Widget(accent, iClob(new_LabelWidget("${prefs.accent.system}", "accent.set arg:2"))), "prefs.accent.2");[m [31m-#endif[m [32m+[m[32m# endif[m }[m addChild_Widget(headings, iClob(makeHeading_Widget("${prefs.accent}")));[m addChildFlags_Widget(values, iClob(accent), arrangeHorizontal_WidgetFlag | arrangeSize_WidgetFlag);[m [31m- makeTwoColumnHeading_("${heading.prefs.pagecontent}", headings, values);[m [32m+[m[32m#endif[m [32m+[m[32m addDialogPadding_(headings, values);[m [32m+[m[32m#if defined (LAGRANGE_ENABLE_CUSTOM_FRAME)[m [32m+[m[32m addDialogToggle_(headings, values, "${prefs.customframe}", "prefs.customframe");[m [32m+[m[32m#endif[m [32m+[m[32m addDialogToggleGroup_([m [32m+[m[32m headings,[m [32m+[m[32m values,[m [32m+[m[32m "${prefs.uilayout}",[m [32m+[m[32m (const char *[]) {[m [32m+[m[32m#if defined (LAGRANGE_MAC_MENUBAR)[m [32m+[m[32m "prefs.bottomnavbar", "prefs.bottomtabbar", NULL[m [32m+[m[32m#else[m [32m+[m[32m "prefs.bottomnavbar", "prefs.bottomtabbar", "prefs.menubar", NULL[m [32m+[m[32m#endif[m [32m+[m[32m },[m [32m+[m[32m iInvalidSize);[m [32m+[m[32m addDialogToggle_(headings, values, "${prefs.evensplit}", "prefs.evensplit");[m[41m [m [32m+[m[32m if (!isTerminal_Platform()) {[m [32m+[m[32m addDialogPadding_(headings, values);[m [32m+[m[32m// makeTwoColumnHeading_("${heading.prefs.sizing}", headings, values);[m [32m+[m[32m addPrefsInputWithHeading_(headings, values, "prefs.uiscale", iClob(new_InputWidget(5)));[m [32m+[m[32m addDialogToggle_(headings, values, "${prefs.retainwindow}", "prefs.retainwindow");[m [32m+[m[32m addDialogPadding_(headings, values);[m [32m+[m[32m addChild_Widget(headings, iClob(makeHeading_Widget("${prefs.font.ui}")));[m [32m+[m[32m addFontButtons_(values, "ui");[m [32m+[m[32m addDialogToggle_(headings, values, "${prefs.font.smooth}", "prefs.font.smooth");[m[41m [m [32m+[m[32m }[m [32m+[m[32m }[m [32m+[m[32m /* Page style. */ {[m [32m+[m[32m setId_Widget(appendTwoColumnTabPage_Widget(tabs,[m [32m+[m[32m fonts_Icon " ${heading.prefs.style}",[m [32m+[m[32m orange_ColorId,[m [32m+[m[32m '3',[m [32m+[m[32m &headings,[m [32m+[m[32m &values),[m [32m+[m[32m "prefs.page.style");[m [32m+[m[32m // makeTwoColumnHeading_("${heading.prefs.paragraph}", headings, values);[m [32m+[m[32m // makeTwoColumnHeading_("${heading.prefs.pagecontent}", headings, values);[m for (int i = 0; i < 2; ++i) {[m const iBool isDark = (i == 0);[m const char *mode = isDark ? "dark" : "light";[m [36m@@ -3173,6 +3212,14 @@[m [miWidget *makePreferences_Widget(void) {[m addRadioButton_(sats, "prefs.saturation.0", "0 %", "saturation.set arg:0");[m }[m addChildFlags_Widget(values, iClob(sats), arrangeHorizontal_WidgetFlag | arrangeSize_WidgetFlag);[m [32m+[m[32m addDialogPadding_(headings, values);[m [32m+[m[32m addDialogToggleGroup_(headings,[m [32m+[m[32m values,[m [32m+[m[32m "${prefs.boldlink}",[m [32m+[m[32m (const char *[]){ "prefs.boldlink.visited",[m [32m+[m[32m "prefs.boldlink.dark",[m [32m+[m[32m "prefs.boldlink.light" },[m [32m+[m[32m 3);[m /* Colorize images. */ {[m addChild_Widget(headings, iClob(makeHeading_Widget("${prefs.imagestyle}")));[m iLabelWidget *button = makeMenuButton_LabelWidget([m [36m@@ -3184,11 +3231,10 @@[m [miWidget *makePreferences_Widget(void) {[m setId_Widget(addChildFlags_Widget(values, iClob(button), alignLeft_WidgetFlag),[m "prefs.imagestyle");[m }[m [31m- }[m [31m- /* Fonts. */ {[m [31m- setId_Widget(appendTwoColumnTabPage_Widget(tabs, "${heading.prefs.fonts}", '4', &headings, &values), "prefs.page.fonts");[m [31m- /* Fonts. */[m [32m+[m[32m// addDialogPadding_(headings, values);[m [32m+[m[32m /* Text settings. */[m if (!isTerminal_Platform()) {[m [32m+[m[32m makeTwoColumnHeading_("${heading.prefs.fonts}", headings, values);[m addChild_Widget(headings, iClob(makeHeading_Widget("${prefs.font.heading}")));[m addFontButtons_(values, "heading");[m addChild_Widget(headings, iClob(makeHeading_Widget("${prefs.font.body}")));[m [36m@@ -3203,28 +3249,20 @@[m [miWidget *makePreferences_Widget(void) {[m 2);[m addChild_Widget(headings, iClob(makeHeading_Widget("${prefs.font.monodoc}")));[m addFontButtons_(values, "monodoc");[m [31m- addDialogPadding_(headings, values);[m [31m- addDialogToggleGroup_(headings,[m [31m- values,[m [31m- "${prefs.gemtext.ansi}",[m [31m- (const char *[]){ "prefs.gemtext.ansi.fg",[m [31m- "prefs.gemtext.ansi.bg",[m [31m- "prefs.gemtext.ansi.fontstyle" },[m [31m- 3);[m [31m- addDialogToggle_(headings, values, "${prefs.font.warnmissing}", "prefs.font.warnmissing");[m [31m- addDialogToggle_(headings, values, "${prefs.font.smooth}", "prefs.font.smooth"); [m [31m- addDialogPadding_(headings, values);[m [31m- addChild_Widget(headings, iClob(makeHeading_Widget("${prefs.font.ui}")));[m [31m- addFontButtons_(values, "ui");[m }[m else {[m /* Terminal font settings. */[m addDialogToggle_(headings, values, "${prefs.tui.simple}", "prefs.tui.simple");[m }[m }[m [31m- /* Style. */ {[m [31m- setId_Widget(appendTwoColumnTabPage_Widget(tabs, "${heading.prefs.style}", '5', &headings, &values), "prefs.page.style");[m [31m-// makeTwoColumnHeading_("${heading.prefs.paragraph}", headings, values);[m [32m+[m[32m /* Page layout. */ {[m [32m+[m[32m setId_Widget(appendTwoColumnTabPage_Widget(tabs,[m [32m+[m[32m pageLayout_Icon " ${heading.prefs.layout}",[m [32m+[m[32m orange_ColorId,[m [32m+[m[32m '4',[m [32m+[m[32m &headings,[m [32m+[m[32m &values),[m [32m+[m[32m "prefs.page.layout");[m addChild_Widget(headings, iClob(makeHeading_Widget("${prefs.linewidth}")));[m iWidget *widths = new_Widget();[m /* Line widths. */ {[m [36m@@ -3241,37 +3279,110 @@[m [miWidget *makePreferences_Widget(void) {[m }[m addChildFlags_Widget(values, iClob(widths), arrangeHorizontal_WidgetFlag | arrangeSize_WidgetFlag);[m addPrefsInputWithHeading_(headings, values, "prefs.linespacing", iClob(new_InputWidget(5)));[m [32m+[m[32m addPrefsInputWithHeading_(headings, values, "prefs.tabwidth", iClob(new_InputWidget(5)));[m #if defined (LAGRANGE_ENABLE_HARFBUZZ)[m addDialogToggle_(headings, values, "${prefs.justify}", "prefs.justify");[m #endif[m addDialogToggle_(headings, values, "${prefs.biglede}", "prefs.biglede");[m [31m- addDialogToggle_(headings, values, "${prefs.plaintext.wrap}", "prefs.plaintext.wrap");[m [31m- addDialogToggle_(headings, values, "${prefs.gopher.gemstyle}", "prefs.gopher.gemstyle");[m addDialogPadding_(headings, values);[m [31m- addPrefsInputWithHeading_(headings, values, "prefs.tabwidth", iClob(new_InputWidget(5)));[m addChild_Widget(headings, iClob(makeHeading_Widget("${prefs.quoteicon}")));[m iWidget *quote = new_Widget(); {[m addRadioButton_(quote, "prefs.quoteicon.1", "${prefs.quoteicon.icon}", "quoteicon.set arg:1");[m addRadioButton_(quote, "prefs.quoteicon.0", "${prefs.quoteicon.line}", "quoteicon.set arg:0");[m }[m addChildFlags_Widget(values, iClob(quote), arrangeHorizontal_WidgetFlag | arrangeSize_WidgetFlag);[m [32m+[m[32m addDialogToggle_(headings, values, "${prefs.plaintext.wrap}", "prefs.plaintext.wrap");[m [32m+[m[32m addDialogPadding_(headings, values);[m [32m+[m[32m addDialogToggle_(headings, values, "${prefs.centershort}", "prefs.centershort");[m [32m+[m[32m addDialogToggle_(headings, values, "${prefs.sideicon}", "prefs.sideicon");[m [32m+[m[32m addDialogToggle_(headings, values, "${prefs.collapsepreonload}", "prefs.collapsepreonload");[m [32m+[m[32m }[m [32m+[m[32m /* Content. */ {[m [32m+[m[32m setId_Widget(appendTwoColumnTabPage_Widget(tabs, photo_Icon " ${heading.prefs.content}", green_ColorId, '5', &headings, &values), "prefs.page.content");[m addDialogToggleGroup_(headings,[m values,[m [31m- "${prefs.boldlink}",[m [31m- (const char *[]){ "prefs.boldlink.visited",[m [31m- "prefs.boldlink.dark",[m [31m- "prefs.boldlink.light" },[m [32m+[m[32m "${prefs.gemtext.ansi}",[m [32m+[m[32m (const char *[]){ "prefs.gemtext.ansi.fg",[m [32m+[m[32m "prefs.gemtext.ansi.bg",[m [32m+[m[32m "prefs.gemtext.ansi.fontstyle" },[m 3);[m [32m+[m[32m addDialogToggle_(headings, values, "${prefs.gopher.gemstyle}", "prefs.gopher.gemstyle");[m [32m+[m[32m addDialogToggle_(headings, values, "${prefs.markdown.viewsource}", "prefs.markdown.viewsource");[m addDialogPadding_(headings, values);[m [31m- addDialogToggle_(headings, values, "${prefs.sideicon}", "prefs.sideicon");[m [31m- addDialogToggle_(headings, values, "${prefs.centershort}", "prefs.centershort");[m [31m- addDialogToggle_(headings, values, "${prefs.collapsepreonload}", "prefs.collapsepreonload");[m [32m+[m[32m addDialogToggle_(headings, values, "${prefs.dataurl.openimages}", "prefs.dataurl.openimages");[m [32m+[m[32m addDialogToggle_(headings, values, "${prefs.archive.openindex}", "prefs.archive.openindex");[m[41m [m [32m+[m[32m addDialogPadding_(headings, values);[m [32m+[m[32m addDialogToggle_(headings, values, "${prefs.font.warnmissing}", "prefs.font.warnmissing");[m [32m+[m[32m }[m [32m+[m[32m /* User Interface. */ {[m [32m+[m[32m setId_Widget(appendTwoColumnTabPage_Widget(tabs, computer_Icon " ${heading.prefs.interface}", cyan_ColorId, '6', &headings, &values),[m [32m+[m[32m "prefs.page.ui");[m [32m+[m[32m addDialogToggle_(headings, values, "${prefs.hoverlink}", "prefs.hoverlink");[m [32m+[m[32m addDialogToggle_(headings, values, "${prefs.bookmarks.addbottom}", "prefs.bookmarks.addbottom");[m [32m+[m[32m /* Return key behaviors. */ {[m [32m+[m[32m addChild_Widget(headings, iClob(makeHeading_Widget("${prefs.returnkey}")));[m [32m+[m[32m iLabelWidget *returnKey = makeMenuButton_LabelWidget([m [32m+[m[32m returnKeyBehaviors[findWidestLabel_MenuItem(returnKeyBehaviors,[m [32m+[m[32m iElemCount(returnKeyBehaviors) - 1)][m [32m+[m[32m .label,[m [32m+[m[32m returnKeyBehaviors,[m [32m+[m[32m iElemCount(returnKeyBehaviors) - 1);[m [32m+[m[32m setBackgroundColor_Widget(findChild_Widget(as_Widget(returnKey), "menu"),[m [32m+[m[32m uiBackgroundMenu_ColorId);[m [32m+[m[32m setId_Widget(addChildFlags_Widget(values, iClob(returnKey), alignLeft_WidgetFlag),[m [32m+[m[32m "prefs.returnkey");[m [32m+[m[32m }[m [32m+[m[32m if (!isTerminal_Platform()) {[m [32m+[m[32m addDialogToggle_(headings, values, "${prefs.imageloadscroll}", "prefs.imageloadscroll");[m [32m+[m[32m }[m [32m+[m[32m addDialogToggle_(headings, values, "${prefs.time.24h}", "prefs.time.24h");[m [32m+[m[32m addDialogPadding_(headings, values);[m [32m+[m[32m addDialogToggle_(headings, values, "${prefs.animate}", "prefs.animate");[m [32m+[m[32m if (!isTerminal_Platform()) {[m [32m+[m[32m addDialogToggle_(headings, values, "${prefs.blink}", "prefs.blink");[m [32m+[m[32m }[m [32m+[m[32m// makeTwoColumnHeading_("${heading.prefs.scrolling}", headings, values);[m [32m+[m[32m addDialogToggle_(headings, values, "${prefs.smoothscroll}", "prefs.smoothscroll");[m [32m+[m[32m /* Scroll speeds. */ {[m [32m+[m[32m for (int type = 0; type < max_ScrollType; type++) {[m [32m+[m[32m const char *typeStr = (type == mouse_ScrollType ? "mouse" : "keyboard");[m [32m+[m[32m addChild_Widget(headings,[m [32m+[m[32m iClob(makeHeading_Widget(type == mouse_ScrollType[m [32m+[m[32m ? "${prefs.scrollspeed.mouse}"[m [32m+[m[32m : "${prefs.scrollspeed.keyboard}")));[m [32m+[m[32m /* TODO: Make a SliderWidget. */[m [32m+[m[32m iWidget *scrollSpeed = new_Widget();[m[41m [m [32m+[m[32m addRadioButton_(scrollSpeed, format_CStr("prefs.scrollspeed.%s.7", typeStr), "0", format_CStr("scrollspeed arg:7 type:%d", type));[m [32m+[m[32m addRadioButton_(scrollSpeed, format_CStr("prefs.scrollspeed.%s.10", typeStr), "1", format_CStr("scrollspeed arg:10 type:%d", type));[m [32m+[m[32m addRadioButton_(scrollSpeed, format_CStr("prefs.scrollspeed.%s.13", typeStr), "2", format_CStr("scrollspeed arg:13 type:%d", type));[m [32m+[m[32m addRadioButton_(scrollSpeed, format_CStr("prefs.scrollspeed.%s.17", typeStr), "3", format_CStr("scrollspeed arg:17 type:%d", type));[m [32m+[m[32m addRadioButton_(scrollSpeed, format_CStr("prefs.scrollspeed.%s.23", typeStr), "4", format_CStr("scrollspeed arg:23 type:%d", type));[m [32m+[m[32m addRadioButton_(scrollSpeed, format_CStr("prefs.scrollspeed.%s.30", typeStr), "5", format_CStr("scrollspeed arg:30 type:%d", type));[m [32m+[m[32m addRadioButton_(scrollSpeed, format_CStr("prefs.scrollspeed.%s.40", typeStr), "6", format_CStr("scrollspeed arg:40 type:%d", type));[m [32m+[m[32m addChildFlags_Widget([m [32m+[m[32m values, iClob(scrollSpeed), arrangeHorizontal_WidgetFlag | arrangeSize_WidgetFlag);[m [32m+[m[32m }[m [32m+[m[32m }[m [32m+[m[32m// if (deviceType_App() == phone_AppDeviceType) {[m [32m+[m[32m// addDialogToggle_(headings, values, "${prefs.hidetoolbarscroll}", "prefs.hidetoolbarscroll");[m [32m+[m[32m// }[m [32m+[m[32m }[m [32m+[m[32m /* Keybindings. */ {[m [32m+[m[32m iBindingsWidget *bind = new_BindingsWidget();[m [32m+[m[32m appendFramelessTabPage_Widget(tabs, iClob(bind), keyboard_Icon " ${heading.prefs.keys}", cyan_ColorId, '7', KMOD_PRIMARY);[m }[m /* Network. */ {[m [31m- setId_Widget(appendTwoColumnTabPage_Widget(tabs, "${heading.prefs.network}", '6', &headings, &values), "prefs.page.network");[m [32m+[m[32m setId_Widget(appendTwoColumnTabPage_Widget(tabs,[m [32m+[m[32m network_Icon " ${heading.prefs.network}",[m [32m+[m[32m blue_ColorId,[m [32m+[m[32m '8',[m [32m+[m[32m &headings,[m [32m+[m[32m &values),[m [32m+[m[32m "prefs.page.network");[m addChild_Widget(headings, iClob(makeHeading_Widget("${prefs.decodeurls}")));[m addChild_Widget(values, iClob(makeToggle_Widget("prefs.decodeurls")));[m addPrefsInputWithHeading_(headings, values, "prefs.urlsize", iClob(new_InputWidget(10)));[m [32m+[m[32m addDialogPadding_(headings, values);[m /* Cache size. */ {[m iInputWidget *cache = new_InputWidget(4);[m setSelectAllOnFocus_InputWidget(cache, iTrue);[m [36m@@ -3294,17 +3405,14 @@[m [miWidget *makePreferences_Widget(void) {[m resizeToParentHeight_WidgetFlag);[m setContentPadding_InputWidget(mem, 0, width_Widget(unit) - 4 * gap_UI);[m }[m [31m- makeTwoColumnHeading_("${heading.prefs.certs}", headings, values);[m [31m- addPrefsInputWithHeading_(headings, values, "prefs.ca.file", iClob(new_InputWidget(0)));[m [31m- addPrefsInputWithHeading_(headings, values, "prefs.ca.path", iClob(new_InputWidget(0)));[m makeTwoColumnHeading_("${heading.prefs.proxies}", headings, values);[m addPrefsInputWithHeading_(headings, values, "prefs.proxy.gemini", iClob(new_InputWidget(0)));[m addPrefsInputWithHeading_(headings, values, "prefs.proxy.gopher", iClob(new_InputWidget(0)));[m addPrefsInputWithHeading_(headings, values, "prefs.proxy.http", iClob(new_InputWidget(0)));[m [32m+[m[32m makeTwoColumnHeading_("${heading.prefs.certs}", headings, values);[m [32m+[m[32m addPrefsInputWithHeading_(headings, values, "prefs.ca.file", iClob(new_InputWidget(0)));[m [32m+[m[32m addPrefsInputWithHeading_(headings, values, "prefs.ca.path", iClob(new_InputWidget(0)));[m }[m [31m- /* Keybindings. */[m [31m- iBindingsWidget *bind = new_BindingsWidget();[m [31m- appendFramelessTabPage_Widget(tabs, iClob(bind), "${heading.prefs.keys}", '7', KMOD_PRIMARY);[m addChild_Widget(dlg, iClob(makePadding_Widget(gap_UI)));[m updatePreferencesLayout_Widget(dlg);[m const iMenuItem actions[] = { { "${menu.fonts}", 0, 0, "!open url:about:fonts" },[m [36m@@ -3314,7 +3422,7 @@[m [miWidget *makePreferences_Widget(void) {[m iWidget *buttons = addChild_Widget([m dlg, iClob(makeDialogButtons_Widget(actions + actOffset, iElemCount(actions) - actOffset)));[m setId_Widget(child_Widget(buttons, 0), "prefs.aboutfonts");[m [31m- setFlags_Widget(findChild_Widget(dlg, "prefs.aboutfonts"), hidden_WidgetFlag, iTrue);[m [32m+[m[32m// setFlags_Widget(findChild_Widget(dlg, "prefs.aboutfonts"), hidden_WidgetFlag, iTrue);[m addChild_Widget(dlg->root->widget, iClob(dlg)); [m setupSheetTransition_Mobile(dlg, iTrue);[m return dlg;[m [36m@@ -3450,7 +3558,7 @@[m [miWidget *makeBookmarkEditor_Widget(uint32_t folderId, iBool withDup) {[m setHint_InputWidget(inputs[3], "${hint.dlg.bookmark.notes}");[m addDialogInputWithHeading_(headings, values, "${dlg.bookmark.icon}", "bmed.icon", iClob(inputs[4] = new_InputWidget(1))); [m /* Buttons for special tags. */[m [31m- addChild_Widget(dlg, iClob(makePadding_Widget(gap_UI)));[m [32m+[m[32m// addChild_Widget(dlg, iClob(makePadding_Widget(gap_UI)));[m iWidget *special = addChild_Widget(dlg, iClob(makeTwoColumns_Widget(&headings, &values)));[m setFlags_Widget(special, collapse_WidgetFlag, iTrue);[m setId_Widget(special, "bmed.special");[m [1mdiff --git a/src/ui/util.h b/src/ui/util.h[m [1mindex b05550df..bb661944 100644[m [1m--- a/src/ui/util.h[m [1m+++ b/src/ui/util.h[m [36m@@ -330,10 +330,11 @@[m [miWidget * makeMenuBar_Widget (const iMenuItem *topLevelMenus, size_t[m [m iWidget * makeTabs_Widget (iWidget *parent);[m void setTabBarPosition_Widget(iWidget *tabs, iBool atBottom);[m [32m+[m[32mvoid setVerticalTabBar_Widget(iWidget *tabs);[m void appendTabPage_Widget (iWidget *tabs, iWidget *page, const char *label, int key, int kmods);[m [31m-void appendFramelessTabPage_Widget(iWidget *tabs, iWidget *page, const char *title, int shortcut, int kmods);[m [31m-iWidget * appendTwoColumnTabPage_Widget(iWidget *tabs, const char *title, int shortcut, iWidget **headings,[m [31m- iWidget **values);[m [32m+[m[32mvoid appendFramelessTabPage_Widget(iWidget *tabs, iWidget *page, const char *title, int iconColor, int shortcut, int kmods);[m [32m+[m[32miWidget * appendTwoColumnTabPage_Widget(iWidget *tabs, const char *title, int iconColor, int shortcut,[m [32m+[m[32m iWidget **headings, iWidget **values);[m void prependTabPage_Widget (iWidget *tabs, iWidget *page, const char *label, int key, int kmods);[m iWidget * removeTabPage_Widget (iWidget *tabs, size_t index); /* returns the page */[m void resizeToLargestPage_Widget (iWidget *tabs);[m [36m@@ -342,6 +343,7 @@[m [mvoid addTabCloseButton_Widget(iWidget *tabs, const iWidget *page, con[m void setTabPageLabel_Widget (iWidget *tabs, const iAnyObject *page, const iString *label);[m iWidget * tabPage_Widget (iWidget *tabs, size_t index);[m iLabelWidget * tabPageButton_Widget (iWidget *tabs, const iAnyObject *page);[m [32m+[m[32miBool isVerticalTabBar_Widget (const iWidget *tabs);[m iBool isTabButton_Widget (const iWidget *);[m void moveTabButtonToEnd_Widget(iWidget *tabButton);[m size_t tabPageIndex_Widget (const iWidget *tabs, const iAnyObject *page);[m
text/gemini; charset=utf-8
This content has been proxied by September (3851b).