nuclear@3: #include nuclear@3: #include nuclear@0: #include nuclear@2: #include nuclear@0: #include "widget.h" nuclear@2: #include "boolanm.h" nuclear@3: #include "theme.h" nuclear@0: nuclear@4: namespace goatkit { nuclear@0: nuclear@2: struct WidgetImpl { nuclear@3: std::string type_str; nuclear@0: std::string name; nuclear@0: BBox box; nuclear@0: nuclear@2: BoolAnim visible, active, press, hover; nuclear@0: }; nuclear@0: nuclear@0: nuclear@0: Widget::Widget() nuclear@0: { nuclear@0: static int widget_count; nuclear@0: nuclear@3: widget = new WidgetImpl; nuclear@3: set_type_string("widget"); nuclear@3: nuclear@0: std::stringstream sstr; nuclear@3: sstr << widget->type_str << widget_count++; nuclear@3: widget->name = sstr.str(); nuclear@0: nuclear@3: widget->box.bmin = Vec2(0, 0); nuclear@3: widget->box.bmax = Vec2(1, 1); nuclear@0: nuclear@3: widget->visible.set(true); nuclear@3: widget->active.set(true); nuclear@0: nuclear@3: widget->hover.set_transition_duration(250); nuclear@3: widget->press.set_transition_duration(50); nuclear@0: } nuclear@0: nuclear@0: Widget::~Widget() nuclear@0: { nuclear@3: delete widget; nuclear@0: } nuclear@0: nuclear@0: void Widget::show() nuclear@0: { nuclear@3: widget->visible.change(true); nuclear@0: } nuclear@0: nuclear@0: void Widget::hide() nuclear@0: { nuclear@3: widget->visible.change(false); nuclear@0: } nuclear@0: nuclear@0: float Widget::get_visibility() const nuclear@0: { nuclear@3: return widget->visible.get_value(); nuclear@3: } nuclear@0: nuclear@3: bool Widget::is_visible() const nuclear@3: { nuclear@3: return widget->visible.get_state(); nuclear@0: } nuclear@0: nuclear@1: void Widget::activate() nuclear@1: { nuclear@3: widget->active.change(true); nuclear@1: } nuclear@1: nuclear@3: void Widget::deactivate() nuclear@0: { nuclear@3: widget->active.change(false); nuclear@0: } nuclear@0: nuclear@3: float Widget::get_active() const nuclear@0: { nuclear@3: return widget->active.get_value(); nuclear@3: } nuclear@0: nuclear@3: bool Widget::is_active() const nuclear@3: { nuclear@3: return widget->active.get_state(); nuclear@3: } nuclear@3: nuclear@3: void Widget::press() nuclear@3: { nuclear@3: widget->press.change(true); nuclear@3: } nuclear@3: nuclear@3: void Widget::release() nuclear@3: { nuclear@3: widget->press.change(false); nuclear@3: } nuclear@3: nuclear@3: float Widget::get_pressed() const nuclear@3: { nuclear@3: return widget->press.get_value(); nuclear@3: } nuclear@3: nuclear@3: bool Widget::is_pressed() const nuclear@3: { nuclear@3: return widget->press.get_state(); nuclear@3: } nuclear@3: nuclear@3: void Widget::mousein() nuclear@3: { nuclear@3: widget->hover.change(true); nuclear@3: } nuclear@3: nuclear@3: void Widget::mouseout() nuclear@3: { nuclear@3: widget->hover.change(false); nuclear@3: } nuclear@3: nuclear@3: float Widget::get_under_mouse() const nuclear@3: { nuclear@3: return widget->hover.get_value(); nuclear@3: } nuclear@3: nuclear@3: bool Widget::is_under_mouse() const nuclear@3: { nuclear@3: return widget->hover.get_state(); nuclear@3: } nuclear@3: nuclear@3: void Widget::set_position(float x, float y) nuclear@3: { nuclear@3: set_position(Vec2(x, y)); nuclear@3: } nuclear@3: nuclear@3: void Widget::set_position(const Vec2 &pos) nuclear@3: { nuclear@3: Vec2 sz = get_size(); nuclear@3: nuclear@3: widget->box.bmin = pos; nuclear@3: widget->box.bmax.x = pos.x + sz.x; nuclear@3: widget->box.bmax.y = pos.y + sz.y; nuclear@3: } nuclear@3: nuclear@3: const Vec2 &Widget::get_position() const nuclear@3: { nuclear@3: return widget->box.bmin; nuclear@3: } nuclear@3: nuclear@3: void Widget::set_size(float x, float y) nuclear@3: { nuclear@3: set_size(Vec2(x, y)); nuclear@3: } nuclear@3: nuclear@3: void Widget::set_size(const Vec2 &sz) nuclear@3: { nuclear@3: widget->box.bmax.x = widget->box.bmin.x + sz.x; nuclear@3: widget->box.bmax.y = widget->box.bmin.y + sz.y; nuclear@3: } nuclear@3: nuclear@3: const Vec2 Widget::get_size() const nuclear@3: { nuclear@3: return Vec2(widget->box.bmax.x - widget->box.bmin.x, nuclear@3: widget->box.bmax.y - widget->box.bmin.y); nuclear@3: } nuclear@3: nuclear@3: nuclear@3: const BBox &Widget::get_box() const nuclear@3: { nuclear@3: return widget->box; nuclear@3: } nuclear@3: nuclear@3: bool Widget::hit_test(const Vec2 &pt) const nuclear@3: { nuclear@3: return pt.x >= widget->box.bmin.x && pt.x < widget->box.bmax.x && nuclear@3: pt.y >= widget->box.bmin.y && pt.y < widget->box.bmax.y; nuclear@3: } nuclear@3: nuclear@3: void Widget::draw() const nuclear@3: { nuclear@3: widget_draw_func draw_func = default_draw_func; nuclear@3: nuclear@3: if(theme) { nuclear@3: draw_func = theme->get_draw_func(widget->type_str.c_str()); nuclear@0: } nuclear@3: nuclear@3: draw_func(this); nuclear@0: } nuclear@3: nuclear@3: // dummy event handlers nuclear@3: void Widget::on_mouse_button(const ButtonEvent &ev) nuclear@3: { nuclear@3: } nuclear@3: nuclear@3: void Widget::on_mouse_motion(const MotionEvent &ev) nuclear@3: { nuclear@3: } nuclear@3: nuclear@3: void Widget::on_mouse_focus(const FocusEvent &ev) nuclear@3: { nuclear@3: } nuclear@3: nuclear@3: void Widget::on_key(const KeyEvent &ev) nuclear@3: { nuclear@3: } nuclear@3: nuclear@3: void Widget::on_click() nuclear@3: { nuclear@3: } nuclear@3: nuclear@3: void Widget::on_double_click() nuclear@3: { nuclear@3: } nuclear@3: nuclear@3: void Widget::on_change() nuclear@3: { nuclear@3: } nuclear@3: nuclear@3: nuclear@3: void Widget::set_type_string(const char *type_str) nuclear@3: { nuclear@3: widget->type_str = type_str; nuclear@3: } nuclear@3: nuclear@3: /* the event dispatcher generates high-level events (click, etc) nuclear@3: * and calls the on_whatever() functions for both low and high-level nuclear@3: * events. nuclear@3: * The on_whatever functions are called *after* any other actions performed nuclear@3: * here, to give subclasses the opportunity to override them easily, by nuclear@3: * overriding the on_ functions, without having to override handle_event itself nuclear@3: */ nuclear@3: // TODO also call callbacks here I guess... nuclear@3: void Widget::handle_event(const Event &ev) nuclear@3: { nuclear@3: switch(ev.type) { nuclear@3: case EV_MOUSE_BUTTON: nuclear@3: if(ev.button.press) { nuclear@3: press(); nuclear@3: } else { nuclear@3: if(is_pressed()) { nuclear@3: on_click(); nuclear@3: } nuclear@3: release(); nuclear@3: } nuclear@3: on_mouse_button(ev.button); nuclear@3: break; nuclear@3: nuclear@3: case EV_MOUSE_MOTION: nuclear@3: on_mouse_motion(ev.motion); nuclear@3: break; nuclear@3: nuclear@3: case EV_MOUSE_FOCUS: nuclear@3: if(ev.focus.enter) { nuclear@3: mousein(); nuclear@3: } else { nuclear@3: mouseout(); nuclear@3: } nuclear@3: on_mouse_focus(ev.focus); nuclear@3: break; nuclear@3: nuclear@3: case EV_KEY: nuclear@3: on_key(ev.key); nuclear@3: break; nuclear@3: nuclear@3: default: nuclear@3: fprintf(stderr, "%s: unknown event id: %d\n", __func__, ev.type); nuclear@3: } nuclear@3: } nuclear@3: nuclear@3: nuclear@4: } // namespace goatkit