diff options
Diffstat (limited to 'src/ui/documentwidget.c')
-rw-r--r-- | src/ui/documentwidget.c | 54 |
1 files changed, 45 insertions, 9 deletions
diff --git a/src/ui/documentwidget.c b/src/ui/documentwidget.c index c3728b75..87c724de 100644 --- a/src/ui/documentwidget.c +++ b/src/ui/documentwidget.c | |||
@@ -287,6 +287,7 @@ struct Impl_DocumentWidget { | |||
287 | iDrawBufs * drawBufs; /* dynamic state for drawing */ | 287 | iDrawBufs * drawBufs; /* dynamic state for drawing */ |
288 | iTranslation * translation; | 288 | iTranslation * translation; |
289 | iWidget * phoneToolbar; | 289 | iWidget * phoneToolbar; |
290 | int overscroll; | ||
290 | int pinchZoomInitial; | 291 | int pinchZoomInitial; |
291 | int pinchZoomPosted; | 292 | int pinchZoomPosted; |
292 | }; | 293 | }; |
@@ -299,8 +300,9 @@ void init_DocumentWidget(iDocumentWidget *d) { | |||
299 | setId_Widget(w, "document000"); | 300 | setId_Widget(w, "document000"); |
300 | setFlags_Widget(w, hover_WidgetFlag, iTrue); | 301 | setFlags_Widget(w, hover_WidgetFlag, iTrue); |
301 | init_PersistentDocumentState(&d->mod); | 302 | init_PersistentDocumentState(&d->mod); |
302 | d->flags = 0; | 303 | d->flags = 0; |
303 | d->phoneToolbar = NULL; | 304 | d->phoneToolbar = NULL; |
305 | d->overscroll = deviceType_App() != desktop_AppDeviceType ? 50 * gap_UI : 0; | ||
304 | iZap(d->certExpiry); | 306 | iZap(d->certExpiry); |
305 | d->certFingerprint = new_Block(0); | 307 | d->certFingerprint = new_Block(0); |
306 | d->certFlags = 0; | 308 | d->certFlags = 0; |
@@ -1255,6 +1257,20 @@ static void refreshWhileScrolling_DocumentWidget_(iAny *ptr) { | |||
1255 | } | 1257 | } |
1256 | } | 1258 | } |
1257 | 1259 | ||
1260 | static int overscroll_DocumentWidget_(const iDocumentWidget *d) { | ||
1261 | if (d->overscroll) { | ||
1262 | const int y = value_Anim(&d->scrollY); | ||
1263 | if (y <= 0) { | ||
1264 | return y; | ||
1265 | } | ||
1266 | const int scrollMax = scrollMax_DocumentWidget_(d); | ||
1267 | if (y >= scrollMax) { | ||
1268 | return y - scrollMax; | ||
1269 | } | ||
1270 | } | ||
1271 | return 0; | ||
1272 | } | ||
1273 | |||
1258 | static void smoothScroll_DocumentWidget_(iDocumentWidget *d, int offset, int duration) { | 1274 | static void smoothScroll_DocumentWidget_(iDocumentWidget *d, int offset, int duration) { |
1259 | /* Get rid of link numbers when scrolling. */ | 1275 | /* Get rid of link numbers when scrolling. */ |
1260 | if (offset && d->flags & showLinkNumbers_DocumentWidgetFlag) { | 1276 | if (offset && d->flags & showLinkNumbers_DocumentWidgetFlag) { |
@@ -1267,19 +1283,19 @@ static void smoothScroll_DocumentWidget_(iDocumentWidget *d, int offset, int dur | |||
1267 | showToolbars_Window(get_Window(), offset < 0); | 1283 | showToolbars_Window(get_Window(), offset < 0); |
1268 | } | 1284 | } |
1269 | } | 1285 | } |
1286 | #if !defined (iPlatformMobile) | ||
1270 | if (!prefs_App()->smoothScrolling) { | 1287 | if (!prefs_App()->smoothScrolling) { |
1271 | duration = 0; /* always instant */ | 1288 | duration = 0; /* always instant */ |
1272 | } | 1289 | } |
1290 | #endif | ||
1273 | int destY = targetValue_Anim(&d->scrollY) + offset; | 1291 | int destY = targetValue_Anim(&d->scrollY) + offset; |
1274 | if (destY < 0) { | 1292 | if (destY < -2 * d->overscroll) { |
1275 | destY = 0; | 1293 | destY = -2 * d->overscroll; |
1276 | stopWidgetMomentum_Touch(as_Widget(d)); | ||
1277 | } | 1294 | } |
1278 | const int scrollMax = scrollMax_DocumentWidget_(d); | 1295 | const int scrollMax = scrollMax_DocumentWidget_(d); |
1279 | if (scrollMax > 0) { | 1296 | if (scrollMax > 0) { |
1280 | if (destY >= scrollMax) { | 1297 | if (destY >= scrollMax + 2 * d->overscroll) { |
1281 | stopWidgetMomentum_Touch(as_Widget(d)); | 1298 | destY = scrollMax + 2 * d->overscroll; |
1282 | destY = scrollMax; | ||
1283 | } | 1299 | } |
1284 | } | 1300 | } |
1285 | else { | 1301 | else { |
@@ -1291,6 +1307,18 @@ static void smoothScroll_DocumentWidget_(iDocumentWidget *d, int offset, int dur | |||
1291 | else { | 1307 | else { |
1292 | setValue_Anim(&d->scrollY, destY, 0); | 1308 | setValue_Anim(&d->scrollY, destY, 0); |
1293 | } | 1309 | } |
1310 | if (d->overscroll && widgetMode_Touch(as_Widget(d)) == momentum_WidgetTouchMode) { | ||
1311 | const int osDelta = overscroll_DocumentWidget_(d); | ||
1312 | if (osDelta) { | ||
1313 | const float remaining = stopWidgetMomentum_Touch(as_Widget(d)); | ||
1314 | duration = iMini(1000, 50 * sqrt(remaining / gap_UI)); | ||
1315 | setValue_Anim(&d->scrollY, osDelta < 0 ? 0 : scrollMax, duration); | ||
1316 | d->scrollY.flags = bounce_AnimFlag | easeOut_AnimFlag | softer_AnimFlag; | ||
1317 | printf("remaining: %f dur: %d\n", remaining, duration); | ||
1318 | d->scrollY.bounce = (osDelta < 0 ? -1 : 1) * | ||
1319 | iMini(10 * d->overscroll, remaining * remaining * 0.00005f); | ||
1320 | } | ||
1321 | } | ||
1294 | updateVisible_DocumentWidget_(d); | 1322 | updateVisible_DocumentWidget_(d); |
1295 | refresh_Widget(as_Widget(d)); | 1323 | refresh_Widget(as_Widget(d)); |
1296 | if (duration > 0) { | 1324 | if (duration > 0) { |
@@ -2594,6 +2622,14 @@ static iBool processEvent_DocumentWidget_(iDocumentWidget *d, const SDL_Event *e | |||
2594 | if (isMetricsChange_UserEvent(ev)) { | 2622 | if (isMetricsChange_UserEvent(ev)) { |
2595 | updateSize_DocumentWidget(d); | 2623 | updateSize_DocumentWidget(d); |
2596 | } | 2624 | } |
2625 | else if (ev->type == SDL_USEREVENT && ev->user.code == widgetTouchEnds_UserEventCode) { | ||
2626 | const int osDelta = overscroll_DocumentWidget_(d); | ||
2627 | if (osDelta) { | ||
2628 | smoothScroll_DocumentWidget_(d, -osDelta, 100 * sqrt(iAbs(osDelta) / gap_UI)); | ||
2629 | d->scrollY.flags = easeOut_AnimFlag | muchSofter_AnimFlag; | ||
2630 | } | ||
2631 | return iTrue; | ||
2632 | } | ||
2597 | else if (ev->type == SDL_USEREVENT && ev->user.code == command_UserEventCode) { | 2633 | else if (ev->type == SDL_USEREVENT && ev->user.code == command_UserEventCode) { |
2598 | if (!handleCommand_DocumentWidget_(d, command_UserEvent(ev))) { | 2634 | if (!handleCommand_DocumentWidget_(d, command_UserEvent(ev))) { |
2599 | /* Base class commands. */ | 2635 | /* Base class commands. */ |
@@ -3913,7 +3949,7 @@ static void draw_DocumentWidget_(const iDocumentWidget *d) { | |||
3913 | }; | 3949 | }; |
3914 | render_DocumentWidget_(d, &ctx, iFalse /* just the mandatory parts */); | 3950 | render_DocumentWidget_(d, &ctx, iFalse /* just the mandatory parts */); |
3915 | setClip_Paint(&ctx.paint, bounds); | 3951 | setClip_Paint(&ctx.paint, bounds); |
3916 | const int yTop = docBounds.pos.y - value_Anim(&d->scrollY); | 3952 | int yTop = docBounds.pos.y - value_Anim(&d->scrollY) + overscroll_DocumentWidget_(d) * 0.667f; |
3917 | draw_VisBuf(d->visBuf, init_I2(bounds.pos.x, yTop), ySpan_Rect(bounds)); | 3953 | draw_VisBuf(d->visBuf, init_I2(bounds.pos.x, yTop), ySpan_Rect(bounds)); |
3918 | /* Text markers. */ | 3954 | /* Text markers. */ |
3919 | const iBool isTouchSelecting = (flags_Widget(w) & touchDrag_WidgetFlag) != 0; | 3955 | const iBool isTouchSelecting = (flags_Widget(w) & touchDrag_WidgetFlag) != 0; |