From edd5fe68be2a2a9e23a87f65f6a89807c34b7c3f Mon Sep 17 00:00:00 2001 From: pixel Date: Fri, 2 Dec 2005 16:21:59 +0000 Subject: Added cascade stuff for buttons, and cleaned source a bit. --- include/widgets.h | 20 +- lib/contextmenu.cc | 416 +++++++++++++++++++++++++++++++++++++++ lib/inputtext.cc | 153 +++++++++++++++ lib/widgets.cc | 565 ++++++----------------------------------------------- 4 files changed, 647 insertions(+), 507 deletions(-) create mode 100644 lib/contextmenu.cc create mode 100644 lib/inputtext.cc 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 +#include +#include +#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::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::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::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::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::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::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::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 +#include +#include +#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 #include @@ -244,6 +244,37 @@ mogltk::widget::~widget() { next->prev = prev; else father->last = prev; + + std::vector::iterator iw; + std::vector::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::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::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::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::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::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::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::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(); -- cgit v1.2.3