istereo2
view src/uitheme.cc @ 20:2b85d05df3f2
animation controls for easier screenshot grabbing
author | John Tsiombikas <nuclear@member.fsf.org> |
---|---|
date | Fri, 02 Oct 2015 04:54:55 +0300 |
parents | 018f997dc646 |
children |
line source
1 #include <map>
2 #include <string>
3 #include "goatkit/goatkit.h"
4 #include "opengl.h"
5 #include "sanegl.h"
6 #include "drawtext.h"
7 #include "sdr.h"
9 #define BEVEL 1.5
10 #define VIS_THRES 0.005
12 using namespace goatkit;
14 struct Color {
15 float r, g, b, a;
17 Color() : r(1), g(1), b(1), a(1) {}
18 Color(float r, float g, float b, float a = 1.0f)
19 {
20 this->r = r;
21 this->g = g;
22 this->b = b;
23 this->a = a;
24 }
25 };
27 enum {
28 TEXT_COLOR,
29 TOP_COLOR,
30 BOTTOM_COLOR,
31 TOP_ON_COLOR,
32 BOTTOM_ON_COLOR,
33 TOP_OFF_COLOR,
34 BOTTOM_OFF_COLOR,
35 BEVEL_LIT_COLOR,
36 BEVEL_SHAD_COLOR,
37 CURSOR_COLOR,
38 SELECTION_COLOR,
39 CHECK_COLOR
40 };
42 static Color colors[] = {
43 Color(0.0, 0.0, 0.0, 1.0), /* text color */
44 Color(0.75, 0.75, 0.75, 1.0), /* top color */
45 Color(0.56, 0.56, 0.56, 1.0), /* bot color */
46 Color(0.4, 0.5, 0.8, 1.0), /* top on color */
47 Color(0.15, 0.2, 0.4, 1.0), /* bottom on color */
48 Color(0.8, 0.5, 0.4, 1.0), /* top off color */
49 Color(0.4, 0.2, 0.15, 1.0), /* bottom off color */
50 Color(0.8, 0.8, 0.8, 1.0), /* lit bevel */
51 Color(0.35, 0.35, 0.35, 1.0), /* shadowed bevel */
52 Color(0.8, 0.25, 0.18, 1.0), /* cursor color */
53 Color(0.68, 0.85, 1.3, 1.0), /* selection color */
54 Color(0.75, 0.1, 0.095, 1.0) /* check color */
55 };
58 #define JLEFT -1.0f
59 #define JCENTER 0.0f
60 #define JRIGHT 1.0f
62 enum { FRAME_INSET, FRAME_OUTSET };
64 extern int view_xsz, view_ysz;
65 extern float view_aspect;
66 extern unsigned int prog_ui, prog_font, prog_color;
67 extern struct dtx_font *font;
69 static void draw_label(const Widget *w);
70 static void draw_button(const Widget *w);
71 static void draw_checkbox(const Widget *w);
72 static void draw_slider(const Widget *w);
73 static void draw_rect(const Widget *w, const Vec2 &pos, const Vec2 &sz, const Color &color);
74 static void draw_rect(const Widget *w, const Vec2 &pos, const Vec2 &sz, const Color &ctop, const Color &cbot);
75 static void draw_shadow_text(const Widget *w, float justify, float x, float y, const Color &col, const char *text, float press = 0.0);
76 static void draw_shadow_text(const Widget *w, float justify, float x, float y, const char *text, float press = 0.0);
77 static void draw_text(const Widget *w, float justify, float x, float y, const char *text);
78 static void draw_frame(const Widget *w, const Vec2 &pos, const Vec2 &sz, float inset);
79 static float lerp(float a, float b, float t);
80 static Color lerp(const Color &a, const Color &b, float t);
82 static struct {
83 const char *name;
84 WidgetDrawFunc func;
85 } widget_funcs[] = {
86 { "label", draw_label },
87 { "button", draw_button },
88 { "checkbox", draw_checkbox },
89 { "slider", draw_slider },
90 {0, 0}
91 };
93 static std::map<std::string, WidgetDrawFunc> funcmap;
96 extern "C" __attribute__ ((used))
97 WidgetDrawFunc get_widget_func(const char *name)
98 {
99 static bool initialized;
101 if(!initialized) {
102 for(int i=0; widget_funcs[i].func; i++) {
103 funcmap[widget_funcs[i].name] = widget_funcs[i].func;
104 }
105 initialized = true;
106 }
107 return funcmap[name];
108 }
110 // register ourselves as a built-in theme
111 GOATKIT_BUILTIN_THEME("istereo", get_widget_func);
113 static void begin_drawing(const Widget *w)
114 {
115 //Vec2 pos = w->get_position();
117 glEnable(GL_BLEND);
118 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
120 gl_matrix_mode(GL_MODELVIEW);
121 gl_push_matrix();
122 gl_load_identity();
123 //gl_translatef(pos.x, pos.y, 0);
124 }
126 static void end_drawing(const Widget *w)
127 {
128 gl_matrix_mode(GL_MODELVIEW);
129 gl_pop_matrix();
130 }
132 static void draw_label(const Widget *w)
133 {
134 Vec2 pos = w->get_position();
135 Vec2 sz = w->get_size();
136 float vis = w->get_visibility();
137 if(vis < VIS_THRES) return;
139 begin_drawing(w);
140 draw_shadow_text(w, JLEFT, pos.x, pos.y + sz.y / 2.0, w->get_text());
141 end_drawing(w);
142 }
144 static void draw_button(const Widget *w)
145 {
146 float vis = w->get_visibility();
147 if(vis < VIS_THRES) return;
149 Vec2 pos = w->get_position();
150 Vec2 sz = w->get_size();
151 float press = w->get_pressed();
153 Color tcol = lerp(colors[TOP_COLOR], colors[BOTTOM_COLOR], press);
154 Color bcol = lerp(colors[BOTTOM_COLOR], colors[TOP_COLOR], press);
156 begin_drawing(w);
158 draw_frame(w, pos, sz, press);
159 draw_rect(w, pos, sz, tcol, bcol);
160 //draw_rect(w, Vec2(pos.x + sz.x / 2.0 - 2.0, pos.y), Vec2(4.0, sz.y),
161 // Color(0.4, 0.5, 1.0));
162 draw_shadow_text(w, JCENTER, pos.x + sz.x / 2.0, pos.y + sz.y / 2.0, w->get_text(), press);
164 end_drawing(w);
165 }
167 static void draw_checkbox(const Widget *w)
168 {
169 float vis = w->get_visibility();
170 if(vis < VIS_THRES) return;
172 Vec2 pos = w->get_position();
173 Vec2 sz = w->get_size();
174 Vec2 boxsz = Vec2(sz.y * 3.0, sz.y);
175 Vec2 boxpos = Vec2(pos.x + sz.x - boxsz.x, pos.y);
177 float checked = ((CheckBox*)w)->get_checked();
179 float vcenter = boxpos.y + boxsz.y / 2.0;
181 begin_drawing(w);
183 draw_frame(w, boxpos, boxsz, 1.0);
184 Color tcol = lerp(colors[TOP_OFF_COLOR], colors[TOP_ON_COLOR], checked);
185 Color bcol = lerp(colors[BOTTOM_OFF_COLOR], colors[BOTTOM_ON_COLOR], checked);
186 draw_rect(w, boxpos, boxsz, bcol, tcol);
188 draw_shadow_text(w, JLEFT, boxpos.x + 2, vcenter, "ON", 0.0);
189 draw_shadow_text(w, JRIGHT, boxpos.x + boxsz.x - 3, vcenter, "OFF", 0.0);
191 Vec2 knobpos = Vec2(0, boxpos.y + 1.0);
192 Vec2 knobsz = Vec2(boxsz.x / 2.0, boxsz.y - 2.0);
194 knobpos.x = lerp(boxpos.x + 1.0, boxpos.x + boxsz.x / 2.0, checked);
196 draw_frame(w, knobpos, knobsz, 0.0);
197 draw_rect(w, knobpos, knobsz, colors[TOP_COLOR], colors[BOTTOM_COLOR]);
199 draw_shadow_text(w, JRIGHT, boxpos.x - 2.0, vcenter, w->get_text(), 0.0);
201 end_drawing(w);
202 }
204 static void draw_slider(const Widget *w)
205 {
206 float vis = w->get_visibility();
207 if(vis < VIS_THRES) return;
209 float nval = ((Slider*)w)->get_value_norm();
211 Vec2 pos = w->get_position();
212 Vec2 sz = w->get_size();
213 Vec2 tsz = Vec2(sz.y * 0.5, sz.y);
214 Vec2 tpos = Vec2(pos.x + sz.x * nval - tsz.x / 2.0, pos.y);
216 // modify original pos/size to correspond to the trough geometry
217 sz.y /= 5.0;
218 pos.y += sz.y * 2.0;
220 begin_drawing(w);
222 // draw trough
223 draw_frame(w, pos, sz, 1.0);
224 draw_rect(w, pos, sz, colors[BOTTOM_COLOR], colors[TOP_COLOR]);
226 // draw thumb
227 draw_frame(w, tpos, tsz, 0.0);
228 draw_rect(w, tpos, tsz, colors[TOP_COLOR], colors[BOTTOM_COLOR]);
230 end_drawing(w);
231 }
233 static void draw_rect(const Widget *w, const Vec2 &pos, const Vec2 &sz, const Color &color)
234 {
235 draw_rect(w, pos, sz, color, color);
236 }
238 static void draw_rect(const Widget *w, const Vec2 &pos, const Vec2 &sz, const Color &ctop, const Color &cbot)
239 {
240 float vis = w ? w->get_visibility() : 1.0;
241 float act = w ? w->get_active() : 1.0;
242 float aspect = sz.x / sz.y;
244 float alpha = vis * (act * 0.5 + 0.5);
246 bind_program(prog_color);
248 gl_begin(GL_QUADS);
249 gl_color4f(cbot.r, cbot.g, cbot.b, cbot.a * alpha);
250 gl_texcoord2f(0, 1);
251 gl_vertex3f(pos.x, pos.y, 0);
252 gl_texcoord2f(aspect, 1);
253 gl_vertex3f(pos.x + sz.x, pos.y, 0);
254 gl_color4f(ctop.r, ctop.g, ctop.b, ctop.a * alpha);
255 gl_texcoord2f(aspect, 0);
256 gl_vertex3f(pos.x + sz.x, pos.y + sz.y, 0);
257 gl_texcoord2f(0, 0);
258 gl_vertex3f(pos.x, pos.y + sz.y, 0);
259 gl_end();
260 }
262 static void draw_shadow_text(const Widget *w, float justify, float x, float y, const Color &col, const char *text, float press)
263 {
264 static const Color cshad = Color(0.1, 0.1, 0.1, 1.0);
266 float xoffs = 1.0 - press;
267 float yoffs = 1.0 - press;
269 Color orig = colors[TEXT_COLOR];
270 colors[TEXT_COLOR] = cshad;
271 colors[TEXT_COLOR].a = (1.0 - press);
272 draw_text(w, justify, x + xoffs, y - yoffs, text);
273 colors[TEXT_COLOR] = col;
274 draw_text(w, justify, x, y, text);
275 colors[TEXT_COLOR] = orig;
276 }
278 static void draw_shadow_text(const Widget *w, float justify, float x, float y, const char *text, float press)
279 {
280 draw_shadow_text(w, justify, x, y, Color(1.0, 1.0, 1.0, 1.0), text, press);
281 }
283 static void draw_text(const Widget *w, float justify, float x, float y, const char *text)
284 {
285 struct dtx_glyphmap *gmap = dtx_get_font_glyphmap_idx(font, 0);
286 dtx_use_font(font, dtx_get_glyphmap_ptsize(gmap));
288 float vis = w ? w->get_visibility() : 1.0;
289 float act = w ? w->get_active() : 1.0;
291 float twidth = dtx_string_width(text);
292 float thalf = twidth / 2.0;
293 float theight = dtx_line_height();
295 gl_matrix_mode(GL_MODELVIEW);
296 gl_push_matrix();
297 gl_load_identity();
298 gl_translatef(x - thalf - justify * thalf, y - theight * 0.25, 0);
300 bind_program(prog_font);
301 const Color &tcol = colors[TEXT_COLOR];
302 set_uniform_float4(prog_font, "ucolor", tcol.r, tcol.g, tcol.b, tcol.a * vis * (act * 0.5 + 0.5));
303 gl_apply_xform(prog_font);
305 dtx_string(text);
307 gl_matrix_mode(GL_MODELVIEW);
308 gl_pop_matrix();
309 }
311 static void draw_frame(const Widget *widget, const Vec2 &pos, const Vec2 &sz, float inset)
312 {
313 float vis = widget ? widget->get_visibility() : 1.0;
314 float act = widget ? widget->get_active() : 1.0;
315 float offs = 300.0 * (1.0 - vis);
317 float alpha = vis * (act * 0.5 + 0.5);
319 float x = pos.x - BEVEL;
320 float y = pos.y - BEVEL;
321 float w = sz.x + BEVEL * 2.0;
322 float h = sz.y + BEVEL * 2.0;
323 float b = BEVEL;
325 Color tcol = lerp(colors[BEVEL_LIT_COLOR], colors[BEVEL_SHAD_COLOR], inset);
326 Color bcol = lerp(colors[BEVEL_SHAD_COLOR], colors[BEVEL_LIT_COLOR], inset);
328 bind_program(prog_color);
330 gl_begin(GL_QUADS);
331 gl_color4f(tcol.r, tcol.g, tcol.b, tcol.a * alpha);
332 gl_vertex2f(x + b + offs, y + h - b);
333 gl_vertex2f(x + w - b + offs, y + h - b);
334 gl_vertex2f(x + w + offs, y + h);
335 gl_vertex2f(x + offs, y + h);
337 gl_vertex2f(x + b, y + b + offs);
338 gl_vertex2f(x, y + offs);
339 gl_vertex2f(x, y + h + offs);
340 gl_vertex2f(x + b, y + h - b + offs);
342 gl_color4f(bcol.r, bcol.g, bcol.b, bcol.a * alpha);
343 gl_vertex2f(x - offs, y);
344 gl_vertex2f(x + b - offs, y + b);
345 gl_vertex2f(x + w - b - offs, y + b);
346 gl_vertex2f(x + w - offs, y);
348 gl_vertex2f(x + w - b, y + b - offs);
349 gl_vertex2f(x + w, y - offs);
350 gl_vertex2f(x + w, y + h - offs);
351 gl_vertex2f(x + w - b, y + h - b - offs);
352 gl_end();
353 }
355 static float lerp(float a, float b, float t)
356 {
357 return a + (b - a) * t;
358 }
360 static Color lerp(const Color &a, const Color &b, float t)
361 {
362 Color res;
363 res.r = a.r + (b.r - a.r) * t;
364 res.g = a.g + (b.g - a.g) * t;
365 res.b = a.b + (b.b - a.b) * t;
366 return res;
367 }