Refactor dialogues: Simplify a lot and remove the tie-in to the main

menu class.
This commit is contained in:
simon.kagstrom 2009-12-31 13:25:46 +00:00
parent ed831048ce
commit 5f916a0dfd
10 changed files with 174 additions and 130 deletions

View File

@ -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

View File

@ -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);
}

View File

@ -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;
};

47
gui.cpp
View File

@ -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()

7
gui.hh
View File

@ -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;

34
listener.hh Normal file
View File

@ -0,0 +1,34 @@
#ifndef __LISTENER_HH__
#define __LISTENER_HH__
#include <string.h>
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__ */

View File

@ -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:

View File

@ -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);

View File

@ -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();

View File

@ -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;