summaryrefslogtreecommitdiff
path: root/src/ui/scrollwidget.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/ui/scrollwidget.c')
-rw-r--r--src/ui/scrollwidget.c85
1 files changed, 80 insertions, 5 deletions
diff --git a/src/ui/scrollwidget.c b/src/ui/scrollwidget.c
index e887ddbf..a08b58d7 100644
--- a/src/ui/scrollwidget.c
+++ b/src/ui/scrollwidget.c
@@ -23,9 +23,23 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
23#include "scrollwidget.h" 23#include "scrollwidget.h"
24#include "paint.h" 24#include "paint.h"
25#include "util.h" 25#include "util.h"
26#include "periodic.h"
27#include "app.h"
28
29#include <SDL_timer.h>
26 30
27iDefineObjectConstruction(ScrollWidget) 31iDefineObjectConstruction(ScrollWidget)
28 32
33static float minOpacity_(void) {
34#if !defined (iPlatformApple)
35 if (deviceType_App() == desktop_AppDeviceType) {
36 /* Don't fade the scrollbars completely. */
37 return 0.333f;
38 }
39#endif
40 return 0.0f;
41}
42
29struct Impl_ScrollWidget { 43struct Impl_ScrollWidget {
30 iWidget widget; 44 iWidget widget;
31 iRangei range; 45 iRangei range;
@@ -33,12 +47,23 @@ struct Impl_ScrollWidget {
33 int thumbSize; 47 int thumbSize;
34 iClick click; 48 iClick click;
35 int startThumb; 49 int startThumb;
50 iAnim opacity;
51 uint32_t fadeStart;
52 iBool willCheckFade;
36}; 53};
37 54
38static void updateMetrics_ScrollWidget_(iScrollWidget *d) { 55static void updateMetrics_ScrollWidget_(iScrollWidget *d) {
39 as_Widget(d)->rect.size.x = gap_UI * 3; 56 as_Widget(d)->rect.size.x = gap_UI * 3;
40} 57}
41 58
59static void animateOpacity_ScrollWidget_(void *ptr) {
60 iScrollWidget *d = ptr;
61 if (!isFinished_Anim(&d->opacity)) {
62 addTicker_App(animateOpacity_ScrollWidget_, ptr);
63 }
64 refresh_Widget(ptr);
65}
66
42void init_ScrollWidget(iScrollWidget *d) { 67void init_ScrollWidget(iScrollWidget *d) {
43 iWidget *w = as_Widget(d); 68 iWidget *w = as_Widget(d);
44 init_Widget(w); 69 init_Widget(w);
@@ -49,10 +74,13 @@ void init_ScrollWidget(iScrollWidget *d) {
49 iTrue); 74 iTrue);
50 updateMetrics_ScrollWidget_(d); 75 updateMetrics_ScrollWidget_(d);
51 init_Click(&d->click, d, SDL_BUTTON_LEFT); 76 init_Click(&d->click, d, SDL_BUTTON_LEFT);
77 init_Anim(&d->opacity, minOpacity_());
78 d->willCheckFade = iFalse;
52} 79}
53 80
54void deinit_ScrollWidget(iScrollWidget *d) { 81void deinit_ScrollWidget(iScrollWidget *d) {
55 iUnused(d); 82 remove_Periodic(periodic_App(), d);
83 removeTicker_App(animateOpacity_ScrollWidget_, d);
56} 84}
57 85
58static int thumbSize_ScrollWidget_(const iScrollWidget *d) { 86static int thumbSize_ScrollWidget_(const iScrollWidget *d) {
@@ -74,10 +102,26 @@ static iRect thumbRect_ScrollWidget_(const iScrollWidget *d) {
74 return rect; 102 return rect;
75} 103}
76 104
105static void unfade_ScrollWidget_(iScrollWidget *d, float opacity) {
106 d->fadeStart = SDL_GetTicks() + 1000;
107 if (targetValue_Anim(&d->opacity) < opacity) {
108 setValue_Anim(&d->opacity, opacity, 66);
109 addTicker_App(animateOpacity_ScrollWidget_, d);
110 }
111 if (!d->willCheckFade) {
112 d->willCheckFade = iTrue;
113 add_Periodic(periodic_App(), d, "scrollbar.fade");
114 }
115 refresh_Widget(d);
116}
117
77static void checkVisible_ScrollWidget_(iScrollWidget *d) { 118static void checkVisible_ScrollWidget_(iScrollWidget *d) {
78 setFlags_Widget(as_Widget(d), 119 const iBool wasHidden = isVisible_Widget(d);
79 hidden_WidgetFlag, 120 const iBool isHidden = d->thumbSize != 0 ? height_Rect(thumbRect_ScrollWidget_(d)) == 0 : iTrue;
80 d->thumbSize != 0 ? height_Rect(thumbRect_ScrollWidget_(d)) == 0 : iTrue); 121 setFlags_Widget(as_Widget(d), hidden_WidgetFlag, isHidden);
122 if (wasHidden && !isHidden) {
123 unfade_ScrollWidget_(d, 1.0f);
124 }
81} 125}
82 126
83void setRange_ScrollWidget(iScrollWidget *d, iRangei range) { 127void setRange_ScrollWidget(iScrollWidget *d, iRangei range) {
@@ -87,9 +131,13 @@ void setRange_ScrollWidget(iScrollWidget *d, iRangei range) {
87} 131}
88 132
89void setThumb_ScrollWidget(iScrollWidget *d, int thumb, int thumbSize) { 133void setThumb_ScrollWidget(iScrollWidget *d, int thumb, int thumbSize) {
134 const int oldThumb = d->thumb;
90 d->thumb = thumb; 135 d->thumb = thumb;
91 d->thumbSize = thumbSize; 136 d->thumbSize = thumbSize;
92 checkVisible_ScrollWidget_(d); 137 checkVisible_ScrollWidget_(d);
138 if (oldThumb != d->thumb && thumbSize) {
139 unfade_ScrollWidget_(d, 1.0f);
140 }
93} 141}
94 142
95static iBool processEvent_ScrollWidget_(iScrollWidget *d, const SDL_Event *ev) { 143static iBool processEvent_ScrollWidget_(iScrollWidget *d, const SDL_Event *ev) {
@@ -97,6 +145,25 @@ static iBool processEvent_ScrollWidget_(iScrollWidget *d, const SDL_Event *ev) {
97 if (isMetricsChange_UserEvent(ev)) { 145 if (isMetricsChange_UserEvent(ev)) {
98 updateMetrics_ScrollWidget_(d); 146 updateMetrics_ScrollWidget_(d);
99 } 147 }
148 if (ev->type == SDL_MOUSEMOTION) {
149 const iInt2 mouse = init_I2(ev->motion.x, ev->motion.y);
150 const iBool isNearby = containsExpanded_Widget(&d->widget, mouse, 4 * gap_UI);
151 const iBool isOver = isNearby && contains_Rect(thumbRect_ScrollWidget_(d), mouse);
152 if (isNearby) {
153 unfade_ScrollWidget_(d, isOver ? 1.0f : 0.4f);
154 }
155 }
156 if (isCommand_UserEvent(ev, "scrollbar.fade")) {
157 if (d->willCheckFade && SDL_GetTicks() > d->fadeStart) {
158 setValue_Anim(&d->opacity, minOpacity_(), 200);
159 remove_Periodic(periodic_App(), d);
160 d->willCheckFade = iFalse;
161 if (!isFinished_Anim(&d->opacity)) {
162 addTicker_App(animateOpacity_ScrollWidget_, d);
163 }
164 }
165 return iFalse;
166 }
100 switch (processEvent_Click(&d->click, ev)) { 167 switch (processEvent_Click(&d->click, ev)) {
101 case started_ClickResult: 168 case started_ClickResult:
102 setFlags_Widget(w, pressed_WidgetFlag, iTrue); 169 setFlags_Widget(w, pressed_WidgetFlag, iTrue);
@@ -146,10 +213,18 @@ static void draw_ScrollWidget_(const iScrollWidget *d) {
146 if (bounds.size.x > 0) { 213 if (bounds.size.x > 0) {
147 iPaint p; 214 iPaint p;
148 init_Paint(&p); 215 init_Paint(&p);
149 //drawVLine_Paint(&p, topLeft_Rect(bounds), height_Rect(bounds), uiSeparator_ColorId); 216 /* Blend if opacity is not at maximum. */
217 p.alpha = 255 * value_Anim(&d->opacity);
218 SDL_Renderer *render = renderer_Window(get_Window());
219 if (p.alpha < 255) {
220 SDL_SetRenderDrawBlendMode(render, SDL_BLENDMODE_BLEND);
221 }
150 const iRect thumbRect = shrunk_Rect( 222 const iRect thumbRect = shrunk_Rect(
151 thumbRect_ScrollWidget_(d), init_I2(isPressed ? gap_UI : (gap_UI * 4 / 3), gap_UI / 2)); 223 thumbRect_ScrollWidget_(d), init_I2(isPressed ? gap_UI : (gap_UI * 4 / 3), gap_UI / 2));
152 fillRect_Paint(&p, thumbRect, isPressed ? uiBackgroundPressed_ColorId : tmQuote_ColorId); 224 fillRect_Paint(&p, thumbRect, isPressed ? uiBackgroundPressed_ColorId : tmQuote_ColorId);
225 if (p.alpha < 255) {
226 SDL_SetRenderDrawBlendMode(render, SDL_BLENDMODE_NONE);
227 }
153 } 228 }
154} 229}
155 230