summaryrefslogtreecommitdiff
path: root/src/ui/documentwidget.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/ui/documentwidget.c')
-rw-r--r--src/ui/documentwidget.c54
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
1260static 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
1258static void smoothScroll_DocumentWidget_(iDocumentWidget *d, int offset, int duration) { 1274static 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;