diff options
| -rw-r--r-- | include/glwidgets.h | 32 | ||||
| -rw-r--r-- | include/widgets.h | 96 | ||||
| -rw-r--r-- | lib/engine.cc | 4 | ||||
| -rw-r--r-- | lib/glbase.cc | 4 | ||||
| -rw-r--r-- | lib/glwidgets.cc | 16 | ||||
| -rw-r--r-- | lib/widgets.cc | 308 | ||||
| -rw-r--r-- | src/test.cc | 12 | 
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  | 
