summaryrefslogtreecommitdiff
path: root/src/ui/util.c
diff options
context:
space:
mode:
authorJaakko Keränen <jaakko.keranen@iki.fi>2021-04-22 10:48:20 +0300
committerJaakko Keränen <jaakko.keranen@iki.fi>2021-04-22 10:48:20 +0300
commitc56870ab69b71887d703f51881c26ac79f4b7969 (patch)
tree9c8e70f49b15265d773c55f29056808b40963ee3 /src/ui/util.c
parent4b7c4ef2659d75ece4d63100a55c278f7c810c9e (diff)
SmoothScroll is a UI utility; moved it
Diffstat (limited to 'src/ui/util.c')
-rw-r--r--src/ui/util.c103
1 files changed, 103 insertions, 0 deletions
diff --git a/src/ui/util.c b/src/ui/util.c
index 877ec7c1..8d1430f8 100644
--- a/src/ui/util.c
+++ b/src/ui/util.c
@@ -36,6 +36,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
36#include "keys.h" 36#include "keys.h"
37#include "widget.h" 37#include "widget.h"
38#include "text.h" 38#include "text.h"
39#include "touch.h"
39#include "window.h" 40#include "window.h"
40 41
41#if defined (iPlatformAppleMobile) 42#if defined (iPlatformAppleMobile)
@@ -444,6 +445,108 @@ iInt2 delta_Click(const iClick *d) {
444 return sub_I2(d->pos, d->startPos); 445 return sub_I2(d->pos, d->startPos);
445} 446}
446 447
448/*----------------------------------------------------------------------------------------------*/
449
450void init_SmoothScroll(iSmoothScroll *d, iWidget *owner, iSmoothScrollNotifyFunc notify) {
451 reset_SmoothScroll(d);
452 d->widget = owner;
453 d->notify = notify;
454}
455
456void reset_SmoothScroll(iSmoothScroll *d) {
457 init_Anim(&d->pos, 0);
458 d->max = 0;
459 d->overscroll = (deviceType_App() != desktop_AppDeviceType ? 100 * gap_UI : 0);
460}
461
462void setMax_SmoothScroll(iSmoothScroll *d, int max) {
463 max = iMax(0, max);
464 if (max != d->max) {
465 d->max = max;
466 if (targetValue_Anim(&d->pos) > d->max) {
467 d->pos.to = d->max;
468 }
469 }
470}
471
472static int overscroll_SmoothScroll_(const iSmoothScroll *d) {
473 if (d->overscroll) {
474 const int y = value_Anim(&d->pos);
475 if (y <= 0) {
476 return y;
477 }
478 if (y >= d->max) {
479 return y - d->max;
480 }
481 }
482 return 0;
483}
484
485float pos_SmoothScroll(const iSmoothScroll *d) {
486 return value_Anim(&d->pos) - overscroll_SmoothScroll_(d) * 0.667f;
487}
488
489iBool isFinished_SmoothScroll(const iSmoothScroll *d) {
490 return isFinished_Anim(&d->pos);
491}
492
493void moveSpan_SmoothScroll(iSmoothScroll *d, int offset, uint32_t span) {
494#if !defined (iPlatformMobile)
495 if (!prefs_App()->smoothScrolling) {
496 span = 0; /* always instant */
497 }
498#endif
499 int destY = targetValue_Anim(&d->pos) + offset;
500 if (destY < -d->overscroll) {
501 destY = -d->overscroll;
502 }
503 if (d->max > 0) {
504 if (destY >= d->max + d->overscroll) {
505 destY = d->max + d->overscroll;
506 }
507 }
508 else {
509 destY = 0;
510 }
511 if (span) {
512 setValueEased_Anim(&d->pos, destY, span);
513 }
514 else {
515 setValue_Anim(&d->pos, destY, 0);
516 }
517 if (d->overscroll && widgetMode_Touch(d->widget) == momentum_WidgetTouchMode) {
518 const int osDelta = overscroll_SmoothScroll_(d);
519 if (osDelta) {
520 const float remaining = stopWidgetMomentum_Touch(d->widget);
521 span = iMini(1000, 50 * sqrt(remaining / gap_UI));
522 setValue_Anim(&d->pos, osDelta < 0 ? 0 : d->max, span);
523 d->pos.flags = bounce_AnimFlag | easeOut_AnimFlag | softer_AnimFlag;
524 // printf("remaining: %f dur: %d\n", remaining, duration);
525 d->pos.bounce = (osDelta < 0 ? -1 : 1) *
526 iMini(5 * d->overscroll, remaining * remaining * 0.00005f);
527 }
528 }
529 if (d->notify) {
530 d->notify(d->widget, offset, span);
531 }
532}
533
534void move_SmoothScroll(iSmoothScroll *d, int offset) {
535 moveSpan_SmoothScroll(d, offset, 0 /* instantly */);
536}
537
538iBool processEvent_SmoothScroll(iSmoothScroll *d, const SDL_Event *ev) {
539 if (ev->type == SDL_USEREVENT && ev->user.code == widgetTouchEnds_UserEventCode) {
540 const int osDelta = overscroll_SmoothScroll_(d);
541 if (osDelta) {
542 moveSpan_SmoothScroll(d, -osDelta, 100 * sqrt(iAbs(osDelta) / gap_UI));
543 d->pos.flags = easeOut_AnimFlag | muchSofter_AnimFlag;
544 }
545 return iTrue;
546 }
547 return iFalse;
548}
549
447/*-----------------------------------------------------------------------------------------------*/ 550/*-----------------------------------------------------------------------------------------------*/
448 551
449iWidget *makePadding_Widget(int size) { 552iWidget *makePadding_Widget(int size) {