From 5f6cec7c2fe2409f5b7f63584e666a3502138718 Mon Sep 17 00:00:00 2001 From: "Julien \"_FrnchFrgg_\" RIVAUD" Date: Sun, 7 Aug 2016 17:20:43 +0200 Subject: [PATCH] Improve placement of Dropdown popups. When an item in the menu corresponds to the currently displayed choice, vertically align the item with the button on menu popup. --- gtk2_ardour/ardour_dropdown.cc | 27 +++++++++++++++++++++++---- 1 file changed, 23 insertions(+), 4 deletions(-) diff --git a/gtk2_ardour/ardour_dropdown.cc b/gtk2_ardour/ardour_dropdown.cc index eabed85c02..ec63c8262e 100644 --- a/gtk2_ardour/ardour_dropdown.cc +++ b/gtk2_ardour/ardour_dropdown.cc @@ -61,6 +61,8 @@ ArdourDropdown::~ArdourDropdown () void ArdourDropdown::position_menu(int& x, int& y, bool& push_in) { + using namespace Menu_Helpers; + /* TODO: lacks support for rotated dropdown buttons */ if (!has_screen () || !get_has_window ()) { @@ -124,14 +126,31 @@ ArdourDropdown::position_menu(int& x, int& y, bool& push_in) { } /* For the y position, try in order: - * a) align the top of the menu with the bottom of the button if there is + * a) if there is a menu item with the same text as the button, align it + * with the button, unless that makes the menu overflow the monitor. + * b) align the top of the menu with the bottom of the button if there is * enough room below the button; - * b) align the bottom of the menu with the top of the button if there is + * c) align the bottom of the menu with the top of the button if there is * enough room above the button; - * c) align the bottom of the menu with the bottom of the monitor if there + * d) align the bottom of the menu with the bottom of the monitor if there * is enough room, but avoid moving the menu to another monitor */ - if (y + allocation.get_height() + menu_req.height <= monitor.get_y() + monitor.get_height()) { + const MenuList& items = _menu.items (); + const std::string button_text = get_text(); + int offset = 0; + + MenuList::const_iterator i = items.begin(); + for ( ; i != items.end(); ++i) { + if (button_text == ((std::string) i->get_label())) { + break; + } + offset += i->size_request().height; + } + if (i != items.end() && + y - offset >= monitor.get_y() && + y - offset + menu_req.height <= monitor.get_y() + monitor.get_height()) { + y -= offset; + } else if (y + allocation.get_height() + menu_req.height <= monitor.get_y() + monitor.get_height()) { y += allocation.get_height(); /* a) */ } else if ((y - menu_req.height) >= monitor.get_y()) { y -= menu_req.height; /* b) */ -- 2.30.2