gameui

view src/widget.cc @ 3:f1014234dece

transitions in gui elements are awesome :)
author John Tsiombikas <nuclear@member.fsf.org>
date Fri, 21 Mar 2014 03:37:16 +0200
parents e5b1525084f7
children e0916bb20b7f
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 gameui {
11 struct WidgetImpl {
12 std::string type_str;
13 std::string name;
14 BBox box;
16 BoolAnim visible, active, press, hover;
17 };
20 Widget::Widget()
21 {
22 static int widget_count;
24 widget = new WidgetImpl;
25 set_type_string("widget");
27 std::stringstream sstr;
28 sstr << widget->type_str << widget_count++;
29 widget->name = sstr.str();
31 widget->box.bmin = Vec2(0, 0);
32 widget->box.bmax = Vec2(1, 1);
34 widget->visible.set(true);
35 widget->active.set(true);
37 widget->hover.set_transition_duration(250);
38 widget->press.set_transition_duration(50);
39 }
41 Widget::~Widget()
42 {
43 delete widget;
44 }
46 void Widget::show()
47 {
48 widget->visible.change(true);
49 }
51 void Widget::hide()
52 {
53 widget->visible.change(false);
54 }
56 float Widget::get_visibility() const
57 {
58 return widget->visible.get_value();
59 }
61 bool Widget::is_visible() const
62 {
63 return widget->visible.get_state();
64 }
66 void Widget::activate()
67 {
68 widget->active.change(true);
69 }
71 void Widget::deactivate()
72 {
73 widget->active.change(false);
74 }
76 float Widget::get_active() const
77 {
78 return widget->active.get_value();
79 }
81 bool Widget::is_active() const
82 {
83 return widget->active.get_state();
84 }
86 void Widget::press()
87 {
88 widget->press.change(true);
89 }
91 void Widget::release()
92 {
93 widget->press.change(false);
94 }
96 float Widget::get_pressed() const
97 {
98 return widget->press.get_value();
99 }
101 bool Widget::is_pressed() const
102 {
103 return widget->press.get_state();
104 }
106 void Widget::mousein()
107 {
108 widget->hover.change(true);
109 }
111 void Widget::mouseout()
112 {
113 widget->hover.change(false);
114 }
116 float Widget::get_under_mouse() const
117 {
118 return widget->hover.get_value();
119 }
121 bool Widget::is_under_mouse() const
122 {
123 return widget->hover.get_state();
124 }
126 void Widget::set_position(float x, float y)
127 {
128 set_position(Vec2(x, y));
129 }
131 void Widget::set_position(const Vec2 &pos)
132 {
133 Vec2 sz = get_size();
135 widget->box.bmin = pos;
136 widget->box.bmax.x = pos.x + sz.x;
137 widget->box.bmax.y = pos.y + sz.y;
138 }
140 const Vec2 &Widget::get_position() const
141 {
142 return widget->box.bmin;
143 }
145 void Widget::set_size(float x, float y)
146 {
147 set_size(Vec2(x, y));
148 }
150 void Widget::set_size(const Vec2 &sz)
151 {
152 widget->box.bmax.x = widget->box.bmin.x + sz.x;
153 widget->box.bmax.y = widget->box.bmin.y + sz.y;
154 }
156 const Vec2 Widget::get_size() const
157 {
158 return Vec2(widget->box.bmax.x - widget->box.bmin.x,
159 widget->box.bmax.y - widget->box.bmin.y);
160 }
163 const BBox &Widget::get_box() const
164 {
165 return widget->box;
166 }
168 bool Widget::hit_test(const Vec2 &pt) const
169 {
170 return pt.x >= widget->box.bmin.x && pt.x < widget->box.bmax.x &&
171 pt.y >= widget->box.bmin.y && pt.y < widget->box.bmax.y;
172 }
174 void Widget::draw() const
175 {
176 widget_draw_func draw_func = default_draw_func;
178 if(theme) {
179 draw_func = theme->get_draw_func(widget->type_str.c_str());
180 }
182 draw_func(this);
183 }
185 // dummy event handlers
186 void Widget::on_mouse_button(const ButtonEvent &ev)
187 {
188 }
190 void Widget::on_mouse_motion(const MotionEvent &ev)
191 {
192 }
194 void Widget::on_mouse_focus(const FocusEvent &ev)
195 {
196 }
198 void Widget::on_key(const KeyEvent &ev)
199 {
200 }
202 void Widget::on_click()
203 {
204 }
206 void Widget::on_double_click()
207 {
208 }
210 void Widget::on_change()
211 {
212 }
215 void Widget::set_type_string(const char *type_str)
216 {
217 widget->type_str = type_str;
218 }
220 /* the event dispatcher generates high-level events (click, etc)
221 * and calls the on_whatever() functions for both low and high-level
222 * events.
223 * The on_whatever functions are called *after* any other actions performed
224 * here, to give subclasses the opportunity to override them easily, by
225 * overriding the on_ functions, without having to override handle_event itself
226 */
227 // TODO also call callbacks here I guess...
228 void Widget::handle_event(const Event &ev)
229 {
230 switch(ev.type) {
231 case EV_MOUSE_BUTTON:
232 if(ev.button.press) {
233 press();
234 } else {
235 if(is_pressed()) {
236 on_click();
237 }
238 release();
239 }
240 on_mouse_button(ev.button);
241 break;
243 case EV_MOUSE_MOTION:
244 on_mouse_motion(ev.motion);
245 break;
247 case EV_MOUSE_FOCUS:
248 if(ev.focus.enter) {
249 mousein();
250 } else {
251 mouseout();
252 }
253 on_mouse_focus(ev.focus);
254 break;
256 case EV_KEY:
257 on_key(ev.key);
258 break;
260 default:
261 fprintf(stderr, "%s: unknown event id: %d\n", __func__, ev.type);
262 }
263 }
266 } // namespace gameui