Allow different custom window title styles.

This commit is contained in:
John Preston 2019-10-14 14:34:51 +04:00
parent c0ce14bb68
commit 40d7581c36
11 changed files with 173 additions and 95 deletions

View file

@ -12,6 +12,10 @@
#include <QtCore/QRect>
#include <QtCore/QPoint>
namespace style {
struct WindowTitle;
} // namespace style
namespace Ui {
class PlainShadow;
@ -23,6 +27,7 @@ public:
TitleWidget(not_null<RpWidget*> 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<const style::WindowTitle*> _st;
object_ptr<Ui::PlainShadow> _shadow;
QString _text;
QFont _font;

View file

@ -21,6 +21,7 @@ namespace Platform {
TitleWidget::TitleWidget(not_null<RpWidget*> 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;
}
@ -45,7 +51,7 @@ void TitleWidget::init(int height) {
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);
}

View file

@ -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<RpWidget*> 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;

View file

@ -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);

View file

@ -21,9 +21,10 @@ namespace Platform {
TitleWidget::TitleWidget(not_null<RpWidget*> 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<RpWidget*> TitleWidget::window() const {
return static_cast<RpWidget*>(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);
}

View file

@ -12,6 +12,10 @@
#include <QtCore/QRect>
#include <QtCore/QPoint>
namespace style {
struct WindowTitle;
} // namespace style
namespace Ui {
class IconButton;
@ -39,6 +43,7 @@ public:
explicit TitleWidget(not_null<RpWidget*> 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<const style::WindowTitle*> _st;
object_ptr<Ui::IconButton> _minimize;
object_ptr<Ui::IconButton> _maximizeRestore;
object_ptr<Ui::IconButton> _close;

View file

@ -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());
}

View file

@ -23,6 +23,7 @@ public:
not_null<RpWidget*> 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;

View file

@ -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,11 +1185,22 @@ backButton: IconButton(defaultIconButton) {
// Windows specific title
titleHeight: 21px;
titleButtonMinimize: IconButton {
windowTitleButton: IconButton {
width: 24px;
height: 21px;
iconPosition: point(0px, 0px);
}
windowTitleButtonClose: IconButton(windowTitleButton) {
width: 25px;
}
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) },
@ -1177,17 +1209,16 @@ titleButtonMinimize: IconButton {
{ size(24px, 21px), titleButtonBgOver },
{ "title_button_minimize", titleButtonFgOver, point(4px, 4px) },
};
iconPosition: point(0px, 0px);
}
titleButtonMinimizeIconActive: icon {
}
minimizeIconActive: icon {
{ size(24px, 21px), titleButtonBgActive },
{ "title_button_minimize", titleButtonFgActive, point(4px, 4px) },
};
titleButtonMinimizeIconActiveOver: icon {
};
minimizeIconActiveOver: icon {
{ size(24px, 21px), titleButtonBgActiveOver },
{ "title_button_minimize", titleButtonFgActiveOver, point(4px, 4px) },
};
titleButtonMaximize: IconButton(titleButtonMinimize) {
};
maximize: IconButton(windowTitleButton) {
icon: icon {
{ size(24px, 21px), titleButtonBg },
{ "title_button_maximize", titleButtonFg, point(4px, 4px) },
@ -1196,34 +1227,32 @@ titleButtonMaximize: IconButton(titleButtonMinimize) {
{ size(24px, 21px), titleButtonBgOver },
{ "title_button_maximize", titleButtonFgOver, point(4px, 4px) },
};
}
titleButtonMaximizeIconActive: icon {
}
maximizeIconActive: icon {
{ size(24px, 21px), titleButtonBgActive },
{ "title_button_maximize", titleButtonFgActive, point(4px, 4px) },
};
titleButtonMaximizeIconActiveOver: icon {
};
maximizeIconActiveOver: icon {
{ size(24px, 21px), titleButtonBgActiveOver },
{ "title_button_maximize", titleButtonFgActiveOver, point(4px, 4px) },
};
titleButtonRestoreIcon: icon {
};
restoreIcon: icon {
{ size(24px, 21px), titleButtonBg },
{ "title_button_restore", titleButtonFg, point(4px, 4px) },
};
titleButtonRestoreIconOver: icon {
};
restoreIconOver: icon {
{ size(24px, 21px), titleButtonBgOver },
{ "title_button_restore", titleButtonFgOver, point(4px, 4px) },
};
titleButtonRestoreIconActive: icon {
};
restoreIconActive: icon {
{ size(24px, 21px), titleButtonBgActive },
{ "title_button_restore", titleButtonFgActive, point(4px, 4px) },
};
titleButtonRestoreIconActiveOver: icon {
};
restoreIconActiveOver: icon {
{ size(24px, 21px), titleButtonBgActiveOver },
{ "title_button_restore", titleButtonFgActiveOver, point(4px, 4px) },
};
titleButtonClose: IconButton(titleButtonMinimize) {
width: 25px;
};
close: IconButton(windowTitleButtonClose) {
icon: icon {
{ size(25px, 21px), titleButtonCloseBg },
{ "title_button_close", titleButtonCloseFg, point(5px, 4px) },
@ -1232,15 +1261,16 @@ titleButtonClose: IconButton(titleButtonMinimize) {
{ size(25px, 21px), titleButtonCloseBgOver },
{ "title_button_close", titleButtonCloseFgOver, point(5px, 4px) },
};
}
titleButtonCloseIconActive: icon {
}
closeIconActive: icon {
{ size(25px, 21px), titleButtonCloseBgActive },
{ "title_button_close", titleButtonCloseFgActive, point(5px, 4px) },
};
titleButtonCloseIconActiveOver: icon {
};
closeIconActiveOver: icon {
{ size(25px, 21px), titleButtonCloseBgActiveOver },
{ "title_button_close", titleButtonCloseFgActiveOver, point(5px, 4px) },
};
};
}
windowShadow: icon {{ "window_shadow", windowShadowFg }};
windowShadowShift: 1px;

View file

@ -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);

View file

@ -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<const RpWidget*> 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);