From b534567e11cd9c39035374364448d2aa76bd0aab Mon Sep 17 00:00:00 2001 From: John Preston Date: Thu, 13 Aug 2020 14:31:41 +0400 Subject: [PATCH] Extract TitleControls from TitleWidget. --- ui/colors.palette | 2 +- ui/platform/win/ui_window_title_win.cpp | 166 ++++++++++++++++-------- ui/platform/win/ui_window_title_win.h | 52 +++++--- 3 files changed, 146 insertions(+), 74 deletions(-) diff --git a/ui/colors.palette b/ui/colors.palette index f13b568..646a4fa 100644 --- a/ui/colors.palette +++ b/ui/colors.palette @@ -538,7 +538,7 @@ notificationBg: windowBg; // custom notification window background // calls callBg: #26282cf2; // old phone call popup background callBgOpaque: #1b1f23 | callBg; // phone call popup background -callBgButton: #1b1f2356 | callBg; // phone call window control buttons bg +callBgButton: #1b1f237f | callBg; // phone call window control buttons bg callNameFg: #ffffff; // phone call popup name text callFingerprintBg: #00000066; // phone call popup emoji fingerprint background callStatusFg: #aaabac; // phone call popup status text diff --git a/ui/platform/win/ui_window_title_win.cpp b/ui/platform/win/ui_window_title_win.cpp index d08e332..0def675 100644 --- a/ui/platform/win/ui_window_title_win.cpp +++ b/ui/platform/win/ui_window_title_win.cpp @@ -19,39 +19,59 @@ namespace Ui { namespace Platform { -TitleWidget::TitleWidget(not_null parent) -: RpWidget(parent) -, _st(&st::defaultWindowTitle) -, _minimize(this, _st->minimize) -, _maximizeRestore(this, _st->maximize) -, _close(this, _st->close) -, _shadow(this, st::titleShadow) -, _maximizedState(parent->windowState() & Qt::WindowMaximized) +TitleControls::TitleControls( + not_null parent, + Fn maximize) +: _st(&st::defaultWindowTitle) +, _minimize(parent, _st->minimize) +, _maximizeRestore(parent, _st->maximize) +, _close(parent, _st->close) +, _maximizedState(parent->windowState() + & (Qt::WindowMaximized | Qt::WindowFullScreen)) , _activeState(parent->isActiveWindow()) { - init(); + init(std::move(maximize)); + + _close->paintRequest( + ) | rpl::start_with_next([=] { + const auto active = window()->isActiveWindow(); + if (_activeState != active) { + _activeState = active; + updateButtonsState(); + } + }, _close->lifetime()); } -void TitleWidget::setText(const QString &text) { - window()->setWindowTitle(text); -} - -void TitleWidget::setStyle(const style::WindowTitle &st) { +void TitleControls::setStyle(const style::WindowTitle &st) { _st = &st; - setGeometry(0, 0, window()->width(), _st->height); updateButtonsState(); - update(); } -not_null TitleWidget::window() const { - return static_cast(parentWidget()); +not_null TitleControls::st() const { + return _st; } -void TitleWidget::setResizeEnabled(bool enabled) { - _resizeEnabled = enabled; - updateControlsVisibility(); +QRect TitleControls::geometry() const { + auto result = QRect(); + const auto add = [&](auto &&control) { + if (!control->isHidden()) { + result = result.united(control->geometry()); + } + }; + add(_minimize); + add(_maximizeRestore); + add(_close); + return result; } -void TitleWidget::init() { +not_null TitleControls::parent() const { + return static_cast(_close->parentWidget()); +} + +not_null TitleControls::window() const { + return _close->window(); +} + +void TitleControls::init(Fn maximize) { _minimize->setClickedCallback([=] { window()->setWindowState( window()->windowState() | Qt::WindowMinimized); @@ -59,9 +79,13 @@ void TitleWidget::init() { }); _minimize->setPointerCursor(false); _maximizeRestore->setClickedCallback([=] { - window()->setWindowState(_maximizedState - ? Qt::WindowNoState - : Qt::WindowMaximized); + if (maximize) { + maximize(!_maximizedState); + } else { + window()->setWindowState(_maximizedState + ? Qt::WindowNoState + : Qt::WindowMaximized); + } _maximizeRestore->clearState(); }); _maximizeRestore->setPointerCursor(false); @@ -71,32 +95,32 @@ void TitleWidget::init() { }); _close->setPointerCursor(false); - setAttribute(Qt::WA_OpaquePaintEvent); - - window()->widthValue( + parent()->widthValue( ) | rpl::start_with_next([=](int width) { - setGeometry(0, 0, width, _st->height); - }, lifetime()); + updateControlsPosition(); + }, _close->lifetime()); window()->createWinId(); - connect( + QObject::connect( window()->windowHandle(), &QWindow::windowStateChanged, [=](Qt::WindowState state) { handleWindowStateChanged(state); }); - _activeState = isActiveWindow(); + _activeState = parent()->isActiveWindow(); updateButtonsState(); } -void TitleWidget::paintEvent(QPaintEvent *e) { - const auto active = isActiveWindow(); - if (_activeState != active) { - _activeState = active; - updateButtonsState(); - } - QPainter(this).fillRect(e->rect(), active ? _st->bgActive : _st->bg); +void TitleControls::setResizeEnabled(bool enabled) { + _resizeEnabled = enabled; + updateControlsVisibility(); } -void TitleWidget::updateControlsPosition() { +void TitleControls::raise() { + _minimize->raise(); + _maximizeRestore->raise(); + _close->raise(); +} + +void TitleControls::updateControlsPosition() { auto right = 0; _close->moveToRight(right, 0); right += _close->width(); _maximizeRestore->moveToRight(right, 0); @@ -106,28 +130,25 @@ void TitleWidget::updateControlsPosition() { _minimize->moveToRight(right, 0); } -void TitleWidget::resizeEvent(QResizeEvent *e) { - updateControlsPosition(); - _shadow->setGeometry(0, height() - st::lineWidth, width(), st::lineWidth); -} - -void TitleWidget::updateControlsVisibility() { +void TitleControls::updateControlsVisibility() { _maximizeRestore->setVisible(_resizeEnabled); updateControlsPosition(); - update(); } -void TitleWidget::handleWindowStateChanged(Qt::WindowState state) { - if (state == Qt::WindowMinimized) return; +void TitleControls::handleWindowStateChanged(Qt::WindowState state) { + if (state == Qt::WindowMinimized) { + return; + } - auto maximized = (state == Qt::WindowMaximized); + auto maximized = (state == Qt::WindowMaximized) + || (state == Qt::WindowFullScreen); if (_maximizedState != maximized) { _maximizedState = maximized; updateButtonsState(); } } -void TitleWidget::updateButtonsState() { +void TitleControls::updateButtonsState() { const auto minimize = _activeState ? &_st->minimizeIconActive : &_st->minimize.icon; @@ -161,12 +182,45 @@ void TitleWidget::updateButtonsState() { _close->setIconOverride(close, closeOver); } +TitleWidget::TitleWidget(not_null parent) +: RpWidget(parent) +, _controls(this) +, _shadow(this, st::titleShadow) { + setAttribute(Qt::WA_OpaquePaintEvent); + + parent->widthValue( + ) | rpl::start_with_next([=](int width) { + setGeometry(0, 0, width, _controls.st()->height); + }, lifetime()); +} + +void TitleWidget::setText(const QString &text) { + window()->setWindowTitle(text); +} + +void TitleWidget::setStyle(const style::WindowTitle &st) { + _controls.setStyle(st); + setGeometry(0, 0, window()->width(), _controls.st()->height); + update(); +} + +void TitleWidget::setResizeEnabled(bool enabled) { + _controls.setResizeEnabled(enabled); +} + +void TitleWidget::paintEvent(QPaintEvent *e) { + const auto active = window()->isActiveWindow(); + QPainter(this).fillRect( + e->rect(), + active ? _controls.st()->bgActive : _controls.st()->bg); +} + +void TitleWidget::resizeEvent(QResizeEvent *e) { + _shadow->setGeometry(0, height() - st::lineWidth, width(), st::lineWidth); +} + HitTestResult TitleWidget::hitTest(QPoint point) const { - if (false - || (_minimize->geometry().contains(point)) - || (_maximizeRestore->geometry().contains(point)) - || (_close->geometry().contains(point)) - ) { + if (_controls.geometry().contains(point)) { return HitTestResult::SysButton; } else if (rect().contains(point)) { return HitTestResult::Caption; diff --git a/ui/platform/win/ui_window_title_win.h b/ui/platform/win/ui_window_title_win.h index 25b706f..7deacb0 100644 --- a/ui/platform/win/ui_window_title_win.h +++ b/ui/platform/win/ui_window_title_win.h @@ -38,6 +38,40 @@ enum class HitTestResult { TopLeft, }; +class TitleControls final { +public: + TitleControls( + not_null parent, + Fn maximize = nullptr); + + void setStyle(const style::WindowTitle &st); + [[nodiscard]] not_null st() const; + [[nodiscard]] QRect geometry() const; + void setResizeEnabled(bool enabled); + void raise(); + +private: + [[nodiscard]] not_null parent() const; + [[nodiscard]] not_null window() const; + + void init(Fn maximize); + void updateControlsVisibility(); + void updateButtonsState(); + void updateControlsPosition(); + void handleWindowStateChanged(Qt::WindowState state = Qt::WindowNoState); + + not_null _st; + + object_ptr _minimize; + object_ptr _maximizeRestore; + object_ptr _close; + + bool _maximizedState = false; + bool _activeState = false; + bool _resizeEnabled = true; + +}; + class TitleWidget : public RpWidget { public: explicit TitleWidget(not_null parent); @@ -52,25 +86,9 @@ protected: void resizeEvent(QResizeEvent *e) override; private: - not_null window() const; - - void init(); - void handleWindowStateChanged(Qt::WindowState state = Qt::WindowNoState); - void updateControlsVisibility(); - void updateButtonsState(); - void updateControlsPosition(); - - not_null _st; - - object_ptr _minimize; - object_ptr _maximizeRestore; - object_ptr _close; + TitleControls _controls; object_ptr _shadow; - bool _maximizedState = false; - bool _activeState = false; - bool _resizeEnabled = true; - }; } // namespace Platform