gameui

view src/widget.cc @ 5:5a84873185ff

rudimentary theme plugin system and other minor fixes
author John Tsiombikas <nuclear@member.fsf.org>
date Sat, 22 Mar 2014 01:50:01 +0200
parents e0916bb20b7f
children
line source
1 #include <stdio.h>
2 #include <math.h>
3 #include <string>
4 #include <sstream>
5 #include "widget.h"
6 #include "boolanm.h"
7 #include "theme.h"
9 namespace goatkit {
11 struct WidgetImpl {
12 std::string name;
13 BBox box;
15 BoolAnim visible, active, press, hover;
16 };
19 Widget::Widget()
20 {
21 static int widget_count;
23 widget = new WidgetImpl;
25 std::stringstream sstr;
26 sstr << get_type_name() << widget_count++;
27 widget->name = sstr.str();
29 widget->box.bmin = Vec2(0, 0);
30 widget->box.bmax = Vec2(1, 1);
32 widget->visible.set(true);
33 widget->active.set(true);
35 widget->hover.set_transition_duration(250);
36 widget->press.set_transition_duration(50);
37 }
39 Widget::~Widget()
40 {
41 delete widget;
42 }
44 const char *Widget::get_type_name() const
45 {
46 return "widget";
47 }
49 void Widget::show()
50 {
51 widget->visible.change(true);
52 }
54 void Widget::hide()
55 {
56 widget->visible.change(false);
57 }
59 float Widget::get_visibility() const
60 {
61 return widget->visible.get_value();
62 }
64 bool Widget::is_visible() const
65 {
66 return widget->visible.get_state();
67 }
69 void Widget::activate()
70 {
71 widget->active.change(true);
72 }
74 void Widget::deactivate()
75 {
76 widget->active.change(false);
77 }
79 float Widget::get_active() const
80 {
81 return widget->active.get_value();
82 }
84 bool Widget::is_active() const
85 {
86 return widget->active.get_state();
87 }
89 void Widget::press()
90 {
91 widget->press.change(true);
92 }
94 void Widget::release()
95 {
96 widget->press.change(false);
97 }
99 float Widget::get_pressed() const
100 {
101 return widget->press.get_value();
102 }
104 bool Widget::is_pressed() const
105 {
106 return widget->press.get_state();
107 }
109 void Widget::mousein()
110 {
111 widget->hover.change(true);
112 }
114 void Widget::mouseout()
115 {
116 widget->hover.change(false);
117 }
119 float Widget::get_under_mouse() const
120 {
121 return widget->hover.get_value();
122 }
124 bool Widget::is_under_mouse() const
125 {
126 return widget->hover.get_state();
127 }
129 void Widget::set_position(float x, float y)
130 {
131 set_position(Vec2(x, y));
132 }
134 void Widget::set_position(const Vec2 &pos)
135 {
136 Vec2 sz = get_size();
138 widget->box.bmin = pos;
139 widget->box.bmax.x = pos.x + sz.x;
140 widget->box.bmax.y = pos.y + sz.y;
141 }
143 const Vec2 &Widget::get_position() const
144 {
145 return widget->box.bmin;
146 }
148 void Widget::set_size(float x, float y)
149 {
150 set_size(Vec2(x, y));
151 }
153 void Widget::set_size(const Vec2 &sz)
154 {
155 widget->box.bmax.x = widget->box.bmin.x + sz.x;
156 widget->box.bmax.y = widget->box.bmin.y + sz.y;
157 }
159 const Vec2 Widget::get_size() const
160 {
161 return Vec2(widget->box.bmax.x - widget->box.bmin.x,
162 widget->box.bmax.y - widget->box.bmin.y);
163 }
166 const BBox &Widget::get_box() const
167 {
168 return widget->box;
169 }
171 bool Widget::hit_test(const Vec2 &pt) const
172 {
173 return pt.x >= widget->box.bmin.x && pt.x < widget->box.bmax.x &&
174 pt.y >= widget->box.bmin.y && pt.y < widget->box.bmax.y;
175 }
177 void Widget::draw() const
178 {
179 WidgetDrawFunc draw_func = default_draw_func;
181 if(theme) {
182 draw_func = theme->get_draw_func(get_type_name());
183 }
185 draw_func(this);
186 }
188 // dummy event handlers
189 void Widget::on_mouse_button(const ButtonEvent &ev)
190 {
191 }
193 void Widget::on_mouse_motion(const MotionEvent &ev)
194 {
195 }
197 void Widget::on_mouse_focus(const FocusEvent &ev)
198 {
199 }
201 void Widget::on_key(const KeyEvent &ev)
202 {
203 }
205 void Widget::on_click()
206 {
207 }
209 void Widget::on_double_click()
210 {
211 }
213 void Widget::on_change()
214 {
215 }
218 /* the event dispatcher generates high-level events (click, etc)
219 * and calls the on_whatever() functions for both low and high-level
220 * events.
221 * The on_whatever functions are called *after* any other actions performed
222 * here, to give subclasses the opportunity to override them easily, by
223 * overriding the on_ functions, without having to override handle_event itself
224 */
225 // TODO also call callbacks here I guess...
226 void Widget::handle_event(const Event &ev)
227 {
228 switch(ev.type) {
229 case EV_MOUSE_BUTTON:
230 if(ev.button.press) {
231 press();
232 } else {
233 if(is_pressed()) {
234 on_click();
235 }
236 release();
237 }
238 on_mouse_button(ev.button);
239 break;
241 case EV_MOUSE_MOTION:
242 on_mouse_motion(ev.motion);
243 break;
245 case EV_MOUSE_FOCUS:
246 if(ev.focus.enter) {
247 mousein();
248 } else {
249 mouseout();
250 }
251 on_mouse_focus(ev.focus);
252 break;
254 case EV_KEY:
255 on_key(ev.key);
256 break;
258 default:
259 fprintf(stderr, "%s: unknown event id: %d\n", __func__, ev.type);
260 }
261 }
264 } // namespace goatkit