summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorpixel <pixel>2004-07-12 15:08:14 +0000
committerpixel <pixel>2004-07-12 15:08:14 +0000
commitbaac659433417ee555e3e04a28ea6c06fa23d588 (patch)
tree0bff5e30087de61b6dddbb3de30174e3222bcde2
parent5cc874802b0b8c4462e7e873654e6daa54be00de (diff)
Widget slowly working...
-rw-r--r--include/glwidgets.h32
-rw-r--r--include/widgets.h96
-rw-r--r--lib/engine.cc4
-rw-r--r--lib/glbase.cc4
-rw-r--r--lib/glwidgets.cc16
-rw-r--r--lib/widgets.cc308
-rw-r--r--src/test.cc12
7 files changed, 424 insertions, 48 deletions
diff --git a/include/glwidgets.h b/include/glwidgets.h
index b606a14..241dd55 100644
--- a/include/glwidgets.h
+++ b/include/glwidgets.h
@@ -1,15 +1,17 @@
-#ifndef __GLWIDGETS_H__
-#define __GLWIDGETS_H__
-
-#include <widgets.h>
-
-namespace mogltk {
- class glRoot : public Root {
- public:
- glRoot(shape *);
- protected:
- virtual void draw();
- };
-};
-
-#endif
+#ifndef __GLWIDGETS_H__
+#define __GLWIDGETS_H__
+
+#include <widgets.h>
+
+namespace mogltk {
+ namespace widgets {
+ class glRoot : public Root {
+ public:
+ glRoot(shape *);
+ protected:
+ virtual void draw();
+ };
+ };
+};
+
+#endif
diff --git a/include/widgets.h b/include/widgets.h
index bef2682..116eef5 100644
--- a/include/widgets.h
+++ b/include/widgets.h
@@ -5,6 +5,18 @@
#include <shape.h>
namespace mogltk {
+ enum event_t {
+ E_MOUSE_START_DRAG,
+ E_MOUSE_DRAG,
+ E_MOUSE_DRAG_OVER,
+ E_MOUSE_END_DRAG,
+ E_MOUSE_END_DRAG_OVER,
+ E_MOUSE_MOVE,
+ E_MOUSE_DOWN,
+ E_MOUSE_UP,
+ E_MOUSE_CLICK,
+ E_MOUSE_DBL_CLICK,
+ };
class widget : public Base {
public:
virtual ~widget();
@@ -18,34 +30,92 @@ namespace mogltk {
int GetAY();
int GetAX2();
int GetAY2();
+ widget * Father();
+ widget * Child();
+ widget * Next();
+ widget * Prev();
void fulldraw();
shape * Shaper();
+ void mainloop();
+ void m_event(int x, int y, event_t event);
+ bool inside(int x, int y);
protected:
widget(widget * father, int x, int y, int sx, int sy, int type, String name, shape *);
- virtual void draw() = 0;
+ virtual void draw();
+ String caption;
+ virtual bool process_event(int x, int y, event_t event);
+ void set_exclusive(widget *);
+ void unset_exclusive(widget *);
private:
void computeabs();
int x, y, sx, sy, ax, ay, ax2, ay2;
widget * father, * next, * prev, * child, * root;
static widget * focused;
int type;
- String name, caption;
+ String name;
shape * sh;
+ widget * exclusive;
void idraw();
+ bool ievent(int x, int y, event_t event);
+ void icomputeabs();
};
- class drawer : public Base {
- public:
- virtual void draw(widget *) = 0;
- };
+ namespace widgets {
+ class drawer : public Base {
+ public:
+ virtual void draw(widget *) = 0;
+ };
- class Root : public widget {
- public:
- Root(shape *, drawer * = 0);
- void setdrawer(drawer *);
- protected:
- virtual void draw();
- drawer * dr;
+ class action : public Base {
+ public:
+ virtual void do_action(widget *) = 0;
+ };
+
+ class Root : public widget {
+ public:
+ Root(shape *, drawer * = 0);
+ void setdrawer(drawer *);
+ protected:
+ virtual void draw();
+ drawer * dr;
+ };
+
+ class Button : public widget {
+ public:
+ Button(action *, shape *, widget * father, int x, int y, int w, int h, const String & caption);
+ protected:
+ virtual void draw();
+ virtual bool process_event(int, int, event_t);
+ bool bevel;
+ private:
+ bool dragging;
+ action * a;
+ };
+
+ class Label : public widget {
+ public:
+ Label(shape *, widget * father, int x, int y, int w, int h, const String & caption, const ColorP & color = BLACK);
+ protected:
+ virtual void draw();
+ private:
+ ColorP color;
+ };
+
+ class SmartBox : public widget {
+ public:
+ SmartBox(shape *, widget * father, int x, int y, int w, int h, const String & caption);
+ protected:
+ virtual void draw();
+ virtual bool process_event(int, int, event_t);
+ private:
+ int ox, oy, oax, oay;
+ };
+
+ class MsgBox : public SmartBox {
+ public:
+ MsgBox(shape *, widget * father, const String & caption, const String & text);
+ virtual ~MsgBox();
+ };
};
};
diff --git a/lib/engine.cc b/lib/engine.cc
index 34317b1..a52aa1b 100644
--- a/lib/engine.cc
+++ b/lib/engine.cc
@@ -66,8 +66,8 @@ class keyhandler_t : public mogltk::engine::keyevent {
mogltk::engine::mouseevent::mouseevent() {
new_handler = 0;
- old_handler = getmouseevent();
- old_handler->new_handler = this;
+ if ((old_handler = getmouseevent()))
+ old_handler->new_handler = this;
setmouseevent(this);
}
diff --git a/lib/glbase.cc b/lib/glbase.cc
index 9c33c54..22cbe3f 100644
--- a/lib/glbase.cc
+++ b/lib/glbase.cc
@@ -165,6 +165,7 @@ void mogltk::glbase::glVertex(GLdouble x, GLdouble y, GLdouble z, GLdouble w) {
}
void mogltk::glbase::changeviewport(int x, int y, unsigned int w, unsigned int h) {
+#if 0
if ((w == 0) && (h == 0)) {
w = GetWidth() - x;
h = GetHeight() - y;
@@ -174,6 +175,9 @@ void mogltk::glbase::changeviewport(int x, int y, unsigned int w, unsigned int h
glViewport(x, y, w, h);
if (!engine::base_o->is2D())
gluPerspective(fovy, ratio, 1.0, 1024.0);
+#endif
+ glScissor(x, GetHeight() - y - h - 1, w + 1, h + 1);
+ glEnable(GL_SCISSOR_TEST);
}
void mogltk::glbase::changefovy(GLdouble nfoyv) {
diff --git a/lib/glwidgets.cc b/lib/glwidgets.cc
index 511cdc4..3119831 100644
--- a/lib/glwidgets.cc
+++ b/lib/glwidgets.cc
@@ -1,8 +1,8 @@
-#include <SDL.h>
-#include <SDL_opengl.h>
-#include "mcolor.h"
-#include "glwidgets.h"
-
-void mogltk::glRoot::draw() {
- Shaper()->box(GetAX(), GetAY(), GetAX2(), GetAY2());
-}
+#include <SDL.h>
+#include <SDL_opengl.h>
+#include "mcolor.h"
+#include "glwidgets.h"
+
+void mogltk::widgets::glRoot::draw() {
+ Shaper()->box(GetAX(), GetAY(), GetAX2(), GetAY2());
+}
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 <SDL.h>
+ #include <SDL.h>
#include <Input.h>
#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;
+}
diff --git a/src/test.cc b/src/test.cc
index d19b5d8..66a2af4 100644
--- a/src/test.cc
+++ b/src/test.cc
@@ -569,7 +569,7 @@ virtual int startup() throw (GeneralException) {
mogltk::texture * sshot = 0, * plastex = new mogltk::texture(1024, 512);
int x, y, sx1, sx2, sy1, sy2, lastframe, curframe, px, py, lasttick = 0, curtick = 0, oldblend, seconds = 0, newseconds = 0;
double t = 0;
- verbosity = M_ERROR;
+ verbosity = M_INFO;
String str;
bool got_transit = false;
Uint8 * plasma = (Uint8 *) malloc(640 * 480), * pplasma;
@@ -642,8 +642,8 @@ virtual int startup() throw (GeneralException) {
mogltk::glSprite * eG1 = new mogltk::glSprite(&Input("elkyaG1.raw"), 53, 100);
mogltk::glSprite * eM1 = new mogltk::glSprite(&Input("elkyaM1.raw"), 53, 100);
// mogltk::glSprite * spr = new mogltk::glSprite(&Input("test.raw"), 200, 200);
- mogltk::widget * w = new mogltk::Root(sh);
#endif
+ mogltk::widget * w = new mogltk::widgets::Root(sh);
#else
mogltk::base * gl = new mogltk::base();
mogltk::shape * sh = new mogltk::shape();
@@ -686,6 +686,14 @@ virtual int startup() throw (GeneralException) {
px = 200;
py = 350;
#endif
+#if 0
+ new mogltk::widgets::Button(0, sh,
+ 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.");
+
+ w->mainloop();
while (!mogltk::engine::quitrequested()) {
#if 0