summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorpixel <pixel>2004-07-15 13:41:31 +0000
committerpixel <pixel>2004-07-15 13:41:31 +0000
commit55524da6af5a98df4d9c38d8408cd65bd233ee57 (patch)
tree714838bc565d0ff0a77ded92ff2c5549b58e7c98
parent652aa99bd5fddbb4ee878ddd65ac637a134dbcbc (diff)
Some more widgets introduced
-rw-r--r--include/sprite.h1
-rw-r--r--include/widgets.h92
-rw-r--r--lib/engine.cc3
-rw-r--r--lib/sprite.cc2
-rw-r--r--lib/widgets.cc498
-rw-r--r--src/test.cc22
6 files changed, 594 insertions, 24 deletions
diff --git a/include/sprite.h b/include/sprite.h
index d328dba..2b1a4a0 100644
--- a/include/sprite.h
+++ b/include/sprite.h
@@ -16,6 +16,7 @@ namespace mogltk {
virtual void draw(int, int, ColorP = WHITE, float = 1.0, float = 1.0);
int GetSX();
int GetSY();
+ static Sprite * Cursor;
protected:
void Bind();
int GetPX();
diff --git a/include/widgets.h b/include/widgets.h
index 116eef5..939c753 100644
--- a/include/widgets.h
+++ b/include/widgets.h
@@ -3,6 +3,7 @@
#include <Exceptions.h>
#include <shape.h>
+#include <base.h>
namespace mogltk {
enum event_t {
@@ -12,16 +13,18 @@ namespace mogltk {
E_MOUSE_END_DRAG,
E_MOUSE_END_DRAG_OVER,
E_MOUSE_MOVE,
+ E_MOUSE_OUT,
E_MOUSE_DOWN,
E_MOUSE_UP,
E_MOUSE_CLICK,
+ E_MOUSE_OUT_CLICK,
E_MOUSE_DBL_CLICK,
};
class widget : public Base {
public:
virtual ~widget();
- void move(int x, int y);
- void resize(int sx, int sy);
+ virtual void move(int x, int y);
+ virtual void resize(int sx, int sy);
int GetX();
int GetY();
int GetH();
@@ -30,6 +33,7 @@ namespace mogltk {
int GetAY();
int GetAX2();
int GetAY2();
+ virtual mogltk::rect GetDrawRect();
widget * Father();
widget * Child();
widget * Next();
@@ -39,15 +43,23 @@ namespace mogltk {
void mainloop();
void m_event(int x, int y, event_t event);
bool inside(int x, int y);
+ bool GetVisible();
+ virtual void SetVisible(bool);
+ bool GetEnabled();
+ virtual void SetEnabled(bool);
protected:
widget(widget * father, int x, int y, int sx, int sy, int type, String name, shape *);
virtual void draw();
- String caption;
virtual bool process_event(int x, int y, event_t event);
+ virtual void resize_notify();
void set_exclusive(widget *);
void unset_exclusive(widget *);
+ void add_out_move();
+ void remove_out_move();
+ void add_out_click();
+ void remove_out_click();
+ String caption;
private:
- void computeabs();
int x, y, sx, sy, ax, ay, ax2, ay2;
widget * father, * next, * prev, * child, * root;
static widget * focused;
@@ -55,9 +67,14 @@ namespace mogltk {
String name;
shape * sh;
widget * exclusive;
- void idraw();
+ bool visible;
+ bool enabled;
+
+ void computeabs();
+ void idraw();
bool ievent(int x, int y, event_t event);
void icomputeabs();
+ void iresize_notify();
};
namespace widgets {
@@ -104,6 +121,7 @@ namespace mogltk {
class SmartBox : public widget {
public:
SmartBox(shape *, widget * father, int x, int y, int w, int h, const String & caption);
+ virtual rect GetDrawRect();
protected:
virtual void draw();
virtual bool process_event(int, int, event_t);
@@ -116,6 +134,70 @@ namespace mogltk {
MsgBox(shape *, widget * father, const String & caption, const String & text);
virtual ~MsgBox();
};
+
+ class Frame : public widget {
+ public:
+ Frame(shape *, widget * father, int x, int y, int w, int h);
+ virtual rect GetDrawRect();
+ protected:
+ virtual void draw();
+ };
+
+ class ContextMenu : public widget {
+ public:
+ ContextMenu(shape *, widget * father, int x, int y);
+ virtual ~ContextMenu();
+ void addnode(const String &, action *);
+ void addline();
+ void addsub(const String &, ContextMenu *);
+ ContextMenu * createsub(const String &);
+ virtual void move(int x, int y);
+ virtual void resize(int w, int h);
+ virtual void SetVisible(bool);
+ virtual void SetEnabled(int i, bool);
+ protected:
+ virtual void draw();
+ virtual bool process_event(int x, int y, event_t event);
+ class node : public Base {
+ public:
+ node(const String &, int x, int y, int w, int h, action * = 0, ContextMenu * sub = 0, ContextMenu * father = 0, bool = false);
+ String GetCaption();
+ action * GetAction();
+ ContextMenu * GetSub();
+ ContextMenu * GetFather();
+ bool GetLine();
+ bool GetEnabled();
+ void SetEnabled(bool);
+ int GetX();
+ int GetY();
+ int GetW();
+ int GetH();
+ private:
+ String caption;
+ int x, y, w, h;
+ action * a;
+ ContextMenu * sub, * father;
+ bool line, enabled;
+ };
+
+ std::vector<node> nodes;
+ int selected;
+ ContextMenu * subselected;
+ private:
+ bool in_click;
+
+ bool iin_click();
+ };
+
+ class Menu : public widget {
+ public:
+ Menu(shape *, widget * father);
+ virtual void resize_notify();
+ protected:
+ virtual void draw();
+ virtual bool process_event(int, int, event_t);
+ private:
+ };
};
};
diff --git a/lib/engine.cc b/lib/engine.cc
index 357de32..e8d232e 100644
--- a/lib/engine.cc
+++ b/lib/engine.cc
@@ -2,6 +2,7 @@
#include <Input.h>
#include "engine.h"
#include "glfont.h"
+#include "glsprite.h"
#ifdef HAVE_CONFIG_H
#include "config.h"
@@ -118,9 +119,11 @@ int mogltk::engine::postsetup() throw(GeneralException) {
if (glbase_o) {
mogltk::SystemFont = new mogltk::glfont(&Input("font.bin"));
mogltk::FixedFont = new mogltk::glfont(&Input("fixed-font.bin"));
+ Sprite::Cursor = new mogltk::glSprite(&Input("cursor.rgba"), 25, 25);
} else {
mogltk::SystemFont = new mogltk::font(&Input("font.bin"));
mogltk::FixedFont = new mogltk::font(&Input("fixed-font.bin"));
+ Sprite::Cursor = new mogltk::Sprite(&Input("cursor.rgba"), 25, 25);
}
return 0;
diff --git a/lib/sprite.cc b/lib/sprite.cc
index 13c09da..77795dc 100644
--- a/lib/sprite.cc
+++ b/lib/sprite.cc
@@ -5,6 +5,8 @@
#define TEXSIZE 1024
+mogltk::Sprite * mogltk::Sprite::Cursor;
+
mogltk::Sprite::TexList * mogltk::Sprite::TexList::header = 0;
mogltk::Sprite::Sprite(Handle * h, int asx, int asy) throw (GeneralException) : sx(asx), sy(asy) {
diff --git a/lib/widgets.cc b/lib/widgets.cc
index f3dc559..f1b558d 100644
--- a/lib/widgets.cc
+++ b/lib/widgets.cc
@@ -1,8 +1,10 @@
- #include <SDL.h>
+#include <SDL.h>
+#include <vector>
#include <Input.h>
#include "font.h"
#include "engine.h"
#include "widgets.h"
+#include "sprite.h"
#ifdef HAVE_CONFIG_H
#include "config.h"
@@ -12,6 +14,8 @@
mogltk::widget * dragged_widget = 0;
+std::vector<mogltk::widget *> out_move, out_click;
+
class widget_mouse_event : public mogltk::engine::mouseevent {
public:
widget_mouse_event(mogltk::widget *);
@@ -28,13 +32,19 @@ widget_mouse_event::widget_mouse_event(mogltk::widget * _root) : root(_root), mo
}
void widget_mouse_event::move(SDL_MouseMotionEvent m) {
+ int mx, my;
bool out_threshold;
+ std::vector<mogltk::widget *>::iterator i;
+ std::vector<mogltk::widget *> out_move_stack;
+
+ mx = mogltk::engine::mouseX();
+ my = mogltk::engine::mouseY();
if (mouse_down) {
int dx, dy;
- dx = ABS(mouse_x_down - mogltk::engine::mouseX());
- dy = ABS(mouse_y_down - mogltk::engine::mouseY());
+ dx = ABS(mouse_x_down - mx);
+ dy = ABS(mouse_y_down - my);
out_threshold = (dx <= 1) && (dy <= 1);
}
@@ -48,57 +58,90 @@ void widget_mouse_event::move(SDL_MouseMotionEvent m) {
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);
+ dragged_widget->m_event(mx, my, 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);
+ root->m_event(mx, my, 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);
+ root->m_event(mx, my, mogltk::E_MOUSE_MOVE);
// generate a mouse_move event
}
+
+ for (i = out_move.begin(); i != out_move.end(); i++) {
+ out_move_stack.push_back(*i);
+ }
+
+ for (i = out_move_stack.begin(); i != out_move_stack.end(); i++) {
+ if (!(*i)->inside(mx, my)) {
+ (*i)->m_event(mx, my, mogltk::E_MOUSE_OUT);
+ // generate a mouse_out event
+ }
+ }
+
+ out_move_stack.empty();
}
void widget_mouse_event::action(SDL_MouseButtonEvent b) {
+ int mx, my;
+ std::vector<mogltk::widget *>::iterator i;
+ std::vector<mogltk::widget *> out_click_stack;
+
+ mx = mogltk::engine::mouseX();
+ my = mogltk::engine::mouseY();
+
if (b.button == 1) {
if (b.state) {
- mouse_x_down = mogltk::engine::mouseX();
- mouse_y_down = mogltk::engine::mouseY();
+ mouse_x_down = mx;
+ mouse_y_down = my;
mouse_down = true;
printm(M_INFO, "mouse_down\n");
- root->m_event(mogltk::engine::mouseX(), mogltk::engine::mouseY(), mogltk::E_MOUSE_DOWN);
+ root->m_event(mx, my, 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);
+ root->m_event(mx, my, 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);
+ dragged_widget->m_event(mx, my, 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);
+ root->m_event(mx, my, mogltk::E_MOUSE_CLICK);
// generate a mouse_click 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();
+
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);
+ root->m_event(mx, my, 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);
+ root->m_event(mx, my, mogltk::E_MOUSE_UP);
// generate a mouse_up event.
}
}
@@ -107,8 +150,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) {
-
+ x(_x), y(_y), sx(_sx), sy(_sy), father(_father), type(_type), name(_name), sh(_sh), exclusive(0), visible(true), enabled(true) {
if (!father) {
root = this;
father = this;
@@ -171,6 +213,8 @@ void mogltk::widget::resize(int nsx, int nsy) {
ax2 = ax + sx;
ay2 = ay + sy;
+
+ iresize_notify();
}
int mogltk::widget::GetX() {
@@ -205,6 +249,16 @@ int mogltk::widget::GetAY2() {
return ay2;
}
+mogltk::rect mogltk::widget::GetDrawRect() {
+ rect r;
+ r.x = 0;
+ r.y = 0;
+ r.w = GetW();
+ r.h = GetH();
+
+ return r;
+}
+
mogltk::widget * mogltk::widget::Father() {
return father;
}
@@ -249,6 +303,9 @@ void mogltk::widget::idraw() {
if (next)
next->idraw();
+ if (!visible)
+ return;
+
x1 = MAX(GetAX(), father->GetAX());
y1 = MAX(GetAY(), father->GetAY());
@@ -264,6 +321,8 @@ void mogltk::widget::idraw() {
}
bool mogltk::widget::inside(int xe, int ye) {
+ if (!visible)
+ return false;
return !((xe < ax) || (xe > ax2) || (ye < ay) || (ye > ay2));
}
@@ -271,6 +330,8 @@ 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:
+ case E_MOUSE_OUT:
+ case E_MOUSE_OUT_CLICK:
process_event(x, y, event);
break;
default:
@@ -293,6 +354,9 @@ bool mogltk::widget::ievent(int xe, int ye, mogltk::event_t event) {
if (child->ievent(xe, ye, event))
return true;
+ if (!enabled || !visible)
+ return false;
+
return process_event(xe, ye, event);
}
@@ -303,6 +367,9 @@ bool mogltk::widget::process_event(int, int, mogltk::event_t) {
return false;
}
+void mogltk::widget::resize_notify() {
+}
+
void mogltk::widget::icomputeabs() {
computeabs();
@@ -313,6 +380,11 @@ void mogltk::widget::icomputeabs() {
child->computeabs();
}
+void mogltk::widget::iresize_notify() {
+ if (child)
+ child->iresize_notify();
+}
+
void mogltk::widget::set_exclusive(mogltk::widget * w) {
w->exclusive = this;
}
@@ -321,11 +393,73 @@ void mogltk::widget::unset_exclusive(mogltk::widget * w) {
w->exclusive = 0;
}
+bool mogltk::widget::GetVisible() {
+ return visible;
+}
+
+void mogltk::widget::SetVisible(bool _visible) {
+ visible = _visible;
+}
+
+bool mogltk::widget::GetEnabled() {
+ return enabled;
+}
+
+void mogltk::widget::SetEnabled(bool _enabled) {
+ enabled = _enabled;
+}
+
+void mogltk::widget::add_out_move() {
+ std::vector<widget *>::iterator i;
+
+ for (i = out_move.begin(); i != out_move.end(); i++) {
+ if (*i == this)
+ return;
+ }
+
+ out_move.push_back(this);
+}
+
+void mogltk::widget::remove_out_move() {
+ std::vector<widget *>::iterator i;
+
+ for (i = out_move.begin(); i != out_move.end(); i++) {
+ if (*i == this) {
+ out_move.erase(i);
+ return;
+ }
+ }
+}
+
+void mogltk::widget::add_out_click() {
+ std::vector<widget *>::iterator i;
+
+ for (i = out_click.begin(); i != out_click.end(); i++) {
+ if (*i == this)
+ return;
+ }
+
+ out_click.push_back(this);
+}
+
+void mogltk::widget::remove_out_click() {
+ std::vector<widget *>::iterator i;
+
+ for (i = out_click.begin(); i != out_click.end(); i++) {
+ if (*i == this) {
+ out_click.erase(i);
+ return;
+ }
+ }
+}
+
/*
* Predefined widgets.
*/
-/* Here is Root */
+/***************
+* Here is Root *
+***************/
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)
@@ -344,6 +478,11 @@ void mogltk::widgets::Root::setdrawer(drawer * _dr) {
dr = _dr;
}
+
+/***********************
+* The classical Button *
+***********************/
+
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;
}
@@ -382,6 +521,11 @@ bool mogltk::widgets::Button::process_event(int xe, int ye, mogltk::event_t even
return false;
}
+
+/**********************
+* The SmartBox window *
+**********************/
+
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;
}
@@ -409,6 +553,22 @@ bool mogltk::widgets::SmartBox::process_event(int x, int y, mogltk::event_t even
return false;
}
+mogltk::rect mogltk::widgets::SmartBox::GetDrawRect() {
+ rect r;
+
+ r.x = 2;
+ r.y = 21;
+ r.w = GetW() - 4;
+ r.h = GetH() - 23;
+
+ return r;
+}
+
+
+/***********************
+* The MessageBox child *
+***********************/
+
class MessageBoxAction : public mogltk::widgets::action {
public:
MessageBoxAction(mogltk::widget * _parent) : parent(_parent) { }
@@ -442,6 +602,11 @@ mogltk::widgets::MsgBox::~MsgBox() {
unset_exclusive(Father());
}
+
+/*****************
+* A simple Label *
+*****************/
+
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;
}
@@ -451,14 +616,311 @@ void mogltk::widgets::Label::draw() {
}
+/*************************
+* The classical 3D Frame *
+*************************/
+
+mogltk::widgets::Frame::Frame(shape * sh, widget * father, int x, int y, int w, int h) : widget(father, x, y, w, h, 0, "Frame", sh) {
+}
+
+void mogltk::widgets::Frame::draw() {
+ Shaper()->obox3d(GetAX(), GetAY(), GetAX2(), GetAY2());
+}
+
+mogltk::rect mogltk::widgets::Frame::GetDrawRect() {
+ rect r;
+
+ r.x = 4;
+ r.y = 4;
+ r.w = GetW() - 8;
+ r.h = GetH() - 8;
+
+ return r;
+}
+
+
+/***********************************
+* The huge and bloated ContextMenu *
+***********************************/
+
+mogltk::widgets::ContextMenu::node::node(const String & _caption, int _x, int _y, int _w, int _h, mogltk::widgets::action * _a, mogltk::widgets::ContextMenu * _sub, mogltk::widgets::ContextMenu * _father, bool _line) : caption(_caption), x(_x), y(_y), w(_w), h(_h), a(_a), sub(_sub), father(_father), line(_line), enabled(true) {
+}
+
+String mogltk::widgets::ContextMenu::node::GetCaption() {
+ return caption;
+}
+
+mogltk::widgets::action * mogltk::widgets::ContextMenu::node::GetAction() {
+ return a;
+}
+
+mogltk::widgets::ContextMenu * mogltk::widgets::ContextMenu::node::GetFather() {
+ return father;
+}
+
+mogltk::widgets::ContextMenu * mogltk::widgets::ContextMenu::node::GetSub() {
+ return sub;
+}
+
+bool mogltk::widgets::ContextMenu::node::GetLine() {
+ return line;
+}
+
+bool mogltk::widgets::ContextMenu::node::GetEnabled() {
+ return enabled;
+}
+
+void mogltk::widgets::ContextMenu::node::SetEnabled(bool _enabled) {
+ enabled = _enabled;
+}
+
+int mogltk::widgets::ContextMenu::node::GetX() {
+ return x;
+}
+
+int mogltk::widgets::ContextMenu::node::GetY() {
+ return y;
+}
+
+int mogltk::widgets::ContextMenu::node::GetW() {
+ return w;
+}
+
+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() {
+ std::vector<node>::iterator i;
+ ContextMenu * sub;
+
+ for (i = nodes.begin(); i != nodes.end(); i++) {
+ if ((sub = i->GetSub()))
+ delete sub;
+ }
+}
+
+void mogltk::widgets::ContextMenu::addnode(const String & caption, mogltk::widgets::action * a) {
+ rect size;
+
+ size = SystemFont->size(caption);
+ nodes.push_back(node(caption, 4, GetH() - 2, size.w, size.h, a, 0, this, false));
+ size.w += 8;
+ if (GetW() > size.w)
+ size.w = GetW();
+ resize(size.w, GetH() + size.h);
+}
+
+void mogltk::widgets::ContextMenu::addsub(const String & caption, mogltk::widgets::ContextMenu * sub) {
+ rect size;
+
+ size = SystemFont->size(caption + " >");
+ nodes.push_back(node(caption + " >", 4, GetH() - 2, size.w, size.h, 0, sub, this, false));
+ size.w += 8;
+ if (GetW() > size.w)
+ size.w = GetW();
+ resize(size.w, GetH() + size.h);
+}
+
+void mogltk::widgets::ContextMenu::addline() {
+ nodes.push_back(node("", 2, GetH() - 1, 0, 0, 0, 0, this, true));
+ resize(GetW(), GetH() + 4);
+}
+
+mogltk::widgets::ContextMenu * mogltk::widgets::ContextMenu::createsub(const String & caption) {
+ ContextMenu * r;
+
+ r = new ContextMenu(Shaper(), Father(), GetX() + GetW(), GetY() + GetH());
+ r->SetVisible(false);
+
+ addsub(caption, r);
+
+ return r;
+}
+
+void mogltk::widgets::ContextMenu::move(int x, int y) {
+ int dx, dy;
+ std::vector<node>::iterator i;
+ ContextMenu * sub;
+
+ dx = x - GetX();
+ dy = y - GetY();
+ widget::move(x, y);
+
+ for (i = nodes.begin(); i != nodes.end(); i++) {
+ if ((sub = i->GetSub()))
+ sub->move(sub->GetX() + dx, sub->GetY() + dy);
+ }
+}
+
+void mogltk::widgets::ContextMenu::resize(int w, int h) {
+ int dw;
+ std::vector<node>::iterator i;
+ ContextMenu * sub;
+
+ dw = w - GetW();
+ widget::resize(w, h);
+
+ for (i = nodes.begin(); i != nodes.end(); i++) {
+ if ((sub = i->GetSub()))
+ sub->move(sub->GetX() + dw, sub->GetY());
+ }
+}
+
+void mogltk::widgets::ContextMenu::SetVisible(bool visible) {
+ widget::SetVisible(visible);
+ if (!visible && subselected) {
+ subselected->SetVisible(false);
+ }
+
+ if (visible) {
+ add_out_click();
+ }
+}
+
+void mogltk::widgets::ContextMenu::SetEnabled(int i, bool e) {
+ nodes[i].SetEnabled(e);
+}
+
+void mogltk::widgets::ContextMenu::draw() {
+ std::vector<node>::iterator i;
+ int n;
+ rect size;
+
+ Shaper()->box3d(GetAX(), GetAY(), GetAX2(), GetAY2());
+
+ for (i = nodes.begin(), n = 0; i != nodes.end(); i++, n++) {
+ size = SystemFont->size(i->GetCaption());
+ if (i->GetLine()) {
+ Shaper()->hline3d(GetAX() + i->GetX(), GetAX() + i->GetX() + GetW() - 4, GetAY() + i->GetY());
+ } else {
+ if (n == selected) {
+ Shaper()->box(GetAX() + 2, GetAY() + i->GetY(), GetAX() + GetW() - 2, GetAY() + i->GetY() + i->GetH(), DOS_MAGENTA);
+ }
+ Shaper()->text(GetAX() + i->GetX(), GetAY() + i->GetY(), i->GetCaption(), i->GetEnabled() ? BLACK : DOS_GRAY);
+ }
+ }
+}
+
+bool mogltk::widgets::ContextMenu::process_event(int xe, int ye, mogltk::event_t event) {
+ std::vector<node>::iterator i;
+ action * a;
+ int n;
+
+ selected = -1;
+
+ switch (event) {
+ case E_MOUSE_MOVE:
+ for (i = nodes.begin(), n = 0; i != nodes.end(); i++, n++) {
+ if (!i->GetLine()) {
+ int ax, ax2, ay, ay2;
+
+ ax = GetAX() + 2;
+ ay = GetAY() + i->GetY();
+ ax2 = GetAX() + GetW() - 2;
+ ay2 = GetAY() + i->GetY() + i->GetH();
+
+ if (!((xe < ax) || (xe > ax2) || (ye < ay) || (ye > ay2))) {
+ selected = n;
+ if (subselected) {
+ subselected->SetVisible(false);
+ subselected->selected = -1;
+ subselected->subselected = 0;
+ }
+ if ((subselected = i->GetSub())) {
+ subselected->SetVisible(true);
+ subselected->selected = -1;
+ subselected->subselected = 0;
+ }
+ }
+ }
+ }
+ 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);
+ in_click = false;
+ SetVisible(false);
+ return true;
+ }
+ }
+ in_click = true;
+ break;
+ case E_MOUSE_OUT:
+ selected = -1;
+ remove_out_move();
+ in_click = false;
+ return true;
+ case E_MOUSE_OUT_CLICK:
+ if (iin_click())
+ return true;
+ selected = -1;
+ subselected = 0;
+ SetVisible(false);
+ return true;
+ }
+
+ return false;
+}
+
+bool mogltk::widgets::ContextMenu::iin_click() {
+ if (in_click)
+ return true;
+
+ if (subselected)
+ return subselected->iin_click();
+
+ return false;
+}
+
+
+/********************
+* The Menu topframe *
+********************/
+
+mogltk::widgets::Menu::Menu(shape * sh, mogltk::widget * father) : widget(father, 0, 0, 0, 0, 0, "Menu", sh) {
+ rect r = father->GetDrawRect();
+ move(r.x, r.y);
+ resize(r.w, r.h);
+}
+
+void mogltk::widgets::Menu::resize_notify() {
+ rect r = Father()->GetDrawRect();
+ resize(r.w, r.h);
+}
+
+void mogltk::widgets::Menu::draw(void) {
+ Shaper()->box(GetAX(), GetAY(), GetAX2(), GetAY() + 16, BLUE);
+}
+
+bool mogltk::widgets::Menu::process_event(int mx, int my, mogltk::event_t event) {
+ return false;
+}
+
+
+/*
+ * The mainloop widget thing.
+ */
void mogltk::widget::mainloop() {
bool end_event_loop = false;
widget_mouse_event * mouse = new widget_mouse_event(this);
+ int mx, my;
while (!end_event_loop && !engine::quitrequested()) {
root->fulldraw();
- Shaper()->pixel(engine::mouseX(), engine::mouseY(), BLACK);
+ mx = mogltk::engine::mouseX();
+ my = mogltk::engine::mouseY();
+ mogltk::ColorP::Max.A = 50;
+ Sprite::Cursor->draw(mx - 6, my - 3, BLACK);
+ mogltk::ColorP::Max.A = 255;
+ Sprite::Cursor->draw(mx - 8, my - 6);
engine::base_o->Flip();
}
diff --git a/src/test.cc b/src/test.cc
index f197c87..45d758c 100644
--- a/src/test.cc
+++ b/src/test.cc
@@ -695,7 +695,27 @@ virtual int startup() throw (GeneralException) {
new mogltk::widgets::SmartBox(sh, w, 120, 50, 100, 100, "Test"),
12, 30, 50, 20, "Toto");
#endif
- new mogltk::widgets::MsgBox(sh, w, "Test", "Blablabla\nCeci est un test de la\nclasse MsgBox.");
+ new mogltk::widgets::Frame(sh, w, 10, 10, 600, 400);
+ //new mogltk::widgets::MsgBox(sh, w, "Test", "Blablabla\nCeci est un test de la\nclasse MsgBox.");
+
+ mogltk::widgets::ContextMenu * c = new mogltk::widgets::ContextMenu(sh, w, 20, 20), * c2;
+ mogltk::widget * sm;
+ mogltk::rect r;
+
+ sm = new mogltk::widgets::SmartBox(sh, w, 250, 300, 100, 70, "SmartBox");
+ r = sm->GetDrawRect();
+ new mogltk::widgets::Menu(sh, w);
+
+ c->addnode("Test", 0);
+ c->addnode("Test2", 0);
+ c->addline();
+ c->addnode("Test3", 0);
+ c->addnode("Test of a long entry", 0);
+
+ c2 = c->createsub("Sub");
+ c2->addnode("A sub", 0);
+ c2->createsub("subsub")->addnode("Toto", 0);
+ c2->SetEnabled(0, false);
w->mainloop();