// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#ifndef WIN32
+#include <config.h>
+
#include <sys/types.h>
#include <ctype.h>
#endif
#include <string>
#include <cassert>
-#include "../app/globals.h"
-#include "../gui/menu.h"
-#include "../video/screen.h"
-#include "../video/drawing_context.h"
-#include "../app/setup.h"
-#include "../special/timer.h"
-#include "../app/gettext.h"
-#include "../math/vector.h"
+#include "app/globals.h"
+#include "menu.h"
+#include "video/screen.h"
+#include "video/drawing_context.h"
+#include "app/setup.h"
+#include "app/gettext.h"
+#include "math/vector.h"
using namespace SuperTux;
current_ = menu;
}
-MenuItem::MenuItem(MenuItemKind _kind, int _id) : kind(_kind) , id(_id)
+MenuItem::MenuItem(MenuItemKind _kind, int _id)
+ : kind(_kind) , id(_id)
{
- list.second = 0;
}
-MenuItem::MenuItem(MenuItemKind _kind, int _id, const std::string& _text) : kind(_kind) , id(_id) , text(_text)
+MenuItem::MenuItem(MenuItemKind _kind, int _id, const std::string& _text)
+ : kind(_kind) , id(_id) , text(_text)
{
- list.second = 0;
}
/* Return a pointer to a new menu item */
pnew_item->target_menu = target_menu_;
pnew_item->int_p = int_p_;
-
- pnew_item->list.second = 0;
+
+ pnew_item->selected = 0;
pnew_item->input_flickering = false;
pnew_item->input_flickering_timer.init(true);
item->change_input(oss.str().c_str());
}
-/* Free a menu and all its items */
Menu::~Menu()
{
- if(item.size() != 0)
- {
- for(unsigned int i = 0; i < item.size(); ++i)
- {
- item[i].list.first.clear();
- }
- }
}
-
Menu::Menu()
{
hit_item = -1;
Menu::additem(MenuItemKind kind_, const std::string& text_, int toggle_, Menu* menu_, int id, int* int_p)
{
additem(MenuItem::create(kind_, text_.c_str(), toggle_, menu_, id, int_p));
+
+ /* If a new menu is being built, the active item shouldn't be set to something
+ that isnt selectable. Keep setting the active item to the most recently
+ added item until a selectable entry is found.
+ */
+ if (item[active_item].kind == MN_HL
+ || item[active_item].kind == MN_LABEL
+ || item[active_item].kind == MN_DEACTIVE)
+ active_item = item.size() - 1;
}
/* Add an item to a menu */
Menu::clear()
{
item.clear();
+ active_item = 0;
}
/* Process actions done on the menu */
hit_item = -1;
if(item.size() != 0)
{
+ int last_active_item = active_item;
switch(menuaction)
{
case MENU_ACTION_UP:
- if (active_item > 0)
- --active_item;
- else
- active_item = int(item.size())-1;
+ do {
+ if (active_item > 0)
+ --active_item;
+ else
+ active_item = int(item.size())-1;
+ } while ((item[active_item].kind == MN_HL
+ || item[active_item].kind == MN_LABEL
+ || item[active_item].kind == MN_DEACTIVE)
+ && (active_item != last_active_item));
+
break;
case MENU_ACTION_DOWN:
- if(active_item < int(item.size())-1)
- ++active_item;
- else
- active_item = 0;
+ do {
+ if(active_item < int(item.size())-1 )
+ ++active_item;
+ else
+ active_item = 0;
+ } while ((item[active_item].kind == MN_HL
+ || item[active_item].kind == MN_LABEL
+ || item[active_item].kind == MN_DEACTIVE)
+ && (active_item != last_active_item));
+
break;
case MENU_ACTION_LEFT:
- if(item[active_item].kind == MN_STRINGSELECT
- && item[active_item].list.first.size() != 0)
- {
- if(item[active_item].list.second != item[active_item].list.first.begin())
- --item[active_item].list.second;
- else
- item[active_item].list.second = item[active_item].list.first.end();
- }
+ if(item[active_item].kind == MN_STRINGSELECT) {
+ if(item[active_item].selected > 0)
+ item[active_item].selected--;
+ else
+ item[active_item].selected = item[active_item].list.size()-1;
+ }
break;
case MENU_ACTION_RIGHT:
- if(item[active_item].kind == MN_STRINGSELECT
- && item[active_item].list.first.size() != 0)
- {
- if(item[active_item].list.second != item[active_item].list.first.end())
- ++item[active_item].list.second;
- else
- item[active_item].list.second = item[active_item].list.first.begin();
- }
+ if(item[active_item].kind == MN_STRINGSELECT) {
+ if(item[active_item].selected+1 < item[active_item].list.size())
+ item[active_item].selected++;
+ else
+ item[active_item].selected = 0;
+ }
break;
case MENU_ACTION_HIT:
}
}
- MenuItem& new_item = item[active_item];
- if(new_item.kind == MN_DEACTIVE
- || new_item.kind == MN_LABEL
- || new_item.kind == MN_HL)
- {
- // Skip the horzontal line item
- if (menuaction != MENU_ACTION_UP && menuaction != MENU_ACTION_DOWN)
- menuaction = MENU_ACTION_DOWN;
-
- if (item.size() > 1)
- action();
- }
menuaction = MENU_ACTION_NONE;
int text_width = int(text_font->get_text_width(pitem.text));
int input_width = int(text_font->get_text_width(pitem.input) + 10);
int list_width = 0;
- std::set<std::string>::iterator tmp = 0;
- if(pitem.list.second != tmp)
- list_width = int(text_font->get_text_width((*pitem.list.second)));
+ if(pitem.list.size() > 0) {
+ list_width = (int) text_font->get_text_width(pitem.list[pitem.selected]);
+ }
if (arrange_left)
x_pos += 24 - menu_width/2 + (text_width + input_width + list_width)/2;
{
case MN_DEACTIVE:
{
- context.draw_text_center(deactive_font, pitem.text,
- Vector(0, y_pos - int(deactive_font->get_height()/2)),
- LAYER_GUI);
+ context.draw_text(deactive_font, pitem.text,
+ Vector(screen->w/2, y_pos - int(deactive_font->get_height()/2)),
+ CENTER_ALLIGN, LAYER_GUI);
break;
}
}
case MN_LABEL:
{
- context.draw_text_center(label_font,
- pitem.text, Vector(0, y_pos - int(label_font->get_height()/2)),
- LAYER_GUI);
+ context.draw_text(label_font, pitem.text,
+ Vector(screen->w/2, y_pos - int(label_font->get_height()/2)),
+ CENTER_ALLIGN, LAYER_GUI);
break;
}
case MN_TEXTFIELD:
context.draw_text(field_font,
pitem.get_input_with_symbol(true),
Vector(input_pos, y_pos - int(field_font->get_height()/2)),
- LAYER_GUI);
+ LEFT_ALLIGN, LAYER_GUI);
else
context.draw_text(field_font,
pitem.get_input_with_symbol(false),
Vector(input_pos, y_pos - int(field_font->get_height()/2)),
- LAYER_GUI);
+ LEFT_ALLIGN, LAYER_GUI);
}
else
context.draw_text(field_font, pitem.input,
Vector(input_pos, y_pos - int(field_font->get_height()/2)),
- LAYER_GUI);
+ LEFT_ALLIGN, LAYER_GUI);
context.draw_text(text_font, pitem.text,
Vector(text_pos, y_pos - int(text_font->get_height()/2)),
- LAYER_GUI);
+ LEFT_ALLIGN, LAYER_GUI);
break;
}
case MN_STRINGSELECT:
Vector(list_pos_2, 18),
Color(0,0,0,128), LAYER_GUI - 5);
- context.draw_text_center(text_font, (*pitem.list.second),
- Vector(text_pos, y_pos - int(text_font->get_height()/2)),
- LAYER_GUI);
- context.draw_text_center(text_font, pitem.text,
- Vector(list_pos_2/2, y_pos - int(text_font->get_height()/2)),
- LAYER_GUI);
+ context.draw_text(text_font, pitem.list[pitem.selected],
+ Vector(screen->w/2 + text_pos, y_pos - int(text_font->get_height()/2)),
+ CENTER_ALLIGN, LAYER_GUI);
+ context.draw_text(text_font, pitem.text,
+ Vector(screen->w/2 + list_pos_2/2, y_pos - int(text_font->get_height()/2)),
+ CENTER_ALLIGN, LAYER_GUI);
break;
}
case MN_BACK:
{
- context.draw_text_center(text_font, pitem.text,
- Vector(0, y_pos - int(text_font->get_height()/2)),
- LAYER_GUI);
+ context.draw_text(text_font, pitem.text,
+ Vector(screen->w/2, y_pos - int(text_font->get_height()/2)),
+ CENTER_ALLIGN, LAYER_GUI);
context.draw_surface(back,
Vector(x_pos + text_width/2 + 16, y_pos - 8),
LAYER_GUI);
case MN_TOGGLE:
{
- context.draw_text_center(text_font, pitem.text,
- Vector(0, y_pos - (text_font->get_height()/2)),
- LAYER_GUI);
+ context.draw_text(text_font, pitem.text,
+ Vector(screen->w/2, y_pos - (text_font->get_height()/2)),
+ CENTER_ALLIGN, LAYER_GUI);
if(pitem.toggled)
context.draw_surface(checkbox_checked,
break;
}
case MN_ACTION:
- context.draw_text_center(text_font, pitem.text,
- Vector(0, y_pos - int(text_font->get_height()/2)),
- LAYER_GUI);
+ context.draw_text(text_font, pitem.text,
+ Vector(screen->w/2, y_pos - int(text_font->get_height()/2)),
+ CENTER_ALLIGN, LAYER_GUI);
break;
case MN_GOTO:
- context.draw_text_center(text_font, pitem.text,
- Vector(0, y_pos - int(text_font->get_height()/2)),
- LAYER_GUI);
+ context.draw_text(text_font, pitem.text,
+ Vector(screen->w/2, y_pos - int(text_font->get_height()/2)),
+ CENTER_ALLIGN, LAYER_GUI);
break;
}
}
int menu_width = 0;
for(unsigned int i = 0; i < item.size(); ++i)
{
- int w = item[i].text.size() + item[i].input.size() + 1; //+ ((item[i].list.second != item[i].list.first.end()) ? (strlen((*(item[i].list.second)).c_str())) : 0);
+ int w = item[i].text.size() + item[i].input.size() + 1;
if( w > menu_width )
{
menu_width = w;
/* An International Character. */
}
- if(item[active_item].kind == MN_CONTROLFIELD_KB)
+ if(item.size() > 0 && item[active_item].kind == MN_CONTROLFIELD_KB)
{
if(key == SDLK_ESCAPE)
{
menuaction = MENU_ACTION_RIGHT;
break;
case SDLK_SPACE:
- if(item[active_item].kind == MN_TEXTFIELD)
+ if(item.size() > 0 && item[active_item].kind == MN_TEXTFIELD)
{
menuaction = MENU_ACTION_INPUT;
mn_input_char = ' ';
joystick_timer.stop();
}
break;
+ case SDL_JOYHATMOTION:
+ if(event.jhat.value & SDL_HAT_UP) {
+ menuaction = MENU_ACTION_UP;
+ } else if(event.jhat.value & SDL_HAT_DOWN) {
+ menuaction = MENU_ACTION_DOWN;
+ }
+ break;
case SDL_JOYBUTTONDOWN:
- if (item[active_item].kind == MN_CONTROLFIELD_JS)
+ if (item.size() > 0 && item[active_item].kind == MN_CONTROLFIELD_JS)
{
// FIXME: This next line does nothing useable, right?
// *item[active_item].int_p = key;
y > pos_y - get_height()/2 &&
y < pos_y + get_height()/2)
{
- active_item = (y - (pos_y - get_height()/2)) / 24;
- if(MouseCursor::current())
- MouseCursor::current()->set_state(MC_LINK);
+ int new_active_item = (y - (pos_y - get_height()/2)) / 24;
+
+ /* only change the mouse focus to a selectable item */
+ if ((item[new_active_item].kind != MN_HL)
+ && (item[new_active_item].kind != MN_LABEL)
+ && (item[new_active_item].kind != MN_DEACTIVE))
+ active_item = new_active_item;
+
+ if(MouseCursor::current())
+ MouseCursor::current()->set_state(MC_LINK);
}
else
{
- if(MouseCursor::current())
- MouseCursor::current()->set_state(MC_NORMAL);
+ if(MouseCursor::current())
+ MouseCursor::current()->set_state(MC_NORMAL);
}
}
break;
}
}
-
-// EOF //