From c56870ab69b71887d703f51881c26ac79f4b7969 Mon Sep 17 00:00:00 2001 From: Jaakko Keränen Date: Thu, 22 Apr 2021 10:48:20 +0300 Subject: SmoothScroll is a UI utility; moved it --- src/ui/documentwidget.c | 117 ------------------------------------------------ src/ui/util.c | 103 ++++++++++++++++++++++++++++++++++++++++++ src/ui/util.h | 25 +++++++++++ 3 files changed, 128 insertions(+), 117 deletions(-) (limited to 'src') diff --git a/src/ui/documentwidget.c b/src/ui/documentwidget.c index 635bf3e6..1298dda9 100644 --- a/src/ui/documentwidget.c +++ b/src/ui/documentwidget.c @@ -198,123 +198,6 @@ static void prerender_DocumentWidget_ (iAny *); static void scrollBegan_DocumentWidget_ (iAnyObject *, int, uint32_t); static const int smoothDuration_DocumentWidget_ = 600; /* milliseconds */ -static const int outlineMinWidth_DocumentWdiget_ = 45; /* times gap_UI */ -static const int outlineMaxWidth_DocumentWidget_ = 65; /* times gap_UI */ -static const int outlinePadding_DocumentWidget_ = 3; /* times gap_UI */ - - -iDeclareType(SmoothScroll) - -typedef void (*iSmoothScrollNotifyFunc)(iAnyObject *, int offset, uint32_t span); - -struct Impl_SmoothScroll { - iWidget *widget; - iSmoothScrollNotifyFunc notify; - iAnim pos; - int max; - int overscroll; -}; - -void reset_SmoothScroll(iSmoothScroll *d) { - init_Anim(&d->pos, 0); - d->max = 0; - d->overscroll = (deviceType_App() != desktop_AppDeviceType ? 100 * gap_UI : 0); -} - -void init_SmoothScroll(iSmoothScroll *d, iWidget *owner, iSmoothScrollNotifyFunc notify) { - d->widget = owner; - d->notify = notify; - reset_SmoothScroll(d); -} - -void setMax_SmoothScroll(iSmoothScroll *d, int max) { - max = iMax(0, max); - if (max != d->max) { - d->max = max; - if (targetValue_Anim(&d->pos) > d->max) { - d->pos.to = d->max; - } - } -} - -static int overscroll_SmoothScroll_(const iSmoothScroll *d) { - if (d->overscroll) { - const int y = value_Anim(&d->pos); - if (y <= 0) { - return y; - } - if (y >= d->max) { - return y - d->max; - } - } - return 0; -} - -float pos_SmoothScroll(const iSmoothScroll *d) { - return value_Anim(&d->pos) - overscroll_SmoothScroll_(d) * 0.667f; -} - -iBool isFinished_SmoothScroll(const iSmoothScroll *d) { - return isFinished_Anim(&d->pos); -} - -void moveSpan_SmoothScroll(iSmoothScroll *d, int offset, uint32_t span) { -#if !defined (iPlatformMobile) - if (!prefs_App()->smoothScrolling) { - span = 0; /* always instant */ - } -#endif - int destY = targetValue_Anim(&d->pos) + offset; - if (destY < -d->overscroll) { - destY = -d->overscroll; - } - if (d->max > 0) { - if (destY >= d->max + d->overscroll) { - destY = d->max + d->overscroll; - } - } - else { - destY = 0; - } - if (span) { - setValueEased_Anim(&d->pos, destY, span); - } - else { - setValue_Anim(&d->pos, destY, 0); - } - if (d->overscroll && widgetMode_Touch(d->widget) == momentum_WidgetTouchMode) { - const int osDelta = overscroll_SmoothScroll_(d); - if (osDelta) { - const float remaining = stopWidgetMomentum_Touch(d->widget); - span = iMini(1000, 50 * sqrt(remaining / gap_UI)); - setValue_Anim(&d->pos, osDelta < 0 ? 0 : d->max, span); - d->pos.flags = bounce_AnimFlag | easeOut_AnimFlag | softer_AnimFlag; -// printf("remaining: %f dur: %d\n", remaining, duration); - d->pos.bounce = (osDelta < 0 ? -1 : 1) * - iMini(5 * d->overscroll, remaining * remaining * 0.00005f); - } - } - if (d->notify) { - d->notify(d->widget, offset, span); - } -} - -void move_SmoothScroll(iSmoothScroll *d, int offset) { - moveSpan_SmoothScroll(d, offset, 0 /* instantly */); -} - -iBool processEvent_SmoothScroll(iSmoothScroll *d, const SDL_Event *ev) { - if (ev->type == SDL_USEREVENT && ev->user.code == widgetTouchEnds_UserEventCode) { - const int osDelta = overscroll_SmoothScroll_(d); - if (osDelta) { - moveSpan_SmoothScroll(d, -osDelta, 100 * sqrt(iAbs(osDelta) / gap_UI)); - d->pos.flags = easeOut_AnimFlag | muchSofter_AnimFlag; - } - return iTrue; - } - return iFalse; -} - enum iRequestState { blank_RequestState, 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. */ #include "keys.h" #include "widget.h" #include "text.h" +#include "touch.h" #include "window.h" #if defined (iPlatformAppleMobile) @@ -444,6 +445,108 @@ iInt2 delta_Click(const iClick *d) { return sub_I2(d->pos, d->startPos); } +/*----------------------------------------------------------------------------------------------*/ + +void init_SmoothScroll(iSmoothScroll *d, iWidget *owner, iSmoothScrollNotifyFunc notify) { + reset_SmoothScroll(d); + d->widget = owner; + d->notify = notify; +} + +void reset_SmoothScroll(iSmoothScroll *d) { + init_Anim(&d->pos, 0); + d->max = 0; + d->overscroll = (deviceType_App() != desktop_AppDeviceType ? 100 * gap_UI : 0); +} + +void setMax_SmoothScroll(iSmoothScroll *d, int max) { + max = iMax(0, max); + if (max != d->max) { + d->max = max; + if (targetValue_Anim(&d->pos) > d->max) { + d->pos.to = d->max; + } + } +} + +static int overscroll_SmoothScroll_(const iSmoothScroll *d) { + if (d->overscroll) { + const int y = value_Anim(&d->pos); + if (y <= 0) { + return y; + } + if (y >= d->max) { + return y - d->max; + } + } + return 0; +} + +float pos_SmoothScroll(const iSmoothScroll *d) { + return value_Anim(&d->pos) - overscroll_SmoothScroll_(d) * 0.667f; +} + +iBool isFinished_SmoothScroll(const iSmoothScroll *d) { + return isFinished_Anim(&d->pos); +} + +void moveSpan_SmoothScroll(iSmoothScroll *d, int offset, uint32_t span) { +#if !defined (iPlatformMobile) + if (!prefs_App()->smoothScrolling) { + span = 0; /* always instant */ + } +#endif + int destY = targetValue_Anim(&d->pos) + offset; + if (destY < -d->overscroll) { + destY = -d->overscroll; + } + if (d->max > 0) { + if (destY >= d->max + d->overscroll) { + destY = d->max + d->overscroll; + } + } + else { + destY = 0; + } + if (span) { + setValueEased_Anim(&d->pos, destY, span); + } + else { + setValue_Anim(&d->pos, destY, 0); + } + if (d->overscroll && widgetMode_Touch(d->widget) == momentum_WidgetTouchMode) { + const int osDelta = overscroll_SmoothScroll_(d); + if (osDelta) { + const float remaining = stopWidgetMomentum_Touch(d->widget); + span = iMini(1000, 50 * sqrt(remaining / gap_UI)); + setValue_Anim(&d->pos, osDelta < 0 ? 0 : d->max, span); + d->pos.flags = bounce_AnimFlag | easeOut_AnimFlag | softer_AnimFlag; + // printf("remaining: %f dur: %d\n", remaining, duration); + d->pos.bounce = (osDelta < 0 ? -1 : 1) * + iMini(5 * d->overscroll, remaining * remaining * 0.00005f); + } + } + if (d->notify) { + d->notify(d->widget, offset, span); + } +} + +void move_SmoothScroll(iSmoothScroll *d, int offset) { + moveSpan_SmoothScroll(d, offset, 0 /* instantly */); +} + +iBool processEvent_SmoothScroll(iSmoothScroll *d, const SDL_Event *ev) { + if (ev->type == SDL_USEREVENT && ev->user.code == widgetTouchEnds_UserEventCode) { + const int osDelta = overscroll_SmoothScroll_(d); + if (osDelta) { + moveSpan_SmoothScroll(d, -osDelta, 100 * sqrt(iAbs(osDelta) / gap_UI)); + d->pos.flags = easeOut_AnimFlag | muchSofter_AnimFlag; + } + return iTrue; + } + return iFalse; +} + /*-----------------------------------------------------------------------------------------------*/ iWidget *makePadding_Widget(int size) { diff --git a/src/ui/util.h b/src/ui/util.h index 191b8a87..223982a8 100644 --- a/src/ui/util.h +++ b/src/ui/util.h @@ -163,6 +163,31 @@ iInt2 delta_Click (const iClick *); /*-----------------------------------------------------------------------------------------------*/ +iDeclareType(SmoothScroll) + +typedef void (*iSmoothScrollNotifyFunc)(iAnyObject *, int offset, uint32_t span); + +struct Impl_SmoothScroll { + iAnim pos; + int max; + int overscroll; + iWidget *widget; + iSmoothScrollNotifyFunc notify; +}; + +void init_SmoothScroll (iSmoothScroll *, iWidget *owner, iSmoothScrollNotifyFunc notify); + +void reset_SmoothScroll (iSmoothScroll *); +void setMax_SmoothScroll (iSmoothScroll *, int max); +void move_SmoothScroll (iSmoothScroll *, int offset); +void moveSpan_SmoothScroll (iSmoothScroll *, int offset, uint32_t span); +iBool processEvent_SmoothScroll (iSmoothScroll *, const SDL_Event *ev); + +float pos_SmoothScroll (const iSmoothScroll *); +iBool isFinished_SmoothScroll (const iSmoothScroll *); + +/*-----------------------------------------------------------------------------------------------*/ + iWidget * makePadding_Widget (int size); iLabelWidget * makeHeading_Widget (const char *text); iWidget * makeHDiv_Widget (void); -- cgit v1.2.3