summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorpixel <pixel>2005-12-02 16:21:59 +0000
committerpixel <pixel>2005-12-02 16:21:59 +0000
commitedd5fe68be2a2a9e23a87f65f6a89807c34b7c3f (patch)
tree1b3dd682e775163290214cedd4dd8a8add5cceee
parent6f594ad00a07365eec68e16d338151dde23bb648 (diff)
Added cascade stuff for buttons, and cleaned source a bit.
-rw-r--r--include/widgets.h20
-rw-r--r--lib/contextmenu.cc416
-rw-r--r--lib/inputtext.cc153
-rw-r--r--lib/widgets.cc565
4 files changed, 647 insertions, 507 deletions
diff --git a/include/widgets.h b/include/widgets.h
index ae29cee..66a6191 100644
--- a/include/widgets.h
+++ b/include/widgets.h
@@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-/* $Id: widgets.h,v 1.12 2005-12-01 13:48:12 pixel Exp $ */
+/* $Id: widgets.h,v 1.13 2005-12-02 16:21:59 pixel Exp $ */
#ifndef __WIDGETS_H__
#define __WIDGETS_H__
@@ -169,13 +169,16 @@ namespace mogltk {
class Button : public widget {
public:
Button(action *, shape *, widget * father, int x, int y, int w, int h, const String & caption);
+ virtual ~Button();
+ void simulate_press();
+ action * cascade_action();
protected:
virtual void draw();
virtual bool process_event(int, int, event_t);
bool bevel;
private:
bool dragging;
- action * a;
+ action * a, * cascade;
};
/*!
@@ -328,13 +331,19 @@ namespace mogltk {
ContextMenu * subselected;
};
+ /*!
+ The InputText widget is used to do a simple input box on the screen.
+ */
class InputText : public widget {
public:
- InputText(shape *, widget * father, int x, int y);
+ InputText(action *, shape *, widget * father, int x, int y);
virtual ~InputText();
virtual void draw();
const String & GetText() const;
void SetText(const String &);
+ void activate();
+ void SetCursorPos(int);
+ virtual bool process_event(int, int, event_t);
private:
class inputtext_keyevent : public mogltk::engine::keyevent {
public:
@@ -345,6 +354,10 @@ namespace mogltk {
InputText * father;
} * it_keyevent;
String text;
+ action * a;
+ bool cursor_visible;
+ int cursor_pos;
+
};
/*!
@@ -363,7 +376,6 @@ namespace mogltk {
action * a;
mogltk::font * InputDialog_font;
};
-
};
};
diff --git a/lib/contextmenu.cc b/lib/contextmenu.cc
new file mode 100644
index 0000000..5b8309e
--- /dev/null
+++ b/lib/contextmenu.cc
@@ -0,0 +1,416 @@
+/*
+ * mogltk
+ * Copyright (C) 1999-2005 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: contextmenu.cc,v 1.1 2005-12-02 16:21:59 pixel Exp $ */
+
+#include <SDL.h>
+#include <vector>
+#include <Input.h>
+#include "font.h"
+#include "engine.h"
+#include "widgets.h"
+#include "sprite.h"
+
+/***********************************
+* 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), subselected(0) {
+ 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;
+}
diff --git a/lib/inputtext.cc b/lib/inputtext.cc
new file mode 100644
index 0000000..20aa34c
--- /dev/null
+++ b/lib/inputtext.cc
@@ -0,0 +1,153 @@
+/*
+ * mogltk
+ * Copyright (C) 1999-2005 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: inputtext.cc,v 1.1 2005-12-02 16:21:59 pixel Exp $ */
+
+#include <SDL.h>
+#include <vector>
+#include <Input.h>
+#include "font.h"
+#include "engine.h"
+#include "widgets.h"
+#include "sprite.h"
+
+/**********************
+* The InputText entry *
+**********************/
+
+mogltk::widgets::InputText::InputText(mogltk::widgets::action * _a, shape * sh, mogltk::widget * father, int _x, int _y) : widget(father, _x, _y, 80, 20, 0, "InputText", sh), it_keyevent(0), a(_a), cursor_visible(false), cursor_pos(0) {
+ it_keyevent = new mogltk::widgets::InputText::inputtext_keyevent(this);
+ set_timed_event(500);
+}
+
+mogltk::widgets::InputText::~InputText() {
+ delete it_keyevent;
+}
+
+void mogltk::widgets::InputText::activate() {
+ if (a)
+ a->do_action(this);
+}
+
+mogltk::widgets::InputText::inputtext_keyevent::inputtext_keyevent(mogltk::widgets::InputText * _father) : father(_father) {
+}
+
+void mogltk::widgets::InputText::inputtext_keyevent::up(SDL_keysym k) {
+}
+
+void mogltk::widgets::InputText::inputtext_keyevent::down(SDL_keysym k) {
+ if (father->GetVisible()) {
+ switch (k.sym) {
+ case SDLK_BACKSPACE:
+ if (father->GetText().strlen() == 1) {
+ father->SetText("");
+ } else if (father->GetText().strlen()) {
+ father->SetText(father->GetText().extract(0, father->GetText().strlen() - 2));
+ }
+ break;
+ case SDLK_RETURN:
+ father->activate();
+ break;
+ default:
+ if (k.unicode) {
+ if (((k.unicode >= 'a') && (k.unicode <= 'z')) ||
+ ((k.unicode >= 'A') && (k.unicode <= 'Z')) ||
+ ((k.unicode >= '0') && (k.unicode <= '9')))
+ father->SetText(father->GetText() + ((char) k.unicode));
+ }
+ }
+ } else {
+ if (old_handler)
+ old_handler->down(k);
+ }
+}
+
+const String & mogltk::widgets::InputText::GetText() const{
+ return text;
+}
+
+void mogltk::widgets::InputText::SetText(const String & _text) {
+ text = _text;
+}
+
+bool mogltk::widgets::InputText::process_event(int x, int y, mogltk::event_t event) {
+ switch (event) {
+ case E_TIMER:
+ set_timed_event(500);
+ cursor_visible = !cursor_visible;
+ return true;
+ }
+ return false;
+}
+
+void mogltk::widgets::InputText::draw() {
+ int x = MIN(SystemFont->singletextsize(text) + GetAX() + 2, GetAX2() - 2);
+
+ Shaper()->box3d(GetAX(), GetAY(), GetAX2(), GetAY2(), DOS_WHITE, DOS_HIGH_WHITE, DOS_GRAY, 2, true);
+ Shaper()->text(x, GetAY() + 2, text, BLACK, RIGHT);
+ if (cursor_visible) {
+ Shaper()->box(x, GetAY() + 2, x + 2, GetAY2() - 2, Color(0, 0, 0, 128));
+ }
+}
+
+
+/************************
+* The InputDialog child *
+************************/
+
+class InputDialogAction : public mogltk::widgets::action {
+ public:
+ InputDialogAction(mogltk::widgets::InputDialog * _parent) : parent(_parent) { }
+ virtual void do_action(mogltk::widget *) {
+ parent->do_action();
+ delete parent;
+ delete this;
+ }
+ private:
+ mogltk::widgets::InputDialog * parent;
+};
+
+mogltk::widgets::InputDialog::InputDialog(mogltk::widgets::action * _a, shape * sh, mogltk::widget * father, const String & caption, const String & text, mogltk::font * _font) : SmartBox(sh, father, 0, 0, 0, 0, caption), a(_a), InputDialog_font(_font) {
+ rect size = InputDialog_font->size(text);
+ rect lsize = size;
+
+ size.w += 12;
+ size.h += 90;
+
+ resize(size.w, size.h);
+ center();
+
+ (it = new InputText((new Button(new InputDialogAction(this), sh, this, size.w / 2 - 25, size.h - 30, 50, 24, "Ok"))->cascade_action(), sh, this, 10, size.h - 60))->resize(size.w - 20, 20);
+ new Label(sh, this, 6, 24, lsize.w, lsize.h, text, BLACK, InputDialog_font);
+
+ set_exclusive(father);
+}
+
+mogltk::widgets::InputDialog::~InputDialog() {
+ unset_exclusive(Father());
+}
+
+String mogltk::widgets::InputDialog::GetText() {
+ return it->GetText();
+}
+
+void mogltk::widgets::InputDialog::do_action() {
+ if (a)
+ a->do_action(this);
+}
diff --git a/lib/widgets.cc b/lib/widgets.cc
index 246a182..0bc1d2e 100644
--- a/lib/widgets.cc
+++ b/lib/widgets.cc
@@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-/* $Id: widgets.cc,v 1.15 2005-12-01 13:48:12 pixel Exp $ */
+/* $Id: widgets.cc,v 1.16 2005-12-02 16:21:59 pixel Exp $ */
#include <SDL.h>
#include <vector>
@@ -244,6 +244,37 @@ mogltk::widget::~widget() {
next->prev = prev;
else
father->last = prev;
+
+ std::vector<mogltk::widget *>::iterator iw;
+ std::vector<mogltk::widget::timed_event>::iterator it;
+
+ for (iw = out_move.begin(); iw != out_move.end(); iw++) {
+ if (*iw == this) {
+ out_move.erase(iw);
+ iw = out_move.begin();
+ }
+ }
+
+ for (iw = out_click.begin(); iw != out_click.end(); iw++) {
+ if (*iw == this) {
+ out_click.erase(iw);
+ iw = out_click.begin();
+ }
+ }
+
+ for (iw = to_delete.begin(); iw != to_delete.end(); iw++) {
+ if (*iw == this) {
+ to_delete.erase(iw);
+ iw = to_delete.begin();
+ }
+ }
+
+ for (it = timed_events.begin(); it != timed_events.end(); it++) {
+ if (it->w == this) {
+ timed_events.erase(it);
+ it = timed_events.begin();
+ }
+ }
}
void mogltk::widget::computeabs() {
@@ -651,14 +682,41 @@ mogltk::widgets::Panel::Panel(shape * sh, widget * father, int x, int y, int w,
* 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) {
+class ButtonCascadeAction : public mogltk::widgets::action {
+ public:
+ ButtonCascadeAction(mogltk::widgets::Button * _parent) : parent(_parent) { }
+ virtual void do_action(mogltk::widget *) {
+ parent->simulate_press();
+ }
+ private:
+ mogltk::widgets::Button * parent;
+};
+
+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), cascade(0) {
caption = _caption;
}
+mogltk::widgets::Button::~Button() {
+ if (cascade)
+ delete cascade;
+}
+
void mogltk::widgets::Button::draw() {
Shaper()->button(GetAX() + 1, GetAY() + 1, GetAX2() - 1, GetAY2() - 1, caption, bevel);
}
+void mogltk::widgets::Button::simulate_press() {
+ if (a)
+ a->do_action(this);
+}
+
+mogltk::widgets::action * mogltk::widgets::Button::cascade_action() {
+ if (!cascade)
+ cascade = new ButtonCascadeAction(this);
+
+ return cascade;
+}
+
bool mogltk::widgets::Button::process_event(int xe, int ye, mogltk::event_t event) {
switch (event) {
case E_MOUSE_DOWN:
@@ -825,505 +883,6 @@ mogltk::rect mogltk::widgets::Frame::GetDrawRect() {
}
-/***********************************
-* 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), subselected(0) {
- 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 InputText entry *
-**********************/
-
-mogltk::widgets::InputText::InputText(shape * sh, mogltk::widget * father, int _x, int _y) : widget(father, _x, _y, 80, 20, 0, "InputText", sh), it_keyevent(0) {
- it_keyevent = new mogltk::widgets::InputText::inputtext_keyevent(this);
-}
-
-mogltk::widgets::InputText::~InputText() {
- delete it_keyevent;
-}
-
-mogltk::widgets::InputText::inputtext_keyevent::inputtext_keyevent(mogltk::widgets::InputText * _father) : father(_father) {
-}
-
-void mogltk::widgets::InputText::inputtext_keyevent::up(SDL_keysym k) {
-}
-
-void mogltk::widgets::InputText::inputtext_keyevent::down(SDL_keysym k) {
- if (father->GetVisible()) {
- switch (k.sym) {
- case SDLK_BACKSPACE:
- if (father->GetText().strlen() == 1) {
- father->SetText("");
- } else if (father->GetText().strlen()) {
- father->SetText(father->GetText().extract(0, father->GetText().strlen() - 2));
- }
- break;
- case SDLK_RETURN:
- break;
- default:
- if (k.unicode) {
- if (((k.unicode >= 'a') && (k.unicode <= 'z')) ||
- ((k.unicode >= 'A') && (k.unicode <= 'Z')) ||
- ((k.unicode >= '0') && (k.unicode <= '9')))
- father->SetText(father->GetText() + ((char) k.unicode));
- }
- }
- } else {
- if (old_handler)
- old_handler->down(k);
- }
-}
-
-const String & mogltk::widgets::InputText::GetText() const{
- return text;
-}
-
-void mogltk::widgets::InputText::SetText(const String & _text) {
- text = _text;
-}
-
-void mogltk::widgets::InputText::draw() {
- int rx;
- rect r = SystemFont->size(text);
-
- rx = r.w + GetAX() + 2;
-
- Shaper()->box3d(GetAX(), GetAY(), GetAX2(), GetAY2(), DOS_WHITE, DOS_HIGH_WHITE, DOS_GRAY, 2, true);
- Shaper()->text(MIN(rx, GetAX2() - 2), GetAY() + 2, text, BLACK, RIGHT);
-}
-
-
-/************************
-* The InputDialog child *
-************************/
-
-class InputDialogAction : public mogltk::widgets::action {
- public:
- InputDialogAction(mogltk::widgets::InputDialog * _parent) : parent(_parent) { }
- virtual void do_action(mogltk::widget *) {
- parent->do_action();
- delete parent;
- delete this;
- }
- private:
- mogltk::widgets::InputDialog * parent;
-};
-
-mogltk::widgets::InputDialog::InputDialog(mogltk::widgets::action * _a, shape * sh, mogltk::widget * father, const String & caption, const String & text, mogltk::font * _font) : SmartBox(sh, father, 0, 0, 0, 0, caption), a(_a), InputDialog_font(_font) {
- rect size = InputDialog_font->size(text);
- rect lsize = size;
-
- size.w += 12;
- size.h += 90;
-
- resize(size.w, size.h);
- center();
-
- new Button(new InputDialogAction(this), sh, this, size.w / 2 - 25, size.h - 30, 50, 24, "Ok");
- it = new InputText(sh, this, 10, size.h - 60);
- it->resize(size.w - 20, 20);
- new Label(sh, this, 6, 24, lsize.w, lsize.h, text, BLACK, InputDialog_font);
-
- set_exclusive(father);
-}
-
-mogltk::widgets::InputDialog::~InputDialog() {
- unset_exclusive(Father());
-}
-
-String mogltk::widgets::InputDialog::GetText() {
- return it->GetText();
-}
-
-void mogltk::widgets::InputDialog::do_action() {
- if (a)
- a->do_action(this);
-}
-
-
/*
* The mainloop widget thing.
*/
@@ -1342,9 +901,9 @@ void mogltk::widget::mainloop() {
Sprite::Cursor->draw(mx - 6, my - 3, Color(0, 0, 0, 50));
Sprite::Cursor->draw(mx - 8, my - 6);
- if (w = root->find_widget(mx, my)) {
+// 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();