frodo-wii/frodo_menu.cpp

384 lines
7.9 KiB
C++
Raw Normal View History

2009-11-28 09:22:19 +01:00
#include <SDL_image.h>
#include <SDL_ttf.h>
#include "menu.hh"
#include "frodo_menu.hh"
#include "menu_messages.hh"
#include "dialogue_box.hh"
2009-11-28 09:22:19 +01:00
#include "sdl_ttf_font.hh"
#include "utils.hh"
extern SDL_Surface *screen;
2009-11-29 15:11:21 +01:00
class Gui;
const char *get_theme_path(const char *dir, const char *what)
{
static char buf[255];
memset(buf, 0, sizeof(buf));
snprintf(buf, 254, "%s/%s",
dir, what);
return buf;
}
class HelpMenu : public Menu
{
public:
HelpMenu(Font *font, const char ***all_messages) : Menu(font)
{
this->all_messages = all_messages;
}
void updateHelpMessage(int which)
{
this->setText(this->all_messages[which]);
}
virtual void selectCallback(int which)
{
}
virtual void hoverCallback(int which)
{
}
virtual void escapeCallback(int which)
{
}
protected:
const char ***all_messages;
};
class MainView;
2009-11-28 09:22:19 +01:00
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);
}
};
2009-11-28 09:22:19 +01:00
public:
MainMenu(Font *font, HelpMenu *help, GuiView *parent) : Menu(font)
2009-11-28 09:22:19 +01:00
{
2009-11-29 15:11:21 +01:00
this->parent = parent;
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;
}
2009-12-06 09:57:57 +01:00
Menu::runLogic();
}
void pushEvent(SDL_Event *ev)
{
if (this->dialogue)
this->dialogue->pushEvent(ev);
else
2009-12-06 09:57:57 +01:00
Menu::pushEvent(ev);
2009-11-28 09:22:19 +01:00
}
virtual void selectCallback(int which)
{
printf("entry %d selected: %s\n", which, this->pp_msgs[which]);
switch (which)
{
case 11:
this->dialogue = new ExitDialogue(this->font);
this->dialogue->setSelectedBackground(NULL, NULL, NULL,
this->submenu_bg_left, this->submenu_bg_middle,
this->submenu_bg_right);
break;
}
2009-11-28 09:22:19 +01:00
}
virtual void hoverCallback(int which)
{
this->help->updateHelpMessage(which);
}
2009-11-28 09:22:19 +01:00
virtual void escapeCallback(int which)
{
2009-12-05 10:33:58 +01:00
this->parent->parent->exitMenu();
2009-11-28 09:22:19 +01:00
}
2009-11-29 15:11:21 +01:00
private:
DialogueBox *dialogue;
GuiView *parent;
HelpMenu *help;
2009-11-28 09:22:19 +01:00
};
class MainView : public GuiView
{
public:
MainView(Gui *parent) : GuiView(parent)
{
this->help = new HelpMenu(NULL, main_menu_help);
this->menu = new MainMenu(NULL, this->help, this);
this->menu->setText(main_menu_messages);
2009-12-04 18:55:25 +01:00
this->bg = NULL;
this->infobox = NULL;
this->textbox = NULL;
this->dialogue_bg = NULL;
}
void updateTheme()
{
this->bg = parent->main_menu_bg;
2009-12-04 18:55:25 +01:00
this->infobox = parent->infobox;
this->textbox = parent->textbox;
this->dialogue_bg = parent->dialogue_bg;
this->menu->setFont(this->parent->default_font);
2009-12-04 21:06:52 +01:00
this->help->setFont(this->parent->small_font);
this->menu->setSelectedBackground(this->parent->bg_left, this->parent->bg_middle,
this->parent->bg_right, this->parent->bg_submenu_left,
this->parent->bg_submenu_middle, this->parent->bg_submenu_right);
}
void runLogic()
{
this->menu->runLogic();
}
void pushEvent(SDL_Event *ev)
{
this->menu->pushEvent(ev);
}
void draw(SDL_Surface *where)
{
SDL_Rect dst;
2009-12-04 18:55:25 +01:00
/* Blit the backgrounds */
dst = (SDL_Rect){20,45,300,400};
SDL_BlitSurface(this->bg, NULL, where, &dst);
2009-12-04 18:55:25 +01:00
dst = (SDL_Rect){350,13,0,0};
SDL_BlitSurface(this->infobox, NULL, where, &dst);
dst = (SDL_Rect){350,242,0,0};
SDL_BlitSurface(this->textbox, NULL, where, &dst);
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 - this->dialogue_bg->w / 2;
int d_y = where->h / 2 - this->dialogue_bg->h / 2;
dst = (SDL_Rect){d_x, d_y, this->dialogue_bg->w, this->dialogue_bg->h};
SDL_BlitSurface(this->dialogue_bg, NULL, where, &dst);
this->menu->dialogue->draw(where, d_x + 10, d_y + 10,
this->dialogue_bg->w - 10, this->dialogue_bg->h - 10);
}
}
protected:
MainMenu *menu;
HelpMenu *help;
SDL_Surface *bg;
2009-12-04 18:55:25 +01:00
SDL_Surface *infobox;
SDL_Surface *textbox;
SDL_Surface *dialogue_bg;
};
2009-11-28 09:22:19 +01:00
Gui::Gui()
{
this->focus = NULL;
this->bg_left = NULL;
this->bg_middle = NULL;
this->bg_right = NULL;
this->bg_submenu_left = NULL;
this->bg_submenu_middle = NULL;
this->bg_submenu_right = NULL;
2009-11-28 09:43:37 +01:00
this->background = NULL;
2009-11-28 09:59:42 +01:00
this->main_menu_bg = NULL;
2009-12-04 18:55:25 +01:00
this->infobox = NULL;
this->textbox = NULL;
this->default_font = NULL;
this->dialogue_bg = NULL;
2009-12-04 21:06:52 +01:00
this->small_font = NULL;
this->n_views = 0;
this->views = NULL;
2009-11-28 09:22:19 +01:00
/* Create the views */
MainView *mv = new MainView(this);
2009-12-04 21:45:17 +01:00
this->pushView(mv);
2009-11-28 09:22:19 +01:00
}
bool Gui::setTheme(const char *path)
{
this->bg_left = this->loadThemeImage(path, "bg_left.png");
this->bg_middle = this->loadThemeImage(path, "bg_middle.png");
this->bg_right = this->loadThemeImage(path, "bg_right.png");
this->bg_submenu_left = this->loadThemeImage(path, "bg_submenu_left.png");
this->bg_submenu_middle = this->loadThemeImage(path, "bg_submenu_middle.png");
this->bg_submenu_right = this->loadThemeImage(path, "bg_submenu_right.png");
2009-11-28 09:43:37 +01:00
this->background = this->loadThemeImage(path, "background.png");
2009-11-28 09:59:42 +01:00
this->main_menu_bg = this->loadThemeImage(path, "main_menu_bg.png");
2009-12-04 18:55:25 +01:00
this->infobox = this->loadThemeImage(path, "infobox.png");
this->textbox = this->loadThemeImage(path, "textbox.png");
this->dialogue_bg = this->loadThemeImage(path, "dialogue_box.png");
2009-11-28 09:43:37 +01:00
2009-12-04 21:06:52 +01:00
this->default_font = this->loadThemeFont(path, "font.ttf", 18);
this->small_font = this->loadThemeFont(path, "font.ttf", 16);
2009-11-28 09:22:19 +01:00
if (!this->bg_left || !this->bg_right || !this->bg_middle ||
!this->bg_submenu_left || !this->bg_submenu_right ||
!this->bg_submenu_middle ||
!this->dialogue_bg ||
2009-12-04 21:06:52 +01:00
!this->default_font ||
!this->small_font)
2009-11-28 09:22:19 +01:00
{
SDL_FreeSurface(this->bg_left);
SDL_FreeSurface(this->bg_middle);
SDL_FreeSurface(this->bg_right);
SDL_FreeSurface(this->bg_submenu_left);
SDL_FreeSurface(this->bg_submenu_middle);
SDL_FreeSurface(this->bg_submenu_right);
2009-11-28 09:43:37 +01:00
SDL_FreeSurface(this->background);
2009-11-28 09:59:42 +01:00
SDL_FreeSurface(this->main_menu_bg);
2009-12-04 18:55:25 +01:00
SDL_FreeSurface(this->infobox);
SDL_FreeSurface(this->dialogue_bg);
2009-12-04 18:55:25 +01:00
SDL_FreeSurface(this->textbox);
2009-11-28 09:22:19 +01:00
if (this->default_font)
delete this->default_font;
2009-12-04 21:06:52 +01:00
if (this->small_font)
delete this->small_font;
2009-11-28 09:22:19 +01:00
return false;
}
for (int i = 0; i < this->n_views; i++)
this->views[i]->updateTheme();
2009-11-28 09:22:19 +01:00
return true;
}
void Gui::runLogic(void)
{
2009-12-05 10:33:58 +01:00
GuiView *cur_view = this->peekView();
2009-12-05 10:33:58 +01:00
if (!this->is_active || !cur_view)
return;
2009-12-05 10:34:58 +01:00
cur_view->runLogic();
2009-11-28 09:22:19 +01:00
}
2009-12-04 21:45:17 +01:00
void Gui::pushView(GuiView *view)
2009-11-28 09:22:19 +01:00
{
int cur = this->n_views;
2009-11-28 09:22:19 +01:00
this->n_views++;
this->views = (GuiView**)xrealloc(this->views,
sizeof(GuiView*) * this->n_views);
this->views[cur] = view;
2009-11-28 09:22:19 +01:00
}
2009-12-04 21:45:17 +01:00
GuiView *Gui::popView()
{
this->n_views--;
if (this->n_views <= 0)
{
this->n_views = 0;
free(this->views);
return NULL;
}
this->views = (GuiView**)xrealloc(this->views,
sizeof(GuiView*) * this->n_views);
return this->views[this->n_views - 1];
}
2009-12-05 10:33:58 +01:00
void Gui::exitMenu()
2009-12-04 21:45:17 +01:00
{
2009-12-05 10:34:58 +01:00
printf("Exiting the menu system\n");
2009-12-04 21:45:17 +01:00
free(this->views);
this->views = NULL;
}
2009-11-28 09:22:19 +01:00
void Gui::pushEvent(SDL_Event *ev)
{
2009-12-05 10:33:58 +01:00
GuiView *cur_view = this->peekView();
if (!this->is_active || !cur_view)
return;
cur_view->pushEvent(ev);
2009-11-28 09:22:19 +01:00
}
void Gui::draw(SDL_Surface *where)
{
2009-12-05 10:33:58 +01:00
GuiView *cur_view = this->peekView();
if (!this->is_active || !cur_view)
2009-11-28 09:22:19 +01:00
return;
2009-11-28 09:43:37 +01:00
SDL_BlitSurface(this->background, NULL, screen, NULL);
2009-12-05 10:33:58 +01:00
cur_view->draw(where);
2009-11-28 09:43:37 +01:00
}
void Gui::activate()
{
this->is_active = true;
}
void Gui::deActivate()
{
this->is_active = false;
2009-11-28 09:22:19 +01:00
}
SDL_Surface *Gui::loadThemeImage(const char *dir, const char *what)
{
return IMG_Load(get_theme_path(dir, what));
2009-11-28 09:22:19 +01:00
}
2009-12-04 21:06:52 +01:00
Font *Gui::loadThemeFont(const char *dir, const char *what, int size)
2009-11-28 09:22:19 +01:00
{
TTF_Font *fnt;
2009-12-04 21:06:52 +01:00
fnt = read_and_alloc_font(get_theme_path(dir, what), size);
2009-11-28 09:22:19 +01:00
if (!fnt)
return NULL;
return new Font_TTF(fnt, 255,255,255);
}