From 14271a8d758c086e0762e7ad0d649dabc8848191 Mon Sep 17 00:00:00 2001 From: pixel Date: Fri, 16 Jul 2004 15:04:52 +0000 Subject: Structuring mogltk into PSX-Bundle, and commiting latest changes --- lib/widgets.cc | 201 +++++++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 190 insertions(+), 11 deletions(-) (limited to 'lib/widgets.cc') diff --git a/lib/widgets.cc b/lib/widgets.cc index c0e09db..3298385 100644 --- a/lib/widgets.cc +++ b/lib/widgets.cc @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -/* $Id: widgets.cc,v 1.6 2004-07-15 14:21:31 pixel Exp $ */ +/* $Id: widgets.cc,v 1.7 2004-07-16 15:04:53 pixel Exp $ */ #include #include @@ -36,6 +36,8 @@ mogltk::widget * dragged_widget = 0; std::vector out_move, out_click; +std::vector mogltk::widget::timed_events; + class widget_mouse_event : public mogltk::engine::mouseevent { public: @@ -122,6 +124,19 @@ void widget_mouse_event::action(SDL_MouseButtonEvent b) { printm(M_INFO, "mouse_down\n"); root->m_event(mx, my, mogltk::E_MOUSE_DOWN); // generate a mouse_down event; + for (i = out_click.begin(); i != out_click.end(); i++) { + out_click_stack.push_back(*i); + } + + for (i = out_click_stack.begin(); i != out_click_stack.end(); i++) { + if (!(*i)->inside(mx, my)) { + (*i)->m_event(mx, my, mogltk::E_MOUSE_OUT_CLICK); + // generate a mouse_out_click event + } + } + + out_click_stack.empty(); + } else { mouse_down = false; if (mouse_drag) { @@ -171,7 +186,7 @@ void widget_mouse_event::action(SDL_MouseButtonEvent b) { 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), exclusive(0), visible(true), enabled(true) { + x(_x), y(_y), sx(_sx), sy(_sy), father(_father), prev(0), child(0), last(0), type(_type), name(_name), sh(_sh), exclusive(0), visible(true), enabled(true) { if (!father) { root = this; father = this; @@ -184,11 +199,11 @@ mogltk::widget::widget(widget * _father, int _x, int _y, int _sx, int _sy, int _ next = father->child; if (next) next->prev = this; + if (!father->last) + father->last = this; father->child = this; root = father->root; } - prev = 0; - child = 0; computeabs(); } @@ -204,6 +219,8 @@ mogltk::widget::~widget() { if (next) next->prev = prev; + else + father->last = prev; } void mogltk::widget::computeabs() { @@ -361,8 +378,8 @@ void mogltk::widget::m_event(int x, int y, mogltk::event_t event) { } bool mogltk::widget::ievent(int xe, int ye, mogltk::event_t event) { - if (next) - if (next->ievent(xe, ye, event)) + if (prev) + if (prev->ievent(xe, ye, event)) return true; if (!inside(xe, ye)) @@ -371,8 +388,8 @@ bool mogltk::widget::ievent(int xe, int ye, mogltk::event_t event) { if (exclusive) return exclusive->ievent(xe, ye, event); - if (child) - if (child->ievent(xe, ye, event)) + if (last) + if (last->ievent(xe, ye, event)) return true; if (!enabled || !visible) @@ -430,6 +447,40 @@ void mogltk::widget::SetEnabled(bool _enabled) { enabled = _enabled; } +void mogltk::widget::MoveOnTop() { + if (!prev) + return; + + if (!next) { + father->last = prev; + } else { + next->prev = prev; + } + prev->next = next; + prev = 0; + next = father->child; + + next->prev = this; + father->child = this; +} + +void mogltk::widget::check_timed_events() { + std::vector::iterator i; + Uint32 t = SDL_GetTicks(); + widget * w; + + for (i = timed_events.begin(); i != timed_events.end(); i++) { + if (i->t <= t) { + w = i->w; + timed_events.erase(i); + w->process_event(engine::mouseX(), engine::mouseY(), E_TIMER); + i = timed_events.begin(); + if (i == timed_events.end()) + return ; + } + } +} + void mogltk::widget::add_out_move() { std::vector::iterator i; @@ -474,6 +525,15 @@ void mogltk::widget::remove_out_click() { } } +void mogltk::widget::set_timed_event(Uint32 t) { + timed_events.push_back(timed_event(this, SDL_GetTicks() + t)); +} + +void mogltk::widget::set_absolute_timed_event(Uint32 t) { + timed_events.push_back(timed_event(this, t)); +} + + /* * Predefined widgets. */ @@ -569,6 +629,7 @@ bool mogltk::widgets::SmartBox::process_event(int x, int y, mogltk::event_t even break; case E_MOUSE_DRAG_OVER: move(x - ox + oax, y - oy + oay); + MoveOnTop(); return true; } return false; @@ -711,7 +772,7 @@ int mogltk::widgets::ContextMenu::node::GetH() { return h; } -mogltk::widgets::ContextMenu::ContextMenu(shape * sh, mogltk::widget * father, int x, int y) : widget(father, x, y, 8, 4, 1, "ContextMenu", sh), selected(-1), subselected(0), in_click(false) { +mogltk::widgets::ContextMenu::ContextMenu(shape * sh, mogltk::widget * father, int x, int y) : widget(father, x, y, 8, 4, 1, "ContextMenu", sh), selected(-1), subselected(0), in_click(false), sticky(false) { } mogltk::widgets::ContextMenu::~ContextMenu() { @@ -792,6 +853,8 @@ void mogltk::widgets::ContextMenu::resize(int w, int h) { } void mogltk::widgets::ContextMenu::SetVisible(bool visible) { + if (!visible && sticky) + return; widget::SetVisible(visible); if (!visible && subselected) { subselected->SetVisible(false); @@ -799,6 +862,7 @@ void mogltk::widgets::ContextMenu::SetVisible(bool visible) { if (visible) { add_out_click(); + MoveOnTop(); } } @@ -806,6 +870,11 @@ void mogltk::widgets::ContextMenu::SetEnabled(int i, bool e) { nodes[i].SetEnabled(e); } +void mogltk::widgets::ContextMenu::StickyDisplay() { + sticky = true; + SetVisible(true); +} + void mogltk::widgets::ContextMenu::draw() { std::vector::iterator i; int n; @@ -835,6 +904,7 @@ bool mogltk::widgets::ContextMenu::process_event(int xe, int ye, mogltk::event_t switch (event) { case E_MOUSE_MOVE: + sticky = false; for (i = nodes.begin(), n = 0; i != nodes.end(); i++, n++) { if (!i->GetLine()) { int ax, ax2, ay, ay2; @@ -873,6 +943,9 @@ bool mogltk::widgets::ContextMenu::process_event(int xe, int ye, mogltk::event_t } in_click = true; break; + case E_MOUSE_DOWN: + in_click = true; + break; case E_MOUSE_OUT: selected = -1; remove_out_move(); @@ -905,7 +978,34 @@ bool mogltk::widgets::ContextMenu::iin_click() { * The Menu topframe * ********************/ -mogltk::widgets::Menu::Menu(shape * sh, mogltk::widget * father) : widget(father, 0, 0, 0, 0, 0, "Menu", sh) { +mogltk::widgets::Menu::node::node(const String & _caption, mogltk::widgets::ContextMenu * _sub, mogltk::widgets::action * _a, int _x) : caption(_caption), sub(_sub), a(_a), x(_x) { +} + +String mogltk::widgets::Menu::node::GetCaption() { + return caption; +} + +mogltk::widgets::ContextMenu * mogltk::widgets::Menu::node::GetSub() { + return sub; +} + +mogltk::widgets::action * mogltk::widgets::Menu::node::GetAction() { + return a; +} + +int mogltk::widgets::Menu::node::GetX() { + return x; +} + +bool mogltk::widgets::Menu::node::GetEnabled() { + return enabled; +} + +void mogltk::widgets::Menu::node::SetEnabled(bool _enabled) { + enabled = _enabled; +} + +mogltk::widgets::Menu::Menu(shape * sh, mogltk::widget * father) : widget(father, 0, 0, 0, 0, 0, "Menu", sh), cur_x(0), selected(-1) { rect r = father->GetDrawRect(); move(r.x, r.y); resize(r.w, 16); @@ -916,11 +1016,89 @@ void mogltk::widgets::Menu::resize_notify() { resize(r.w, 16); } +void mogltk::widgets::Menu::addnode(const String & caption, mogltk::widgets::action * a) { + nodes.push_back(node(caption, 0, a, cur_x)); + cur_x += SystemFont->singletextsize(caption) + 6; +} + +void mogltk::widgets::Menu::addsub(const String & caption, mogltk::widgets::ContextMenu * sub) { + nodes.push_back(node(caption, sub, 0, cur_x)); + cur_x += SystemFont->singletextsize(caption) + 6; +} + +mogltk::widgets::ContextMenu * mogltk::widgets::Menu::createsub(const String & caption) { + ContextMenu * r = new ContextMenu(Shaper(), Father(), GetX() + cur_x, GetY() + 16); + addsub(caption, r); + r->SetVisible(false); + return r; +} + +void mogltk::widgets::Menu::SetEnabled(int i, bool e) { + nodes[i].SetEnabled(e); +} + void mogltk::widgets::Menu::draw(void) { - Shaper()->box(GetAX(), GetAY(), GetAX2(), GetAY2(), BLUE); + std::vector::iterator i; + int n; + + Shaper()->box(GetAX(), GetAY(), GetAX2(), GetAY2(), DOS_WHITE); + + for (i = nodes.begin(), n = 0; i != nodes.end(); i++, n++) { + if (selected == n) { + if ((i + 1) == nodes.end()) { + Shaper()->box(GetAX() + i->GetX(), GetAY(), cur_x, GetAY2(), DOS_MAGENTA); + } else { + Shaper()->box(GetAX() + i->GetX(), GetAY(), GetAX() + i[1].GetX(), GetAY2(), DOS_MAGENTA); + } + } + Shaper()->text(GetAX() + i->GetX() + 3, GetAY(), i->GetCaption(), BLACK); + } } bool mogltk::widgets::Menu::process_event(int mx, int my, mogltk::event_t event) { + std::vector::iterator i; + action * a; + ContextMenu * sub; + int n; + + switch (event) { + case E_MOUSE_MOVE: + selected = -1; + for (i = nodes.begin(), n = 0; i != nodes.end(); i++, n++) { + int ax, ax2, ay, ay2; + + ax = GetAX() + i->GetX(); + ay = GetAY(); + if ((i + 1) != nodes.end()) { + ax2 = GetAX() + i[1].GetX(); + } else { + ax2 = GetAX() + cur_x; + } + ay2 = GetAY2(); + + if (!((mx < ax) || (mx > ax2) || (my < ay) || (my > ay2))) { + selected = n; + } + } + add_out_move(); + return true; + case E_MOUSE_CLICK: + a = 0; + if (selected != -1) { + if ((a = nodes[selected].GetAction()) && nodes[selected].GetEnabled()) { + a->do_action(this); + return true; + } else if ((sub = nodes[selected].GetSub()) && nodes[selected].GetEnabled()) { + sub->StickyDisplay(); + return true; + } + } + break; + case E_MOUSE_OUT: + selected = -1; + remove_out_move(); + return true; + } return false; } @@ -943,6 +1121,7 @@ void mogltk::widget::mainloop() { mogltk::ColorP::Max.A = 255; Sprite::Cursor->draw(mx - 8, my - 6); engine::base_o->Flip(); + widget::check_timed_events(); } delete mouse; -- cgit v1.2.3