diff --git a/ui/platform/mac/ui_window_title_mac.h b/ui/platform/mac/ui_window_title_mac.h index 7061ef2..af31a29 100644 --- a/ui/platform/mac/ui_window_title_mac.h +++ b/ui/platform/mac/ui_window_title_mac.h @@ -12,6 +12,10 @@ #include #include +namespace style { +struct WindowTitle; +} // namespace style + namespace Ui { class PlainShadow; @@ -23,6 +27,7 @@ public: TitleWidget(not_null parent, int height); void setText(const QString &text); + void setStyle(const style::WindowTitle &st); [[nodiscard]] QString text() const; protected: @@ -35,6 +40,7 @@ private: void init(int height); + not_null _st; object_ptr _shadow; QString _text; QFont _font; diff --git a/ui/platform/mac/ui_window_title_mac.mm b/ui/platform/mac/ui_window_title_mac.mm index 2f0720f..abd431b 100644 --- a/ui/platform/mac/ui_window_title_mac.mm +++ b/ui/platform/mac/ui_window_title_mac.mm @@ -21,6 +21,7 @@ namespace Platform { TitleWidget::TitleWidget(not_null parent, int height) : RpWidget(parent) +, _st(&st::defaultWindowTitle) , _shadow(this, st::titleShadow) { init(height); } @@ -32,6 +33,11 @@ void TitleWidget::setText(const QString &text) { } } +void TitleWidget::setStyle(const style::WindowTitle &st) { + _st = &st; + update(); +} + QString TitleWidget::text() const { return _text; } @@ -42,10 +48,10 @@ not_null TitleWidget::window() const { void TitleWidget::init(int height) { setAttribute(Qt::WA_OpaquePaintEvent); - + window()->widthValue( ) | rpl::start_with_next([=](int width) { - setGeometry(0, 0, width, st::titleHeight); + setGeometry(0, 0, width, height); }, lifetime()); const auto families = QStringList{ @@ -70,10 +76,10 @@ void TitleWidget::paintEvent(QPaintEvent *e) { QPainter p(this); const auto active = isActiveWindow(); - p.fillRect(rect(), active ? st::titleBgActive : st::titleBg); + p.fillRect(rect(), active ? _st->bgActive : _st->bg); p.setFont(_font); - p.setPen(active ? st::titleFgActive : st::titleFg); + p.setPen(active ? _st->fgActive : _st->fg); p.drawText(rect(), _text, style::al_center); } diff --git a/ui/platform/ui_platform_window.h b/ui/platform/ui_platform_window.h index 757c71d..4fff950 100644 --- a/ui/platform/ui_platform_window.h +++ b/ui/platform/ui_platform_window.h @@ -6,6 +6,10 @@ // #pragma once +namespace style { +struct WindowTitle; +} // namespace style + namespace Ui { class RpWidget; @@ -16,6 +20,7 @@ class BasicWindowHelper { public: [[nodiscard]] virtual not_null body() = 0; virtual void setTitle(const QString &title) = 0; + virtual void setTitleStyle(const style::WindowTitle &st) = 0; virtual void setMinimumSize(QSize size) = 0; virtual void setFixedSize(QSize size) = 0; virtual void setGeometry(QRect rect) = 0; diff --git a/ui/platform/win/ui_window_shadow_win.cpp b/ui/platform/win/ui_window_shadow_win.cpp index e571d09..9b703fe 100644 --- a/ui/platform/win/ui_window_shadow_win.cpp +++ b/ui/platform/win/ui_window_shadow_win.cpp @@ -545,7 +545,7 @@ LRESULT WindowShadow::windowCallback( case WM_NCHITTEST: { if (!_resizeEnabled) { - return HTTRANSPARENT; + return HTNOWHERE; } const auto xPos = GET_X_LPARAM(lParam); const auto yPos = GET_Y_LPARAM(lParam); diff --git a/ui/platform/win/ui_window_title_win.cpp b/ui/platform/win/ui_window_title_win.cpp index 96e3166..986cca5 100644 --- a/ui/platform/win/ui_window_title_win.cpp +++ b/ui/platform/win/ui_window_title_win.cpp @@ -21,9 +21,10 @@ namespace Platform { TitleWidget::TitleWidget(not_null parent) : RpWidget(parent) -, _minimize(this, st::titleButtonMinimize) -, _maximizeRestore(this, st::titleButtonMaximize) -, _close(this, st::titleButtonClose) +, _st(&st::defaultWindowTitle) +, _minimize(this, _st->minimize) +, _maximizeRestore(this, _st->maximize) +, _close(this, _st->close) , _shadow(this, st::titleShadow) , _maximizedState(parent->windowState() & Qt::WindowMaximized) , _activeState(parent->isActiveWindow()) { @@ -34,6 +35,13 @@ void TitleWidget::setText(const QString &text) { window()->setWindowTitle(text); } +void TitleWidget::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()); } @@ -66,7 +74,7 @@ void TitleWidget::init() { window()->widthValue( ) | rpl::start_with_next([=](int width) { - setGeometry(0, 0, width, st::titleHeight); + setGeometry(0, 0, width, _st->height); }, lifetime()); window()->createWinId(); @@ -84,7 +92,7 @@ void TitleWidget::paintEvent(QPaintEvent *e) { _activeState = active; updateButtonsState(); } - QPainter(this).fillRect(e->rect(), active ? st::titleBgActive : st::titleBg); + QPainter(this).fillRect(e->rect(), active ? _st->bgActive : _st->bg); } void TitleWidget::updateControlsPosition() { @@ -120,35 +128,35 @@ void TitleWidget::handleWindowStateChanged(Qt::WindowState state) { void TitleWidget::updateButtonsState() { const auto minimize = _activeState - ? &st::titleButtonMinimizeIconActive - : nullptr; + ? &_st->minimizeIconActive + : &_st->minimize.icon; const auto minimizeOver = _activeState - ? &st::titleButtonMinimizeIconActiveOver - : nullptr; + ? &_st->minimizeIconActiveOver + : &_st->minimize.iconOver; _minimize->setIconOverride(minimize, minimizeOver); if (_maximizedState) { const auto restore = _activeState - ? &st::titleButtonRestoreIconActive - : &st::titleButtonRestoreIcon; + ? &_st->restoreIconActive + : &_st->restoreIcon; const auto restoreOver = _activeState - ? &st::titleButtonRestoreIconActiveOver - : &st::titleButtonRestoreIconOver; + ? &_st->restoreIconActiveOver + : &_st->restoreIconOver; _maximizeRestore->setIconOverride(restore, restoreOver); } else { const auto maximize = _activeState - ? &st::titleButtonMaximizeIconActive - : nullptr; + ? &_st->maximizeIconActive + : &_st->maximize.icon; const auto maximizeOver = _activeState - ? &st::titleButtonMaximizeIconActiveOver - : nullptr; + ? &_st->maximizeIconActiveOver + : &_st->maximize.iconOver; _maximizeRestore->setIconOverride(maximize, maximizeOver); } const auto close = _activeState - ? &st::titleButtonCloseIconActive - : nullptr; + ? &_st->closeIconActive + : &_st->close.icon; const auto closeOver = _activeState - ? &st::titleButtonCloseIconActiveOver - : nullptr; + ? &_st->closeIconActiveOver + : &_st->close.iconOver; _close->setIconOverride(close, closeOver); } diff --git a/ui/platform/win/ui_window_title_win.h b/ui/platform/win/ui_window_title_win.h index 171225f..25b706f 100644 --- a/ui/platform/win/ui_window_title_win.h +++ b/ui/platform/win/ui_window_title_win.h @@ -12,6 +12,10 @@ #include #include +namespace style { +struct WindowTitle; +} // namespace style + namespace Ui { class IconButton; @@ -39,6 +43,7 @@ public: explicit TitleWidget(not_null parent); void setText(const QString &text); + void setStyle(const style::WindowTitle &st); [[nodiscard]] HitTestResult hitTest(QPoint point) const; void setResizeEnabled(bool enabled); @@ -55,6 +60,8 @@ private: void updateButtonsState(); void updateControlsPosition(); + not_null _st; + object_ptr _minimize; object_ptr _maximizeRestore; object_ptr _close; diff --git a/ui/platform/win/ui_window_win.cpp b/ui/platform/win/ui_window_win.cpp index bab61a7..58fb94a 100644 --- a/ui/platform/win/ui_window_win.cpp +++ b/ui/platform/win/ui_window_win.cpp @@ -99,6 +99,10 @@ void WindowHelper::setTitle(const QString &title) { _window->setWindowTitle(title); } +void WindowHelper::setTitleStyle(const style::WindowTitle &st) { + _title->setStyle(st); +} + void WindowHelper::setMinimumSize(QSize size) { _window->setMinimumSize(size.width(), _title->height() + size.height()); } @@ -494,7 +498,7 @@ HWND GetWindowHandle(not_null widget) { } std::unique_ptr CreateWindowHelper( - not_null window) { + not_null window) { return std::make_unique(window); } diff --git a/ui/platform/win/ui_window_win.h b/ui/platform/win/ui_window_win.h index 04b0c2b..ff88284 100644 --- a/ui/platform/win/ui_window_win.h +++ b/ui/platform/win/ui_window_win.h @@ -23,6 +23,7 @@ public: not_null body() override; void setTitle(const QString &title) override; + void setTitleStyle(const style::WindowTitle &st) override; void setMinimumSize(QSize size) override; void setFixedSize(QSize size) override; void setGeometry(QRect rect) override; diff --git a/ui/widgets/widgets.style b/ui/widgets/widgets.style index 087b52d..8b24e36 100644 --- a/ui/widgets/widgets.style +++ b/ui/widgets/widgets.style @@ -523,6 +523,27 @@ PassportScanRow { restore: RoundButton; } +WindowTitle { + height: pixels; + bg: color; + bgActive: color; + fg: color; + fgActive: color; + minimize: IconButton; + minimizeIconActive: icon; + minimizeIconActiveOver: icon; + maximize: IconButton; + maximizeIconActive: icon; + maximizeIconActiveOver: icon; + restoreIcon: icon; + restoreIconOver: icon; + restoreIconActive: icon; + restoreIconActiveOver: icon; + close: IconButton; + closeIconActive: icon; + closeIconActiveOver: icon; +} + defaultLabelSimple: LabelSimple { font: normalFont; maxWidth: 0px; @@ -1164,83 +1185,92 @@ backButton: IconButton(defaultIconButton) { // Windows specific title -titleHeight: 21px; -titleButtonMinimize: IconButton { +windowTitleButton: IconButton { width: 24px; height: 21px; - - icon: icon { - { size(24px, 21px), titleButtonBg }, - { "title_button_minimize", titleButtonFg, point(4px, 4px) }, - }; - iconOver: icon { - { size(24px, 21px), titleButtonBgOver }, - { "title_button_minimize", titleButtonFgOver, point(4px, 4px) }, - }; iconPosition: point(0px, 0px); } -titleButtonMinimizeIconActive: icon { - { size(24px, 21px), titleButtonBgActive }, - { "title_button_minimize", titleButtonFgActive, point(4px, 4px) }, -}; -titleButtonMinimizeIconActiveOver: icon { - { size(24px, 21px), titleButtonBgActiveOver }, - { "title_button_minimize", titleButtonFgActiveOver, point(4px, 4px) }, -}; -titleButtonMaximize: IconButton(titleButtonMinimize) { - icon: icon { - { size(24px, 21px), titleButtonBg }, - { "title_button_maximize", titleButtonFg, point(4px, 4px) }, - }; - iconOver: icon { - { size(24px, 21px), titleButtonBgOver }, - { "title_button_maximize", titleButtonFgOver, point(4px, 4px) }, - }; -} -titleButtonMaximizeIconActive: icon { - { size(24px, 21px), titleButtonBgActive }, - { "title_button_maximize", titleButtonFgActive, point(4px, 4px) }, -}; -titleButtonMaximizeIconActiveOver: icon { - { size(24px, 21px), titleButtonBgActiveOver }, - { "title_button_maximize", titleButtonFgActiveOver, point(4px, 4px) }, -}; -titleButtonRestoreIcon: icon { - { size(24px, 21px), titleButtonBg }, - { "title_button_restore", titleButtonFg, point(4px, 4px) }, -}; -titleButtonRestoreIconOver: icon { - { size(24px, 21px), titleButtonBgOver }, - { "title_button_restore", titleButtonFgOver, point(4px, 4px) }, -}; -titleButtonRestoreIconActive: icon { - { size(24px, 21px), titleButtonBgActive }, - { "title_button_restore", titleButtonFgActive, point(4px, 4px) }, -}; -titleButtonRestoreIconActiveOver: icon { - { size(24px, 21px), titleButtonBgActiveOver }, - { "title_button_restore", titleButtonFgActiveOver, point(4px, 4px) }, -}; -titleButtonClose: IconButton(titleButtonMinimize) { +windowTitleButtonClose: IconButton(windowTitleButton) { width: 25px; +} - icon: icon { - { size(25px, 21px), titleButtonCloseBg }, - { "title_button_close", titleButtonCloseFg, point(5px, 4px) }, +defaultWindowTitle: WindowTitle { + height: 21px; + bg: titleBg; + bgActive: titleBgActive; + fg: titleFg; + fgActive: titleFgActive; + minimize: IconButton(windowTitleButton) { + icon: icon { + { size(24px, 21px), titleButtonBg }, + { "title_button_minimize", titleButtonFg, point(4px, 4px) }, + }; + iconOver: icon { + { size(24px, 21px), titleButtonBgOver }, + { "title_button_minimize", titleButtonFgOver, point(4px, 4px) }, + }; + } + minimizeIconActive: icon { + { size(24px, 21px), titleButtonBgActive }, + { "title_button_minimize", titleButtonFgActive, point(4px, 4px) }, }; - iconOver: icon { - { size(25px, 21px), titleButtonCloseBgOver }, - { "title_button_close", titleButtonCloseFgOver, point(5px, 4px) }, + minimizeIconActiveOver: icon { + { size(24px, 21px), titleButtonBgActiveOver }, + { "title_button_minimize", titleButtonFgActiveOver, point(4px, 4px) }, + }; + maximize: IconButton(windowTitleButton) { + icon: icon { + { size(24px, 21px), titleButtonBg }, + { "title_button_maximize", titleButtonFg, point(4px, 4px) }, + }; + iconOver: icon { + { size(24px, 21px), titleButtonBgOver }, + { "title_button_maximize", titleButtonFgOver, point(4px, 4px) }, + }; + } + maximizeIconActive: icon { + { size(24px, 21px), titleButtonBgActive }, + { "title_button_maximize", titleButtonFgActive, point(4px, 4px) }, + }; + maximizeIconActiveOver: icon { + { size(24px, 21px), titleButtonBgActiveOver }, + { "title_button_maximize", titleButtonFgActiveOver, point(4px, 4px) }, + }; + restoreIcon: icon { + { size(24px, 21px), titleButtonBg }, + { "title_button_restore", titleButtonFg, point(4px, 4px) }, + }; + restoreIconOver: icon { + { size(24px, 21px), titleButtonBgOver }, + { "title_button_restore", titleButtonFgOver, point(4px, 4px) }, + }; + restoreIconActive: icon { + { size(24px, 21px), titleButtonBgActive }, + { "title_button_restore", titleButtonFgActive, point(4px, 4px) }, + }; + restoreIconActiveOver: icon { + { size(24px, 21px), titleButtonBgActiveOver }, + { "title_button_restore", titleButtonFgActiveOver, point(4px, 4px) }, + }; + close: IconButton(windowTitleButtonClose) { + icon: icon { + { size(25px, 21px), titleButtonCloseBg }, + { "title_button_close", titleButtonCloseFg, point(5px, 4px) }, + }; + iconOver: icon { + { size(25px, 21px), titleButtonCloseBgOver }, + { "title_button_close", titleButtonCloseFgOver, point(5px, 4px) }, + }; + } + closeIconActive: icon { + { size(25px, 21px), titleButtonCloseBgActive }, + { "title_button_close", titleButtonCloseFgActive, point(5px, 4px) }, + }; + closeIconActiveOver: icon { + { size(25px, 21px), titleButtonCloseBgActiveOver }, + { "title_button_close", titleButtonCloseFgActiveOver, point(5px, 4px) }, }; } -titleButtonCloseIconActive: icon { - { size(25px, 21px), titleButtonCloseBgActive }, - { "title_button_close", titleButtonCloseFgActive, point(5px, 4px) }, -}; -titleButtonCloseIconActiveOver: icon { - { size(25px, 21px), titleButtonCloseBgActiveOver }, - { "title_button_close", titleButtonCloseFgActiveOver, point(5px, 4px) }, -}; windowShadow: icon {{ "window_shadow", windowShadowFg }}; windowShadowShift: 1px; diff --git a/ui/widgets/window.cpp b/ui/widgets/window.cpp index 440fde8..113fb7f 100644 --- a/ui/widgets/window.cpp +++ b/ui/widgets/window.cpp @@ -34,6 +34,12 @@ void Window::setTitle(const QString &title) { } } +void Window::setTitleStyle(const style::WindowTitle &st) { + if (_helper) { + _helper->setTitleStyle(st); + } +} + void Window::setMinimumSize(QSize size) { if (_helper) { _helper->setMinimumSize(size); diff --git a/ui/widgets/window.h b/ui/widgets/window.h index 8194b62..7a96a6a 100644 --- a/ui/widgets/window.h +++ b/ui/widgets/window.h @@ -8,6 +8,10 @@ #include "ui/rp_widget.h" +namespace style { +struct WindowTitle; +} // namespace style + namespace Ui { namespace Platform { class BasicWindowHelper; @@ -22,6 +26,7 @@ public: [[nodiscard]] not_null body() const; void setTitle(const QString &title); + void setTitleStyle(const style::WindowTitle &st); void setMinimumSize(QSize size); void setFixedSize(QSize size); void setGeometry(QRect rect);