From baac659433417ee555e3e04a28ea6c06fa23d588 Mon Sep 17 00:00:00 2001 From: pixel Date: Mon, 12 Jul 2004 15:08:14 +0000 Subject: Widget slowly working... --- lib/widgets.cc | 308 +++++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 300 insertions(+), 8 deletions(-) (limited to 'lib/widgets.cc') diff --git a/lib/widgets.cc b/lib/widgets.cc index 91e5904..5676721 100644 --- a/lib/widgets.cc +++ b/lib/widgets.cc @@ -1,8 +1,8 @@ -#include + #include #include #include "font.h" -#include "widgets.h" #include "engine.h" +#include "widgets.h" #ifdef HAVE_CONFIG_H #include "config.h" @@ -10,10 +10,104 @@ #include "gettext.h" +mogltk::widget * dragged_widget = 0; + +class widget_mouse_event : public mogltk::engine::mouseevent { + public: + widget_mouse_event(mogltk::widget *); + virtual void move(SDL_MouseMotionEvent); + virtual void action(SDL_MouseButtonEvent); + private: + mogltk::widget * root; + int mouse_x_down, mouse_y_down; + bool mouse_down, mouse_drag; + Uint32 old_click; +}; + +widget_mouse_event::widget_mouse_event(mogltk::widget * _root) : root(_root), mouse_down(false), mouse_drag(false) { +} + +void widget_mouse_event::move(SDL_MouseMotionEvent m) { + bool out_threshold; + + if (mouse_down) { + int dx, dy; + + dx = ABS(mouse_x_down - mogltk::engine::mouseX()); + dy = ABS(mouse_y_down - mogltk::engine::mouseY()); + + out_threshold = (dx <= 1) && (dy <= 1); + } + + if (mouse_down && (out_threshold || mouse_drag)) { + if (!mouse_drag) { + printm(M_INFO, "mouse_start_drag\n"); + // generate a mouse_start_drag event + root->m_event(mouse_x_down, mouse_y_down, mogltk::E_MOUSE_START_DRAG); + } + if (dragged_widget) { + printm(M_INFO, "mouse_drag_over"); + // generate a mouse_drag_over event + dragged_widget->m_event(mogltk::engine::mouseX(), mogltk::engine::mouseY(), mogltk::E_MOUSE_DRAG_OVER); + } + + printm(M_INFO, "mouse_drag\n"); + // generate a mouse_drag event + root->m_event(mogltk::engine::mouseX(), mogltk::engine::mouseY(), mogltk::E_MOUSE_DRAG); + mouse_drag = true; + } else { + printm(M_INFO, "mouse_move\n"); + root->m_event(mogltk::engine::mouseX(), mogltk::engine::mouseY(), mogltk::E_MOUSE_MOVE); + // generate a mouse_move event + } +} + +void widget_mouse_event::action(SDL_MouseButtonEvent b) { + if (b.button == 1) { + if (b.state) { + mouse_x_down = mogltk::engine::mouseX(); + mouse_y_down = mogltk::engine::mouseY(); + mouse_down = true; + printm(M_INFO, "mouse_down\n"); + root->m_event(mogltk::engine::mouseX(), mogltk::engine::mouseY(), mogltk::E_MOUSE_DOWN); + // generate a mouse_down event; + } else { + mouse_down = false; + if (mouse_drag) { + mouse_drag = false; + printm(M_INFO, "mouse_end_drag\n"); + root->m_event(mogltk::engine::mouseX(), mogltk::engine::mouseY(), mogltk::E_MOUSE_END_DRAG); + // generate a mouse_end_drag event + if (dragged_widget) { + printm(M_INFO, "mouse_end_drag_over"); + dragged_widget->m_event(mogltk::engine::mouseX(), mogltk::engine::mouseY(), mogltk::E_MOUSE_END_DRAG_OVER); + // generate a mouse_end_drag_over event + dragged_widget = 0; + } + } else { + printm(M_INFO, "mouse_click\n"); + root->m_event(mogltk::engine::mouseX(), mogltk::engine::mouseY(), mogltk::E_MOUSE_CLICK); + // generate a mouse_click event + + if ((SDL_GetTicks() - old_click) < 500) { + printm(M_INFO, "mouse_dbl_click\n"); + root->m_event(mogltk::engine::mouseX(), mogltk::engine::mouseY(), mogltk::E_MOUSE_DBL_CLICK); + // generate a mouse_dbl_click event + } + + old_click = SDL_GetTicks(); + } + printm(M_INFO, "mouse_up\n"); + root->m_event(mogltk::engine::mouseX(), mogltk::engine::mouseY(), mogltk::E_MOUSE_UP); + // generate a mouse_up event. + } + } +} + mogltk::widget * mogltk::widget::focused = 0; mogltk::widget::widget(widget * _father, int _x, int _y, int _sx, int _sy, int _type, String _name, mogltk::shape * _sh) : - x(_x), y(_y), sx(_sx), sy(_sy), father(_father), type(_type), name(_name), sh(_sh) { + x(_x), y(_y), sx(_sx), sy(_sy), father(_father), type(_type), name(_name), sh(_sh), exclusive(0) { if (!father) { root = this; @@ -66,6 +160,9 @@ void mogltk::widget::move(int nx, int ny) { y = ny; computeabs(); + + if (child) + child->icomputeabs(); } void mogltk::widget::resize(int nsx, int nsy) { @@ -85,11 +182,11 @@ int mogltk::widget::GetY() { } int mogltk::widget::GetH() { - return sx; + return sy; } int mogltk::widget::GetW() { - return sy; + return sx; } int mogltk::widget::GetAX() { @@ -108,6 +205,22 @@ int mogltk::widget::GetAY2() { return ay2; } +mogltk::widget * mogltk::widget::Father() { + return father; +} + +mogltk::widget * mogltk::widget::Child() { + return child; +} + +mogltk::widget * mogltk::widget::Next() { + return next; +} + +mogltk::widget * mogltk::widget::Prev() { + return prev; +} + mogltk::shape * mogltk::widget::Shaper() { return sh; } @@ -150,25 +263,204 @@ void mogltk::widget::idraw() { child->idraw(); } +bool mogltk::widget::inside(int xe, int ye) { + return !((xe < ax) || (xe > ax2) || (ye < ay) || (ye > ay2)); +} + +void mogltk::widget::m_event(int x, int y, mogltk::event_t event) { + switch (event) { + case E_MOUSE_DRAG_OVER: + case E_MOUSE_END_DRAG_OVER: + process_event(x, y, event); + break; + default: + ievent(x, y, event); + } +} + +bool mogltk::widget::ievent(int xe, int ye, mogltk::event_t event) { + if (next) + if (next->ievent(xe, ye, event)) + return true; + + if (!inside(xe, ye)) + return false; + + if (exclusive) + return exclusive->ievent(xe, ye, event); + + if (child) + if (child->ievent(xe, ye, event)) + return true; + + return process_event(xe, ye, event); +} + +void mogltk::widget::draw() { +} + +bool mogltk::widget::process_event(int, int, mogltk::event_t) { + return false; +} + +void mogltk::widget::icomputeabs() { + computeabs(); + + if (next) + next->computeabs(); + + if (child) + child->computeabs(); +} + +void mogltk::widget::set_exclusive(mogltk::widget * w) { + w->exclusive = this; +} + +void mogltk::widget::unset_exclusive(mogltk::widget * w) { + w->exclusive = 0; +} + /* * Predefined widgets. */ /* Here is Root */ -mogltk::Root::Root(mogltk::shape * sh, mogltk::drawer * _dr) : widget(0, 0, 0, 0, 0, 0, "Root", sh), dr(_dr) { +mogltk::widgets::Root::Root(mogltk::shape * sh, mogltk::widgets::drawer * _dr) : widget(0, 0, 0, 0, 0, 0, "Root", sh), dr(_dr) { if (engine::root) delete engine::root; engine::root = this; } -void mogltk::Root::draw() { +void mogltk::widgets::Root::draw() { if (dr) dr->draw(this); else Shaper()->box(GetAX(), GetAY(), GetAX2(), GetAY2()); } -void mogltk::Root::setdrawer(drawer * _dr) { +void mogltk::widgets::Root::setdrawer(drawer * _dr) { dr = _dr; } + +mogltk::widgets::Button::Button(action * _a, shape * sh, widget * father, int x, int y, int w, int h, const String & _caption) : widget(father, x, y, w, h, 0, "Button", sh), bevel(false), dragging(false), a(_a) { + caption = _caption; +} + +void mogltk::widgets::Button::draw() { + Shaper()->button(GetAX() + 1, GetAY() + 1, GetAX2() - 1, GetAY2() - 1, caption, bevel); +} + +bool mogltk::widgets::Button::process_event(int xe, int ye, mogltk::event_t event) { + switch (event) { + case E_MOUSE_DOWN: + bevel = true; + return true; + case E_MOUSE_CLICK: + bevel = false; + // action here. + if (a) + a->do_action(this); + return true; + case E_MOUSE_START_DRAG: + dragged_widget = this; + dragging = true; + return true; + case E_MOUSE_DRAG_OVER: + bevel = inside(xe, ye); + return true; + case E_MOUSE_END_DRAG_OVER: + dragging = false; + if (bevel); + // action here. + if (a) + a->do_action(this); + bevel = false; + return true; + } + return false; +} + +mogltk::widgets::SmartBox::SmartBox(shape * sh, mogltk::widget * father, int x, int y, int w, int h, const String & _caption) : widget(father, x, y, w, h, 0, "SmartBox", sh) { + caption = _caption; +} + +void mogltk::widgets::SmartBox::draw() { + Shaper()->window(GetAX(), GetAY(), GetAX2(), GetAY2(), caption); +} + +bool mogltk::widgets::SmartBox::process_event(int x, int y, mogltk::event_t event) { + switch (event) { + case E_MOUSE_START_DRAG: + if ((GetAY() + 20) > y) { + dragged_widget = this; + ox = x; + oy = y; + oax = GetX(); + oay = GetY(); + return true; + } + break; + case E_MOUSE_DRAG_OVER: + move(x - ox + oax, y - oy + oay); + return true; + } + return false; +} + +class MessageBoxAction : public mogltk::widgets::action { + public: + MessageBoxAction(mogltk::widget * _parent) : parent(_parent) { } + virtual void do_action(mogltk::widget *) { + delete parent; + delete this; + } + private: + mogltk::widget * parent; +}; + +mogltk::widgets::MsgBox::MsgBox(shape * sh, mogltk::widget * father, const String & caption, const String & text) : SmartBox(sh, father, 0, 0, 0, 0, caption) { + rect size = SystemFont->size(text); + rect lsize = size; + + size.w += 12; + size.h += 60; + + size.x = (father->GetW() - size.w) / 2; + size.y = (father->GetH() - size.h) / 2; + resize(size.w, size.h); + move(size.x, size.y); + + new Button(new MessageBoxAction(this), sh, this, size.w / 2 - 25, size.h - 30, 50, 24, "Ok"); + new Label(sh, this, 6, 24, lsize.w, lsize.h, text, BLACK); + + set_exclusive(father); +} + +mogltk::widgets::MsgBox::~MsgBox() { + unset_exclusive(Father()); +} + +mogltk::widgets::Label::Label(shape * sh, mogltk::widget * father, int x, int y, int w, int h, const String & _caption, const ColorP & _color) : widget(father, x, y, w, h, 0, "Label", sh), color(_color) { + caption = _caption; +} + +void mogltk::widgets::Label::draw() { + Shaper()->text(GetAX(), GetAY(), caption, color); +} + + + +void mogltk::widget::mainloop() { + bool end_event_loop = false; + widget_mouse_event * mouse = new widget_mouse_event(this); + + while (!end_event_loop && !engine::quitrequested()) { + root->fulldraw(); + Shaper()->pixel(engine::mouseX(), engine::mouseY(), BLACK); + engine::base_o->Flip(); + } + + delete mouse; +} -- cgit v1.2.3