From 5f916a0dfd7bc4adb692e1f731aeb386fdd44a42 Mon Sep 17 00:00:00 2001 From: "simon.kagstrom" Date: Thu, 31 Dec 2009 13:25:46 +0000 Subject: [PATCH] Refactor dialogues: Simplify a lot and remove the tie-in to the main menu class. --- Makefile | 8 +++-- dialogue_box.cpp | 43 ++++++++++++++++++++--- dialogue_box.hh | 24 ++++++++++--- gui.cpp | 47 ++++++++++++++++++++++--- gui.hh | 7 ++++ listener.hh | 34 ++++++++++++++++++ main_menu.cpp | 84 +++++++++++--------------------------------- menu.hh | 2 +- virtual_keyboard.cpp | 43 ++--------------------- virtual_keyboard.hh | 12 ++----- 10 files changed, 174 insertions(+), 130 deletions(-) create mode 100644 listener.hh diff --git a/Makefile b/Makefile index 5eb0126..858bfff 100644 --- a/Makefile +++ b/Makefile @@ -1,5 +1,5 @@ OBJS=menu.oo main.oo utils.oo gui.oo dialogue_box.oo menu_messages.oo \ - timer.oo game_info.oo widget.oo virtual_keyboard.oo + timer.oo game_info.oo widget.oo virtual_keyboard.oo listener.oo all: menu @@ -15,7 +15,7 @@ gui.oo: gui.cpp gui.hh Makefile font.hh menu.hh sdl_ttf_font.hh \ file_browser.hh timer.hh game_info.hh widget.hh options_menu.cpp \ network_menu.cpp -virtual_keyboard.oo: virtual_keyboard.hh virtual_keyboard.cpp widget.hh +virtual_keyboard.oo: virtual_keyboard.hh virtual_keyboard.cpp widget.hh listener.hh game_info.oo: game_info.hh game_info.cpp @@ -23,7 +23,9 @@ utils.oo: utils.cpp utils.hh Makefile timer.oo: timer.cpp timer.hh utils.hh Makefile -dialogue_box.oo: dialogue_box.cpp dialogue_box.hh menu.hh Makefile +dialogue_box.oo: dialogue_box.cpp dialogue_box.hh menu.hh listener.hh + +listener.oo: listener.cpp listener.hh main.oo: menu.hh utils.hh sdl_ttf_font.hh Makefile diff --git a/dialogue_box.cpp b/dialogue_box.cpp index 7a40994..4b4b2fe 100644 --- a/dialogue_box.cpp +++ b/dialogue_box.cpp @@ -1,10 +1,24 @@ #include "dialogue_box.hh" -DialogueBox::DialogueBox(Font *font, const char *msgs[], int cancel) : Menu(font) +void DialogueListener::escapeCallback(DialogueBox *which, int selected) +{ + Gui::gui->popDialogueBox(); +} + +void DialogueListener::selectCallback(DialogueBox *which, int selected) +{ + Gui::gui->popDialogueBox(); +} + +DialogueBox::DialogueBox(const char *msgs[], int cancel) : Menu(NULL), ListenerManager() { - this->m_selected = -1; this->m_cancel = cancel; + this->setFont(Gui::gui->default_font); + this->setSelectedBackground(NULL, NULL, NULL, + Gui::gui->bg_left, Gui::gui->bg_middle, + Gui::gui->bg_right); + this->setText(msgs, NULL); /* Place on the second to last entry */ this->cur_sel = this->n_entries - 2; @@ -12,6 +26,7 @@ DialogueBox::DialogueBox(Font *font, const char *msgs[], int cancel) : Menu(font int DialogueBox::selectNext(event_t ev) { + printf("Al vobb: %d!\n", ev); /* No up/down movement please! */ if (ev == KEY_UP || ev == KEY_DOWN) return this->cur_sel; @@ -20,7 +35,10 @@ int DialogueBox::selectNext(event_t ev) void DialogueBox::selectCallback(int which) { - this->m_selected = this->p_submenus[0].sel; + for (int i = 0; i < this->nListeners(); i++) + if (this->listeners[i]) + ((DialogueListener*)this->listeners[i])->selectCallback(this, + this->p_submenus[0].sel); } void DialogueBox::hoverCallback(int which) @@ -29,5 +47,22 @@ void DialogueBox::hoverCallback(int which) void DialogueBox::escapeCallback(int which) { - this->m_selected = this->m_cancel; + for (int i = 0; i < this->nListeners(); i++) + if (this->listeners[i]) + ((DialogueListener*)this->listeners[i])->selectCallback(this, + this->p_submenus[0].sel); } + +void DialogueBox::draw(SDL_Surface *where) +{ + int d_x = where->w / 2 - Gui::gui->dialogue_bg->w / 2; + int d_y = where->h / 2 - Gui::gui->dialogue_bg->h / 2; + + SDL_Rect dst = (SDL_Rect){d_x, d_y, + Gui::gui->dialogue_bg->w, Gui::gui->dialogue_bg->h}; + SDL_BlitSurface(Gui::gui->dialogue_bg, NULL, where, &dst); + + Menu::draw(where, d_x + 10, d_y + 10, + Gui::gui->dialogue_bg->w - 10, Gui::gui->dialogue_bg->h - 10); +} + diff --git a/dialogue_box.hh b/dialogue_box.hh index 766298c..6dbffec 100644 --- a/dialogue_box.hh +++ b/dialogue_box.hh @@ -2,11 +2,24 @@ #define __DIALOGUE_BOX_HH__ #include "menu.hh" +#include "listener.hh" +#include "gui_view.hh" +#include "gui.hh" -class DialogueBox : public Menu +class DialogueBox; + +class DialogueListener : public Listener { public: - DialogueBox(Font *font, const char *msgs[], int cancel = 1); + virtual void selectCallback(DialogueBox *which, int selected); + + virtual void escapeCallback(DialogueBox *which, int selected); +}; + +class DialogueBox : public Menu, public ListenerManager +{ +public: + DialogueBox(const char *msgs[], int cancel = 1); virtual void selectCallback(int which); @@ -16,13 +29,14 @@ public: virtual int selectNext(event_t ev); - int selected() + virtual void draw(SDL_Surface *where); + + int cancelIndex() { - return this->m_selected; + return this->m_cancel; } protected: - int m_selected; int m_cancel; }; diff --git a/gui.cpp b/gui.cpp index 2ba6446..b54dcb1 100644 --- a/gui.cpp +++ b/gui.cpp @@ -38,6 +38,18 @@ GuiView::GuiView() { } +void GuiView::updateTheme() +{ +} + +void GuiView::viewPushCallback() +{ +} + +void GuiView::viewPopCallback() +{ +} + Gui::Gui() { this->focus = NULL; @@ -66,6 +78,8 @@ Gui::Gui() this->metadata_base_path = METADATA_ROOT_PATH; this->game_base_path = GAME_ROOT_PATH; + this->dlg = NULL; + /* Create the views */ this->mv = new MainView(); this->dv = new DiscView(); @@ -146,7 +160,10 @@ void Gui::runLogic(void) if (!this->is_active || !cur_view) return; - cur_view->runLogic(); + if (this->dlg) + this->dlg->runLogic(); + else + cur_view->runLogic(); this->timerController->tick(); } @@ -158,14 +175,29 @@ void Gui::pushView(GuiView *view) this->views = (GuiView**)xrealloc(this->views, sizeof(GuiView*) * this->n_views); this->views[cur] = view; + view->viewPushCallback(); +} + +void Gui::pushDialogueBox(DialogueBox *dlg) +{ + this->dlg = dlg; +} + +DialogueBox *Gui::popDialogueBox() +{ + DialogueBox *out = this->dlg; + this->dlg = NULL; + + return out; } GuiView *Gui::popView() { GuiView *cur = this->peekView(); - if (cur) - delete cur; + if (!cur) + return NULL; + cur->viewPopCallback(); this->n_views--; if (this->n_views <= 0) @@ -181,7 +213,7 @@ GuiView *Gui::popView() this->views = (GuiView**)xrealloc(this->views, sizeof(GuiView*) * this->n_views); - return this->views[this->n_views - 1]; + return cur; } void Gui::exitMenu() @@ -199,6 +231,11 @@ void Gui::pushEvent(SDL_Event *ev) if (!this->is_active || !cur_view) return; + if (this->dlg) + { + this->dlg->pushEvent(ev); + return; + } cur_view->pushEvent(ev); } @@ -211,6 +248,8 @@ void Gui::draw(SDL_Surface *where) SDL_BlitSurface(this->background, NULL, screen, NULL); cur_view->draw(where); + if (this->dlg) + this->dlg->draw(where); } void Gui::activate() diff --git a/gui.hh b/gui.hh index ec88f54..0541aa2 100644 --- a/gui.hh +++ b/gui.hh @@ -9,6 +9,7 @@ #include "gui_view.hh" class MainView; +class DialogueBox; class DiscView; class OptionsView; class NetworkView; @@ -35,6 +36,10 @@ public: void pushView(GuiView *view); + void pushDialogueBox(DialogueBox *dlg); + + DialogueBox *popDialogueBox(); + GuiView *popView(); GuiView *peekView() @@ -72,6 +77,8 @@ public: Font *small_font; TimerController *timerController; + DialogueBox *dlg; + MainView *mv; DiscView *dv; OptionsView *ov; diff --git a/listener.hh b/listener.hh new file mode 100644 index 0000000..03db713 --- /dev/null +++ b/listener.hh @@ -0,0 +1,34 @@ +#ifndef __LISTENER_HH__ +#define __LISTENER_HH__ + +#include + +class Listener +{ + /* Implemented by the child */ +}; + +class ListenerManager +{ +public: + ListenerManager(); + + void registerListener(Listener *l); + + void unregisterListener(Listener *l); + + void flushListeners() + { + memset(this->listeners, 0, sizeof(this->listeners)); + } + + int nListeners() + { + return sizeof(this->listeners) / sizeof(*this->listeners); + } + +protected: + Listener *listeners[8]; +}; + +#endif /* __LISTENER_HH__ */ diff --git a/main_menu.cpp b/main_menu.cpp index e3796cf..bc8ea31 100644 --- a/main_menu.cpp +++ b/main_menu.cpp @@ -1,4 +1,5 @@ #include "menu.hh" +#include "dialogue_box.hh" class KeyboardTypingListener : public KeyboardListener { @@ -15,63 +16,31 @@ class KeyboardTypingListener : public KeyboardListener } }; +class ExitListener : public DialogueListener +{ + void escapeCallback(DialogueBox *which, int selected) + { + delete this; + } + + void selectCallback(DialogueBox *which, int selected) + { + if (selected != which->cancelIndex()) + exit(0); + Gui::gui->popView(); + delete this; + } +}; + class MainView; class MainMenu : public Menu { friend class MainView; - class ExitDialogue : public DialogueBox - { - public: - ExitDialogue(Font *font) : DialogueBox(font, exit_dialogue_messages, 1) - { - } - - void selectCallback(int which) - { - this->m_selected = this->p_submenus[0].sel; - /* Do the exit */ - if (this->m_selected != this->m_cancel) - exit(1); - } - }; - public: MainMenu(Font *font, HelpBox *help) : Menu(font) { this->help = help; - /* The dialogue box is only present when needed */ - this->dialogue = NULL; - } - - ~MainMenu() - { - if (this->dialogue) - delete this->dialogue; - } - - void runLogic() - { - if (this->dialogue) - { - this->dialogue->runLogic(); - if (this->dialogue->selected() >= 0) - { - delete this->dialogue; - this->dialogue = NULL; - } - return; - } - - Menu::runLogic(); - } - - void pushEvent(SDL_Event *ev) - { - if (this->dialogue) - this->dialogue->pushEvent(ev); - else - Menu::pushEvent(ev); } virtual void selectCallback(int which) @@ -105,10 +74,9 @@ public: break; case 11: /* Exit */ - this->dialogue = new ExitDialogue(this->font); - this->dialogue->setSelectedBackground(NULL, NULL, NULL, - this->submenu_bg_left, this->submenu_bg_middle, - this->submenu_bg_right); + DialogueBox *exit_dialogue = new DialogueBox(exit_dialogue_messages, 1); + exit_dialogue->registerListener(new ExitListener()); + Gui::gui->pushDialogueBox(exit_dialogue); break; } } @@ -124,7 +92,6 @@ public: } private: - DialogueBox *dialogue; HelpBox *help; }; @@ -180,17 +147,6 @@ public: this->menu->draw(where, 50, 70, 300, 400); this->help->draw(where, 354, 24, 264, 210); - if (this->menu->dialogue) { - int d_x = where->w / 2 - Gui::gui->dialogue_bg->w / 2; - int d_y = where->h / 2 - Gui::gui->dialogue_bg->h / 2; - - dst = (SDL_Rect){d_x, d_y, - Gui::gui->dialogue_bg->w, Gui::gui->dialogue_bg->h}; - SDL_BlitSurface(Gui::gui->dialogue_bg, NULL, where, &dst); - - this->menu->dialogue->draw(where, d_x + 10, d_y + 10, - Gui::gui->dialogue_bg->w - 10, Gui::gui->dialogue_bg->h - 10); - } } protected: diff --git a/menu.hh b/menu.hh index 1273d50..45261f2 100644 --- a/menu.hh +++ b/menu.hh @@ -55,7 +55,7 @@ public: void setText(const char **messages, int *submenu_defaults = NULL); - void runLogic(); + virtual void runLogic(); void draw(SDL_Surface *where, int x, int y, int w, int h); diff --git a/virtual_keyboard.cpp b/virtual_keyboard.cpp index 2dbba82..030ddf7 100644 --- a/virtual_keyboard.cpp +++ b/virtual_keyboard.cpp @@ -78,7 +78,7 @@ static const char *shifted_names[KEY_COLS * KEY_ROWS] = { NULL, NULL, NULL, NULL, NULL, NULL, "f2", "f4", "f6", "f8", "Ins", NULL, NULL, NULL, NULL, }; -VirtualKeyboard::VirtualKeyboard(Font *font) : GuiView() +VirtualKeyboard::VirtualKeyboard(Font *font) : GuiView(), ListenerManager() { this->font = font; this->sel_x = 0; @@ -90,8 +90,6 @@ VirtualKeyboard::VirtualKeyboard(Font *font) : GuiView() this->buf_len = 255; this->buf = (struct virtkey*)xmalloc(sizeof(struct virtkey) * this->buf_len); memset(this->buf, 0, sizeof(struct virtkey) * this->buf_len); - - this->flushListeners(); } void VirtualKeyboard::draw(SDL_Surface *where, int x_base, int y_base, int w, int h) @@ -259,36 +257,6 @@ const char VirtualKeyboard::keycodeToChar(int kc) return s[0]; } -void VirtualKeyboard::registerListener(KeyboardListener *kl) -{ - int n_listeners = sizeof(this->listeners) / sizeof(*this->listeners); - int i; - - /* Don't register already registered listeners */ - for (i = 0; i < n_listeners; i++) - if (this->listeners[i] == kl) - return; - /* Find a free spot */ - for (i = 0; i < n_listeners; i++) - if (!this->listeners[i]) - break; - - panic_if(i == n_listeners, - "No free listeners!\n"); - this->listeners[i] = kl; -} - -void VirtualKeyboard::unregisterListener(KeyboardListener *kl) -{ - int n_listeners = sizeof(this->listeners) / sizeof(*this->listeners); - - for (int i = 0; i < n_listeners; i++) - { - if (this->listeners[i] == kl) - this->listeners[i] = NULL; - } -} - void VirtualKeyboard::activate() { this->is_active = true; @@ -362,16 +330,11 @@ void VirtualKeyboard::pushKey(struct virtkey *vk) for (int i = 0; i < n_listeners; i++) { if (this->listeners[i]) - this->listeners[i]->keyCallback(this->shift_on, + ((KeyboardListener*)this->listeners[i])->keyCallback(this->shift_on, vk->name); } } -void VirtualKeyboard::flushListeners() -{ - memset(this->listeners, 0, sizeof(this->listeners)); -} - void VirtualKeyboard::deactivate() { this->is_active = false; @@ -390,7 +353,7 @@ void VirtualKeyboard::done() for (int i = 0; i < n_listeners; i++) { if (this->listeners[i]) - this->listeners[i]->stringCallback(buf); + ((KeyboardListener*)this->listeners[i])->stringCallback(buf); } free(buf); this->deactivate(); diff --git a/virtual_keyboard.hh b/virtual_keyboard.hh index fb11c47..36c5995 100644 --- a/virtual_keyboard.hh +++ b/virtual_keyboard.hh @@ -17,10 +17,11 @@ #include "widget.hh" #include "gui_view.hh" #include "font.hh" +#include "listener.hh" struct virtkey; -class KeyboardListener +class KeyboardListener : public Listener { public: ~KeyboardListener(); @@ -35,14 +36,11 @@ public: } }; -class VirtualKeyboard : public GuiView +class VirtualKeyboard : public GuiView, public ListenerManager { public: VirtualKeyboard(Font *font); - void registerListener(KeyboardListener *kl); - void unregisterListener(KeyboardListener *kl); - /* Conversions */ const char *keycodeToString(int kc); const char keycodeToChar(int kc); @@ -77,8 +75,6 @@ public: /* Singleton object */ static VirtualKeyboard *kbd; private: - KeyboardListener *listeners[8]; - void selectNext(int dx, int dy); void toggleShift(); @@ -87,8 +83,6 @@ private: void done(); - void flushListeners(); - Font *font; int sel_x; int sel_y;