diff options
-rw-r--r-- | CMakeLists.txt | 2 | ||||
-rw-r--r-- | src/app.c | 4 | ||||
-rw-r--r-- | src/app.h | 1 | ||||
-rw-r--r-- | src/ui/documentwidget.c | 9 | ||||
-rw-r--r-- | src/ui/documentwidget.h | 2 | ||||
-rw-r--r-- | src/ui/sidebarwidget.c | 58 | ||||
-rw-r--r-- | src/ui/widget.c | 11 |
7 files changed, 80 insertions, 7 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index 8992e87f..dbfaa140 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt | |||
@@ -1,7 +1,7 @@ | |||
1 | cmake_minimum_required (VERSION 3.9) | 1 | cmake_minimum_required (VERSION 3.9) |
2 | 2 | ||
3 | project (Lagrange | 3 | project (Lagrange |
4 | VERSION 1.0.0 | 4 | VERSION 0.1.0 |
5 | DESCRIPTION "Beautiful Gemini Client" | 5 | DESCRIPTION "Beautiful Gemini Client" |
6 | LANGUAGES C | 6 | LANGUAGES C |
7 | ) | 7 | ) |
@@ -326,6 +326,10 @@ void refresh_App(void) { | |||
326 | d->pendingRefresh = iFalse; | 326 | d->pendingRefresh = iFalse; |
327 | } | 327 | } |
328 | 328 | ||
329 | iBool isRefreshPending_App(void) { | ||
330 | return app_.pendingRefresh; | ||
331 | } | ||
332 | |||
329 | int run_App(int argc, char **argv) { | 333 | int run_App(int argc, char **argv) { |
330 | init_App_(&app_, argc, argv); | 334 | init_App_(&app_, argc, argv); |
331 | const int rc = run_App_(&app_); | 335 | const int rc = run_App_(&app_); |
@@ -27,6 +27,7 @@ int run_App (int argc, char **argv); | |||
27 | void processEvents_App (enum iAppEventMode mode); | 27 | void processEvents_App (enum iAppEventMode mode); |
28 | iBool handleCommand_App (const char *cmd); | 28 | iBool handleCommand_App (const char *cmd); |
29 | void refresh_App (void); | 29 | void refresh_App (void); |
30 | iBool isRefreshPending_App(void); | ||
30 | 31 | ||
31 | iGmCerts * certs_App (void); | 32 | iGmCerts * certs_App (void); |
32 | iVisited * visited_App (void); | 33 | iVisited * visited_App (void); |
diff --git a/src/ui/documentwidget.c b/src/ui/documentwidget.c index 57709384..483dc983 100644 --- a/src/ui/documentwidget.c +++ b/src/ui/documentwidget.c | |||
@@ -159,6 +159,7 @@ void init_DocumentWidget(iDocumentWidget *d) { | |||
159 | d->isRequestUpdated = iFalse; | 159 | d->isRequestUpdated = iFalse; |
160 | d->media = new_ObjectList(); | 160 | d->media = new_ObjectList(); |
161 | d->doc = new_GmDocument(); | 161 | d->doc = new_GmDocument(); |
162 | d->initialScrollY = 0; | ||
162 | d->scrollY = 0; | 163 | d->scrollY = 0; |
163 | d->selecting = iFalse; | 164 | d->selecting = iFalse; |
164 | d->selectMark = iNullRange; | 165 | d->selectMark = iNullRange; |
@@ -558,7 +559,7 @@ static iBool updateFromHistory_DocumentWidget_(iDocumentWidget *d) { | |||
558 | const iGmResponse *resp = recent->cachedResponse; | 559 | const iGmResponse *resp = recent->cachedResponse; |
559 | d->state = fetching_RequestState; | 560 | d->state = fetching_RequestState; |
560 | /* Use the cached response data. */ | 561 | /* Use the cached response data. */ |
561 | d->scrollY = recent->scrollY; | 562 | d->scrollY = d->initialScrollY = recent->scrollY; |
562 | updateTrust_DocumentWidget_(d, resp); | 563 | updateTrust_DocumentWidget_(d, resp); |
563 | updateDocument_DocumentWidget_(d, resp); | 564 | updateDocument_DocumentWidget_(d, resp); |
564 | d->state = ready_RequestState; | 565 | d->state = ready_RequestState; |
@@ -824,6 +825,11 @@ static void changeTextSize_DocumentWidget_(iDocumentWidget *d, int delta) { | |||
824 | postCommandf_App("font.setfactor arg:%d", d->mod.textSizePercent); | 825 | postCommandf_App("font.setfactor arg:%d", d->mod.textSizePercent); |
825 | } | 826 | } |
826 | 827 | ||
828 | void updateSize_DocumentWidget(iDocumentWidget *d) { | ||
829 | setWidth_GmDocument(d->doc, documentWidth_DocumentWidget_(d)); | ||
830 | updateVisible_DocumentWidget_(d); | ||
831 | } | ||
832 | |||
827 | static iBool handleCommand_DocumentWidget_(iDocumentWidget *d, const char *cmd) { | 833 | static iBool handleCommand_DocumentWidget_(iDocumentWidget *d, const char *cmd) { |
828 | iWidget *w = as_Widget(d); | 834 | iWidget *w = as_Widget(d); |
829 | if (equal_Command(cmd, "window.resized") || equal_Command(cmd, "font.changed")) { | 835 | if (equal_Command(cmd, "window.resized") || equal_Command(cmd, "font.changed")) { |
@@ -956,6 +962,7 @@ static iBool handleCommand_DocumentWidget_(iDocumentWidget *d, const char *cmd) | |||
956 | return handleMediaCommand_DocumentWidget_(d, cmd); | 962 | return handleMediaCommand_DocumentWidget_(d, cmd); |
957 | } | 963 | } |
958 | else if (equal_Command(cmd, "document.reload") && document_App() == d) { | 964 | else if (equal_Command(cmd, "document.reload") && document_App() == d) { |
965 | d->initialScrollY = d->scrollY; | ||
959 | fetch_DocumentWidget_(d); | 966 | fetch_DocumentWidget_(d); |
960 | return iTrue; | 967 | return iTrue; |
961 | } | 968 | } |
diff --git a/src/ui/documentwidget.h b/src/ui/documentwidget.h index 810c1392..05b8b50f 100644 --- a/src/ui/documentwidget.h +++ b/src/ui/documentwidget.h | |||
@@ -22,3 +22,5 @@ const iGmDocument * document_DocumentWidget (const iDocumentWidget *); | |||
22 | void setUrl_DocumentWidget (iDocumentWidget *, const iString *url); | 22 | void setUrl_DocumentWidget (iDocumentWidget *, const iString *url); |
23 | void setUrlFromCache_DocumentWidget (iDocumentWidget *, const iString *url, iBool isFromCache); | 23 | void setUrlFromCache_DocumentWidget (iDocumentWidget *, const iString *url, iBool isFromCache); |
24 | void setInitialScroll_DocumentWidget (iDocumentWidget *, int scrollY); /* set after content received */ | 24 | void setInitialScroll_DocumentWidget (iDocumentWidget *, int scrollY); /* set after content received */ |
25 | |||
26 | void updateSize_DocumentWidget (iDocumentWidget *); | ||
diff --git a/src/ui/sidebarwidget.c b/src/ui/sidebarwidget.c index fa550176..c5e7d05f 100644 --- a/src/ui/sidebarwidget.c +++ b/src/ui/sidebarwidget.c | |||
@@ -9,6 +9,7 @@ | |||
9 | #include "app.h" | 9 | #include "app.h" |
10 | 10 | ||
11 | #include <the_Foundation/array.h> | 11 | #include <the_Foundation/array.h> |
12 | #include <SDL_mouse.h> | ||
12 | 13 | ||
13 | iDeclareType(SidebarItem) | 14 | iDeclareType(SidebarItem) |
14 | 15 | ||
@@ -50,10 +51,16 @@ struct Impl_SidebarWidget { | |||
50 | iArray items; | 51 | iArray items; |
51 | size_t hoverItem; | 52 | size_t hoverItem; |
52 | iClick click; | 53 | iClick click; |
54 | iWidget *resizer; | ||
55 | SDL_Cursor *resizeCursor; | ||
53 | }; | 56 | }; |
54 | 57 | ||
55 | iDefineObjectConstruction(SidebarWidget) | 58 | iDefineObjectConstruction(SidebarWidget) |
56 | 59 | ||
60 | static iBool isResizing_SidebarWidget_(const iSidebarWidget *d) { | ||
61 | return (flags_Widget(d->resizer) & pressed_WidgetFlag) != 0; | ||
62 | } | ||
63 | |||
57 | static void clearItems_SidebarWidget_(iSidebarWidget *d) { | 64 | static void clearItems_SidebarWidget_(iSidebarWidget *d) { |
58 | iForEach(Array, i, &d->items) { | 65 | iForEach(Array, i, &d->items) { |
59 | deinit_SidebarItem(i.value); | 66 | deinit_SidebarItem(i.value); |
@@ -150,9 +157,19 @@ void init_SidebarWidget(iSidebarWidget *d) { | |||
150 | addChild_Widget(w, iClob(d->scroll = new_ScrollWidget())); | 157 | addChild_Widget(w, iClob(d->scroll = new_ScrollWidget())); |
151 | setThumb_ScrollWidget(d->scroll, 0, 0); | 158 | setThumb_ScrollWidget(d->scroll, 0, 0); |
152 | setMode_SidebarWidget(d, documentOutline_SidebarMode); | 159 | setMode_SidebarWidget(d, documentOutline_SidebarMode); |
160 | d->resizer = addChildFlags_Widget( | ||
161 | w, | ||
162 | iClob(new_Widget()), | ||
163 | hover_WidgetFlag | commandOnClick_WidgetFlag | fixedWidth_WidgetFlag | | ||
164 | resizeToParentHeight_WidgetFlag | moveToParentRightEdge_WidgetFlag); | ||
165 | setId_Widget(d->resizer, "sidebar.grab"); | ||
166 | d->resizer->rect.size.x = gap_UI; | ||
167 | setBackgroundColor_Widget(d->resizer, red_ColorId); | ||
168 | d->resizeCursor = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_SIZEWE); | ||
153 | } | 169 | } |
154 | 170 | ||
155 | void deinit_SidebarWidget(iSidebarWidget *d) { | 171 | void deinit_SidebarWidget(iSidebarWidget *d) { |
172 | SDL_FreeCursor(d->resizeCursor); | ||
156 | clearItems_SidebarWidget_(d); | 173 | clearItems_SidebarWidget_(d); |
157 | deinit_Array(&d->items); | 174 | deinit_Array(&d->items); |
158 | } | 175 | } |
@@ -206,6 +223,37 @@ static iBool processEvent_SidebarWidget_(iSidebarWidget *d, const SDL_Event *ev) | |||
206 | if (isResize_UserEvent(ev)) { | 223 | if (isResize_UserEvent(ev)) { |
207 | updateVisible_SidebarWidget_(d); | 224 | updateVisible_SidebarWidget_(d); |
208 | } | 225 | } |
226 | else if (isCommand_Widget(w, ev, "mouse.clicked")) { | ||
227 | const char *cmd = command_UserEvent(ev); | ||
228 | if (argLabel_Command(cmd, "button") == SDL_BUTTON_LEFT) { | ||
229 | if (arg_Command(cmd)) { | ||
230 | setFlags_Widget(d->resizer, pressed_WidgetFlag, iTrue); | ||
231 | setBackgroundColor_Widget(d->resizer, orange_ColorId); | ||
232 | setMouseGrab_Widget(d->resizer); | ||
233 | refresh_Widget(d->resizer); | ||
234 | } | ||
235 | else { | ||
236 | setFlags_Widget(d->resizer, pressed_WidgetFlag, iFalse); | ||
237 | setBackgroundColor_Widget(d->resizer, red_ColorId); | ||
238 | setMouseGrab_Widget(NULL); | ||
239 | refresh_Widget(d->resizer); | ||
240 | } | ||
241 | } | ||
242 | return iTrue; | ||
243 | } | ||
244 | else if (isCommand_Widget(w, ev, "mouse.moved")) { | ||
245 | const char *cmd = command_UserEvent(ev); | ||
246 | if (isResizing_SidebarWidget_(d)) { | ||
247 | const iInt2 local = localCoord_Widget(w, coord_Command(cmd)); | ||
248 | w->rect.size.x = local.x + d->resizer->rect.size.x / 2; | ||
249 | arrange_Widget(findWidget_App("doctabs")); | ||
250 | if (!isRefreshPending_App()) { | ||
251 | updateSize_DocumentWidget(document_App()); | ||
252 | refresh_Widget(w); | ||
253 | } | ||
254 | } | ||
255 | return iTrue; | ||
256 | } | ||
209 | else if (isCommand_Widget(w, ev, "scroll.moved")) { | 257 | else if (isCommand_Widget(w, ev, "scroll.moved")) { |
210 | d->scrollY = arg_Command(command_UserEvent(ev)); | 258 | d->scrollY = arg_Command(command_UserEvent(ev)); |
211 | d->hoverItem = iInvalidPos; | 259 | d->hoverItem = iInvalidPos; |
@@ -226,8 +274,14 @@ static iBool processEvent_SidebarWidget_(iSidebarWidget *d, const SDL_Event *ev) | |||
226 | if (ev->type == SDL_MOUSEMOTION) { | 274 | if (ev->type == SDL_MOUSEMOTION) { |
227 | const iInt2 mouse = init_I2(ev->motion.x, ev->motion.y); | 275 | const iInt2 mouse = init_I2(ev->motion.x, ev->motion.y); |
228 | size_t hover = iInvalidPos; | 276 | size_t hover = iInvalidPos; |
229 | if (contains_Widget(w, mouse)) { | 277 | if (contains_Widget(d->resizer, mouse)) { |
230 | hover = itemIndex_SidebarWidget_(d, mouse); | 278 | SDL_SetCursor(d->resizeCursor); |
279 | } | ||
280 | else { | ||
281 | SDL_SetCursor(NULL); | ||
282 | if (contains_Widget(w, mouse)) { | ||
283 | hover = itemIndex_SidebarWidget_(d, mouse); | ||
284 | } | ||
231 | } | 285 | } |
232 | if (hover != d->hoverItem) { | 286 | if (hover != d->hoverItem) { |
233 | d->hoverItem = hover; | 287 | d->hoverItem = hover; |
diff --git a/src/ui/widget.c b/src/ui/widget.c index b9fb12b9..2a889683 100644 --- a/src/ui/widget.c +++ b/src/ui/widget.c | |||
@@ -424,9 +424,9 @@ iBool processEvent_Widget(iWidget *d, const SDL_Event *ev) { | |||
424 | return iTrue; | 424 | return iTrue; |
425 | } | 425 | } |
426 | } | 426 | } |
427 | else if (d->flags & commandOnClick_WidgetFlag && (ev->type == SDL_MOUSEBUTTONDOWN || | 427 | else if (d->flags & commandOnClick_WidgetFlag && |
428 | ev->type == SDL_MOUSEBUTTONUP) && | 428 | (ev->type == SDL_MOUSEBUTTONDOWN || ev->type == SDL_MOUSEBUTTONUP) && |
429 | contains_Widget(d, init_I2(ev->button.x, ev->button.y))) { | 429 | (mouseGrab_Widget() == d || contains_Widget(d, init_I2(ev->button.x, ev->button.y)))) { |
430 | postCommand_Widget(d, | 430 | postCommand_Widget(d, |
431 | "mouse.clicked arg:%d button:%d coord:%d %d", | 431 | "mouse.clicked arg:%d button:%d coord:%d %d", |
432 | ev->type == SDL_MOUSEBUTTONDOWN ? 1 : 0, | 432 | ev->type == SDL_MOUSEBUTTONDOWN ? 1 : 0, |
@@ -435,6 +435,11 @@ iBool processEvent_Widget(iWidget *d, const SDL_Event *ev) { | |||
435 | ev->button.y); | 435 | ev->button.y); |
436 | return iTrue; | 436 | return iTrue; |
437 | } | 437 | } |
438 | else if (d->flags & commandOnClick_WidgetFlag && | ||
439 | mouseGrab_Widget() == d && ev->type == SDL_MOUSEMOTION) { | ||
440 | postCommand_Widget(d, "mouse.moved coord:%d %d", ev->motion.x, ev->motion.y); | ||
441 | return iTrue; | ||
442 | } | ||
438 | switch (ev->type) { | 443 | switch (ev->type) { |
439 | case SDL_USEREVENT: { | 444 | case SDL_USEREVENT: { |
440 | if (ev->user.code == command_UserEventCode && d->commandHandler && | 445 | if (ev->user.code == command_UserEventCode && d->commandHandler && |