1 #include "switch.h"
2 
3 #include "draw.h"
4 #include "tooltip.h"
5 
6 #include "../macros.h"
7 #include "../ui.h"
8 #include "../theme.h"
9 
calculate_pos_and_width(UISWITCH * s,int * x,int * w)10 static void calculate_pos_and_width(UISWITCH *s, int *x, int *w) {
11     int old_w = *w;
12 
13     // Push away from the right border to fit,
14     // if our panel is right-adjusted.
15     if (s->panel.x < 0) {
16         *x -= *w - old_w;
17     }
18 }
19 
switch_draw(UISWITCH * s,int x,int y,int w,int h)20 void switch_draw(UISWITCH *s, int x, int y, int w, int h) {
21     // Switch is hidden
22     if (s->nodraw) {
23         return;
24     }
25 
26     // If `update` function is defined, call it on each draw
27     if (s->update) {
28         s->update(s);
29     }
30 
31     // Switch background color
32     uint32_t color = s->mousedown ? s->press_color : (s->mouseover ? s->hover_color : s->bg_color);
33     drawalpha(s->style_outer, x, y, w, h, s->disabled ? s->disabled_color : color);
34 
35     // SVG offsets, used for centering
36     int tx = ((w / 2 - s->toggle_w) / 2), ty = ((h - s->toggle_h) / 2), ix0 = ((w / 2 - s->icon_off_w) / 2),
37         iy0 = ((h - s->icon_off_h) / 2), ix1 = ((w / 2 - s->icon_on_w) / 2), iy1 = ((h - s->icon_on_h) / 2);
38 
39     if (s->style_toggle) {
40         if (s->switch_on) {
41             drawalpha(s->style_toggle, x + (w / 2) + tx, y + ty, s->toggle_w, s->toggle_h, s->sw_color);
42         } else {
43             drawalpha(s->style_toggle, x + tx, y + ty, s->toggle_w, s->toggle_h, s->sw_color);
44         }
45     }
46 
47     if (s->style_icon_off && !s->switch_on) {
48         drawalpha(s->style_icon_off, x + (w / 2) + ix0, y + iy0, s->icon_off_w, s->icon_off_h, s->sw_color);
49     } else if (s->style_icon_on && s->switch_on) {
50         drawalpha(s->style_icon_on, x + ix1, y + iy1, s->icon_on_w, s->icon_on_h, s->sw_color);
51     }
52 }
53 
switch_mmove(UISWITCH * s,int UNUSED (x),int UNUSED (y),int width,int height,int mx,int my,int UNUSED (dx),int UNUSED (dy))54 bool switch_mmove(UISWITCH *s, int UNUSED(x), int UNUSED(y), int width, int height, int mx, int my, int UNUSED(dx),
55                   int UNUSED(dy)) {
56     // Ensure that font is set before calculating position and width.
57     setfont(FONT_SELF_NAME);
58 
59     int real_x = 0, real_w = width;
60     calculate_pos_and_width(s, &real_x, &real_w);
61 
62     bool mouseover = inrect(mx, my, real_x, 0, real_w, height);
63     if (mouseover) {
64         if (!s->disabled) {
65             cursor = CURSOR_HAND;
66         }
67 
68         if (maybe_i18nal_string_is_valid(&s->tooltip_text)) {
69             tooltip_new(&s->tooltip_text);
70         }
71     }
72     if (mouseover != s->mouseover) {
73         s->mouseover = mouseover;
74         return 1;
75     }
76 
77     return 0;
78 }
79 
switch_mdown(UISWITCH * s)80 bool switch_mdown(UISWITCH *s) {
81     if (!s->mousedown && s->mouseover) {
82         s->mousedown = 1;
83         return 1;
84     }
85 
86     return 0;
87 }
88 
switch_mright(UISWITCH * s)89 bool switch_mright(UISWITCH *s) {
90     if (s->mouseover && s->onright) {
91         s->onright();
92         return 1;
93     }
94     return 0;
95 }
96 
switch_mwheel(UISWITCH * UNUSED (s),int UNUSED (height),double UNUSED (d),bool UNUSED (smooth))97 bool switch_mwheel(UISWITCH *UNUSED(s), int UNUSED(height), double UNUSED(d), bool UNUSED(smooth)) {
98     return 0;
99 }
100 
switch_mup(UISWITCH * s)101 bool switch_mup(UISWITCH *s) {
102     // ignore click when switch is disabled
103     if (s->mousedown && !s->disabled) {
104         if (s->mouseover) {
105             s->switch_on = !s->switch_on;
106             s->on_mup();
107         }
108         s->mousedown = 0;
109         return 1;
110     }
111     s->mousedown = 0;
112     return 0;
113 }
114 
switch_mleave(UISWITCH * s)115 bool switch_mleave(UISWITCH *s) {
116     if (s->mouseover) {
117         s->mouseover = 0;
118         return 1;
119     }
120     return 0;
121 }
122 
switch_set_colors(UISWITCH * s)123 static void switch_set_colors(UISWITCH *s) {
124     if (s->switch_on) {
125         s->bg_color    = COLOR_BTN_SUCCESS_BKGRND;
126         s->sw_color    = COLOR_BTN_SUCCESS_TEXT;
127         s->press_color = COLOR_BTN_SUCCESS_BKGRND_HOVER;
128         s->hover_color = COLOR_BTN_SUCCESS_BKGRND_HOVER;
129     } else {
130         s->bg_color    = COLOR_BTN_DISABLED_BKGRND;
131         s->sw_color    = COLOR_BTN_DISABLED_FORGRND;
132         s->hover_color = COLOR_BTN_DISABLED_BKGRND_HOVER;
133         s->press_color = COLOR_BTN_DISABLED_BKGRND_HOVER;
134     }
135 }
136 
switch_set_size(UISWITCH * s)137 static void switch_set_size(UISWITCH *s) {
138     s->toggle_w   = BM_SWITCH_TOGGLE_WIDTH;
139     s->toggle_h   = BM_SWITCH_TOGGLE_HEIGHT;
140     s->icon_off_w = BM_FB_WIDTH;
141     s->icon_off_h = BM_FB_HEIGHT;
142     s->icon_on_w  = BM_FB_WIDTH;
143     s->icon_on_h  = BM_FB_HEIGHT;
144 }
145 
switch_update(UISWITCH * s)146 void switch_update(UISWITCH *s) {
147     switch_set_colors(s);
148     switch_set_size(s);
149 }
150