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