istereo2

annotate libs/goatkit/widget.cc @ 6:3bccfc7d10fe

goatkit is drawing
author John Tsiombikas <nuclear@member.fsf.org>
date Wed, 23 Sep 2015 05:44:58 +0300
parents
children 018f997dc646
rev   line source
nuclear@6 1 /*
nuclear@6 2 GoatKit - a themable/animated widget toolkit for games
nuclear@6 3 Copyright (C) 2014 John Tsiombikas <nuclear@member.fsf.org>
nuclear@6 4
nuclear@6 5 This program is free software: you can redistribute it and/or modify
nuclear@6 6 it under the terms of the GNU Lesser General Public License as published by
nuclear@6 7 the Free Software Foundation, either version 3 of the License, or
nuclear@6 8 (at your option) any later version.
nuclear@6 9
nuclear@6 10 This program is distributed in the hope that it will be useful,
nuclear@6 11 but WITHOUT ANY WARRANTY; without even the implied warranty of
nuclear@6 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
nuclear@6 13 GNU Lesser General Public License for more details.
nuclear@6 14
nuclear@6 15 You should have received a copy of the GNU Lesser General Public License
nuclear@6 16 along with this program. If not, see <http://www.gnu.org/licenses/>.
nuclear@6 17 */
nuclear@6 18 #include <stdio.h>
nuclear@6 19 #include <string.h>
nuclear@6 20 #include <math.h>
nuclear@6 21 #include <string>
nuclear@6 22 #include <sstream>
nuclear@6 23 #include "widget.h"
nuclear@6 24 #include "boolanm.h"
nuclear@6 25 #include "theme.h"
nuclear@6 26 #include "screen.h"
nuclear@6 27
nuclear@6 28 namespace goatkit {
nuclear@6 29
nuclear@6 30 struct WidgetImpl {
nuclear@6 31 Screen *scr;
nuclear@6 32 std::string name, text;
nuclear@6 33 BBox box;
nuclear@6 34
nuclear@6 35 BoolAnim visible, active, press, hover, focus;
nuclear@6 36
nuclear@6 37 struct {
nuclear@6 38 EventCallback func;
nuclear@6 39 void *cls;
nuclear@6 40 } cb[NUM_EVENTS];
nuclear@6 41 };
nuclear@6 42
nuclear@6 43
nuclear@6 44 Widget::Widget()
nuclear@6 45 {
nuclear@6 46 static int widget_count;
nuclear@6 47
nuclear@6 48 widget = new WidgetImpl;
nuclear@6 49 widget->scr = 0;
nuclear@6 50
nuclear@6 51 std::stringstream sstr;
nuclear@6 52 sstr << get_type_name() << widget_count++;
nuclear@6 53 widget->name = sstr.str();
nuclear@6 54
nuclear@6 55 widget->box.bmin = Vec2(0, 0);
nuclear@6 56 widget->box.bmax = Vec2(1, 1);
nuclear@6 57
nuclear@6 58 widget->visible.set(true);
nuclear@6 59 widget->active.set(true);
nuclear@6 60
nuclear@6 61 widget->hover.set_transition_duration(250);
nuclear@6 62 widget->press.set_transition_duration(50);
nuclear@6 63
nuclear@6 64 memset(widget->cb, 0, sizeof widget->cb);
nuclear@6 65 }
nuclear@6 66
nuclear@6 67 Widget::~Widget()
nuclear@6 68 {
nuclear@6 69 delete widget;
nuclear@6 70 }
nuclear@6 71
nuclear@6 72 void Widget::set_screen(Screen *scr)
nuclear@6 73 {
nuclear@6 74 widget->scr = scr;
nuclear@6 75 }
nuclear@6 76
nuclear@6 77 Screen *Widget::get_screen() const
nuclear@6 78 {
nuclear@6 79 return widget->scr;
nuclear@6 80 }
nuclear@6 81
nuclear@6 82 const char *Widget::get_type_name() const
nuclear@6 83 {
nuclear@6 84 return "widget";
nuclear@6 85 }
nuclear@6 86
nuclear@6 87 void Widget::set_name(const char *name)
nuclear@6 88 {
nuclear@6 89 widget->name = std::string(name);
nuclear@6 90 }
nuclear@6 91
nuclear@6 92 const char *Widget::get_name() const
nuclear@6 93 {
nuclear@6 94 return widget->name.c_str();
nuclear@6 95 }
nuclear@6 96
nuclear@6 97 void Widget::set_text(const char *text)
nuclear@6 98 {
nuclear@6 99 widget->text = std::string(text);
nuclear@6 100 }
nuclear@6 101
nuclear@6 102 const char *Widget::get_text() const
nuclear@6 103 {
nuclear@6 104 return widget->text.c_str();
nuclear@6 105 }
nuclear@6 106
nuclear@6 107 void Widget::show()
nuclear@6 108 {
nuclear@6 109 widget->visible.change(true);
nuclear@6 110 }
nuclear@6 111
nuclear@6 112 void Widget::hide()
nuclear@6 113 {
nuclear@6 114 widget->visible.change(false);
nuclear@6 115 }
nuclear@6 116
nuclear@6 117 float Widget::get_visibility() const
nuclear@6 118 {
nuclear@6 119 return widget->visible.get_value();
nuclear@6 120 }
nuclear@6 121
nuclear@6 122 bool Widget::is_visible() const
nuclear@6 123 {
nuclear@6 124 return widget->visible.get_state();
nuclear@6 125 }
nuclear@6 126
nuclear@6 127 void Widget::activate()
nuclear@6 128 {
nuclear@6 129 widget->active.change(true);
nuclear@6 130 }
nuclear@6 131
nuclear@6 132 void Widget::deactivate()
nuclear@6 133 {
nuclear@6 134 widget->active.change(false);
nuclear@6 135 }
nuclear@6 136
nuclear@6 137 float Widget::get_active() const
nuclear@6 138 {
nuclear@6 139 return widget->active.get_value();
nuclear@6 140 }
nuclear@6 141
nuclear@6 142 bool Widget::is_active() const
nuclear@6 143 {
nuclear@6 144 return widget->active.get_state();
nuclear@6 145 }
nuclear@6 146
nuclear@6 147 void Widget::press()
nuclear@6 148 {
nuclear@6 149 widget->press.change(true);
nuclear@6 150 }
nuclear@6 151
nuclear@6 152 void Widget::release()
nuclear@6 153 {
nuclear@6 154 widget->press.change(false);
nuclear@6 155 }
nuclear@6 156
nuclear@6 157 float Widget::get_pressed() const
nuclear@6 158 {
nuclear@6 159 return widget->press.get_value();
nuclear@6 160 }
nuclear@6 161
nuclear@6 162 bool Widget::is_pressed() const
nuclear@6 163 {
nuclear@6 164 return widget->press.get_state();
nuclear@6 165 }
nuclear@6 166
nuclear@6 167 void Widget::mousein()
nuclear@6 168 {
nuclear@6 169 widget->hover.change(true);
nuclear@6 170 }
nuclear@6 171
nuclear@6 172 void Widget::mouseout()
nuclear@6 173 {
nuclear@6 174 widget->hover.change(false);
nuclear@6 175 if(widget->press) {
nuclear@6 176 widget->press.change(false);
nuclear@6 177 }
nuclear@6 178 }
nuclear@6 179
nuclear@6 180 float Widget::get_under_mouse() const
nuclear@6 181 {
nuclear@6 182 return widget->hover.get_value();
nuclear@6 183 }
nuclear@6 184
nuclear@6 185 bool Widget::is_under_mouse() const
nuclear@6 186 {
nuclear@6 187 return widget->hover.get_state();
nuclear@6 188 }
nuclear@6 189
nuclear@6 190 bool Widget::can_focus() const
nuclear@6 191 {
nuclear@6 192 return false;
nuclear@6 193 }
nuclear@6 194
nuclear@6 195 void Widget::focusin()
nuclear@6 196 {
nuclear@6 197 widget->focus.change(true);
nuclear@6 198 }
nuclear@6 199
nuclear@6 200 void Widget::focusout()
nuclear@6 201 {
nuclear@6 202 widget->focus.change(false);
nuclear@6 203 }
nuclear@6 204
nuclear@6 205 float Widget::get_focus() const
nuclear@6 206 {
nuclear@6 207 return widget->focus.get_value();
nuclear@6 208 }
nuclear@6 209
nuclear@6 210 bool Widget::is_focused() const
nuclear@6 211 {
nuclear@6 212 return widget->focus.get_state();
nuclear@6 213 }
nuclear@6 214
nuclear@6 215 void Widget::set_position(float x, float y)
nuclear@6 216 {
nuclear@6 217 set_position(Vec2(x, y));
nuclear@6 218 }
nuclear@6 219
nuclear@6 220 void Widget::set_position(const Vec2 &pos)
nuclear@6 221 {
nuclear@6 222 Vec2 sz = get_size();
nuclear@6 223
nuclear@6 224 widget->box.bmin = pos;
nuclear@6 225 widget->box.bmax.x = pos.x + sz.x;
nuclear@6 226 widget->box.bmax.y = pos.y + sz.y;
nuclear@6 227 }
nuclear@6 228
nuclear@6 229 const Vec2 &Widget::get_position() const
nuclear@6 230 {
nuclear@6 231 return widget->box.bmin;
nuclear@6 232 }
nuclear@6 233
nuclear@6 234 void Widget::set_size(float x, float y)
nuclear@6 235 {
nuclear@6 236 set_size(Vec2(x, y));
nuclear@6 237 }
nuclear@6 238
nuclear@6 239 void Widget::set_size(const Vec2 &sz)
nuclear@6 240 {
nuclear@6 241 widget->box.bmax.x = widget->box.bmin.x + sz.x;
nuclear@6 242 widget->box.bmax.y = widget->box.bmin.y + sz.y;
nuclear@6 243 }
nuclear@6 244
nuclear@6 245 const Vec2 Widget::get_size() const
nuclear@6 246 {
nuclear@6 247 return Vec2(widget->box.bmax.x - widget->box.bmin.x,
nuclear@6 248 widget->box.bmax.y - widget->box.bmin.y);
nuclear@6 249 }
nuclear@6 250
nuclear@6 251
nuclear@6 252 const BBox &Widget::get_box() const
nuclear@6 253 {
nuclear@6 254 return widget->box;
nuclear@6 255 }
nuclear@6 256
nuclear@6 257 bool Widget::hit_test(const Vec2 &pt) const
nuclear@6 258 {
nuclear@6 259 return pt.x >= widget->box.bmin.x && pt.x < widget->box.bmax.x &&
nuclear@6 260 pt.y >= widget->box.bmin.y && pt.y < widget->box.bmax.y;
nuclear@6 261 }
nuclear@6 262
nuclear@6 263 void Widget::draw() const
nuclear@6 264 {
nuclear@6 265 WidgetDrawFunc draw_func = default_draw_func;
nuclear@6 266
nuclear@6 267 if(theme) {
nuclear@6 268 draw_func = theme->get_draw_func(get_type_name());
nuclear@6 269 }
nuclear@6 270
nuclear@6 271 draw_func(this);
nuclear@6 272 }
nuclear@6 273
nuclear@6 274 // dummy event handlers
nuclear@6 275 void Widget::on_mouse_button(const ButtonEvent &ev)
nuclear@6 276 {
nuclear@6 277 }
nuclear@6 278
nuclear@6 279 void Widget::on_mouse_motion(const MotionEvent &ev)
nuclear@6 280 {
nuclear@6 281 }
nuclear@6 282
nuclear@6 283 void Widget::on_mouse_focus(const FocusEvent &ev)
nuclear@6 284 {
nuclear@6 285 }
nuclear@6 286
nuclear@6 287 void Widget::on_key(const KeyEvent &ev)
nuclear@6 288 {
nuclear@6 289 }
nuclear@6 290
nuclear@6 291 void Widget::on_click()
nuclear@6 292 {
nuclear@6 293 }
nuclear@6 294
nuclear@6 295 void Widget::on_double_click()
nuclear@6 296 {
nuclear@6 297 }
nuclear@6 298
nuclear@6 299 void Widget::on_change()
nuclear@6 300 {
nuclear@6 301 }
nuclear@6 302
nuclear@6 303
nuclear@6 304 #define CALL_CB(w, ev) \
nuclear@6 305 do { \
nuclear@6 306 if((w)->widget->cb[ev.type].func) { \
nuclear@6 307 (w)->widget->cb[ev.type].func((w), ev, (w)->widget->cb[ev.type].cls); \
nuclear@6 308 } \
nuclear@6 309 } while(0)
nuclear@6 310
nuclear@6 311 #define CALL_CB_TYPE(w, t) \
nuclear@6 312 do { \
nuclear@6 313 Event ev; \
nuclear@6 314 ev.type = (t); \
nuclear@6 315 CALL_CB(w, ev); \
nuclear@6 316 } while(0)
nuclear@6 317
nuclear@6 318 /* the event dispatcher generates high-level events (click, etc)
nuclear@6 319 * and calls the on_whatever() functions for both low and high-level
nuclear@6 320 * events.
nuclear@6 321 * The on_whatever functions are called *after* any other actions performed
nuclear@6 322 * here, to give subclasses the opportunity to override them easily, by
nuclear@6 323 * overriding the on_ functions, without having to override handle_event itself
nuclear@6 324 */
nuclear@6 325 // TODO also call callbacks here I guess...
nuclear@6 326 void Widget::handle_event(const Event &ev)
nuclear@6 327 {
nuclear@6 328 switch(ev.type) {
nuclear@6 329 case EV_MOUSE_BUTTON:
nuclear@6 330 if(ev.button.press) {
nuclear@6 331 press();
nuclear@6 332 } else {
nuclear@6 333 if(is_pressed()) {
nuclear@6 334 CALL_CB_TYPE(this, EV_CLICK);
nuclear@6 335 on_click();
nuclear@6 336 }
nuclear@6 337 release();
nuclear@6 338 }
nuclear@6 339
nuclear@6 340 on_mouse_button(ev.button);
nuclear@6 341 break;
nuclear@6 342
nuclear@6 343 case EV_MOUSE_MOTION:
nuclear@6 344 on_mouse_motion(ev.motion);
nuclear@6 345 break;
nuclear@6 346
nuclear@6 347 case EV_MOUSE_FOCUS:
nuclear@6 348 if(ev.focus.enter) {
nuclear@6 349 mousein();
nuclear@6 350 } else {
nuclear@6 351 mouseout();
nuclear@6 352 }
nuclear@6 353 on_mouse_focus(ev.focus);
nuclear@6 354 break;
nuclear@6 355
nuclear@6 356 case EV_KEY:
nuclear@6 357 on_key(ev.key);
nuclear@6 358 break;
nuclear@6 359
nuclear@6 360 case EV_CHANGE:
nuclear@6 361 on_change();
nuclear@6 362 break;
nuclear@6 363
nuclear@6 364 default:
nuclear@6 365 break;
nuclear@6 366 }
nuclear@6 367
nuclear@6 368 CALL_CB(this, ev);
nuclear@6 369 }
nuclear@6 370
nuclear@6 371
nuclear@6 372 void Widget::set_callback(EventType evtype, EventCallback func, void *cls)
nuclear@6 373 {
nuclear@6 374 widget->cb[evtype].func = func;
nuclear@6 375 widget->cb[evtype].cls = cls;
nuclear@6 376 }
nuclear@6 377
nuclear@6 378
nuclear@6 379 } // namespace goatkit