From c94469c3b5e46fa15939de271e6a4e1cc812dea3 Mon Sep 17 00:00:00 2001 From: Jaakko Keränen Date: Mon, 17 May 2021 21:28:07 +0300 Subject: SidebarWidget: Animate show/hide Also addressed clipping issues when using multiple roots. --- src/ui/paint.c | 17 ++++++++--------- src/ui/sidebarwidget.c | 33 +++++++++++++++++++++++++++++++-- src/ui/window.c | 2 +- 3 files changed, 40 insertions(+), 12 deletions(-) diff --git a/src/ui/paint.c b/src/ui/paint.c index faaf403d..c575d5fc 100644 --- a/src/ui/paint.c +++ b/src/ui/paint.c @@ -62,20 +62,19 @@ void endTarget_Paint(iPaint *d) { } void setClip_Paint(iPaint *d, iRect rect) { - if (rect.pos.y < 0) { - const int off = rect.pos.y; - rect.pos.y -= off; - rect.size.y = iMax(0, rect.size.y + off); - } - if (rect.pos.x < 0) { - const int off = rect.pos.x; - rect.pos.x -= off; - rect.size.x = iMax(0, rect.size.x + off); + rect = intersect_Rect(rect, rect_Root(get_Root())); + if (isEmpty_Rect(rect)) { + rect = init_Rect(0, 0, 1, 1); } SDL_RenderSetClipRect(renderer_Paint_(d), (const SDL_Rect *) &rect); } void unsetClip_Paint(iPaint *d) { + if (numRoots_Window(get_Window()) > 1) { + const iRect rect = rect_Root(get_Root()); + SDL_RenderSetClipRect(renderer_Paint_(d), (const SDL_Rect *) &rect); + return; + } #if SDL_VERSION_ATLEAST(2, 0, 12) SDL_RenderSetClipRect(renderer_Paint_(d), NULL); #else diff --git a/src/ui/sidebarwidget.c b/src/ui/sidebarwidget.c index d4e2fb3b..436eb250 100644 --- a/src/ui/sidebarwidget.c +++ b/src/ui/sidebarwidget.c @@ -878,10 +878,31 @@ static iBool handleSidebarCommand_SidebarWidget_(iSidebarWidget *d, const char * if (arg_Command(cmd) && isVisible_Widget(w)) { return iTrue; } + const iBool isAnimated = (deviceType_App() != phone_AppDeviceType); + int visX = 0; + if (isVisible_Widget(w)) { + visX = left_Rect(bounds_Widget(w)) - left_Rect(w->root->widget->rect); + } setFlags_Widget(w, hidden_WidgetFlag, isVisible_Widget(w)); if (isVisible_Widget(w)) { + setFlags_Widget(w, keepOnTop_WidgetFlag, iFalse); w->rect.size.x = d->widthAsGaps * gap_UI; invalidate_ListWidget(d->list); + if (isAnimated) { + setFlags_Widget(w, horizontalOffset_WidgetFlag, iTrue); + setVisualOffset_Widget(w, (d->side == left_SideBarSide ? -1 : 1) * w->rect.size.x, 0, 0); + setVisualOffset_Widget(w, 0, 300, easeOut_AnimFlag | softer_AnimFlag); + } + } + else if (isAnimated) { + if (d->side == right_SideBarSide) { + setVisualOffset_Widget(w, visX, 0, 0); + setVisualOffset_Widget(w, visX + w->rect.size.x, 300, easeOut_AnimFlag | softer_AnimFlag); + } + else { + setFlags_Widget(w, keepOnTop_WidgetFlag, iTrue); + setVisualOffset_Widget(w, -w->rect.size.x, 300, easeOut_AnimFlag | softer_AnimFlag); + } } arrange_Widget(w->parent); /* BUG: Rearranging because the arrange above didn't fully resolve the height. */ @@ -1433,9 +1454,17 @@ static void draw_SidebarWidget_(const iSidebarWidget *d) { const iRect bounds = bounds_Widget(w); iPaint p; init_Paint(&p); + if (flags_Widget(w) & visualOffset_WidgetFlag && isVisible_Widget(w)) { + fillRect_Paint(&p, boundsWithoutVisualOffset_Widget(w), tmBackground_ColorId); + } draw_Widget(w); - drawVLine_Paint( - &p, addX_I2(topRight_Rect(bounds), -1), height_Rect(bounds), uiSeparator_ColorId); + if (isVisible_Widget(w)) { + drawVLine_Paint( + &p, + addX_I2(d->side == left_SideBarSide ? topRight_Rect(bounds) : topLeft_Rect(bounds), -1), + height_Rect(bounds), + uiSeparator_ColorId); + } } static void draw_SidebarItem_(const iSidebarItem *d, iPaint *p, iRect itemRect, diff --git a/src/ui/window.c b/src/ui/window.c index ff565b84..abdc363d 100644 --- a/src/ui/window.c +++ b/src/ui/window.c @@ -1007,11 +1007,11 @@ void draw_Window(iWindow *d) { init_Paint(&p); /* Clear the window. The clear color is visible as a border around the window when the custom frame is being used. */ { + setCurrent_Root(d->roots[0]); #if defined (iPlatformAppleMobile) iColor back = get_Color(uiBackground_ColorId); if (deviceType_App() == phone_AppDeviceType) { /* Page background extends to safe area, so fill it completely. */ - setCurrent_Root(d->roots[0]); back = get_Color(tmBackground_ColorId); } #else -- cgit v1.2.3