summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJaakko Keränen <jaakko.keranen@iki.fi>2020-08-13 07:42:26 +0300
committerJaakko Keränen <jaakko.keranen@iki.fi>2020-08-13 07:42:26 +0300
commit61ce76bde91aaa6a5267e88577e10115f9627e5f (patch)
tree5b1c7c98580c7109d9a6862e72a671a43b4554d5
parentfab098d5701a55fd4a0b3fb74ae332797e3be377 (diff)
Toggle sidebar visibility; save width and mode
-rw-r--r--src/app.c8
-rw-r--r--src/gmdocument.c4
-rw-r--r--src/gmdocument.h1
-rw-r--r--src/ui/documentwidget.c15
-rw-r--r--src/ui/sidebarwidget.c115
-rw-r--r--src/ui/sidebarwidget.h4
-rw-r--r--src/ui/widget.c4
-rw-r--r--src/ui/window.c8
8 files changed, 110 insertions, 49 deletions
diff --git a/src/app.c b/src/app.c
index 92e303b5..12f3393c 100644
--- a/src/app.c
+++ b/src/app.c
@@ -8,6 +8,7 @@
8#include "ui/window.h" 8#include "ui/window.h"
9#include "ui/inputwidget.h" 9#include "ui/inputwidget.h"
10#include "ui/labelwidget.h" 10#include "ui/labelwidget.h"
11#include "ui/sidebarwidget.h"
11#include "ui/documentwidget.h" 12#include "ui/documentwidget.h"
12#include "ui/util.h" 13#include "ui/util.h"
13#include "ui/text.h" 14#include "ui/text.h"
@@ -90,13 +91,18 @@ const iString *dateStr_(const iDate *date) {
90 91
91static iString *serializePrefs_App_(const iApp *d) { 92static iString *serializePrefs_App_(const iApp *d) {
92 iString *str = new_String(); 93 iString *str = new_String();
93 iWindow *win = get_Window(); 94 const iSidebarWidget *sidebar = findWidget_App("sidebar");
94 if (d->retainWindowSize) { 95 if (d->retainWindowSize) {
95 int w, h, x, y; 96 int w, h, x, y;
96 SDL_GetWindowSize(d->window->win, &w, &h); 97 SDL_GetWindowSize(d->window->win, &w, &h);
97 SDL_GetWindowPosition(d->window->win, &x, &y); 98 SDL_GetWindowPosition(d->window->win, &x, &y);
98 appendFormat_String(str, "restorewindow width:%d height:%d coord:%d %d\n", w, h, x, y); 99 appendFormat_String(str, "restorewindow width:%d height:%d coord:%d %d\n", w, h, x, y);
100 appendFormat_String(str, "sidebar.width arg:%d\n", width_SidebarWidget(sidebar));
99 } 101 }
102 if (isVisible_Widget(constAs_Widget(sidebar))) {
103 appendCStr_String(str, "sidebar.toggle\n");
104 }
105 appendFormat_String(str, "sidebar.mode arg:%d\n", mode_SidebarWidget(sidebar));
100 appendFormat_String(str, "uiscale arg:%f\n", uiScale_Window(d->window)); 106 appendFormat_String(str, "uiscale arg:%f\n", uiScale_Window(d->window));
101 return str; 107 return str;
102} 108}
diff --git a/src/gmdocument.c b/src/gmdocument.c
index 3fa4a32a..ed1d1cae 100644
--- a/src/gmdocument.c
+++ b/src/gmdocument.c
@@ -907,6 +907,10 @@ const iArray *headings_GmDocument(const iGmDocument *d) {
907 return &d->headings; 907 return &d->headings;
908} 908}
909 909
910const iString *source_GmDocument(const iGmDocument *d) {
911 return &d->source;
912}
913
910iRangecc findText_GmDocument(const iGmDocument *d, const iString *text, const char *start) { 914iRangecc findText_GmDocument(const iGmDocument *d, const iString *text, const char *start) {
911 const char * src = constBegin_String(&d->source); 915 const char * src = constBegin_String(&d->source);
912 const size_t startPos = (start ? start - src : 0); 916 const size_t startPos = (start ? start - src : 0);
diff --git a/src/gmdocument.h b/src/gmdocument.h
index fd5882bf..9f4bc1ca 100644
--- a/src/gmdocument.h
+++ b/src/gmdocument.h
@@ -86,6 +86,7 @@ void render_GmDocument (const iGmDocument *, iRangei visRan
86iInt2 size_GmDocument (const iGmDocument *); 86iInt2 size_GmDocument (const iGmDocument *);
87iBool hasSiteBanner_GmDocument (const iGmDocument *); 87iBool hasSiteBanner_GmDocument (const iGmDocument *);
88const iArray * headings_GmDocument (const iGmDocument *); 88const iArray * headings_GmDocument (const iGmDocument *);
89const iString * source_GmDocument (const iGmDocument *);
89 90
90iRangecc findText_GmDocument (const iGmDocument *, const iString *text, const char *start); 91iRangecc findText_GmDocument (const iGmDocument *, const iString *text, const char *start);
91iRangecc findTextBefore_GmDocument (const iGmDocument *, const iString *text, const char *before); 92iRangecc findTextBefore_GmDocument (const iGmDocument *, const iString *text, const char *before);
diff --git a/src/ui/documentwidget.c b/src/ui/documentwidget.c
index 483dc983..11b92e63 100644
--- a/src/ui/documentwidget.c
+++ b/src/ui/documentwidget.c
@@ -887,17 +887,22 @@ static iBool handleCommand_DocumentWidget_(iDocumentWidget *d, const char *cmd)
887 : "Not trusted")); 887 : "Not trusted"));
888 return iTrue; 888 return iTrue;
889 } 889 }
890 else if (equal_Command(cmd, "copy")) { 890 else if (equal_Command(cmd, "copy") && document_App() == d) {
891 iString *copied;
891 if (d->selectMark.start) { 892 if (d->selectMark.start) {
892 iRangecc mark = d->selectMark; 893 iRangecc mark = d->selectMark;
893 if (mark.start > mark.end) { 894 if (mark.start > mark.end) {
894 iSwap(const char *, mark.start, mark.end); 895 iSwap(const char *, mark.start, mark.end);
895 } 896 }
896 iString *copied = newRange_String(mark); 897 copied = newRange_String(mark);
897 SDL_SetClipboardText(cstr_String(copied)); 898 }
898 delete_String(copied); 899 else {
899 return iTrue; 900 /* Full document. */
901 copied = copy_String(source_GmDocument(d->doc));
900 } 902 }
903 SDL_SetClipboardText(cstr_String(copied));
904 delete_String(copied);
905 return iTrue;
901 } 906 }
902 else if (equalWidget_Command(cmd, w, "document.copylink")) { 907 else if (equalWidget_Command(cmd, w, "document.copylink")) {
903 if (d->hoverLink) { 908 if (d->hoverLink) {
diff --git a/src/ui/sidebarwidget.c b/src/ui/sidebarwidget.c
index 8ca2e448..a5e0e4ee 100644
--- a/src/ui/sidebarwidget.c
+++ b/src/ui/sidebarwidget.c
@@ -46,6 +46,7 @@ struct Impl_SidebarWidget {
46 enum iSidebarMode mode; 46 enum iSidebarMode mode;
47 iScrollWidget *scroll; 47 iScrollWidget *scroll;
48 int scrollY; 48 int scrollY;
49 int width;
49 iLabelWidget *modeButtons[max_SidebarMode]; 50 iLabelWidget *modeButtons[max_SidebarMode];
50 int itemHeight; 51 int itemHeight;
51 int maxButtonLabelWidth; 52 int maxButtonLabelWidth;
@@ -131,6 +132,14 @@ void setMode_SidebarWidget(iSidebarWidget *d, enum iSidebarMode mode) {
131 d->itemHeight = heights[mode] * lineHeight_Text(default_FontId); 132 d->itemHeight = heights[mode] * lineHeight_Text(default_FontId);
132} 133}
133 134
135enum iSidebarMode mode_SidebarWidget(const iSidebarWidget *d) {
136 return d->mode;
137}
138
139int width_SidebarWidget(const iSidebarWidget *d) {
140 return d->width;
141}
142
134static const char *normalModeLabels_[max_SidebarMode] = { 143static const char *normalModeLabels_[max_SidebarMode] = {
135 "\U0001f5b9 Outline", 144 "\U0001f5b9 Outline",
136 "\U0001f588 Bookmarks", 145 "\U0001f588 Bookmarks",
@@ -148,11 +157,15 @@ static const char *tightModeLabels_[max_SidebarMode] = {
148void init_SidebarWidget(iSidebarWidget *d) { 157void init_SidebarWidget(iSidebarWidget *d) {
149 iWidget *w = as_Widget(d); 158 iWidget *w = as_Widget(d);
150 init_Widget(w); 159 init_Widget(w);
160 setId_Widget(w, "sidebar");
151 setBackgroundColor_Widget(w, none_ColorId); 161 setBackgroundColor_Widget(w, none_ColorId);
152 setFlags_Widget(w, hover_WidgetFlag | arrangeHorizontal_WidgetFlag | resizeWidthOfChildren_WidgetFlag, iTrue); 162 setFlags_Widget(w,
163 hidden_WidgetFlag | hover_WidgetFlag | arrangeHorizontal_WidgetFlag |
164 resizeWidthOfChildren_WidgetFlag | collapse_WidgetFlag,
165 iTrue);
153 d->scrollY = 0; 166 d->scrollY = 0;
154 d->mode = -1; 167 d->mode = -1;
155 w->rect.size.x = 75 * gap_UI; 168 d->width = 75 * gap_UI;
156 init_Array(&d->items, sizeof(iSidebarItem)); 169 init_Array(&d->items, sizeof(iSidebarItem));
157 d->hoverItem = iInvalidPos; 170 d->hoverItem = iInvalidPos;
158 init_Click(&d->click, d, SDL_BUTTON_LEFT); 171 init_Click(&d->click, d, SDL_BUTTON_LEFT);
@@ -165,7 +178,8 @@ void init_SidebarWidget(iSidebarWidget *d) {
165 new_LabelWidget(normalModeLabels_[i], 0, 0, format_CStr("sidebar.mode arg:%d", i))), 178 new_LabelWidget(normalModeLabels_[i], 0, 0, format_CStr("sidebar.mode arg:%d", i))),
166 frameless_WidgetFlag | expand_WidgetFlag); 179 frameless_WidgetFlag | expand_WidgetFlag);
167 d->maxButtonLabelWidth = 180 d->maxButtonLabelWidth =
168 iMaxi(d->maxButtonLabelWidth, 3 * gap_UI + measure_Text(default_FontId, normalModeLabels_[i]).x); 181 iMaxi(d->maxButtonLabelWidth,
182 3 * gap_UI + measure_Text(default_FontId, normalModeLabels_[i]).x);
169 } 183 }
170 addChild_Widget(w, iClob(d->scroll = new_ScrollWidget())); 184 addChild_Widget(w, iClob(d->scroll = new_ScrollWidget()));
171 setThumb_ScrollWidget(d->scroll, 0, 0); 185 setThumb_ScrollWidget(d->scroll, 0, 0);
@@ -245,6 +259,21 @@ static void checkModeButtonLayout_SidebarWidget_(iSidebarWidget *d) {
245 } 259 }
246} 260}
247 261
262void setWidth_SidebarWidget(iSidebarWidget *d, int width) {
263 iWidget *w = as_Widget(d);
264 width = iMax(30 * gap_UI, width);
265 d->width = width;
266 if (isVisible_Widget(w)) {
267 w->rect.size.x = width;
268 }
269 arrange_Widget(findWidget_App("doctabs"));
270 checkModeButtonLayout_SidebarWidget_(d);
271 if (!isRefreshPending_App()) {
272 updateSize_DocumentWidget(document_App());
273 refresh_Widget(w);
274 }
275}
276
248static iBool processEvent_SidebarWidget_(iSidebarWidget *d, const SDL_Event *ev) { 277static iBool processEvent_SidebarWidget_(iSidebarWidget *d, const SDL_Event *ev) {
249 iWidget *w = as_Widget(d); 278 iWidget *w = as_Widget(d);
250 /* Handle commands. */ 279 /* Handle commands. */
@@ -252,51 +281,57 @@ static iBool processEvent_SidebarWidget_(iSidebarWidget *d, const SDL_Event *ev)
252 updateVisible_SidebarWidget_(d); 281 updateVisible_SidebarWidget_(d);
253 checkModeButtonLayout_SidebarWidget_(d); 282 checkModeButtonLayout_SidebarWidget_(d);
254 } 283 }
255 else if (isCommand_Widget(w, ev, "mouse.clicked")) { 284 else if (ev->type == SDL_USEREVENT && ev->user.code == command_UserEventCode) {
256 const char *cmd = command_UserEvent(ev); 285 const char *cmd = command_UserEvent(ev);
257 if (argLabel_Command(cmd, "button") == SDL_BUTTON_LEFT) { 286 if (isCommand_Widget(w, ev, "mouse.clicked")) {
258 if (arg_Command(cmd)) { 287 if (argLabel_Command(cmd, "button") == SDL_BUTTON_LEFT) {
259 setFlags_Widget(d->resizer, pressed_WidgetFlag, iTrue); 288 if (arg_Command(cmd)) {
260 setBackgroundColor_Widget(d->resizer, gray75_ColorId); 289 setFlags_Widget(d->resizer, pressed_WidgetFlag, iTrue);
261 setMouseGrab_Widget(d->resizer); 290 setBackgroundColor_Widget(d->resizer, gray75_ColorId);
262 refresh_Widget(d->resizer); 291 setMouseGrab_Widget(d->resizer);
263 } 292 refresh_Widget(d->resizer);
264 else { 293 }
265 setFlags_Widget(d->resizer, pressed_WidgetFlag, iFalse); 294 else {
266 setBackgroundColor_Widget(d->resizer, none_ColorId); 295 setFlags_Widget(d->resizer, pressed_WidgetFlag, iFalse);
267 setMouseGrab_Widget(NULL); 296 setBackgroundColor_Widget(d->resizer, none_ColorId);
268 refresh_Widget(d->resizer); 297 setMouseGrab_Widget(NULL);
298 refresh_Widget(d->resizer);
299 }
269 } 300 }
301 return iTrue;
270 } 302 }
271 return iTrue; 303 else if (isCommand_Widget(w, ev, "mouse.moved")) {
272 } 304 if (isResizing_SidebarWidget_(d)) {
273 else if (isCommand_Widget(w, ev, "mouse.moved")) { 305 const iInt2 local = localCoord_Widget(w, coord_Command(cmd));
274 const char *cmd = command_UserEvent(ev); 306 setWidth_SidebarWidget(d, local.x + d->resizer->rect.size.x / 2);
275 if (isResizing_SidebarWidget_(d)) {
276 const iInt2 local = localCoord_Widget(w, coord_Command(cmd));
277 w->rect.size.x = iMax(30 * gap_UI, local.x + d->resizer->rect.size.x / 2);
278 arrange_Widget(findWidget_App("doctabs"));
279 checkModeButtonLayout_SidebarWidget_(d);
280 if (!isRefreshPending_App()) {
281 updateSize_DocumentWidget(document_App());
282 refresh_Widget(w);
283 } 307 }
308 return iTrue;
284 } 309 }
285 return iTrue; 310 else if (equal_Command(cmd, "sidebar.width")) {
286 } 311 setWidth_SidebarWidget(d, arg_Command(cmd));
287 else if (isCommand_Widget(w, ev, "scroll.moved")) { 312 return iTrue;
288 d->scrollY = arg_Command(command_UserEvent(ev)); 313 }
289 d->hoverItem = iInvalidPos; 314 else if (equal_Command(cmd, "sidebar.mode")) {
290 refresh_Widget(w);
291 return iTrue;
292 }
293 else if (ev->type == SDL_USEREVENT && ev->user.code == command_UserEventCode) {
294 const char *cmd = command_UserEvent(ev);
295 if (isCommand_Widget(w, ev, "sidebar.mode")) {
296 setMode_SidebarWidget(d, arg_Command(cmd)); 315 setMode_SidebarWidget(d, arg_Command(cmd));
297 updateItems_SidebarWidget_(d); 316 updateItems_SidebarWidget_(d);
298 return iTrue; 317 return iTrue;
299 } 318 }
319 else if (equal_Command(cmd, "sidebar.toggle")) {
320 setFlags_Widget(w, hidden_WidgetFlag, isVisible_Widget(w));
321 if (isVisible_Widget(w)) {
322 w->rect.size.x = d->width;
323 }
324 arrange_Widget(w->parent);
325 updateSize_DocumentWidget(document_App());
326 refresh_Widget(w->parent);
327 return iTrue;
328 }
329 else if (equal_Command(cmd, "scroll.moved")) {
330 d->scrollY = arg_Command(command_UserEvent(ev));
331 d->hoverItem = iInvalidPos;
332 refresh_Widget(w);
333 return iTrue;
334 }
300 else if (equal_Command(cmd, "tabs.changed") || equal_Command(cmd, "document.changed")) { 335 else if (equal_Command(cmd, "tabs.changed") || equal_Command(cmd, "document.changed")) {
301 updateItems_SidebarWidget_(d); 336 updateItems_SidebarWidget_(d);
302 } 337 }
diff --git a/src/ui/sidebarwidget.h b/src/ui/sidebarwidget.h
index 80f22fca..4d002eee 100644
--- a/src/ui/sidebarwidget.h
+++ b/src/ui/sidebarwidget.h
@@ -15,4 +15,6 @@ iDeclareObjectConstruction(SidebarWidget)
15 15
16void setMode_SidebarWidget (iSidebarWidget *, enum iSidebarMode mode); 16void setMode_SidebarWidget (iSidebarWidget *, enum iSidebarMode mode);
17 17
18enum iSidebarMode mode_SidebarWidget(const iSidebarWidget *); 18enum iSidebarMode mode_SidebarWidget (const iSidebarWidget *);
19int width_SidebarWidget (const iSidebarWidget *);
20void setWidth_SidebarWidget (iSidebarWidget *, int width);
diff --git a/src/ui/widget.c b/src/ui/widget.c
index 2a889683..07f1f17d 100644
--- a/src/ui/widget.c
+++ b/src/ui/widget.c
@@ -149,13 +149,13 @@ static int widestChild_Widget_(const iWidget *d) {
149} 149}
150 150
151static void setWidth_Widget_(iWidget *d, int width) { 151static void setWidth_Widget_(iWidget *d, int width) {
152 if (~d->flags & fixedWidth_WidgetFlag) { 152 if (~d->flags & fixedWidth_WidgetFlag || d->flags & collapse_WidgetFlag) {
153 d->rect.size.x = width; 153 d->rect.size.x = width;
154 } 154 }
155} 155}
156 156
157static void setHeight_Widget_(iWidget *d, int height) { 157static void setHeight_Widget_(iWidget *d, int height) {
158 if (~d->flags & fixedHeight_WidgetFlag) { 158 if (~d->flags & fixedHeight_WidgetFlag || d->flags & collapse_WidgetFlag) {
159 d->rect.size.y = height; 159 d->rect.size.y = height;
160 } 160 }
161} 161}
diff --git a/src/ui/window.c b/src/ui/window.c
index 3a6b6e30..599044aa 100644
--- a/src/ui/window.c
+++ b/src/ui/window.c
@@ -71,6 +71,10 @@ static const iMenuItem navMenuItems[] = {
71 { "New Tab", 't', KMOD_PRIMARY, "tabs.new" }, 71 { "New Tab", 't', KMOD_PRIMARY, "tabs.new" },
72 { "Open Location...", SDLK_l, KMOD_PRIMARY, "focus.set id:url" }, 72 { "Open Location...", SDLK_l, KMOD_PRIMARY, "focus.set id:url" },
73 { "---", 0, 0, NULL }, 73 { "---", 0, 0, NULL },
74 { "Copy Source Text", SDLK_c, KMOD_PRIMARY, "copy" },
75 { "---", 0, 0, NULL },
76 { "Toggle Sidebar", SDLK_s, KMOD_PRIMARY | KMOD_ALT, "sidebar.toggle" },
77 { "---", 0, 0, NULL },
74 { "Preferences...", SDLK_COMMA, KMOD_PRIMARY, "preferences" }, 78 { "Preferences...", SDLK_COMMA, KMOD_PRIMARY, "preferences" },
75 { "---", 0, 0, NULL }, 79 { "---", 0, 0, NULL },
76 { "Quit Lagrange", 'q', KMOD_PRIMARY, "quit" } 80 { "Quit Lagrange", 'q', KMOD_PRIMARY, "quit" }
@@ -85,9 +89,11 @@ static const iMenuItem fileMenuItems[] = {
85}; 89};
86 90
87static const iMenuItem editMenuItems[] = { 91static const iMenuItem editMenuItems[] = {
92 { "Copy Source Text", SDLK_c, KMOD_PRIMARY, "copy" },
88}; 93};
89 94
90static const iMenuItem viewMenuItems[] = { 95static const iMenuItem viewMenuItems[] = {
96 { "Toggle Sidebar", SDLK_s, KMOD_PRIMARY | KMOD_ALT, "sidebar.toggle" },
91}; 97};
92#endif 98#endif
93 99
@@ -265,6 +271,8 @@ static void setupUserInterface_Window(iWindow *d) {
265 addChild_Widget(navBar, iClob(navMenu)); 271 addChild_Widget(navBar, iClob(navMenu));
266#else 272#else
267 insertMenuItems_MacOS("File", fileMenuItems, iElemCount(fileMenuItems)); 273 insertMenuItems_MacOS("File", fileMenuItems, iElemCount(fileMenuItems));
274 insertMenuItems_MacOS("Edit", editMenuItems, iElemCount(editMenuItems));
275 insertMenuItems_MacOS("View", viewMenuItems, iElemCount(viewMenuItems));
268#endif 276#endif
269 } 277 }
270 /* Tab bar. */ { 278 /* Tab bar. */ {