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