Use GUI2 for game menus
There are still a few minor glitches with the implementation: - The first menu-item is always outlined, as if selected - Submenus appear at the mouse click location instead of anchored to their item - The editor groups menu may cover up its button, due to the menu not knowing the size of the button
This commit is contained in:
parent
f6974f01f6
commit
8699ad0a05
4 changed files with 97 additions and 36 deletions
|
@ -4,7 +4,14 @@
|
|||
###
|
||||
|
||||
#define FORMULA_WINDOW_HEIGHT
|
||||
min(if(window_height > 0, window_height, screen_width), max(button_y, screen_height - button_h - button_y)) #enddef
|
||||
min(
|
||||
if(window_height > 0,
|
||||
window_height,
|
||||
screen_width
|
||||
),
|
||||
max(button_y, screen_height - button_h - button_y)
|
||||
)
|
||||
#enddef
|
||||
|
||||
[window]
|
||||
id = "drop_down_list"
|
||||
|
@ -17,7 +24,14 @@ min(if(window_height > 0, window_height, screen_width), max(button_y, screen_hei
|
|||
height = "({FORMULA_WINDOW_HEIGHT})"
|
||||
## Show the droplist below or above the button, wherever we have enough space. Below is prefered.
|
||||
x = "(min(button_x, screen_width - window_width))"
|
||||
y = "(if(screen_height - button_h - button_y > {FORMULA_WINDOW_HEIGHT}, button_h + button_y, button_y - {FORMULA_WINDOW_HEIGHT}))"
|
||||
y = "(
|
||||
if(screen_height - button_h - button_y >= best_height,
|
||||
button_h + button_y,
|
||||
button_y - best_height
|
||||
)
|
||||
where
|
||||
best_height = {FORMULA_WINDOW_HEIGHT}
|
||||
)"
|
||||
automatic_placement = false
|
||||
|
||||
[tooltip]
|
||||
|
@ -57,6 +71,7 @@ min(if(window_height > 0, window_height, screen_width), max(button_y, screen_hei
|
|||
[toggle_panel]
|
||||
definition = "default"
|
||||
[grid]
|
||||
id = "menu_item"
|
||||
|
||||
[row]
|
||||
|
||||
|
@ -80,6 +95,17 @@ min(if(window_height > 0, window_height, screen_width), max(button_y, screen_hei
|
|||
id = "label"
|
||||
[/label]
|
||||
[/column]
|
||||
|
||||
[column]
|
||||
grow_factor = 1
|
||||
border = "all"
|
||||
border_size = 5
|
||||
horizontal_grow = "false"
|
||||
horizontal_alignment = "right"
|
||||
[label]
|
||||
id = "label_right"
|
||||
[/label]
|
||||
[/column]
|
||||
[/row]
|
||||
[/grid]
|
||||
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
#include "gui/widgets/integer_selector.hpp"
|
||||
#include "gui/widgets/window.hpp"
|
||||
#include "gui/widgets/settings.hpp"
|
||||
#include "gui/widgets/image.hpp"
|
||||
|
||||
#include "utils/functional.hpp"
|
||||
|
||||
|
@ -65,12 +66,32 @@ void tdrop_down_list::pre_show(twindow& window)
|
|||
item["label"] = entry["icon"];
|
||||
data.emplace("icon", item);
|
||||
|
||||
item["label"] = entry["label"];
|
||||
item["tooltip"] = entry["tooltip"];
|
||||
item["use_markup"] = use_markup_ ? "true" : "false";
|
||||
data.emplace("label", item);
|
||||
if(!entry.has_attribute("image")) {
|
||||
item["label"] = entry["label"];
|
||||
item["tooltip"] = entry["tooltip"];
|
||||
item["use_markup"] = use_markup_ ? "true" : "false";
|
||||
data.emplace("label", item);
|
||||
}
|
||||
|
||||
list.add_row(data);
|
||||
if(entry.has_attribute("label_right")) {
|
||||
item["label"] = entry["label_right"];
|
||||
item["tooltip"] = entry["tooltip"];
|
||||
item["use_markup"] = use_markup_ ? "true" : "false";
|
||||
data.emplace("label_right", item);
|
||||
}
|
||||
|
||||
tgrid& new_row = list.add_row(data);
|
||||
|
||||
if(entry.has_attribute("image")) {
|
||||
timage* img = new timage;
|
||||
img->set_definition("default");
|
||||
img->set_label(entry["image"]);
|
||||
img->set_tooltip(entry["tooltip"]);
|
||||
tgrid* mi_grid = dynamic_cast<tgrid*>(new_row.find("menu_item", false));
|
||||
if(mi_grid) {
|
||||
delete mi_grid->swap_child("label", img, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
list.select_row(selected_item_);
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
#include "gui/dialogs/message.hpp"
|
||||
#include "gui/dialogs/screenshot_notification.hpp"
|
||||
#include "gui/dialogs/transient_message.hpp"
|
||||
#include "gui/dialogs/drop_down_list.hpp"
|
||||
#include "gui/widgets/window.hpp"
|
||||
#include "wml_separators.hpp"
|
||||
#include "filesystem.hpp"
|
||||
|
@ -363,13 +364,15 @@ void command_executor::show_menu(const std::vector<std::string>& items_arg, int
|
|||
std::vector<std::string> items = items_arg;
|
||||
if (items.empty()) return;
|
||||
|
||||
std::vector<std::string> menu = get_menu_images(gui, items);
|
||||
int res = 0;
|
||||
std::vector<config> menu = get_menu_images(gui, items);
|
||||
int res = -1;
|
||||
{
|
||||
gui::dialog mmenu = gui::dialog(gui.video(),"","",
|
||||
gui::MESSAGE, gui::dialog::hotkeys_style);
|
||||
mmenu.set_menu(menu);
|
||||
res = mmenu.show(xloc, yloc);
|
||||
SDL_Rect pos = {xloc, yloc, 1, 1};
|
||||
gui2::tdrop_down_list mmenu(pos, menu, 0, false);
|
||||
mmenu.show(gui.video());
|
||||
if(mmenu.get_retval() == gui2::twindow::OK) {
|
||||
res = mmenu.selected_item();
|
||||
}
|
||||
} // This will kill the dialog.
|
||||
if (res < 0 || size_t(res) >= items.size()) return;
|
||||
|
||||
|
@ -405,6 +408,13 @@ void command_executor::execute_action(const std::vector<std::string>& items_arg,
|
|||
|
||||
std::string command_executor::get_menu_image(display& disp, const std::string& command, int index) const {
|
||||
|
||||
// TODO: Find a way to do away with the fugly special markup
|
||||
if(command[0] == '&') {
|
||||
size_t n = command.find_first_of('=');
|
||||
if(n != std::string::npos)
|
||||
return command.substr(1, n - 1);
|
||||
}
|
||||
|
||||
const std::string base_image_name = "icons/action/" + command + "_25.png";
|
||||
const std::string pressed_image_name = "icons/action/" + command + "_25-pressed.png";
|
||||
|
||||
|
@ -439,32 +449,45 @@ std::string command_executor::get_menu_image(display& disp, const std::string& c
|
|||
}
|
||||
}
|
||||
|
||||
std::vector<std::string> command_executor::get_menu_images(display& disp, const std::vector<std::string>& items) {
|
||||
std::vector<std::string> result;
|
||||
bool has_image = false;
|
||||
std::vector<config> command_executor::get_menu_images(display& disp, const std::vector<std::string>& items) {
|
||||
std::vector<config> result;
|
||||
|
||||
for (size_t i = 0; i < items.size(); ++i) {
|
||||
for(size_t i = 0; i < items.size(); ++i) {
|
||||
std::string const& item = items[i];
|
||||
const hotkey::HOTKEY_COMMAND hk = hotkey::get_id(item);
|
||||
result.emplace_back();
|
||||
|
||||
std::stringstream str;
|
||||
//see if this menu item has an associated image
|
||||
std::string img(get_menu_image(disp, item, i));
|
||||
if (img.empty() == false) {
|
||||
has_image = true;
|
||||
str << IMAGE_PREFIX << img << COLUMN_SEPARATOR;
|
||||
result.back()["icon"] = img;
|
||||
}
|
||||
|
||||
const theme::menu* menu = disp.get_theme().get_menu_item(item);
|
||||
if (hk == hotkey::HOTKEY_NULL) {
|
||||
if (menu)
|
||||
str << menu->title();
|
||||
else
|
||||
str << item.substr(0, item.find_last_not_of(' ') + 1) << COLUMN_SEPARATOR;
|
||||
result.back()["label"] = menu->title();
|
||||
else {
|
||||
std::string label(item.begin(), item.begin() + item.find_last_not_of(' ') + 1);
|
||||
|
||||
// TODO: To away with the fugly markup, both '=' and 0x01
|
||||
size_t i = label.find_first_of('=');
|
||||
if(i != std::string::npos)
|
||||
result.back()["label"] = label.substr(i + 1);
|
||||
else {
|
||||
i = label.find_first_of(1);
|
||||
if(i != std::string::npos) {
|
||||
result.back()["label_right"] = label.substr(i + 1);
|
||||
result.back()["image"] = label.substr(1, i - 1);
|
||||
} else {
|
||||
result.back()["label"] = label;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
||||
if (menu)
|
||||
str << menu->title();
|
||||
result.back()["label"] = menu->title();
|
||||
else {
|
||||
std::string desc = hotkey::get_description(item);
|
||||
if (hk == HOTKEY_ENDTURN) {
|
||||
|
@ -473,17 +496,8 @@ std::vector<std::string> command_executor::get_menu_images(display& disp, const
|
|||
desc = b->title();
|
||||
}
|
||||
}
|
||||
str << desc << COLUMN_SEPARATOR << hotkey::get_names(item);
|
||||
}
|
||||
}
|
||||
|
||||
result.push_back(str.str());
|
||||
}
|
||||
//If any of the menu items have an image, create an image column
|
||||
if (has_image) {
|
||||
for (std::vector<std::string>::iterator i = result.begin(); i != result.end(); ++i) {
|
||||
if (*(i->begin()) != IMAGE_PREFIX) {
|
||||
i->insert(i->begin(), COLUMN_SEPARATOR);
|
||||
result.back()["label"] = desc;
|
||||
result.back()["label_right"] = hotkey::get_names(item);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -130,7 +130,7 @@ public:
|
|||
// Returns the appropriate menu image. Checkable items will get a checked/unchecked image.
|
||||
std::string get_menu_image(display& disp, const std::string& command, int index=-1) const;
|
||||
// Returns a vector of images for a given menu.
|
||||
std::vector<std::string> get_menu_images(display &, const std::vector<std::string>& items_arg);
|
||||
std::vector<config> get_menu_images(display &, const std::vector<std::string>& items_arg);
|
||||
|
||||
virtual void show_menu(const std::vector<std::string>& items_arg, int xloc, int yloc, bool context_menu, display& gui);
|
||||
void execute_action(const std::vector<std::string>& items_arg, int xloc, int yloc, bool context_menu, display& gui);
|
||||
|
|
Loading…
Add table
Reference in a new issue