summaryrefslogtreecommitdiff
path: root/src/ui/documentwidget.c
diff options
context:
space:
mode:
authorJaakko Keränen <jaakko.keranen@iki.fi>2020-07-23 15:42:12 +0300
committerJaakko Keränen <jaakko.keranen@iki.fi>2020-07-23 15:42:12 +0300
commita624d11136f16b5799abecda2433c49500094b9b (patch)
treea9d5eee1bc72e1b641443910ea2fad3f461a232d /src/ui/documentwidget.c
parenta3610ec020882015ae15b3b2808a443f81f651e6 (diff)
DocumentWidget: Scrolling via scrollbar and keys
Diffstat (limited to 'src/ui/documentwidget.c')
-rw-r--r--src/ui/documentwidget.c80
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
24struct Impl_DocumentWidget { 23struct 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
157static void fetch_DocumentWidget_(iDocumentWidget *d) { 156static 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
230static 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
231static iRangecc dirPath_(iRangecc path) { 246static 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)) {