Close several PopupWindows at the same time w/one click

Clicking outside a popup window we can close several popup
windows (e.g. tool box tooltip + tool box group popup, or brush pop +
brush params popup).

Before this change a kMouseDownMessage in a PopupWindow will close the
window only if the Manager::getTopWindow() was equal to the PopupWindow.
This commit is contained in:
David Capello 2021-05-15 14:33:29 -03:00
parent e4e8bfb246
commit 54c286407b
5 changed files with 31 additions and 8 deletions

View File

@ -58,7 +58,19 @@ void show_popup_menu(PopupWindow* popupWindow,
const gfx::Point& pt,
Display* display)
{
// Add the menu window region when it popups to the the BrushPopup
// hot region, so when we click inside the popup menu it doesn't
// close the BrushPopup.
obs::scoped_connection c = popupMenu->OpenPopup.connect([popupWindow, popupMenu]{
gfx::Region rgn(popupWindow->boundsOnScreen());
rgn |= gfx::Region(popupMenu->boundsOnScreen());
popupWindow->setHotRegion(rgn);
});
popupMenu->showPopup(pt, display);
// Restore hot region of the BrushPopup window
popupWindow->setHotRegion(gfx::Region(popupWindow->boundsOnScreen()));
}
class SelectBrushItem : public ButtonSet::Item {
@ -322,7 +334,7 @@ private:
} // anonymous namespace
BrushPopup::BrushPopup()
: PopupWindow("", ClickBehavior::CloseOnClickInOtherWindow)
: PopupWindow("", ClickBehavior::CloseOnClickOutsideHotRegion)
, m_standardBrushes(3)
, m_customBrushes(nullptr)
{

View File

@ -163,6 +163,13 @@ public:
SkinPartPtr part(new SkinPart);
part->setBitmap(0, BrushPopup::createSurfaceForBrush(BrushRef(nullptr)));
addItem(part);
m_popupWindow.Open.connect(
[this]{
gfx::Region rgn(m_popupWindow.boundsOnScreen());
rgn |= gfx::Region(this->boundsOnScreen());
m_popupWindow.setHotRegion(rgn);
});
}
~BrushTypeField() {
@ -221,10 +228,6 @@ private:
m_popupWindow.regenerate(display(), popupPosCandidate());
m_popupWindow.setBrush(brush.get());
Region rgn(m_popupWindow.boundsOnScreen().createUnion(boundsOnScreen()));
m_popupWindow.setHotRegion(rgn);
m_popupWindow.openWindow();
}

View File

@ -214,6 +214,11 @@ Menu::~Menu()
}
}
void Menu::onOpenPopup()
{
OpenPopup();
}
//////////////////////////////////////////////////////////////////////
// MenuBox
@ -350,6 +355,8 @@ void Menu::showPopup(const gfx::Point& pos,
// New window and new menu-box
std::unique_ptr<Window> window(new Window(Window::WithoutTitleBar));
window->Open.connect([this]{ this->onOpenPopup(); });
MenuBox* menubox = new MenuBox();
MenuBaseData* base = menubox->createBase();
base->was_clicked = true;

View File

@ -37,10 +37,13 @@ namespace ui {
return m_menuitem;
}
obs::signal<void()> OpenPopup;
protected:
virtual void onPaint(PaintEvent& ev) override;
virtual void onResize(ResizeEvent& ev) override;
virtual void onSizeHint(SizeHintEvent& ev) override;
virtual void onOpenPopup();
private:
void setOwnerMenuItem(MenuItem* ownerMenuItem) {

View File

@ -134,9 +134,7 @@ bool PopupWindow::onProcessMessage(Message* msg)
break;
case kMouseDownMessage:
if (m_filtering &&
manager()->getTopWindow() == this &&
msg->display()) {
if (m_filtering && msg->display()) {
gfx::Point mousePos = static_cast<MouseMessage*>(msg)->position();
gfx::Point screenPos = msg->display()->nativeWindow()->pointToScreen(mousePos);