diff --git a/ui/abstract_button.cpp b/ui/abstract_button.cpp index 61eac90..8767ce1 100644 --- a/ui/abstract_button.cpp +++ b/ui/abstract_button.cpp @@ -104,18 +104,20 @@ void AbstractButton::setPointerCursor(bool enablePointerCursor) { } void AbstractButton::setOver(bool over, StateChangeSource source) { - if (over && !(_state & StateFlag::Over)) { - auto was = _state; + if (over == isOver()) { + return; + } + const auto was = _state; + if (over) { _state |= StateFlag::Over; Integration::Instance().registerLeaveSubscription(this); - onStateChanged(was, source); - } else if (!over && (_state & StateFlag::Over)) { - auto was = _state; + } else { _state &= ~State(StateFlag::Over); Integration::Instance().unregisterLeaveSubscription(this); - onStateChanged(was, source); } + onStateChanged(was, source); updateCursor(); + update(); } bool AbstractButton::setDown( @@ -149,8 +151,11 @@ bool AbstractButton::setDown( } void AbstractButton::updateCursor() { - auto pointerCursor = _enablePointerCursor && (_state & StateFlag::Over); - setCursor(pointerCursor ? style::cur_pointer : style::cur_default); + const auto pointerCursor = _enablePointerCursor && isOver(); + if (_pointerCursor != pointerCursor) { + _pointerCursor = pointerCursor; + setCursor(_pointerCursor ? style::cur_pointer : style::cur_default); + } } void AbstractButton::setDisabled(bool disabled) { diff --git a/ui/abstract_button.h b/ui/abstract_button.h index 2710de9..7673827 100644 --- a/ui/abstract_button.h +++ b/ui/abstract_button.h @@ -16,22 +16,29 @@ class AbstractButton : public RpWidget { public: AbstractButton(QWidget *parent); - Qt::KeyboardModifiers clickModifiers() const { + [[nodiscard]] Qt::KeyboardModifiers clickModifiers() const { return _modifiers; } void setDisabled(bool disabled = true); virtual void clearState(); - bool isOver() const { + [[nodiscard]] bool isOver() const { return _state & StateFlag::Over; } - bool isDown() const { + [[nodiscard]] bool isDown() const { return _state & StateFlag::Down; } - bool isDisabled() const { + [[nodiscard]] bool isDisabled() const { return _state & StateFlag::Disabled; } + void setSynteticOver(bool over) { + setOver(over, StateChangeSource::ByPress); + } + void setSynteticDown(bool down, Qt::MouseButton button = Qt::LeftButton) { + setDown(down, StateChangeSource::ByPress, {}, button); + } + void setPointerCursor(bool enablePointerCursor); void setAcceptBoth(bool acceptBoth = true); @@ -95,9 +102,10 @@ private: State _state = StateFlag::None; - bool _acceptBoth = false; Qt::KeyboardModifiers _modifiers; bool _enablePointerCursor = true; + bool _pointerCursor = false; + bool _acceptBoth = false; Fn _clickedCallback; diff --git a/ui/platform/ui_platform_window_title.cpp b/ui/platform/ui_platform_window_title.cpp index 4e826c1..af4bbb6 100644 --- a/ui/platform/ui_platform_window_title.cpp +++ b/ui/platform/ui_platform_window_title.cpp @@ -65,30 +65,94 @@ void SetupSemiNativeSystemButtons( }, lifetime); } -class TitleControls::Button final : public IconButton { -public: - using IconButton::IconButton; +object_ptr IconTitleButtons::create( + not_null parent, + TitleControl control, + const style::WindowTitle &st) { + const auto make = [&]( + QPointer &my, + const style::IconButton &st) { + Expects(!my); - void setOver(bool over) { - IconButton::setOver(over, StateChangeSource::ByPress); + auto result = object_ptr(parent, st); + my = result.data(); + return result; + }; + switch (control) { + case TitleControl::Minimize: + return make(_minimize, st.minimize); + case TitleControl::Maximize: + return make(_maximizeRestore, st.maximize); + case TitleControl::Close: + return make(_close, st.close); } - void setDown(bool down) { - IconButton::setDown( - down, - StateChangeSource::ByPress, - {}, - Qt::LeftButton); + Unexpected("Control in IconTitleButtons::create."); +} + +void IconTitleButtons::updateState( + bool active, + bool maximized, + const style::WindowTitle &st) { + if (_minimize) { + const auto minimize = active + ? &st.minimizeIconActive + : &st.minimize.icon; + const auto minimizeOver = active + ? &st.minimizeIconActiveOver + : &st.minimize.iconOver; + _minimize->setIconOverride(minimize, minimizeOver); } -}; + if (_maximizeRestore) { + if (maximized) { + const auto restore = active + ? &st.restoreIconActive + : &st.restoreIcon; + const auto restoreOver = active + ? &st.restoreIconActiveOver + : &st.restoreIconOver; + _maximizeRestore->setIconOverride(restore, restoreOver); + } else { + const auto maximize = active + ? &st.maximizeIconActive + : &st.maximize.icon; + const auto maximizeOver = active + ? &st.maximizeIconActiveOver + : &st.maximize.iconOver; + _maximizeRestore->setIconOverride(maximize, maximizeOver); + } + } + if (_close) { + const auto close = active + ? &st.closeIconActive + : &st.close.icon; + const auto closeOver = active + ? &st.closeIconActiveOver + : &st.close.iconOver; + _close->setIconOverride(close, closeOver); + } +} TitleControls::TitleControls( not_null parent, const style::WindowTitle &st, Fn maximize) +: TitleControls( + parent, + st, + std::make_unique(), + std::move(maximize)) { +} + +TitleControls::TitleControls( + not_null parent, + const style::WindowTitle &st, + std::unique_ptr buttons, + Fn maximize) : _st(&st) -, _minimize(parent, _st->minimize) -, _maximizeRestore(parent, _st->maximize) -, _close(parent, _st->close) +, _buttons(std::move(buttons)) +, _minimize(_buttons->create(parent, Control::Minimize, st)) +, _maximizeRestore(_buttons->create(parent, Control::Maximize, st)) +, _close(_buttons->create(parent, Control::Close, st)) , _maximizedState(parent->windowState() & (Qt::WindowMaximized | Qt::WindowFullScreen)) , _activeState(parent->isActiveWindow()) { @@ -216,7 +280,9 @@ void TitleControls::raise() { } HitTestResult TitleControls::hitTest(QPoint point, int padding) const { - const auto test = [&](const object_ptr