summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--res/about/version.gmi2
-rw-r--r--src/app.c16
-rw-r--r--src/gmdocument.c9
-rw-r--r--src/gmdocument.h1
-rw-r--r--src/prefs.c1
-rw-r--r--src/prefs.h1
-rw-r--r--src/ui/documentwidget.c11
-rw-r--r--src/ui/util.c6
-rw-r--r--src/ui/window.c12
-rw-r--r--src/ui/window.h1
10 files changed, 55 insertions, 5 deletions
diff --git a/res/about/version.gmi b/res/about/version.gmi
index 488db36c..70f6135f 100644
--- a/res/about/version.gmi
+++ b/res/about/version.gmi
@@ -9,7 +9,9 @@
9## 0.6 9## 0.6
10* Added new color themes for page content: Colorful Light, Black, Gray, Sepia, High Contrast. 10* Added new color themes for page content: Colorful Light, Black, Gray, Sepia, High Contrast.
11* Dark and light mode page content themes can be chosen in Preferences. 11* Dark and light mode page content themes can be chosen in Preferences.
12* Added quote indicator option: icon or vertical line.
12* macOS: Fixed glitchy window dragging during audio playback. 13* macOS: Fixed glitchy window dragging during audio playback.
14* Fixed cached page timestamps.
13 15
14## 0.5 16## 0.5
15* Added MP3 support in the audio player (using mpg123). 17* Added MP3 support in the audio player (using mpg123).
diff --git a/src/app.c b/src/app.c
index b38f8ae2..da106141 100644
--- a/src/app.c
+++ b/src/app.c
@@ -182,6 +182,7 @@ static iString *serializePrefs_App_(const iApp *d) {
182 appendFormat_String(str, "linewidth.set arg:%d\n", d->prefs.lineWidth); 182 appendFormat_String(str, "linewidth.set arg:%d\n", d->prefs.lineWidth);
183 appendFormat_String(str, "prefs.biglede.changed arg:%d\n", d->prefs.bigFirstParagraph); 183 appendFormat_String(str, "prefs.biglede.changed arg:%d\n", d->prefs.bigFirstParagraph);
184 appendFormat_String(str, "prefs.sideicon.changed arg:%d\n", d->prefs.sideIcon); 184 appendFormat_String(str, "prefs.sideicon.changed arg:%d\n", d->prefs.sideIcon);
185 appendFormat_String(str, "quoteicon.set arg:%d\n", d->prefs.quoteIcon ? 1 : 0);
185 appendFormat_String(str, "prefs.hoveroutline.changed arg:%d\n", d->prefs.hoverOutline); 186 appendFormat_String(str, "prefs.hoveroutline.changed arg:%d\n", d->prefs.hoverOutline);
186 appendFormat_String(str, "theme.set arg:%d auto:1\n", d->prefs.theme); 187 appendFormat_String(str, "theme.set arg:%d auto:1\n", d->prefs.theme);
187 appendFormat_String(str, "ostheme arg:%d\n", d->prefs.useSystemTheme); 188 appendFormat_String(str, "ostheme arg:%d\n", d->prefs.useSystemTheme);
@@ -735,6 +736,12 @@ static iBool handlePrefsCommands_(iWidget *d, const char *cmd) {
735 destroy_Widget(d); 736 destroy_Widget(d);
736 return iTrue; 737 return iTrue;
737 } 738 }
739 else if (equal_Command(cmd, "quoteicon.set")) {
740 const int arg = arg_Command(cmd);
741 setFlags_Widget(findChild_Widget(d, "prefs.quoteicon.0"), selected_WidgetFlag, arg == 0);
742 setFlags_Widget(findChild_Widget(d, "prefs.quoteicon.1"), selected_WidgetFlag, arg == 1);
743 return iFalse;
744 }
738 else if (equal_Command(cmd, "doctheme.dark.set")) { 745 else if (equal_Command(cmd, "doctheme.dark.set")) {
739 updateColorThemeButton_(findChild_Widget(d, "prefs.doctheme.dark"), arg_Command(cmd)); 746 updateColorThemeButton_(findChild_Widget(d, "prefs.doctheme.dark"), arg_Command(cmd));
740 return iFalse; 747 return iFalse;
@@ -946,6 +953,11 @@ iBool handleCommand_App(const char *cmd) {
946 postCommand_App("document.layout.changed"); 953 postCommand_App("document.layout.changed");
947 return iTrue; 954 return iTrue;
948 } 955 }
956 else if (equal_Command(cmd, "quoteicon.set")) {
957 d->prefs.quoteIcon = arg_Command(cmd) != 0;
958 postCommand_App("document.layout.changed");
959 return iTrue;
960 }
949 else if (equal_Command(cmd, "prefs.biglede.changed")) { 961 else if (equal_Command(cmd, "prefs.biglede.changed")) {
950 d->prefs.bigFirstParagraph = arg_Command(cmd) != 0; 962 d->prefs.bigFirstParagraph = arg_Command(cmd) != 0;
951 postCommand_App("document.layout.changed"); 963 postCommand_App("document.layout.changed");
@@ -1091,6 +1103,10 @@ iBool handleCommand_App(const char *cmd) {
1091 findChild_Widget(dlg, format_CStr("prefs.linewidth.%d", d->prefs.lineWidth)), 1103 findChild_Widget(dlg, format_CStr("prefs.linewidth.%d", d->prefs.lineWidth)),
1092 selected_WidgetFlag, 1104 selected_WidgetFlag,
1093 iTrue); 1105 iTrue);
1106 setFlags_Widget(
1107 findChild_Widget(dlg, format_CStr("prefs.quoteicon.%d", d->prefs.quoteIcon)),
1108 selected_WidgetFlag,
1109 iTrue);
1094 setToggle_Widget(findChild_Widget(dlg, "prefs.biglede"), d->prefs.bigFirstParagraph); 1110 setToggle_Widget(findChild_Widget(dlg, "prefs.biglede"), d->prefs.bigFirstParagraph);
1095 setToggle_Widget(findChild_Widget(dlg, "prefs.sideicon"), d->prefs.sideIcon); 1111 setToggle_Widget(findChild_Widget(dlg, "prefs.sideicon"), d->prefs.sideIcon);
1096 updateColorThemeButton_(findChild_Widget(dlg, "prefs.doctheme.dark"), d->prefs.docThemeDark); 1112 updateColorThemeButton_(findChild_Widget(dlg, "prefs.doctheme.dark"), d->prefs.docThemeDark);
diff --git a/src/gmdocument.c b/src/gmdocument.c
index 7982d57b..f2ac936f 100644
--- a/src/gmdocument.c
+++ b/src/gmdocument.c
@@ -290,7 +290,7 @@ static void doLayout_GmDocument_(iGmDocument *d) {
290 iRangecc contentLine = iNullRange; 290 iRangecc contentLine = iNullRange;
291 iInt2 pos = zero_I2(); 291 iInt2 pos = zero_I2();
292 iBool isFirstText = isGemini && prefs->bigFirstParagraph; 292 iBool isFirstText = isGemini && prefs->bigFirstParagraph;
293 iBool addQuoteIcon = iTrue; 293 iBool addQuoteIcon = prefs->quoteIcon;
294 iBool isPreformat = iFalse; 294 iBool isPreformat = iFalse;
295 iRangecc preAltText = iNullRange; 295 iRangecc preAltText = iNullRange;
296 int preFont = preformatted_FontId; 296 int preFont = preformatted_FontId;
@@ -446,7 +446,7 @@ static void doLayout_GmDocument_(iGmDocument *d) {
446 pushBack_Array(&d->layout, &quoteRun); 446 pushBack_Array(&d->layout, &quoteRun);
447 } 447 }
448 else if (type != quote_GmLineType) { 448 else if (type != quote_GmLineType) {
449 addQuoteIcon = iTrue; 449 addQuoteIcon = prefs->quoteIcon;
450 } 450 }
451 /* Link icon. */ 451 /* Link icon. */
452 if (type == link_GmLineType) { 452 if (type == link_GmLineType) {
@@ -485,6 +485,9 @@ static void doLayout_GmDocument_(iGmDocument *d) {
485 iRangecc runLine = line; 485 iRangecc runLine = line;
486 /* Create one or more text runs for this line. */ 486 /* Create one or more text runs for this line. */
487 run.flags |= startOfLine_GmRunFlag; 487 run.flags |= startOfLine_GmRunFlag;
488 if (!prefs->quoteIcon && type == quote_GmLineType) {
489 run.flags |= quoteBorder_GmRunFlag;
490 }
488 iAssert(!isEmpty_Range(&runLine)); /* must have something at this point */ 491 iAssert(!isEmpty_Range(&runLine)); /* must have something at this point */
489 while (!isEmpty_Range(&runLine)) { 492 while (!isEmpty_Range(&runLine)) {
490 /* Little bit of breathing space between wrapped lines. */ 493 /* Little bit of breathing space between wrapped lines. */
@@ -835,7 +838,7 @@ void setThemeSeed_GmDocument(iGmDocument *d, const iBlock *seed) {
835 violet_Hue, 838 violet_Hue,
836 pink_Hue 839 pink_Hue
837 }; 840 };
838 static const float hues[] = { 5, 25, 40, 56, 80, 120, 160, 180, 208, 231, 270, 324 }; 841 static const float hues[] = { 5, 25, 40, 56, 80, 120, 160, 180, 208, 231, 270, 324 };
839 static const struct { 842 static const struct {
840 int index[2]; 843 int index[2];
841 } altHues[iElemCount(hues)] = { 844 } altHues[iElemCount(hues)] = {
diff --git a/src/gmdocument.h b/src/gmdocument.h
index 05bf026c..f27446ab 100644
--- a/src/gmdocument.h
+++ b/src/gmdocument.h
@@ -79,6 +79,7 @@ enum iGmRunFlags {
79 startOfLine_GmRunFlag = iBit(2), 79 startOfLine_GmRunFlag = iBit(2),
80 endOfLine_GmRunFlag = iBit(3), 80 endOfLine_GmRunFlag = iBit(3),
81 siteBanner_GmRunFlag = iBit(4), /* area reserved for the site banner */ 81 siteBanner_GmRunFlag = iBit(4), /* area reserved for the site banner */
82 quoteBorder_GmRunFlag = iBit(5),
82}; 83};
83 84
84struct Impl_GmRun { 85struct Impl_GmRun {
diff --git a/src/prefs.c b/src/prefs.c
index 146f3838..1fcb1b8e 100644
--- a/src/prefs.c
+++ b/src/prefs.c
@@ -7,6 +7,7 @@ void init_Prefs(iPrefs *d) {
7 d->retainWindowSize = iTrue; 7 d->retainWindowSize = iTrue;
8 d->zoomPercent = 100; 8 d->zoomPercent = 100;
9 d->forceLineWrap = iFalse; 9 d->forceLineWrap = iFalse;
10 d->quoteIcon = iTrue;
10 d->font = nunito_TextFont; 11 d->font = nunito_TextFont;
11 d->headingFont = nunito_TextFont; 12 d->headingFont = nunito_TextFont;
12 d->lineWidth = 40; 13 d->lineWidth = 40;
diff --git a/src/prefs.h b/src/prefs.h
index a19cc0ca..bfc0c174 100644
--- a/src/prefs.h
+++ b/src/prefs.h
@@ -25,6 +25,7 @@ struct Impl_Prefs {
25 int lineWidth; 25 int lineWidth;
26 iBool bigFirstParagraph; 26 iBool bigFirstParagraph;
27 iBool forceLineWrap; 27 iBool forceLineWrap;
28 iBool quoteIcon;
28 iBool sideIcon; 29 iBool sideIcon;
29 iBool hoverOutline; 30 iBool hoverOutline;
30 enum iGmDocumentTheme docThemeDark; 31 enum iGmDocumentTheme docThemeDark;
diff --git a/src/ui/documentwidget.c b/src/ui/documentwidget.c
index 558c320d..8d3716a6 100644
--- a/src/ui/documentwidget.c
+++ b/src/ui/documentwidget.c
@@ -1234,6 +1234,10 @@ static iBool handleCommand_DocumentWidget_(iDocumentWidget *d, const char *cmd)
1234 refresh_Widget(w); 1234 refresh_Widget(w);
1235 updateWindowTitle_DocumentWidget_(d); 1235 updateWindowTitle_DocumentWidget_(d);
1236 } 1236 }
1237 else if (equal_Command(cmd, "window.mouse.exited")) {
1238 updateOutlineOpacity_DocumentWidget_(d);
1239 return iFalse;
1240 }
1237 else if (equal_Command(cmd, "theme.changed") && document_App() == d) { 1241 else if (equal_Command(cmd, "theme.changed") && document_App() == d) {
1238 updateTheme_DocumentWidget_(d); 1242 updateTheme_DocumentWidget_(d);
1239 invalidate_DocumentWidget_(d); 1243 invalidate_DocumentWidget_(d);
@@ -2116,7 +2120,6 @@ static void drawRun_DrawContext_(void *context, const iGmRun *run) {
2116 } 2120 }
2117 else if (run->audioId) { 2121 else if (run->audioId) {
2118 /* Audio player UI is drawn afterwards as a dynamic overlay. */ 2122 /* Audio player UI is drawn afterwards as a dynamic overlay. */
2119 //fillRect_Paint(&d->paint, moved_Rect(run->visBounds, origin), red_ColorId);
2120 return; 2123 return;
2121 } 2124 }
2122 enum iColorId fg = run->color; 2125 enum iColorId fg = run->color;
@@ -2181,6 +2184,12 @@ static void drawRun_DrawContext_(void *context, const iGmRun *run) {
2181 goto runDrawn; 2184 goto runDrawn;
2182 } 2185 }
2183 } 2186 }
2187 if (run->flags & quoteBorder_GmRunFlag) {
2188 drawVLine_Paint(&d->paint,
2189 addX_I2(visPos, -gap_Text * 5 / 2),
2190 height_Rect(run->visBounds),
2191 tmQuoteIcon_ColorId);
2192 }
2184 drawRange_Text(run->font, visPos, fg, run->text); 2193 drawRange_Text(run->font, visPos, fg, run->text);
2185// printf("{%s}\n", cstr_Rangecc(run->text)); 2194// printf("{%s}\n", cstr_Rangecc(run->text));
2186 runDrawn:; 2195 runDrawn:;
diff --git a/src/ui/util.c b/src/ui/util.c
index 35eea9c3..bef839dc 100644
--- a/src/ui/util.c
+++ b/src/ui/util.c
@@ -991,6 +991,12 @@ iWidget *makePreferences_Widget(void) {
991 addRadioButton_(widths, "prefs.linewidth.1000", "Window", "linewidth.set arg:1000"); 991 addRadioButton_(widths, "prefs.linewidth.1000", "Window", "linewidth.set arg:1000");
992 } 992 }
993 addChildFlags_Widget(values, iClob(widths), arrangeHorizontal_WidgetFlag | arrangeSize_WidgetFlag); 993 addChildFlags_Widget(values, iClob(widths), arrangeHorizontal_WidgetFlag | arrangeSize_WidgetFlag);
994 addChild_Widget(headings, iClob(makeHeading_Widget("Quote indicator:")));
995 iWidget *quote = new_Widget(); {
996 addRadioButton_(quote, "prefs.quoteicon.1", "Icon", "quoteicon.set arg:1");
997 addRadioButton_(quote, "prefs.quoteicon.0", "Line", "quoteicon.set arg:0");
998 }
999 addChildFlags_Widget(values, iClob(quote), arrangeHorizontal_WidgetFlag | arrangeSize_WidgetFlag);
994 addChild_Widget(headings, iClob(makeHeading_Widget("Big 1st paragaph:"))); 1000 addChild_Widget(headings, iClob(makeHeading_Widget("Big 1st paragaph:")));
995 addChild_Widget(values, iClob(makeToggle_Widget("prefs.biglede"))); 1001 addChild_Widget(values, iClob(makeToggle_Widget("prefs.biglede")));
996 makeTwoColumnHeading_("WIDE LAYOUT", headings, values); 1002 makeTwoColumnHeading_("WIDE LAYOUT", headings, values);
diff --git a/src/ui/window.c b/src/ui/window.c
index 40215506..c5194ea0 100644
--- a/src/ui/window.c
+++ b/src/ui/window.c
@@ -524,6 +524,7 @@ void init_Window(iWindow *d, iRect rect) {
524 d->lastRect = rect; 524 d->lastRect = rect;
525 d->pendingCursor = NULL; 525 d->pendingCursor = NULL;
526 d->isDrawFrozen = iTrue; 526 d->isDrawFrozen = iTrue;
527 d->isMouseInside = iTrue;
527 uint32_t flags = 0; 528 uint32_t flags = 0;
528#if defined (iPlatformApple) 529#if defined (iPlatformApple)
529 SDL_SetHint(SDL_HINT_RENDER_DRIVER, shouldDefaultToMetalRenderer_MacOS() ? "metal" : "opengl"); 530 SDL_SetHint(SDL_HINT_RENDER_DRIVER, shouldDefaultToMetalRenderer_MacOS() ? "metal" : "opengl");
@@ -543,7 +544,7 @@ void init_Window(iWindow *d, iRect rect) {
543 if (left_Rect(rect) >= 0 || top_Rect(rect) >= 0) { 544 if (left_Rect(rect) >= 0 || top_Rect(rect) >= 0) {
544 SDL_SetWindowPosition(d->win, left_Rect(rect), top_Rect(rect)); 545 SDL_SetWindowPosition(d->win, left_Rect(rect), top_Rect(rect));
545 } 546 }
546 const iInt2 minSize = init_I2(425, 250); 547 const iInt2 minSize = init_I2(425, 300);
547 SDL_SetWindowMinimumSize(d->win, minSize.x, minSize.y); 548 SDL_SetWindowMinimumSize(d->win, minSize.x, minSize.y);
548 SDL_SetWindowTitle(d->win, "Lagrange"); 549 SDL_SetWindowTitle(d->win, "Lagrange");
549 /* Some info. */ { 550 /* Some info. */ {
@@ -655,6 +656,12 @@ static iBool handleWindowEvent_Window_(iWindow *d, const SDL_WindowEvent *ev) {
655 return iTrue; 656 return iTrue;
656 case SDL_WINDOWEVENT_LEAVE: 657 case SDL_WINDOWEVENT_LEAVE:
657 unhover_Widget(); 658 unhover_Widget();
659 d->isMouseInside = iFalse;
660 postCommand_App("window.mouse.exited");
661 return iTrue;
662 case SDL_WINDOWEVENT_ENTER:
663 d->isMouseInside = iTrue;
664 postCommand_App("window.mouse.entered");
658 return iTrue; 665 return iTrue;
659 default: 666 default:
660 break; 667 break;
@@ -812,6 +819,9 @@ iInt2 coord_Window(const iWindow *d, int x, int y) {
812} 819}
813 820
814iInt2 mouseCoord_Window(const iWindow *d) { 821iInt2 mouseCoord_Window(const iWindow *d) {
822 if (!d->isMouseInside) {
823 return init_I2(-1000000, -1000000);
824 }
815 int x, y; 825 int x, y;
816 SDL_GetMouseState(&x, &y); 826 SDL_GetMouseState(&x, &y);
817 return coord_Window(d, x, y); 827 return coord_Window(d, x, y);
diff --git a/src/ui/window.h b/src/ui/window.h
index da4a2123..3ede1578 100644
--- a/src/ui/window.h
+++ b/src/ui/window.h
@@ -37,6 +37,7 @@ struct Impl_Window {
37 iInt2 initialPos; 37 iInt2 initialPos;
38 iRect lastRect; /* updated when window is moved/resized */ 38 iRect lastRect; /* updated when window is moved/resized */
39 iBool isDrawFrozen; /* avoids premature draws while restoring window state */ 39 iBool isDrawFrozen; /* avoids premature draws while restoring window state */
40 iBool isMouseInside;
40 SDL_Renderer *render; 41 SDL_Renderer *render;
41 iWidget * root; 42 iWidget * root;
42 float pixelRatio; 43 float pixelRatio;