qonk-0.3.1/0000777000175000017500000000000010672420073007471 500000000000000qonk-0.3.1/src/0000777000175000017500000000000010672420073010260 500000000000000qonk-0.3.1/src/ui/0000777000175000017500000000000010672420073010675 500000000000000qonk-0.3.1/src/ui/menu.cpp0000644000175000017500000001030210672417547012271 00000000000000#include "menu.h" #include #include "menu.h" #include "menusystem.h" #include "menuentry.h" #include "menuaction.h" using namespace gcn; using namespace std; Menu::Menu(Id parentId, std::string menuTitle, int x) : menuSystem(0), selected(-1), locx(x) { parentMenuId = parentId; container = new Container(); title = new Label(menuTitle); container->add(title); container->setOpaque(false); container->setVisible(false); entries = new vector < MenuEntry * >(); } Menu::~Menu() { for (vector< MenuEntry * >::iterator i = entries->begin(); i != entries->end(); i++) { delete (*i); } delete entries; delete container; } void Menu::addEntry(MenuEntry *entry) { entries->push_back(entry); container->add(entry->getWidget()); if (menuSystem) entry->registered(menuSystem); } Container * Menu::getContainer() const { return container; } void Menu::enter() { container->setVisible(true); if (selected == -1) { selected = 0; entries->at(0)->getWidget()->setFont(menuSystem->getHighlightedFont()); } } void Menu::leave() { container->setVisible(false); } void Menu::registered(MenuSystem *system) { menuSystem = system; for (vector< MenuEntry * >::iterator i = entries->begin(); i != entries->end(); i++) (*i)->registered(system); } void Menu::resize(int w, int h) { container->setSize(w, h); int maxWidth = 0; for (vector< MenuEntry * >::iterator i = entries->begin(); i != entries->end(); i++) { gcn::Widget *w = (*i)->getWidget(); maxWidth = max(w->getWidth(), maxWidth); } int x = (!locx) ? (w/2 - maxWidth/2) : locx; int y = h/8; title->setPosition(x, y); y += 2 * title->getHeight(); for (vector< MenuEntry * >::iterator i = entries->begin(); i != entries->end(); i++) { gcn::Widget *w = (*i)->getWidget(); w->setPosition(x, y); y += w->getHeight(); } } void Menu::up() { entries->at(selected)->getWidget()->setFont(menuSystem->getNormalFont()); if (--selected < 0) selected = entries->size()-1; entries->at(selected)->getWidget()->setFont(menuSystem->getHighlightedFont()); } void Menu::down() { entries->at(selected)->getWidget()->setFont(menuSystem->getNormalFont()); if (++selected >= entries->size()) selected = 0; entries->at(selected)->getWidget()->setFont(menuSystem->getHighlightedFont()); } void Menu::cancel() { // If the cancel operation aborted some operation we skip going one // menu level up. if (!entries->at(selected)->cancel()) { entries->at(selected)->getWidget()->setFont(menuSystem->getNormalFont()); selected = 0; entries->at(selected)->getWidget()->setFont(menuSystem->getHighlightedFont()); menuSystem->enter(parentMenuId); } } void Menu::reset() { entries->at(selected)->reset(); } void Menu::invoke() { entries->at(selected)->invoke(); } void Menu::next() { entries->at(selected)->next(); } void Menu::previous() { entries->at(selected)->previous(); } class ActionEntry : public MenuEntry { MenuAction *action; public: ActionEntry(string s, MenuAction *a) : action(a), MenuEntry(a->getWidget(s)) { } ~ActionEntry() { delete action; } void invoke() { action->invoke(); } void previous() { action->previous(); } void next() { action->next(); } /** Delegates the question if some action was * cancelled or not to the action. */ bool cancel() { return action->cancel(); } void reset() { action->reset(); } }; void Menu::addAction(string s, MenuAction *action) { addEntry(new ActionEntry(s, action)); } class LinkEntry : public MenuEntry { Menu::Id target; public: LinkEntry(string s, Menu::Id id) : MenuEntry(new Label(s)), target(id) { } void invoke() { menuSystem->enter(target); } }; void Menu::addLink(string s, Menu::Id id) { addEntry(new LinkEntry(s, id)); } class BackLink : public MenuEntry { Menu *menu; public: BackLink(Menu *newMenu) : MenuEntry(new Label("back")), menu(newMenu) { } void invoke() { menu->cancel(); } }; void Menu::addBackLink() { addEntry(new BackLink(this)); } qonk-0.3.1/src/ui/menuentry.h0000644000175000017500000000172210672417547013026 00000000000000// menuentry.h // // (c) Robert Schuster, 2007 // // Licensed under GNU GPL version 2 or, at your option, any later version. #ifndef MENUENTRY_H #define MENUENTRY_H #include "guichan/guichan.hpp" class MenuSystem; class MenuEntry { protected: gcn::Widget *widget; MenuSystem *menuSystem; MenuEntry(gcn::Widget *); public: virtual ~MenuEntry(); void registered(MenuSystem *); gcn::Widget *getWidget() const { return widget; } virtual void invoke() = 0; virtual void next() { }; virtual void previous() { }; /** Returns true if some operation was cancelled or false if not. * * This is neccessary for the menu to know whether it should go * on level up or not. */ virtual bool cancel() { return false; } /** * Puts the underlying attribute to its default value. * * Needs only be implemented by entries that support this. */ virtual void reset() { }; }; #endif qonk-0.3.1/src/ui/menuaction.h0000644000175000017500000000131210672417547013135 00000000000000// menuaction.h // // (c) Robert Schuster, 2007 // // Licensed under GNU GPL version 2 or, at your option, any later version. #ifndef MENUACTION_H #define MENUACTION_H #include "guichan/guichan.hpp" /* TODO: Realize all customized behavior with specific MenuEntry subclasses * and remove the need for a MenuAction delegate object. */ class MenuAction { public: virtual gcn::Widget *getWidget(std::string); virtual void invoke() = 0; virtual void next() { }; virtual void previous() { }; virtual void update() { }; /** Returns true if some operation was cancelled or false if not. */ virtual bool cancel() { return false; } virtual void reset() { } }; #endif qonk-0.3.1/src/ui/menusystem.h0000644000175000017500000000334410672417547013213 00000000000000// menusystem.h // // (c) Robert Schuster, 2007 // // Licensed under GNU GPL version 2 or, at your option, any later version. #ifndef MENUSYSTEM_H #define MENUSYSTEM_H #include #include "guichan/guichan.hpp" #include "guichan/guichan/sdl.hpp" #include "menu.h" /** * MenuSystem cares for all the low-level interaction of the menu system with * guichan. * * It is only supposed to be called through MenuManager. */ class MenuSystem { class KeyListener : public gcn::KeyListener { MenuSystem &system; public: KeyListener(MenuSystem &menuSystem); virtual void keyReleased(gcn::KeyEvent &); }; gcn::Gui *gui; gcn::ImageFont *normal; gcn::ImageFont *highlighted; gcn::Container *top; std::map< Menu::Id, Menu * > *menus; Menu *currentMenu, *nextMenu; KeyListener *menuKeyListener; static gcn::ImageFont *loadFont(std::string); static gcn::Image *loadImage(std::string); public: MenuSystem(gcn::SDLInput *); ~MenuSystem(); void render(); bool update(); void resize(); void addMenu(Menu::Id, Menu *); void enter(Menu::Id = Menu::MAIN); /** Cancels whatever operation is currently in progress. * * At the moment the following operations are known: *