diff options
-rw-r--r-- | include/widgets.h | 534 | ||||
-rw-r--r-- | lib/glbase.cc | 534 | ||||
-rw-r--r-- | lib/widgets.cc | 2317 |
3 files changed, 1720 insertions, 1665 deletions
diff --git a/include/widgets.h b/include/widgets.h index 7a919f4..600bcec 100644 --- a/include/widgets.h +++ b/include/widgets.h @@ -1,263 +1,271 @@ -/* - * mogltk - * Copyright (C) 1999-2004 Nicolas "Pixel" Noble - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -/* $Id: widgets.h,v 1.6 2004-07-17 10:08:16 pixel Exp $ */ - -#ifndef __WIDGETS_H__ -#define __WIDGETS_H__ - -#include <Exceptions.h> -#include <shape.h> -#include <base.h> - -namespace mogltk { - enum event_t { - E_TIMER, - 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_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(); - virtual void move(int x, int y); - virtual void resize(int sx, int sy); - int GetX(); - int GetY(); - int GetH(); - int GetW(); - int GetAX(); - int GetAY(); - int GetAX2(); - int GetAY2(); - virtual mogltk::rect GetDrawRect(); - 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); - bool GetVisible(); - virtual void SetVisible(bool); - bool GetEnabled(); - virtual void SetEnabled(bool); - void MoveOnTop(); - static void check_timed_events(); - protected: - widget(widget * father, int x, int y, int sx, int sy, int type, String name, shape *); - virtual void draw(); - 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(); - void set_timed_event(Uint32); - void set_absolute_timed_event(Uint32); - String caption; - private: - int x, y, sx, sy, ax, ay, ax2, ay2; - widget * father, * next, * prev, * child, * last, * root; - static widget * focused; - int type; - String name; - shape * sh; - widget * exclusive; - bool visible; - bool enabled; - class timed_event { - public: - timed_event(widget * _w, Uint32 _t) : w(_w), t(_t) { } - widget * w; - Uint32 t; - }; - static std::vector<timed_event> timed_events; - - void computeabs(); - void idraw(); - bool ievent(int x, int y, event_t event); - void icomputeabs(); - void iresize_notify(); - }; - - namespace widgets { - class drawer : public Base { - public: - virtual void draw(widget *) = 0; - }; - - 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); - virtual rect GetDrawRect(); - 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(); - }; - - 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); - void StickyDisplay(); - 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, sticky; - - bool iin_click(); - }; - - class Menu : public widget { - public: - Menu(shape *, widget * father); - void addnode(const String &, action *); - void addsub(const String &, ContextMenu * sub); - ContextMenu * createsub(const String &); - virtual void SetEnabled(int i, bool); - void SetCaption(int i, const String &); - protected: - virtual void resize_notify(); - virtual void draw(); - virtual bool process_event(int, int, event_t); - class node : public Base { - public: - node(const String & caption, ContextMenu * sub, action * a, int x); - String GetCaption(); - void SetCaption(const String &); - ContextMenu * GetSub(); - action * GetAction(); - int GetX(); - bool GetEnabled(); - void SetEnabled(bool); - private: - String caption; - ContextMenu * sub; - action * a; - int x; - bool enabled; - }; - private: - std::vector<node> nodes; - int cur_x; - int selected; - }; - }; -}; - -#endif +/*
+ * mogltk
+ * Copyright (C) 1999-2004 Nicolas "Pixel" Noble
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/* $Id: widgets.h,v 1.7 2004-10-19 01:27:29 pixel Exp $ */
+
+#ifndef __WIDGETS_H__
+#define __WIDGETS_H__
+
+#include <Exceptions.h>
+#include <shape.h>
+#include <base.h>
+
+namespace mogltk {
+ enum event_t {
+ E_TIMER,
+ 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_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();
+ virtual void move(int x, int y);
+ virtual void resize(int sx, int sy);
+ int GetX();
+ int GetY();
+ int GetH();
+ int GetW();
+ int GetAX();
+ int GetAY();
+ int GetAX2();
+ int GetAY2();
+ virtual mogltk::rect GetDrawRect();
+ widget * Father();
+ widget * Child();
+ widget * Next();
+ widget * Prev();
+ widget * InnerPanel();
+ virtual widget * find_widget(int x, int y);
+ void fulldraw();
+ shape * Shaper();
+ 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);
+ void MoveOnTop();
+ static void check_timed_events();
+ protected:
+ widget(widget * father, int x, int y, int sx, int sy, int type, String name, shape *);
+ virtual void draw();
+ virtual bool process_event(int x, int y, event_t event);
+ virtual void resize_notify();
+ virtual widget * create_panel();
+ void set_exclusive(widget *);
+ void unset_exclusive(widget *);
+ void add_out_move();
+ void remove_out_move();
+ void add_out_click();
+ void remove_out_click();
+ void set_timed_event(Uint32);
+ void set_absolute_timed_event(Uint32);
+ String caption;
+ private:
+ int x, y, sx, sy, ax, ay, ax2, ay2;
+ widget * father, * next, * prev, * child, * last, * root, * panel;
+ static widget * focused;
+ int type;
+ String name;
+ shape * sh;
+ widget * exclusive;
+ bool visible;
+ bool enabled;
+ class timed_event {
+ public:
+ timed_event(widget * _w, Uint32 _t) : w(_w), t(_t) { }
+ widget * w;
+ Uint32 t;
+ };
+ static std::vector<timed_event> timed_events;
+
+ void computeabs();
+ void idraw();
+ bool ievent(int x, int y, event_t event);
+ void icomputeabs();
+ void iresize_notify();
+ };
+
+ namespace widgets {
+ class drawer : public Base {
+ public:
+ virtual void draw(widget *) = 0;
+ };
+
+ 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 Panel : public widget {
+ public:
+ Panel(shape *, widget * father, int x, int y, int w, int h);
+ };
+
+ 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);
+ virtual rect GetDrawRect();
+ 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();
+ };
+
+ 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);
+ void StickyDisplay();
+ 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, sticky;
+
+ bool iin_click();
+ };
+
+ class Menu : public widget {
+ public:
+ Menu(shape *, widget * father);
+ void addnode(const String &, action *);
+ void addsub(const String &, ContextMenu * sub);
+ ContextMenu * createsub(const String &);
+ virtual void SetEnabled(int i, bool);
+ void SetCaption(int i, const String &);
+ protected:
+ virtual void resize_notify();
+ virtual void draw();
+ virtual bool process_event(int, int, event_t);
+ class node : public Base {
+ public:
+ node(const String & caption, ContextMenu * sub, action * a, int x);
+ String GetCaption();
+ void SetCaption(const String &);
+ ContextMenu * GetSub();
+ action * GetAction();
+ int GetX();
+ bool GetEnabled();
+ void SetEnabled(bool);
+ private:
+ String caption;
+ ContextMenu * sub;
+ action * a;
+ int x;
+ bool enabled;
+ };
+ private:
+ std::vector<node> nodes;
+ int cur_x;
+ int selected;
+ };
+ };
+};
+
+#endif
diff --git a/lib/glbase.cc b/lib/glbase.cc index cbb1927..abd3f1e 100644 --- a/lib/glbase.cc +++ b/lib/glbase.cc @@ -1,267 +1,267 @@ -/* - * mogltk - * Copyright (C) 1999-2004 Nicolas "Pixel" Noble - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -/* $Id: glbase.cc,v 1.20 2004-07-17 10:08:16 pixel Exp $ */ - -#include <stdio.h> -#include <SDL.h> -#include <SDL_opengl.h> -#include <Output.h> -#include <Handle.h> -#include "glbase.h" -#include "engine.h" -#include "generic.h" -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -mogltk::glbase::glbase(int w, int h, int flags) throw (GeneralException) : mogltk::base(w, h, flags, 0), twoD(0), fovy(60.0) { - SDL_Surface * surface; - GLint bits; - - mogltk::engine::setup(); - if (SDL_InitSubSystem(SDL_INIT_VIDEO) < 0) { - throw GeneralException(String("Couldn't initialise Video SubSystem: ") + SDL_GetError()); - } - -#if 1 - SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8); - SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8); - SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8); -// SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 32); - SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 8); - SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); - SDL_GL_SetAttribute(SDL_GL_ACCUM_RED_SIZE, 8); - SDL_GL_SetAttribute(SDL_GL_ACCUM_GREEN_SIZE, 8); - SDL_GL_SetAttribute(SDL_GL_ACCUM_BLUE_SIZE, 8); -#endif - if (!(surface = SDL_SetVideoMode(w, h, 0, flags | SDL_OPENGL | SDL_HWSURFACE))) { - throw GeneralException(String("Couldn't set GL mode: ") + SDL_GetError()); - } - - mogltk::engine::glbase_o = this; - mogltk::engine::base_o = this; - - ratio = (GLdouble) surface->w / surface->h; - - glGetIntegerv(GL_STENCIL_BITS, &bits); - - printm(M_INFO, "Video resolution: %dx%dx%d (ratio = %3.2f)\n", surface->w, surface->h, surface->format->BitsPerPixel, ratio); - printm(M_INFO, "\n"); - printm(M_INFO, "OpenGL infos\n"); - printm(M_INFO, "------------\n"); - printm(M_INFO, String("Vendor : ") + (char *) glGetString(GL_VENDOR) + "\n"); - printm(M_INFO, String("Renderer : ") + (char *) glGetString(GL_RENDERER) + "\n"); - printm(M_INFO, String("Version : ") + (char *) glGetString(GL_VERSION) + "\n"); - printm(M_INFO, String("Extensions: ") + (char *) glGetString(GL_EXTENSIONS) + "\n"); - - glViewport(0, 0, surface->w, surface->h); - - glCullFace(GL_BACK); - glFrontFace(GL_CCW); - glEnable(GL_CULL_FACE); - - glClearColor(0, 0, 0, 0); - glShadeModel(GL_SMOOTH); - - glEnable(GL_DEPTH_TEST); - glDepthFunc(GL_LEQUAL); - glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); - - glMatrixMode(GL_PROJECTION); - glLoadIdentity(); - gluPerspective(fovy, ratio, 1.0, 1024.0); - - glMatrixMode(GL_MODELVIEW); - glLoadIdentity(); - - glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); - - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - - SDL_GL_SwapBuffers(); - SDL_ShowCursor(SDL_DISABLE); - - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - - setsurface(surface); - mogltk::engine::postsetup(); -} - -mogltk::glbase::~glbase() { -} - -void mogltk::glbase::Enter2DMode(void) { - if (twoD) - return; - - glPushAttrib(GL_ENABLE_BIT); - glDisable(GL_DEPTH_TEST); - glDisable(GL_CULL_FACE); - glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - - glMatrixMode(GL_PROJECTION); - glPushMatrix(); - glLoadIdentity(); - glOrtho(0.0, GetWidth(), GetHeight(), 0.0, 0.0, 1.0); - - glMatrixMode(GL_MODELVIEW); - glPushMatrix(); - glLoadIdentity(); - - twoD = 1; -} - -void mogltk::glbase::Leave2DMode(void) { - if (!twoD) - return; - - glMatrixMode(GL_MODELVIEW); - glPopMatrix(); - glMatrixMode(GL_PROJECTION); - glPopMatrix(); - - glPopAttrib(); - - twoD = 0; -} - -void mogltk::glbase::Flip(bool clear) { - mogltk::engine::pollevents(); - SDL_GL_SwapBuffers(); - if (clear) - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); -} - -bool mogltk::glbase::is2D() { - return twoD; -} - -void mogltk::glbase::glVertex(GLshort x, GLshort y, GLshort z, GLshort w) { -#ifdef DEBUG - printm(M_INFO, "Calling glVertex(%i, %i, %i, %i) (shorts)\n", x, y, z, w); -#endif - glVertex4i(x, y, z, w); -} - -void mogltk::glbase::glVertex(GLint x, GLint y, GLint z, GLint w) { -#ifdef DEBUG - printm(M_INFO, "Calling glVertex(%i, %i, %i, %i) (ints)\n", x, y, z, w); -#endif - glVertex4i(x, y, z, w); -} - -void mogltk::glbase::glVertex(GLfloat x, GLfloat y, GLfloat z, GLfloat w) { -#ifdef DEBUG - printm(M_INFO, "Calling glVertex(%f, %f, %f, %f) (floats)\n", x, y, z, w); -#endif - glVertex4f(x, y, z, w); -} - -void mogltk::glbase::glVertex(GLdouble x, GLdouble y, GLdouble z, GLdouble w) { -#ifdef DEBUG - printm(M_INFO, "Calling glVertex(%f, %f, %f, %f) (doubles)\n", x, y, z, w); -#endif - glVertex4d(x, y, z, 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; - } - - ratio = (GLdouble) w / 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) { - fovy = nfoyv; - if (!engine::base_o->is2D()) - gluPerspective(fovy, ratio, 1.0, 1024.0); -} - -inline static unsigned int nextpower(unsigned int n) { - unsigned int i; - - if (!n) - return n; - - if (ISPOT(n)) - return n; - - for (i = 31; i >= 0; i--) { - if ((n >> i) & 1) { - return 1 << (i + 1); - } - } -} - -mogltk::texture * mogltk::glbase::GrabTexture() { - int w = nextpower(GetWidth()); - int h = nextpower(GetHeight()); - texture * r = new texture(w, h); - SDL_Surface * t; - - t = GrabSurface(); - SDL_BlitSurface(t, NULL, r->GetSurface(), NULL); - SDL_FreeSurface(t); - - return r; -} - -SDL_Surface * mogltk::glbase::GrabSurface() { - int i; - SDL_Surface * r; - Uint8 * pixels = (Uint8 *) malloc(GetWidth() * GetHeight() * 3); - Uint8 * s, * d; - - glReadPixels(0, 0, GetWidth(), GetHeight(), GL_RGB, GL_UNSIGNED_BYTE, pixels); - - r = SDL_CreateRGBSurface(SDL_SWSURFACE, GetWidth(), GetHeight(), 24, -#if SDL_BYTEORDER == SDL_BIG_ENDIAN - 0xff000000, - 0x00ff0000, - 0x0000ff00, - 0x00000000 -#else - 0x000000ff, - 0x0000ff00, - 0x00ff0000, - 0x00000000 -#endif - ); - - for (i = 0; i < GetHeight(); i++) { - s = pixels + i * GetWidth() * 3; - d = ((Uint8 *) r->pixels) + (GetHeight() - i - 1) * GetWidth() * 3; - memcpy(d, s, GetWidth() * 3); - } - - free(pixels); - - return r; -} +/*
+ * mogltk
+ * Copyright (C) 1999-2004 Nicolas "Pixel" Noble
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/* $Id: glbase.cc,v 1.21 2004-10-19 01:27:30 pixel Exp $ */
+
+#include <stdio.h>
+#include <SDL.h>
+#include <SDL_opengl.h>
+#include <Output.h>
+#include <Handle.h>
+#include "glbase.h"
+#include "engine.h"
+#include "generic.h"
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+mogltk::glbase::glbase(int w, int h, int flags) throw (GeneralException) : mogltk::base(w, h, flags, 0), twoD(0), fovy(60.0) {
+ SDL_Surface * surface;
+ GLint bits;
+
+ mogltk::engine::setup();
+ if (SDL_InitSubSystem(SDL_INIT_VIDEO) < 0) {
+ throw GeneralException(String("Couldn't initialise Video SubSystem: ") + SDL_GetError());
+ }
+
+#if 1
+ SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8);
+ SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8);
+ SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8);
+// SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 32);
+ SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 8);
+ SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
+ SDL_GL_SetAttribute(SDL_GL_ACCUM_RED_SIZE, 8);
+ SDL_GL_SetAttribute(SDL_GL_ACCUM_GREEN_SIZE, 8);
+ SDL_GL_SetAttribute(SDL_GL_ACCUM_BLUE_SIZE, 8);
+#endif
+ if (!(surface = SDL_SetVideoMode(w, h, 0, flags | SDL_OPENGL | SDL_HWSURFACE))) {
+ throw GeneralException(String("Couldn't set GL mode: ") + SDL_GetError());
+ }
+
+ mogltk::engine::glbase_o = this;
+ mogltk::engine::base_o = this;
+
+ ratio = (GLdouble) surface->w / surface->h;
+
+ glGetIntegerv(GL_STENCIL_BITS, &bits);
+
+ printm(M_INFO, "Video resolution: %dx%dx%d (ratio = %3.2f)\n", surface->w, surface->h, surface->format->BitsPerPixel, ratio);
+ printm(M_INFO, "\n");
+ printm(M_INFO, "OpenGL infos\n");
+ printm(M_INFO, "------------\n");
+ printm(M_INFO, String("Vendor : ") + (char *) glGetString(GL_VENDOR) + "\n");
+ printm(M_INFO, String("Renderer : ") + (char *) glGetString(GL_RENDERER) + "\n");
+ printm(M_INFO, String("Version : ") + (char *) glGetString(GL_VERSION) + "\n");
+ printm(M_INFO, String("Extensions: ") + (char *) glGetString(GL_EXTENSIONS) + "\n");
+
+ glViewport(0, 0, surface->w, surface->h);
+
+ glCullFace(GL_BACK);
+ glFrontFace(GL_CCW);
+ glEnable(GL_CULL_FACE);
+
+ glClearColor(0, 0, 0, 0);
+ glShadeModel(GL_SMOOTH);
+
+ glEnable(GL_DEPTH_TEST);
+ glDepthFunc(GL_LEQUAL);
+ glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
+
+ glMatrixMode(GL_PROJECTION);
+ glLoadIdentity();
+ gluPerspective(fovy, ratio, 1.0, 1024.0);
+
+ glMatrixMode(GL_MODELVIEW);
+ glLoadIdentity();
+
+ glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
+
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+
+ SDL_GL_SwapBuffers();
+ SDL_ShowCursor(SDL_DISABLE);
+
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+
+ setsurface(surface);
+ mogltk::engine::postsetup();
+}
+
+mogltk::glbase::~glbase() {
+}
+
+void mogltk::glbase::Enter2DMode(void) {
+ if (twoD)
+ return;
+
+ glPushAttrib(GL_ENABLE_BIT);
+ glDisable(GL_DEPTH_TEST);
+ glDisable(GL_CULL_FACE);
+ glEnable(GL_BLEND);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+
+ glMatrixMode(GL_PROJECTION);
+ glPushMatrix();
+ glLoadIdentity();
+ glOrtho(0.0, GetWidth(), GetHeight(), 0.0, 0.0, 1.0);
+
+ glMatrixMode(GL_MODELVIEW);
+ glPushMatrix();
+ glLoadIdentity();
+
+ twoD = 1;
+}
+
+void mogltk::glbase::Leave2DMode(void) {
+ if (!twoD)
+ return;
+
+ glMatrixMode(GL_MODELVIEW);
+ glPopMatrix();
+ glMatrixMode(GL_PROJECTION);
+ glPopMatrix();
+
+ glPopAttrib();
+
+ twoD = 0;
+}
+
+void mogltk::glbase::Flip(bool clear) {
+ mogltk::engine::pollevents();
+ SDL_GL_SwapBuffers();
+ if (clear)
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+}
+
+bool mogltk::glbase::is2D() {
+ return twoD;
+}
+
+void mogltk::glbase::glVertex(GLshort x, GLshort y, GLshort z, GLshort w) {
+#ifdef DEBUG
+ printm(M_INFO, "Calling glVertex(%i, %i, %i, %i) (shorts)\n", x, y, z, w);
+#endif
+ glVertex4i(x, y, z, w);
+}
+
+void mogltk::glbase::glVertex(GLint x, GLint y, GLint z, GLint w) {
+#ifdef DEBUG
+ printm(M_INFO, "Calling glVertex(%i, %i, %i, %i) (ints)\n", x, y, z, w);
+#endif
+ glVertex4i(x, y, z, w);
+}
+
+void mogltk::glbase::glVertex(GLfloat x, GLfloat y, GLfloat z, GLfloat w) {
+#ifdef DEBUG
+ printm(M_INFO, "Calling glVertex(%f, %f, %f, %f) (floats)\n", x, y, z, w);
+#endif
+ glVertex4f(x, y, z, w);
+}
+
+void mogltk::glbase::glVertex(GLdouble x, GLdouble y, GLdouble z, GLdouble w) {
+#ifdef DEBUG
+ printm(M_INFO, "Calling glVertex(%f, %f, %f, %f) (doubles)\n", x, y, z, w);
+#endif
+ glVertex4d(x, y, z, 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;
+ }
+
+ ratio = (GLdouble) w / 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) {
+ fovy = nfoyv;
+ if (!engine::base_o->is2D())
+ gluPerspective(fovy, ratio, 1.0, 1024.0);
+}
+
+inline static unsigned int nextpower(unsigned int n) {
+ unsigned int i;
+
+ if (!n)
+ return n;
+
+ if (ISPOT(n))
+ return n;
+
+ for (i = 31; i >= 0; i--) {
+ if ((n >> i) & 1) {
+ return 1 << (i + 1);
+ }
+ }
+}
+
+mogltk::texture * mogltk::glbase::GrabTexture() {
+ int w = nextpower(GetWidth());
+ int h = nextpower(GetHeight());
+ texture * r = new texture(w, h);
+ SDL_Surface * t;
+
+ t = GrabSurface();
+ SDL_BlitSurface(t, NULL, r->GetSurface(), NULL);
+ SDL_FreeSurface(t);
+
+ return r;
+}
+
+SDL_Surface * mogltk::glbase::GrabSurface() {
+ int i;
+ SDL_Surface * r;
+ Uint8 * pixels = (Uint8 *) malloc(GetWidth() * GetHeight() * 3);
+ Uint8 * s, * d;
+
+ glReadPixels(0, 0, GetWidth(), GetHeight(), GL_RGB, GL_UNSIGNED_BYTE, pixels);
+
+ r = SDL_CreateRGBSurface(SDL_SWSURFACE, GetWidth(), GetHeight(), 24,
+#if SDL_BYTEORDER == SDL_BIG_ENDIAN
+ 0xff000000,
+ 0x00ff0000,
+ 0x0000ff00,
+ 0x00000000
+#else
+ 0x000000ff,
+ 0x0000ff00,
+ 0x00ff0000,
+ 0x00000000
+#endif
+ );
+
+ for (i = 0; i < GetHeight(); i++) {
+ s = pixels + i * GetWidth() * 3;
+ d = ((Uint8 *) r->pixels) + (GetHeight() - i - 1) * GetWidth() * 3;
+ memcpy(d, s, GetWidth() * 3);
+ }
+
+ free(pixels);
+
+ return r;
+}
diff --git a/lib/widgets.cc b/lib/widgets.cc index 9d62bd9..c70ad95 100644 --- a/lib/widgets.cc +++ b/lib/widgets.cc @@ -1,1135 +1,1182 @@ -/* - * mogltk - * Copyright (C) 1999-2004 Nicolas "Pixel" Noble - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -/* $Id: widgets.cc,v 1.8 2004-07-17 10:08:16 pixel Exp $ */ - -#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" -#endif - -#include "gettext.h" - -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: - 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) { - 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 - mx); - dy = ABS(mouse_y_down - my); - - 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(mx, my, mogltk::E_MOUSE_DRAG_OVER); - } - - printm(M_INFO, "mouse_drag\n"); - // generate a mouse_drag event - root->m_event(mx, my, mogltk::E_MOUSE_DRAG); - mouse_drag = true; - } else { - printm(M_INFO, "mouse_move\n"); - 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 = mx; - mouse_y_down = my; - mouse_down = true; - 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) { - mouse_drag = false; - printm(M_INFO, "mouse_end_drag\n"); - 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(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(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(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(mx, my, 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), prev(0), child(0), last(0), type(_type), name(_name), sh(_sh), exclusive(0), visible(true), enabled(true) { - if (!father) { - root = this; - father = this; - next = 0; - x = 0; - y = 0; - sx = engine::base_o->GetWidth(); - sy = engine::base_o->GetHeight(); - } else { - next = father->child; - if (next) - next->prev = this; - if (!father->last) - father->last = this; - father->child = this; - root = father->root; - } - - computeabs(); -} - -mogltk::widget::~widget() { - while(child) - delete child; - - if (prev) - prev->next = next; - else - father->child = next; - - if (next) - next->prev = prev; - else - father->last = prev; -} - -void mogltk::widget::computeabs() { - if (father != this) { - ax = father->ax + x; - ay = father->ay + y; - } else { - ax = x; - ay = y; - } - ax2 = ax + sx; - ay2 = ay + sy; -} - -void mogltk::widget::move(int nx, int ny) { - x = nx; - y = ny; - - computeabs(); - - if (child) - child->icomputeabs(); -} - -void mogltk::widget::resize(int nsx, int nsy) { - sx = nsx; - sy = nsy; - - ax2 = ax + sx; - ay2 = ay + sy; - - iresize_notify(); -} - -int mogltk::widget::GetX() { - return x; -} - -int mogltk::widget::GetY() { - return y; -} - -int mogltk::widget::GetH() { - return sy; -} - -int mogltk::widget::GetW() { - return sx; -} - -int mogltk::widget::GetAX() { - return ax; -} - -int mogltk::widget::GetAY() { - return ay; -} - -int mogltk::widget::GetAX2() { - return ax2; -} - -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; -} - -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; -} - -void mogltk::widget::fulldraw() { - bool was2D = true; - - if (mogltk::engine::glbase_o) - if (!(was2D = mogltk::engine::glbase_o->is2D())) - mogltk::engine::glbase_o->Enter2DMode(); - - texture::Unbind(); - mogltk::ColorP::Max = WHITE; - mogltk::ColorP::Min = BLACK; - mogltk::ColorP::Min.A = 0; - - root->idraw(); - - if (!was2D) - mogltk::engine::glbase_o->Leave2DMode(); -} - -void mogltk::widget::idraw() { - int x1, y1, x2, y2; - - if (next) - next->idraw(); - - if (!visible) - return; - - x1 = MAX(GetAX(), father->GetAX()); - y1 = MAX(GetAY(), father->GetAY()); - - x2 = MIN(GetAX2(), father->GetAX2()); - y2 = MIN(GetAY2(), father->GetAY2()); - - engine::base_o->changeviewport(x1, y1, x2 - x1, y2 - y1); - - draw(); - - if (child) - child->idraw(); -} - -bool mogltk::widget::inside(int xe, int ye) { - if (!visible) - return false; - 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: - case E_MOUSE_OUT: - case E_MOUSE_OUT_CLICK: - process_event(x, y, event); - break; - default: - ievent(x, y, event); - } -} - -bool mogltk::widget::ievent(int xe, int ye, mogltk::event_t event) { - if (prev) - if (prev->ievent(xe, ye, event)) - return true; - - if (!inside(xe, ye)) - return false; - - if (exclusive) - return exclusive->ievent(xe, ye, event); - - if (last) - if (last->ievent(xe, ye, event)) - return true; - - if (!enabled || !visible) - return false; - - 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::resize_notify() { -} - -void mogltk::widget::icomputeabs() { - computeabs(); - - if (next) - next->computeabs(); - - if (child) - child->computeabs(); -} - -void mogltk::widget::iresize_notify() { - if (child) - child->iresize_notify(); -} - -void mogltk::widget::set_exclusive(mogltk::widget * w) { - w->exclusive = this; -} - -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::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; - - 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; - } - } -} - -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. - */ - -/*************** -* 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) - delete engine::root; - engine::root = this; -} - -void mogltk::widgets::Root::draw() { - if (dr) - dr->draw(this); - else - Shaper()->box(GetAX(), GetAY(), GetAX2(), GetAY2()); -} - -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; -} - -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; -} - - -/********************** -* 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; -} - -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); - MoveOnTop(); - return true; - } - 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) { } - 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()); -} - - -/***************** -* 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; -} - -void mogltk::widgets::Label::draw() { - Shaper()->text(GetAX(), GetAY(), caption, color); -} - - -/************************* -* 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), sticky(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) { - if (!visible && sticky) - return; - widget::SetVisible(visible); - if (!visible && subselected) { - subselected->SetVisible(false); - } - - if (visible) { - add_out_click(); - MoveOnTop(); - } -} - -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; - 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; - - switch (event) { - case E_MOUSE_MOVE: - sticky = false; - selected = -1; - 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_DOWN: - 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::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; -} - -void mogltk::widgets::Menu::node::SetCaption(const String & s) { - caption = s; -} - -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); -} - -void mogltk::widgets::Menu::resize_notify() { - rect r = Father()->GetDrawRect(); - 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::SetCaption(int i, const String & s) { - nodes[i].SetCaption(s); -} - -void mogltk::widgets::Menu::draw(void) { - 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; -} - - -/* - * 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(); - 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(); - widget::check_timed_events(); - } - - delete mouse; -} +/*
+ * mogltk
+ * Copyright (C) 1999-2004 Nicolas "Pixel" Noble
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/* $Id: widgets.cc,v 1.9 2004-10-19 01:27:30 pixel Exp $ */
+
+#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"
+#endif
+
+#include "gettext.h"
+
+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:
+ 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) {
+ 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 - mx);
+ dy = ABS(mouse_y_down - my);
+
+ 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(mx, my, mogltk::E_MOUSE_DRAG_OVER);
+ }
+
+ printm(M_INFO, "mouse_drag\n");
+ // generate a mouse_drag event
+ root->m_event(mx, my, mogltk::E_MOUSE_DRAG);
+ mouse_drag = true;
+ } else {
+ printm(M_INFO, "mouse_move\n");
+ 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 = mx;
+ mouse_y_down = my;
+ mouse_down = true;
+ 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) {
+ mouse_drag = false;
+ printm(M_INFO, "mouse_end_drag\n");
+ 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(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(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(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(mx, my, 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), prev(0), child(0), last(0), panel(0), type(_type), name(_name), sh(_sh), exclusive(0), visible(true), enabled(true) {
+ if (!father) {
+ root = this;
+ father = this;
+ next = 0;
+ x = 0;
+ y = 0;
+ sx = engine::base_o->GetWidth();
+ sy = engine::base_o->GetHeight();
+ } else {
+ next = father->child;
+ if (next)
+ next->prev = this;
+ if (!father->last)
+ father->last = this;
+ father->child = this;
+ root = father->root;
+ }
+
+ computeabs();
+}
+
+mogltk::widget::~widget() {
+ while(child)
+ delete child;
+
+ if (prev)
+ prev->next = next;
+ else
+ father->child = next;
+
+ if (next)
+ next->prev = prev;
+ else
+ father->last = prev;
+}
+
+void mogltk::widget::computeabs() {
+ if (father != this) {
+ ax = father->ax + x;
+ ay = father->ay + y;
+ } else {
+ ax = x;
+ ay = y;
+ }
+ ax2 = ax + sx;
+ ay2 = ay + sy;
+}
+
+void mogltk::widget::move(int nx, int ny) {
+ x = nx;
+ y = ny;
+
+ computeabs();
+
+ if (child)
+ child->icomputeabs();
+}
+
+void mogltk::widget::resize(int nsx, int nsy) {
+ sx = nsx;
+ sy = nsy;
+
+ ax2 = ax + sx;
+ ay2 = ay + sy;
+
+ if (child)
+ child->iresize_notify();
+}
+
+int mogltk::widget::GetX() {
+ return x;
+}
+
+int mogltk::widget::GetY() {
+ return y;
+}
+
+int mogltk::widget::GetH() {
+ return sy;
+}
+
+int mogltk::widget::GetW() {
+ return sx;
+}
+
+int mogltk::widget::GetAX() {
+ return ax;
+}
+
+int mogltk::widget::GetAY() {
+ return ay;
+}
+
+int mogltk::widget::GetAX2() {
+ return ax2;
+}
+
+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;
+}
+
+mogltk::widget * mogltk::widget::Child() {
+ return child;
+}
+
+mogltk::widget * mogltk::widget::Next() {
+ return next;
+}
+
+mogltk::widget * mogltk::widget::Prev() {
+ return prev;
+}
+
+mogltk::widget * mogltk::widget::InnerPanel() {
+ if (!panel)
+ panel = create_panel();
+ return panel;
+}
+
+mogltk::widget * mogltk::widget::find_widget(int _x, int _y) {
+ widget * r = 0;
+
+ if (visible && enabled && (_x >= ax) && (_y >= ay) && (_x <= ax2) && (_y <= ay2)) {
+ if (child)
+ r = child->find_widget(_x, _y);
+ if (!r)
+ r = this;
+ }
+
+ if (!r && next) {
+ r = next->find_widget(_x, _y);
+ }
+
+ return r;
+}
+
+mogltk::shape * mogltk::widget::Shaper() {
+ return sh;
+}
+
+void mogltk::widget::fulldraw() {
+ bool was2D = true;
+
+ if (mogltk::engine::glbase_o)
+ if (!(was2D = mogltk::engine::glbase_o->is2D()))
+ mogltk::engine::glbase_o->Enter2DMode();
+
+ texture::Unbind();
+ mogltk::ColorP::Max = WHITE;
+ mogltk::ColorP::Min = BLACK;
+ mogltk::ColorP::Min.A = 0;
+
+ root->idraw();
+
+ if (!was2D)
+ mogltk::engine::glbase_o->Leave2DMode();
+}
+
+void mogltk::widget::idraw() {
+ int x1, y1, x2, y2;
+
+ if (next)
+ next->idraw();
+
+ if (!visible)
+ return;
+
+ x1 = MAX(GetAX(), father->GetAX());
+ y1 = MAX(GetAY(), father->GetAY());
+
+ x2 = MIN(GetAX2(), father->GetAX2());
+ y2 = MIN(GetAY2(), father->GetAY2());
+
+ engine::base_o->changeviewport(x1, y1, x2 - x1, y2 - y1);
+
+ draw();
+
+ if (child)
+ child->idraw();
+}
+
+bool mogltk::widget::inside(int xe, int ye) {
+ if (!visible)
+ return false;
+ 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:
+ case E_MOUSE_OUT:
+ case E_MOUSE_OUT_CLICK:
+ process_event(x, y, event);
+ break;
+ default:
+ ievent(x, y, event);
+ }
+}
+
+bool mogltk::widget::ievent(int xe, int ye, mogltk::event_t event) {
+ if (prev)
+ if (prev->ievent(xe, ye, event))
+ return true;
+
+ if (!inside(xe, ye))
+ return false;
+
+ if (exclusive)
+ return exclusive->ievent(xe, ye, event);
+
+ if (last)
+ if (last->ievent(xe, ye, event))
+ return true;
+
+ if (!enabled || !visible)
+ return false;
+
+ 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::resize_notify() {
+}
+
+mogltk::widget * mogltk::widget::create_panel() {
+ mogltk::rect r = GetDrawRect();
+ return new widgets::Panel(Shaper(), this, r.x, r.y, r.w, r.h);
+}
+
+void mogltk::widget::icomputeabs() {
+ computeabs();
+
+ if (next)
+ next->computeabs();
+
+ if (child)
+ child->computeabs();
+}
+
+void mogltk::widget::iresize_notify() {
+ if (next)
+ next->iresize_notify();
+ if (child)
+ child->iresize_notify();
+ resize_notify();
+}
+
+void mogltk::widget::set_exclusive(mogltk::widget * w) {
+ w->exclusive = this;
+}
+
+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::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;
+
+ 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;
+ }
+ }
+}
+
+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.
+ */
+
+/***************
+* 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)
+ delete engine::root;
+ engine::root = this;
+}
+
+void mogltk::widgets::Root::draw() {
+ if (dr)
+ dr->draw(this);
+ else
+ Shaper()->box(GetAX(), GetAY(), GetAX2(), GetAY2());
+}
+
+void mogltk::widgets::Root::setdrawer(drawer * _dr) {
+ dr = _dr;
+}
+
+
+/**************************
+* A simple clipping Panel *
+**************************/
+
+mogltk::widgets::Panel::Panel(shape * sh, widget * father, int x, int y, int w, int h) : widget(father, x, y, w, h, 0, "Panel", sh) {
+}
+
+
+/***********************
+* 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;
+}
+
+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;
+}
+
+
+/**********************
+* 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;
+}
+
+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);
+ MoveOnTop();
+ return true;
+ }
+ 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) { }
+ 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());
+}
+
+
+/*****************
+* 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;
+}
+
+void mogltk::widgets::Label::draw() {
+ Shaper()->text(GetAX(), GetAY(), caption, color);
+}
+
+
+/*************************
+* 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), sticky(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) {
+ if (!visible && sticky)
+ return;
+ widget::SetVisible(visible);
+ if (!visible && subselected) {
+ subselected->SetVisible(false);
+ }
+
+ if (visible) {
+ add_out_click();
+ MoveOnTop();
+ }
+}
+
+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;
+ 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;
+
+ switch (event) {
+ case E_MOUSE_MOVE:
+ sticky = false;
+ selected = -1;
+ 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_DOWN:
+ 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::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;
+}
+
+void mogltk::widgets::Menu::node::SetCaption(const String & s) {
+ caption = s;
+}
+
+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);
+}
+
+void mogltk::widgets::Menu::resize_notify() {
+ rect r = Father()->GetDrawRect();
+ 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::SetCaption(int i, const String & s) {
+ nodes[i].SetCaption(s);
+}
+
+void mogltk::widgets::Menu::draw(void) {
+ 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;
+}
+
+
+/*
+ * The mainloop widget thing.
+ */
+
+void mogltk::widget::mainloop() {
+ bool end_event_loop = false;
+ widget_mouse_event * mouse = new widget_mouse_event(this);
+ widget * w;
+ int mx, my;
+
+ while (!end_event_loop && !engine::quitrequested()) {
+ root->fulldraw();
+ 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);
+
+ if (w = root->find_widget(mx, my)) {
+ sh->box(w->GetAX(), w->GetAY(), w->GetAX2(), w->GetAY2(), Color(100, 150, 60, 50));
+ }
+
+ engine::base_o->Flip();
+ widget::check_timed_events();
+ }
+
+ delete mouse;
+}
|