diff options
author | Jaakko Keränen <jaakko.keranen@iki.fi> | 2020-07-23 15:42:12 +0300 |
---|---|---|
committer | Jaakko Keränen <jaakko.keranen@iki.fi> | 2020-07-23 15:42:12 +0300 |
commit | a624d11136f16b5799abecda2433c49500094b9b (patch) | |
tree | a9d5eee1bc72e1b641443910ea2fad3f461a232d /src/ui/documentwidget.c | |
parent | a3610ec020882015ae15b3b2808a443f81f651e6 (diff) |
DocumentWidget: Scrolling via scrollbar and keys
Diffstat (limited to 'src/ui/documentwidget.c')
-rw-r--r-- | src/ui/documentwidget.c | 80 |
1 files changed, 54 insertions, 26 deletions
diff --git a/src/ui/documentwidget.c b/src/ui/documentwidget.c index 8c707206..38c19fdd 100644 --- a/src/ui/documentwidget.c +++ b/src/ui/documentwidget.c | |||
@@ -1,6 +1,7 @@ | |||
1 | #include "documentwidget.h" | 1 | #include "documentwidget.h" |
2 | #include "scrollwidget.h" | 2 | #include "scrollwidget.h" |
3 | #include "paint.h" | 3 | #include "paint.h" |
4 | #include "command.h" | ||
4 | #include "util.h" | 5 | #include "util.h" |
5 | #include "app.h" | 6 | #include "app.h" |
6 | #include "../gemini.h" | 7 | #include "../gemini.h" |
@@ -19,8 +20,6 @@ enum iDocumentState { | |||
19 | ready_DocumentState, | 20 | ready_DocumentState, |
20 | }; | 21 | }; |
21 | 22 | ||
22 | |||
23 | |||
24 | struct Impl_DocumentWidget { | 23 | struct Impl_DocumentWidget { |
25 | iWidget widget; | 24 | iWidget widget; |
26 | enum iDocumentState state; | 25 | enum iDocumentState state; |
@@ -74,16 +73,16 @@ void init_DocumentWidget(iDocumentWidget *d) { | |||
74 | iWidget *w = as_Widget(d); | 73 | iWidget *w = as_Widget(d); |
75 | init_Widget(w); | 74 | init_Widget(w); |
76 | setId_Widget(w, "document"); | 75 | setId_Widget(w, "document"); |
77 | d->state = blank_DocumentState; | 76 | d->state = blank_DocumentState; |
78 | d->url = new_String(); | 77 | d->url = new_String(); |
79 | d->statusCode = 0; | 78 | d->statusCode = 0; |
80 | d->request = NULL; | 79 | d->request = NULL; |
81 | d->newSource = new_String(); | 80 | d->newSource = new_String(); |
82 | d->doc = new_GmDocument(); | 81 | d->doc = new_GmDocument(); |
83 | d->pageMargin = 5; | 82 | d->pageMargin = 5; |
84 | d->scrollY = 0; | 83 | d->scrollY = 0; |
84 | d->hoverLink = NULL; | ||
85 | init_PtrArray(&d->visibleLinks); | 85 | init_PtrArray(&d->visibleLinks); |
86 | d->hoverLink = NULL; | ||
87 | init_Click(&d->click, d, SDL_BUTTON_LEFT); | 86 | init_Click(&d->click, d, SDL_BUTTON_LEFT); |
88 | addChild_Widget(w, iClob(d->scroll = new_ScrollWidget())); | 87 | addChild_Widget(w, iClob(d->scroll = new_ScrollWidget())); |
89 | } | 88 | } |
@@ -151,7 +150,7 @@ static void requestFinished_DocumentWidget_(iAnyObject *obj) { | |||
151 | iReleaseLater(d->request); | 150 | iReleaseLater(d->request); |
152 | d->request = NULL; | 151 | d->request = NULL; |
153 | fflush(stdout); | 152 | fflush(stdout); |
154 | postRefresh_App(); | 153 | refresh_Widget(constAs_Widget(d)); |
155 | } | 154 | } |
156 | 155 | ||
157 | static void fetch_DocumentWidget_(iDocumentWidget *d) { | 156 | static void fetch_DocumentWidget_(iDocumentWidget *d) { |
@@ -164,7 +163,7 @@ static void fetch_DocumentWidget_(iDocumentWidget *d) { | |||
164 | iFile *f = new_File(collect_String(newRange_String(url.path))); | 163 | iFile *f = new_File(collect_String(newRange_String(url.path))); |
165 | if (open_File(f, readOnly_FileMode)) { | 164 | if (open_File(f, readOnly_FileMode)) { |
166 | setBlock_String(d->newSource, collect_Block(readAll_File(f))); | 165 | setBlock_String(d->newSource, collect_Block(readAll_File(f))); |
167 | postRefresh_App(); | 166 | refresh_Widget(constAs_Widget(d)); |
168 | } | 167 | } |
169 | iRelease(f); | 168 | iRelease(f); |
170 | return; | 169 | return; |
@@ -228,6 +227,22 @@ static void updateVisible_DocumentWidget_(iDocumentWidget *d) { | |||
228 | render_GmDocument(d->doc, visRange, addVisibleLink_DocumentWidget_, d); | 227 | render_GmDocument(d->doc, visRange, addVisibleLink_DocumentWidget_, d); |
229 | } | 228 | } |
230 | 229 | ||
230 | static void scroll_DocumentWidget_(iDocumentWidget *d, int offset) { | ||
231 | d->scrollY += offset; | ||
232 | if (d->scrollY < 0) { | ||
233 | d->scrollY = 0; | ||
234 | } | ||
235 | const int scrollMax = scrollMax_DocumentWidget_(d); | ||
236 | if (scrollMax > 0) { | ||
237 | d->scrollY = iMin(d->scrollY, scrollMax); | ||
238 | } | ||
239 | else { | ||
240 | d->scrollY = 0; | ||
241 | } | ||
242 | updateVisible_DocumentWidget_(d); | ||
243 | refresh_Widget(as_Widget(d)); | ||
244 | } | ||
245 | |||
231 | static iRangecc dirPath_(iRangecc path) { | 246 | static iRangecc dirPath_(iRangecc path) { |
232 | const size_t pos = lastIndexOfCStr_Rangecc(&path, "/"); | 247 | const size_t pos = lastIndexOfCStr_Rangecc(&path, "/"); |
233 | if (pos == iInvalidPos) return path; | 248 | if (pos == iInvalidPos) return path; |
@@ -287,10 +302,35 @@ static iBool processEvent_DocumentWidget_(iDocumentWidget *d, const SDL_Event *e | |||
287 | setWidth_GmDocument(d->doc, documentWidth_DocumentWidget_(d)); | 302 | setWidth_GmDocument(d->doc, documentWidth_DocumentWidget_(d)); |
288 | updateVisible_DocumentWidget_(d); | 303 | updateVisible_DocumentWidget_(d); |
289 | } | 304 | } |
305 | else if (isCommand_Widget(w, ev, "scroll.moved")) { | ||
306 | d->scrollY = arg_Command(command_UserEvent(ev)); | ||
307 | updateVisible_DocumentWidget_(d); | ||
308 | return iTrue; | ||
309 | } | ||
310 | else if (isCommand_Widget(w, ev, "scroll.page")) { | ||
311 | scroll_DocumentWidget_( | ||
312 | d, arg_Command(command_UserEvent(ev)) * height_Rect(documentBounds_DocumentWidget_(d))); | ||
313 | return iTrue; | ||
314 | } | ||
290 | if (ev->type == SDL_KEYDOWN) { | 315 | if (ev->type == SDL_KEYDOWN) { |
291 | const int mods = keyMods_Sym(ev->key.keysym.mod); | 316 | const int mods = keyMods_Sym(ev->key.keysym.mod); |
292 | const int key = ev->key.keysym.sym; | 317 | const int key = ev->key.keysym.sym; |
293 | switch (key) { | 318 | switch (key) { |
319 | case SDLK_HOME: | ||
320 | d->scrollY = 0; | ||
321 | updateVisible_DocumentWidget_(d); | ||
322 | refresh_Widget(w); | ||
323 | return iTrue; | ||
324 | case SDLK_END: | ||
325 | d->scrollY = scrollMax_DocumentWidget_(d); | ||
326 | updateVisible_DocumentWidget_(d); | ||
327 | refresh_Widget(w); | ||
328 | return iTrue; | ||
329 | case SDLK_PAGEUP: | ||
330 | case SDLK_PAGEDOWN: | ||
331 | case ' ': | ||
332 | postCommand_Widget(w, "scroll.page arg:%d", key == SDLK_PAGEUP ? -1 : +1); | ||
333 | return iTrue; | ||
294 | case 'r': | 334 | case 'r': |
295 | if (mods == KMOD_PRIMARY) { | 335 | if (mods == KMOD_PRIMARY) { |
296 | fetch_DocumentWidget_(d); | 336 | fetch_DocumentWidget_(d); |
@@ -300,7 +340,7 @@ static iBool processEvent_DocumentWidget_(iDocumentWidget *d, const SDL_Event *e | |||
300 | case '0': { | 340 | case '0': { |
301 | extern int enableHalfPixelGlyphs_Text; | 341 | extern int enableHalfPixelGlyphs_Text; |
302 | enableHalfPixelGlyphs_Text = !enableHalfPixelGlyphs_Text; | 342 | enableHalfPixelGlyphs_Text = !enableHalfPixelGlyphs_Text; |
303 | postRefresh_App(); | 343 | refresh_Widget(w); |
304 | printf("halfpixel: %d\n", enableHalfPixelGlyphs_Text); | 344 | printf("halfpixel: %d\n", enableHalfPixelGlyphs_Text); |
305 | fflush(stdout); | 345 | fflush(stdout); |
306 | break; | 346 | break; |
@@ -308,19 +348,7 @@ static iBool processEvent_DocumentWidget_(iDocumentWidget *d, const SDL_Event *e | |||
308 | } | 348 | } |
309 | } | 349 | } |
310 | else if (ev->type == SDL_MOUSEWHEEL) { | 350 | else if (ev->type == SDL_MOUSEWHEEL) { |
311 | d->scrollY -= 3 * ev->wheel.y * lineHeight_Text(default_FontId); | 351 | scroll_DocumentWidget_(d, -3 * ev->wheel.y * lineHeight_Text(default_FontId)); |
312 | if (d->scrollY < 0) { | ||
313 | d->scrollY = 0; | ||
314 | } | ||
315 | const int scrollMax = scrollMax_DocumentWidget_(d); | ||
316 | if (scrollMax > 0) { | ||
317 | d->scrollY = iMin(d->scrollY, scrollMax); | ||
318 | } | ||
319 | else { | ||
320 | d->scrollY = 0; | ||
321 | } | ||
322 | updateVisible_DocumentWidget_(d); | ||
323 | postRefresh_App(); | ||
324 | return iTrue; | 352 | return iTrue; |
325 | } | 353 | } |
326 | else if (ev->type == SDL_MOUSEMOTION) { | 354 | else if (ev->type == SDL_MOUSEMOTION) { |
@@ -339,7 +367,7 @@ static iBool processEvent_DocumentWidget_(iDocumentWidget *d, const SDL_Event *e | |||
339 | } | 367 | } |
340 | } | 368 | } |
341 | if (d->hoverLink != oldHoverLink) { | 369 | if (d->hoverLink != oldHoverLink) { |
342 | postRefresh_App(); | 370 | refresh_Widget(w); |
343 | } | 371 | } |
344 | } | 372 | } |
345 | switch (processEvent_Click(&d->click, ev)) { | 373 | switch (processEvent_Click(&d->click, ev)) { |