summaryrefslogtreecommitdiff
path: root/lib/widgets.cc
diff options
context:
space:
mode:
Diffstat (limited to 'lib/widgets.cc')
-rw-r--r--lib/widgets.cc201
1 files changed, 190 insertions, 11 deletions
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 <SDL.h>
#include <vector>
@@ -36,6 +36,8 @@
mogltk::widget * dragged_widget = 0;
std::vector<mogltk::widget *> out_move, out_click;
+std::vector<mogltk::widget::timed_event> 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<timed_event>::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<widget *>::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<node>::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<node>::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<node>::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;