mirror of
https://github.com/wesnoth/wesnoth
synced 2025-04-13 20:57:09 +00:00
gui: Better positioning of submenus in the main UI (#8517)
This makes it possible to fetch the on-screen coordinates of a drop down menu item as the menu is dismissed by clicking on it so the caller can use these coordinates to make a more informed decision as to where to spawn a submenu, improving the previous mechanism wherein the submenu would have its top left corner set at the mouse's location which would produce different results depending on where exactly in the menu item's box the mouse was at the time the parent menu was dismissed.
This commit is contained in:
parent
20c95a472c
commit
5a7bd7c51f
2
changelog_entries/submenu-positioning.md
Normal file
2
changelog_entries/submenu-positioning.md
Normal file
|
@ -0,0 +1,2 @@
|
|||
### User interface
|
||||
* Submenus are now positioned at the location of the menu item that spawned them, rather than the location of the mouse cursor at the time of click
|
|
@ -85,6 +85,7 @@ drop_down_menu::drop_down_menu(styled_widget* parent, const std::vector<config>&
|
|||
, items_(items.begin(), items.end())
|
||||
, button_pos_(parent->get_rectangle())
|
||||
, selected_item_(selected_item)
|
||||
, selected_item_pos_(-1, -1)
|
||||
, use_markup_(parent->get_use_markup())
|
||||
, keep_open_(keep_open)
|
||||
, mouse_down_happened_(false)
|
||||
|
@ -241,7 +242,17 @@ void drop_down_menu::pre_show()
|
|||
|
||||
void drop_down_menu::post_show()
|
||||
{
|
||||
selected_item_ = find_widget<listbox>("list", true).get_selected_row();
|
||||
const listbox& list = find_widget<listbox>("list", true);
|
||||
selected_item_ = list.get_selected_row();
|
||||
if(selected_item_ != -1) {
|
||||
const grid* row_grid = list.get_row_grid(selected_item_);
|
||||
if(row_grid) {
|
||||
selected_item_pos_.x = row_grid->get_x();
|
||||
selected_item_pos_.y = row_grid->get_y();
|
||||
}
|
||||
} else {
|
||||
selected_item_pos_.x = selected_item_pos_.y = -1;
|
||||
}
|
||||
}
|
||||
|
||||
boost::dynamic_bitset<> drop_down_menu::get_toggle_states() const
|
||||
|
|
|
@ -44,6 +44,11 @@ public:
|
|||
return selected_item_;
|
||||
}
|
||||
|
||||
point selected_item_pos() const
|
||||
{
|
||||
return selected_item_pos_;
|
||||
}
|
||||
|
||||
/** If a toggle button widget is present, returns the toggled state of each row's button. */
|
||||
boost::dynamic_bitset<> get_toggle_states() const;
|
||||
|
||||
|
@ -86,6 +91,7 @@ private:
|
|||
SDL_Rect button_pos_;
|
||||
|
||||
int selected_item_;
|
||||
point selected_item_pos_;
|
||||
|
||||
bool use_markup_;
|
||||
|
||||
|
|
|
@ -417,11 +417,19 @@ void command_executor::show_menu(const std::vector<config>& items_arg, int xloc,
|
|||
get_menu_images(gui, items);
|
||||
|
||||
int res = -1;
|
||||
point selection_pos;
|
||||
{
|
||||
SDL_Rect pos {xloc, yloc, 1, 1};
|
||||
gui2::dialogs::drop_down_menu mmenu(pos, items, -1, true, false); // TODO: last value should be variable
|
||||
if(mmenu.show()) {
|
||||
res = mmenu.selected_item();
|
||||
if(res >= 0) {
|
||||
// Get selection coordinates for a potential submenu below
|
||||
selection_pos = mmenu.selected_item_pos();
|
||||
// Compensate for borders
|
||||
selection_pos.x--;
|
||||
selection_pos.y--;
|
||||
}
|
||||
}
|
||||
} // This will kill the dialog.
|
||||
if (res < 0 || std::size_t(res) >= items.size()) return;
|
||||
|
@ -429,8 +437,7 @@ void command_executor::show_menu(const std::vector<config>& items_arg, int xloc,
|
|||
std::string id = items[res]["id"];
|
||||
const theme::menu* submenu = gui.get_theme().get_menu_item(id);
|
||||
if (submenu) {
|
||||
auto [x, y] = sdl::get_mouse_location();
|
||||
this->show_menu(submenu->items(), x, y, submenu->is_context(), gui);
|
||||
this->show_menu(submenu->items(), selection_pos.x, selection_pos.y, submenu->is_context(), gui);
|
||||
} else {
|
||||
hotkey::ui_command cmd = hotkey::ui_command(id, res);
|
||||
do_execute_command(cmd);
|
||||
|
|
Loading…
Reference in New Issue
Block a user