From 75894073d4c74b030053977e590d8e55f59cde9c Mon Sep 17 00:00:00 2001 From: David Capello Date: Thu, 8 Sep 2016 19:48:29 -0300 Subject: [PATCH] Make fg/bg color selector dialogs resizable (fix #1250) --- src/app/ui/color_button.cpp | 3 +- src/app/ui/color_popup.cpp | 23 +++++++++++++- src/app/ui/color_popup.h | 3 ++ src/app/ui/popup_window_pin.cpp | 17 ++++------- src/app/ui/popup_window_pin.h | 2 +- src/ui/popup_window.cpp | 54 ++++++++++++++++++++++++++------- src/ui/popup_window.h | 6 +++- src/ui/window.cpp | 9 +++++- src/ui/window.h | 4 ++- 9 files changed, 93 insertions(+), 28 deletions(-) diff --git a/src/app/ui/color_button.cpp b/src/app/ui/color_button.cpp index 43e4d8f73..bd99d41bc 100644 --- a/src/app/ui/color_button.cpp +++ b/src/app/ui/color_button.cpp @@ -279,7 +279,8 @@ void ColorButton::openSelectorDialog() gfx::Rect winBounds = m_windowDefaultBounds; if (!pinned) { - winBounds = m_window->bounds(); + winBounds = gfx::Rect(m_window->bounds().origin(), + m_window->sizeHint()); winBounds.x = MID(0, bounds().x, ui::display_w()-winBounds.w); if (bounds().y2() <= ui::display_h()-winBounds.h) winBounds.y = MAX(0, bounds().y2()); diff --git a/src/app/ui/color_popup.cpp b/src/app/ui/color_popup.cpp index 6e83c146d..1eab8f158 100644 --- a/src/app/ui/color_popup.cpp +++ b/src/app/ui/color_popup.cpp @@ -55,6 +55,7 @@ ColorPopup::ColorPopup(bool canPin) , m_colorPalette(false, PaletteView::SelectOneColor, this, 7*guiscale()) , m_colorType(5) , m_maskLabel("Transparent Color Selected") + , m_canPin(canPin) , m_disableHexUpdate(false) { m_colorType.addItem("Index"); @@ -94,7 +95,7 @@ ColorPopup::ColorPopup(bool canPin) m_graySlider.ColorChange.connect(&ColorPopup::onColorSlidersChange, this); m_hexColorEntry.ColorChange.connect(&ColorPopup::onColorHexEntryChange, this); - if (!canPin) + if (!m_canPin) showPin(false); selectColorType(app::Color::RgbType); @@ -135,6 +136,26 @@ app::Color ColorPopup::getColor() const return m_color; } +void ColorPopup::onMakeFloating() +{ + PopupWindowPin::onMakeFloating(); + + if (m_canPin) { + setSizeable(true); + setMoveable(true); + } +} + +void ColorPopup::onMakeFixed() +{ + PopupWindowPin::onMakeFixed(); + + if (m_canPin) { + setSizeable(false); + setMoveable(true); + } +} + void ColorPopup::onPaletteViewIndexChange(int index, ui::MouseButtons buttons) { setColorWithSignal(app::Color::fromIndex(index)); diff --git a/src/app/ui/color_popup.h b/src/app/ui/color_popup.h index 80de63222..fc9899d45 100644 --- a/src/app/ui/color_popup.h +++ b/src/app/ui/color_popup.h @@ -41,6 +41,8 @@ namespace app { base::Signal1 ColorChange; protected: + void onMakeFloating() override; + void onMakeFixed() override; void onColorSlidersChange(ColorSlidersChangeEvent& ev); void onColorHexEntryChange(const app::Color& color); void onColorTypeClick(); @@ -66,6 +68,7 @@ namespace app { GraySlider m_graySlider; ui::Label m_maskLabel; base::ScopedConnection m_onPaletteChangeConn; + bool m_canPin; // This variable is used to avoid updating the m_hexColorEntry text // when the color change is generated from a diff --git a/src/app/ui/popup_window_pin.cpp b/src/app/ui/popup_window_pin.cpp index 3b9d88ba4..2dd6192a2 100644 --- a/src/app/ui/popup_window_pin.cpp +++ b/src/app/ui/popup_window_pin.cpp @@ -81,19 +81,14 @@ bool PopupWindowPin::onProcessMessage(Message* msg) return PopupWindow::onProcessMessage(msg); } -void PopupWindowPin::onHitTest(HitTestEvent& ev) +void PopupWindowPin::onWindowMovement() { - PopupWindow::onHitTest(ev); + PopupWindow::onWindowMovement(); - if ((m_pin.isSelected()) && - (ev.hit() == HitTestClient)) { - if (ev.point().x <= bounds().x+2) - ev.setHit(HitTestBorderW); - else if (ev.point().x >= bounds().x2()-3) - ev.setHit(HitTestBorderE); - else - ev.setHit(HitTestCaption); - } + // If the window isn't pinned and we move it, we can automatically + // pin it. + if (!m_pin.isSelected()) + setPinned(true); } } // namespace app diff --git a/src/app/ui/popup_window_pin.h b/src/app/ui/popup_window_pin.h index 03658df5a..5b178d720 100644 --- a/src/app/ui/popup_window_pin.h +++ b/src/app/ui/popup_window_pin.h @@ -23,7 +23,7 @@ namespace app { protected: virtual bool onProcessMessage(ui::Message* msg) override; - virtual void onHitTest(ui::HitTestEvent& ev) override; + virtual void onWindowMovement() override; // The pin. Your derived class must add this pin in some place of // the frame as a children, and you must to remove the pin from the diff --git a/src/ui/popup_window.cpp b/src/ui/popup_window.cpp index 462b056a8..a49791a86 100644 --- a/src/ui/popup_window.cpp +++ b/src/ui/popup_window.cpp @@ -1,5 +1,5 @@ // Aseprite UI Library -// Copyright (C) 2001-2013, 2015 David Capello +// Copyright (C) 2001-2016 David Capello // // This file is released under the terms of the MIT license. // Read LICENSE.txt for more information. @@ -26,6 +26,7 @@ PopupWindow::PopupWindow(const std::string& text, , m_clickBehavior(clickBehavior) , m_enterBehavior(enterBehavior) , m_filtering(false) + , m_fixed(false) { setSizeable(false); setMoveable(false); @@ -64,12 +65,18 @@ void PopupWindow::makeFloating() { stopFilteringMessages(); setMoveable(true); + m_fixed = false; + + onMakeFloating(); } void PopupWindow::makeFixed() { startFilteringMessages(); setMoveable(false); + m_fixed = true; + + onMakeFixed(); } bool PopupWindow::onProcessMessage(Message* msg) @@ -91,7 +98,7 @@ bool PopupWindow::onProcessMessage(Message* msg) break; case kMouseLeaveMessage: - if (m_hotRegion.isEmpty() && !isMoveable()) + if (m_hotRegion.isEmpty() && m_fixed) closeWindow(nullptr); break; @@ -139,7 +146,7 @@ bool PopupWindow::onProcessMessage(Message* msg) break; case kMouseMoveMessage: - if (!isMoveable() && + if (m_fixed && !m_hotRegion.isEmpty() && manager()->getCapture() == NULL) { gfx::Point mousePos = static_cast(msg)->position(); @@ -202,19 +209,34 @@ void PopupWindow::onInitTheme(InitThemeEvent& ev) void PopupWindow::onHitTest(HitTestEvent& ev) { + Window::onHitTest(ev); + Widget* picked = manager()->pick(ev.point()); if (picked) { WidgetType type = picked->type(); - if ((type == kWindowWidget && picked == this) || - type == kBoxWidget || - type == kLabelWidget || - type == kGridWidget || - type == kSeparatorWidget) { - ev.setHit(HitTestCaption); - return; + if (type == kWindowWidget && picked == this) { + if (isSizeable() && (ev.hit() == HitTestBorderNW || + ev.hit() == HitTestBorderN || + ev.hit() == HitTestBorderNE || + ev.hit() == HitTestBorderE || + ev.hit() == HitTestBorderSE || + ev.hit() == HitTestBorderS || + ev.hit() == HitTestBorderSW || + ev.hit() == HitTestBorderW)) { + // Use the hit value from Window::onHitTest() + return; + } + else { + ev.setHit(isMoveable() ? HitTestCaption: HitTestClient); + } + } + else if (type == kBoxWidget || + type == kLabelWidget || + type == kGridWidget || + type == kSeparatorWidget) { + ev.setHit(isMoveable() ? HitTestCaption: HitTestClient); } } - Window::onHitTest(ev); } void PopupWindow::startFilteringMessages() @@ -241,4 +263,14 @@ void PopupWindow::stopFilteringMessages() } } +void PopupWindow::onMakeFloating() +{ + // Do nothing +} + +void PopupWindow::onMakeFixed() +{ + // Do nothing +} + } // namespace ui diff --git a/src/ui/popup_window.h b/src/ui/popup_window.h index 1b3750774..4def669fd 100644 --- a/src/ui/popup_window.h +++ b/src/ui/popup_window.h @@ -1,5 +1,5 @@ // Aseprite UI Library -// Copyright (C) 2001-2013, 2015 David Capello +// Copyright (C) 2001-2016 David Capello // // This file is released under the terms of the MIT license. // Read LICENSE.txt for more information. @@ -46,6 +46,9 @@ namespace ui { void onInitTheme(InitThemeEvent& ev) override; void onHitTest(HitTestEvent& ev) override; + virtual void onMakeFloating(); + virtual void onMakeFixed(); + private: void startFilteringMessages(); void stopFilteringMessages(); @@ -54,6 +57,7 @@ namespace ui { EnterBehavior m_enterBehavior; gfx::Region m_hotRegion; bool m_filtering; + bool m_fixed; }; } // namespace ui diff --git a/src/ui/window.cpp b/src/ui/window.cpp index 09e7b587b..79f4a1f0f 100644 --- a/src/ui/window.cpp +++ b/src/ui/window.cpp @@ -1,5 +1,5 @@ // Aseprite UI Library -// Copyright (C) 2001-2015 David Capello +// Copyright (C) 2001-2016 David Capello // // This file is released under the terms of the MIT license. // Read LICENSE.txt for more information. @@ -182,6 +182,11 @@ void Window::onWindowResize() // Do nothing } +void Window::onWindowMovement() +{ + // Do nothing +} + void Window::remapWindow() { if (m_isAutoRemap) { @@ -579,6 +584,8 @@ void Window::moveWindow(const gfx::Rect& rect, bool use_blit) } manager->invalidateDisplayRegion(invalidManagerRegion); + + onWindowMovement(); } } // namespace ui diff --git a/src/ui/window.h b/src/ui/window.h index 3f1120544..c64d7ce9e 100644 --- a/src/ui/window.h +++ b/src/ui/window.h @@ -1,5 +1,5 @@ // Aseprite UI Library -// Copyright (C) 2001-2013, 2015 David Capello +// Copyright (C) 2001-2016 David Capello // // This file is released under the terms of the MIT license. // Read LICENSE.txt for more information. @@ -46,6 +46,7 @@ namespace ui { bool isDesktop() const { return m_isDesktop; } bool isOnTop() const { return m_isOnTop; } bool isWantFocus() const { return m_isWantFocus; } + bool isSizeable() const { return m_isSizeable; } bool isMoveable() const { return m_isMoveable; } HitTest hitTest(const gfx::Point& point); @@ -67,6 +68,7 @@ namespace ui { virtual void onClose(CloseEvent& ev); virtual void onHitTest(HitTestEvent& ev); virtual void onWindowResize(); + virtual void onWindowMovement(); private: void windowSetPosition(const gfx::Rect& rect);