X-Git-Url: https://git.verplant.org/?a=blobdiff_plain;f=lib%2Fgui%2Fmenu.cpp;h=ddddbb7fed08f80ab0469b497c50963e003bb032;hb=00a953f5f0e3ab98735736d34b1359756bf82f5c;hp=5e899a8849f8309ea6269bbc9329b0edd1f2b31e;hpb=28a78871d5b6d03c5267b9ef98c7082af5e41a29;p=supertux.git diff --git a/lib/gui/menu.cpp b/lib/gui/menu.cpp index 5e899a884..ddddbb7fe 100644 --- a/lib/gui/menu.cpp +++ b/lib/gui/menu.cpp @@ -152,15 +152,23 @@ Menu::set_current(Menu* menu) current_ = menu; } +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) +{ + list.second = 0; +} + /* Return a pointer to a new menu item */ MenuItem* -MenuItem::create(MenuItemKind kind_, const char *text_, int init_toggle_, Menu* target_menu_, int id, int* int_p_) +MenuItem::create(MenuItemKind kind_, const std::string& text_, int init_toggle_, Menu* target_menu_, int id_, int* int_p_) { - MenuItem *pnew_item = new MenuItem; + MenuItem *pnew_item = new MenuItem(kind_,id_); - pnew_item->kind = kind_; - pnew_item->text = (char*) malloc(sizeof(char) * (strlen(text_) + 1)); - strcpy(pnew_item->text, text_); + pnew_item->text = text_; if(kind_ == MN_TOGGLE) pnew_item->toggled = init_toggle_; @@ -168,19 +176,10 @@ MenuItem::create(MenuItemKind kind_, const char *text_, int init_toggle_, Menu* pnew_item->toggled = false; pnew_item->target_menu = target_menu_; - pnew_item->input = (char*) malloc(sizeof(char)); - pnew_item->input[0] = '\0'; - - if(kind_ == MN_STRINGSELECT) - { - pnew_item->list = (string_list_type*) malloc(sizeof(string_list_type)); - string_list_init(pnew_item->list); - } - else - pnew_item->list = NULL; - pnew_item->id = id; pnew_item->int_p = int_p_; + + pnew_item->list.second = 0; pnew_item->input_flickering = false; pnew_item->input_flickering_timer.init(true); @@ -190,25 +189,15 @@ MenuItem::create(MenuItemKind kind_, const char *text_, int init_toggle_, Menu* } void -MenuItem::change_text(const char *text_) +MenuItem::change_text(const std::string& text_) { - if (text_) - { - free(text); - text = (char*) malloc(sizeof(char )*(strlen(text_)+1)); - strcpy(text, text_); - } + text = text_; } void -MenuItem::change_input(const char *text_) +MenuItem::change_input(const std::string& text_) { - if(text) - { - free(input); - input = (char*) malloc(sizeof(char )*(strlen(text_)+1)); - strcpy(input, text_); - } + input = text_; } std::string MenuItem::get_input_with_symbol(bool active_item) @@ -229,9 +218,9 @@ std::string MenuItem::get_input_with_symbol(bool active_item) char str[1024]; if(input_flickering) - sprintf(str,"%s ",input); + sprintf(str,"%s ",input.c_str()); else - sprintf(str,"%s_",input); + sprintf(str,"%s_",input.c_str()); std::string string = str; @@ -304,9 +293,7 @@ Menu::~Menu() { for(unsigned int i = 0; i < item.size(); ++i) { - free(item[i].text); - free(item[i].input); - string_list_free(item[i].list); + item[i].list.first.clear(); } } } @@ -348,6 +335,13 @@ Menu::additem(MenuItem* pmenu_item) delete pmenu_item; } +/* Add an item to a menu */ +void +Menu::additem(const MenuItem& pmenu_item) +{ + item.push_back(pmenu_item); +} + void Menu::clear() { @@ -379,23 +373,23 @@ Menu::action() case MENU_ACTION_LEFT: if(item[active_item].kind == MN_STRINGSELECT - && item[active_item].list->num_items != 0) + && item[active_item].list.first.size() != 0) { - if(item[active_item].list->active_item > 0) - --item[active_item].list->active_item; + if(item[active_item].list.second != item[active_item].list.first.begin()) + --item[active_item].list.second; else - item[active_item].list->active_item = item[active_item].list->num_items-1; + item[active_item].list.second = item[active_item].list.first.end(); } break; case MENU_ACTION_RIGHT: if(item[active_item].kind == MN_STRINGSELECT - && item[active_item].list->num_items != 0) + && item[active_item].list.first.size() != 0) { - if(item[active_item].list->active_item < item[active_item].list->num_items-1) - ++item[active_item].list->active_item; + if(item[active_item].list.second != item[active_item].list.first.end()) + ++item[active_item].list.second; else - item[active_item].list->active_item = 0; + item[active_item].list.second = item[active_item].list.first.begin(); } break; @@ -438,13 +432,13 @@ Menu::action() if(item[active_item].kind == MN_TEXTFIELD || item[active_item].kind == MN_NUMFIELD) { - if(item[active_item].input != NULL) + if(!item[active_item].input.empty()) { - int i = strlen(item[active_item].input); + int i = item[active_item].input.size(); while(delete_character > 0) /* remove charactes */ { - item[active_item].input[i-1] = '\0'; + item[active_item].input.resize(i-1); delete_character--; } } @@ -455,19 +449,7 @@ Menu::action() if(item[active_item].kind == MN_TEXTFIELD || (item[active_item].kind == MN_NUMFIELD && mn_input_char >= '0' && mn_input_char <= '9')) { - if(item[active_item].input != NULL) - { - int i = strlen(item[active_item].input); - item[active_item].input = (char*) realloc(item[active_item].input,sizeof(char)*(i + 2)); - item[active_item].input[i] = mn_input_char; - item[active_item].input[i+1] = '\0'; - } - else - { - item[active_item].input = (char*) malloc(2*sizeof(char)); - item[active_item].input[0] = mn_input_char; - item[active_item].input[1] = '\0'; - } + item[active_item].input.push_back(mn_input_char); } case MENU_ACTION_NONE: @@ -475,17 +457,22 @@ Menu::action() } } - MenuItem& new_item = item[active_item]; - if(new_item.kind == MN_DEACTIVE - || new_item.kind == MN_LABEL - || new_item.kind == MN_HL) + if(active_item > 0 && active_item < (int)item.size()) { + // FIXME: wtf?! having a hack to avoid horizontal lines... + // Elegant solution would be to check for horizontal lines, right + // when it was asked to move menu up and down + if(item[active_item].kind == MN_DEACTIVE || + item[active_item].kind == MN_LABEL || + item[active_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; @@ -526,9 +513,11 @@ Menu::draw_item(DrawingContext& context, int shadow_size = 2; 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 = - int(text_font->get_text_width(string_list_active(pitem.list))); - + int list_width = 0; + std::set::iterator tmp = 0; + if(pitem.list.second != tmp) + list_width = int(text_font->get_text_width((*pitem.list.second))); + if (arrange_left) x_pos += 24 - menu_width/2 + (text_width + input_width + list_width)/2; @@ -637,7 +626,7 @@ Menu::draw_item(DrawingContext& context, Vector(list_pos_2, 18), Color(0,0,0,128), LAYER_GUI - 5); - context.draw_text_center(text_font, string_list_active(pitem.list), + 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, @@ -693,7 +682,7 @@ int Menu::get_width() const int menu_width = 0; for(unsigned int i = 0; i < item.size(); ++i) { - int w = strlen(item[i].text) + (item[i].input ? strlen(item[i].input) + 1 : 0) + strlen(string_list_active(item[i].list)); + 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); if( w > menu_width ) { menu_width = w; @@ -714,8 +703,9 @@ int Menu::get_height() const void Menu::draw(DrawingContext& context) { + int menu_height = get_height(); - int menu_width = get_width(); + int menu_width = get_width(); /* Draw a transparent background */ context.draw_filled_rect( @@ -779,7 +769,7 @@ Menu::event(SDL_Event& event) /* 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) { @@ -807,7 +797,7 @@ Menu::event(SDL_Event& event) 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 = ' '; @@ -857,7 +847,7 @@ Menu::event(SDL_Event& event) } 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;