mirror of
https://github.com/Chatterino/chatterino2.git
synced 2024-11-21 22:24:07 +01:00
started working on a custom window frame
This commit is contained in:
parent
177cd734ab
commit
c50e6d7809
11 changed files with 335 additions and 67 deletions
|
@ -53,7 +53,23 @@ void ThemeManager::update()
|
||||||
// multiplier: 1 = white, 0.8 = light, -0.8 dark, -1 black
|
// multiplier: 1 = white, 0.8 = light, -0.8 dark, -1 black
|
||||||
void ThemeManager::actuallyUpdate(double hue, double multiplier)
|
void ThemeManager::actuallyUpdate(double hue, double multiplier)
|
||||||
{
|
{
|
||||||
lightTheme = multiplier > 0;
|
isLight = multiplier > 0;
|
||||||
|
bool isLightTabs;
|
||||||
|
|
||||||
|
QColor themeColor = QColor::fromHslF(hue, 0.5, 0.5);
|
||||||
|
QColor themeColorNoSat = QColor::fromHslF(hue, 0.5, 0.5);
|
||||||
|
|
||||||
|
#ifdef USEWINSDK
|
||||||
|
QColor tabFg = isLight ? "#000" : "#fff";
|
||||||
|
this->windowBg = isLight ? "#fff" : "#444";
|
||||||
|
|
||||||
|
isLightTabs = isLight;
|
||||||
|
#else
|
||||||
|
QColor tabFg = lightTheme ? "#000" : "#fff";
|
||||||
|
this->windowBg = "#fff";
|
||||||
|
|
||||||
|
isLightTabs = true;
|
||||||
|
#endif
|
||||||
|
|
||||||
qreal sat = 0.05;
|
qreal sat = 0.05;
|
||||||
|
|
||||||
|
@ -70,30 +86,30 @@ void ThemeManager::actuallyUpdate(double hue, double multiplier)
|
||||||
|
|
||||||
// message (referenced later)
|
// message (referenced later)
|
||||||
this->messages.textColors.caret = //
|
this->messages.textColors.caret = //
|
||||||
this->messages.textColors.regular = lightTheme ? QColor(0, 0, 0) : QColor(255, 255, 255);
|
this->messages.textColors.regular = isLight ? "#000" : "#fff";
|
||||||
|
|
||||||
// tabs
|
// tabs
|
||||||
// text, {regular, hover, unfocused}
|
// text, {regular, hover, unfocused}
|
||||||
this->tabs.regular = {QColor(0, 0, 0),
|
this->tabs.regular = {tabFg, {windowBg, blendColors(windowBg, "#999", 0.5), windowBg}};
|
||||||
{QColor(255, 255, 255), QColor(200, 200, 200), QColor(255, 255, 255)}};
|
|
||||||
|
|
||||||
this->tabs.selected = {QColor(255, 255, 255),
|
this->tabs.selected = {"#fff", {themeColor, themeColor, QColor::fromHslF(hue, 0, 0.5)}};
|
||||||
{QColor::fromHslF(hue, 0.5, 0.5), QColor::fromHslF(hue, 0.5, 0.5),
|
|
||||||
QColor::fromHslF(hue, 0, 0.5)}};
|
|
||||||
|
|
||||||
this->tabs.newMessage = {QColor(0, 0, 0),
|
this->tabs.newMessage = {
|
||||||
{QBrush(QColor::fromHslF(hue, 0.5, 0.8), Qt::DiagCrossPattern),
|
tabFg,
|
||||||
QBrush(QColor::fromHslF(hue, 0.5, 0.7), Qt::DiagCrossPattern),
|
{QBrush(blendColors(themeColor, windowBg, 0.5), Qt::DiagCrossPattern),
|
||||||
QBrush(QColor::fromHslF(hue, 0, 0.8), Qt::DiagCrossPattern)}};
|
QBrush(blendColors(themeColor, windowBg, 0.3), Qt::DiagCrossPattern),
|
||||||
|
QBrush(blendColors(themeColorNoSat, windowBg, 0.5), Qt::DiagCrossPattern)}};
|
||||||
|
|
||||||
this->tabs.highlighted = {QColor(0, 0, 0),
|
this->tabs.highlighted = {
|
||||||
{QColor::fromHslF(hue, 0.5, 0.8), QColor::fromHslF(hue, 0.5, 0.7),
|
tabFg,
|
||||||
QColor::fromHslF(hue, 0, 0.8)}};
|
{QBrush(blendColors(themeColor, windowBg, 0.5), Qt::DiagCrossPattern),
|
||||||
|
QBrush(blendColors(themeColor, windowBg, 0.3), Qt::DiagCrossPattern),
|
||||||
|
QBrush(blendColors(themeColorNoSat, windowBg, 0.5), Qt::DiagCrossPattern)}};
|
||||||
|
|
||||||
// Split
|
// Split
|
||||||
bool flat = lightTheme;
|
bool flat = isLight;
|
||||||
|
|
||||||
this->splits.messageSeperator = lightTheme ? QColor(127, 127, 127) : QColor(80, 80, 80);
|
this->splits.messageSeperator = isLight ? QColor(127, 127, 127) : QColor(80, 80, 80);
|
||||||
this->splits.background = getColor(0, sat, 1);
|
this->splits.background = getColor(0, sat, 1);
|
||||||
this->splits.dropPreview = getColor(hue, 0.5, 0.5, 0.6);
|
this->splits.dropPreview = getColor(hue, 0.5, 0.5, 0.6);
|
||||||
// this->splits.border
|
// this->splits.border
|
||||||
|
@ -113,7 +129,7 @@ void ThemeManager::actuallyUpdate(double hue, double multiplier)
|
||||||
"selection-background-color:" + this->tabs.selected.backgrounds.regular.color().name();
|
"selection-background-color:" + this->tabs.selected.backgrounds.regular.color().name();
|
||||||
|
|
||||||
// Message
|
// Message
|
||||||
this->messages.textColors.link = lightTheme ? QColor(66, 134, 244) : QColor(66, 134, 244);
|
this->messages.textColors.link = isLight ? QColor(66, 134, 244) : QColor(66, 134, 244);
|
||||||
this->messages.textColors.system = QColor(140, 127, 127);
|
this->messages.textColors.system = QColor(140, 127, 127);
|
||||||
|
|
||||||
this->messages.backgrounds.regular = splits.background;
|
this->messages.backgrounds.regular = splits.background;
|
||||||
|
@ -151,7 +167,7 @@ QColor ThemeManager::blendColors(const QColor &color1, const QColor &color2, qre
|
||||||
|
|
||||||
void ThemeManager::normalizeColor(QColor &color)
|
void ThemeManager::normalizeColor(QColor &color)
|
||||||
{
|
{
|
||||||
if (this->lightTheme) {
|
if (this->isLight) {
|
||||||
if (color.lightnessF() > 0.5f) {
|
if (color.lightnessF() > 0.5f) {
|
||||||
color.setHslF(color.hueF(), color.saturationF(), 0.5f);
|
color.setHslF(color.hueF(), color.saturationF(), 0.5f);
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,7 +20,7 @@ public:
|
||||||
|
|
||||||
inline bool isLightTheme() const
|
inline bool isLightTheme() const
|
||||||
{
|
{
|
||||||
return this->lightTheme;
|
return this->isLight;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct TabColors {
|
struct TabColors {
|
||||||
|
@ -97,6 +97,9 @@ public:
|
||||||
QColor background;
|
QColor background;
|
||||||
} tooltip;
|
} tooltip;
|
||||||
|
|
||||||
|
QColor windowBg;
|
||||||
|
QColor windowText;
|
||||||
|
|
||||||
void normalizeColor(QColor &color);
|
void normalizeColor(QColor &color);
|
||||||
|
|
||||||
void update();
|
void update();
|
||||||
|
@ -116,7 +119,7 @@ private:
|
||||||
void fillLookupTableValues(double (&array)[360], double from, double to, double fromValue,
|
void fillLookupTableValues(double (&array)[360], double from, double to, double fromValue,
|
||||||
double toValue);
|
double toValue);
|
||||||
|
|
||||||
bool lightTheme = false;
|
bool isLight = false;
|
||||||
|
|
||||||
pajlada::Signals::NoArgSignal repaintVisibleChatWidgets;
|
pajlada::Signals::NoArgSignal repaintVisibleChatWidgets;
|
||||||
|
|
||||||
|
|
|
@ -11,22 +11,22 @@
|
||||||
namespace chatterino {
|
namespace chatterino {
|
||||||
namespace widgets {
|
namespace widgets {
|
||||||
|
|
||||||
BaseWidget::BaseWidget(singletons::ThemeManager &_themeManager, QWidget *parent)
|
BaseWidget::BaseWidget(singletons::ThemeManager &_themeManager, QWidget *parent, Qt::WindowFlags f)
|
||||||
: QWidget(parent)
|
: QWidget(parent, f)
|
||||||
, themeManager(_themeManager)
|
, themeManager(_themeManager)
|
||||||
{
|
{
|
||||||
this->init();
|
this->init();
|
||||||
}
|
}
|
||||||
|
|
||||||
BaseWidget::BaseWidget(BaseWidget *parent)
|
BaseWidget::BaseWidget(BaseWidget *parent, Qt::WindowFlags f)
|
||||||
: QWidget(parent)
|
: QWidget(parent, f)
|
||||||
, themeManager(singletons::ThemeManager::getInstance())
|
, themeManager(singletons::ThemeManager::getInstance())
|
||||||
{
|
{
|
||||||
this->init();
|
this->init();
|
||||||
}
|
}
|
||||||
|
|
||||||
BaseWidget::BaseWidget(QWidget *parent)
|
BaseWidget::BaseWidget(QWidget *parent, Qt::WindowFlags f)
|
||||||
: QWidget(parent)
|
: QWidget(parent, f)
|
||||||
, themeManager(singletons::ThemeManager::getInstance())
|
, themeManager(singletons::ThemeManager::getInstance())
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,9 +14,10 @@ class BaseWidget : public QWidget
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit BaseWidget(singletons::ThemeManager &_themeManager, QWidget *parent);
|
explicit BaseWidget(singletons::ThemeManager &_themeManager, QWidget *parent,
|
||||||
explicit BaseWidget(BaseWidget *parent);
|
Qt::WindowFlags f = Qt::WindowFlags());
|
||||||
explicit BaseWidget(QWidget *parent = nullptr);
|
explicit BaseWidget(BaseWidget *parent, Qt::WindowFlags f = Qt::WindowFlags());
|
||||||
|
explicit BaseWidget(QWidget *parent = nullptr, Qt::WindowFlags f = Qt::WindowFlags());
|
||||||
|
|
||||||
singletons::ThemeManager &themeManager;
|
singletons::ThemeManager &themeManager;
|
||||||
|
|
||||||
|
|
|
@ -4,28 +4,46 @@
|
||||||
#include "util/nativeeventhelper.hpp"
|
#include "util/nativeeventhelper.hpp"
|
||||||
#include "widgets/tooltipwidget.hpp"
|
#include "widgets/tooltipwidget.hpp"
|
||||||
|
|
||||||
|
#include <QApplication>
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
#include <QIcon>
|
#include <QIcon>
|
||||||
|
|
||||||
|
#ifdef USEWINSDK
|
||||||
|
#include <dwmapi.h>
|
||||||
|
#include <gdiplus.h>
|
||||||
|
#include <objidl.h>
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
|
#include <windowsx.h>
|
||||||
|
#pragma comment(lib, "Dwmapi.lib")
|
||||||
|
|
||||||
|
#include <QHBoxLayout>
|
||||||
|
#include <QVBoxLayout>
|
||||||
|
#include "widgets/helper/rippleeffectlabel.hpp"
|
||||||
|
|
||||||
|
#define WM_DPICHANGED 0x02E0
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace chatterino {
|
namespace chatterino {
|
||||||
namespace widgets {
|
namespace widgets {
|
||||||
|
|
||||||
BaseWindow::BaseWindow(singletons::ThemeManager &_themeManager, QWidget *parent)
|
BaseWindow::BaseWindow(singletons::ThemeManager &_themeManager, QWidget *parent,
|
||||||
: BaseWidget(_themeManager, parent)
|
bool _enableCustomFrame)
|
||||||
|
: BaseWidget(_themeManager, parent, Qt::Window)
|
||||||
|
, enableCustomFrame(_enableCustomFrame)
|
||||||
{
|
{
|
||||||
this->init();
|
this->init();
|
||||||
}
|
}
|
||||||
|
|
||||||
BaseWindow::BaseWindow(BaseWidget *parent)
|
BaseWindow::BaseWindow(BaseWidget *parent, bool _enableCustomFrame)
|
||||||
: BaseWidget(parent)
|
: BaseWidget(parent, Qt::Window)
|
||||||
|
, enableCustomFrame(_enableCustomFrame)
|
||||||
{
|
{
|
||||||
this->init();
|
this->init();
|
||||||
}
|
}
|
||||||
|
|
||||||
BaseWindow::BaseWindow(QWidget *parent)
|
BaseWindow::BaseWindow(QWidget *parent, bool _enableCustomFrame)
|
||||||
: BaseWidget(parent)
|
: BaseWidget(parent, Qt::Window)
|
||||||
|
, enableCustomFrame(_enableCustomFrame)
|
||||||
{
|
{
|
||||||
this->init();
|
this->init();
|
||||||
}
|
}
|
||||||
|
@ -35,6 +53,51 @@ void BaseWindow::init()
|
||||||
this->setWindowIcon(QIcon(":/images/icon.png"));
|
this->setWindowIcon(QIcon(":/images/icon.png"));
|
||||||
|
|
||||||
#ifdef USEWINSDK
|
#ifdef USEWINSDK
|
||||||
|
if (this->hasCustomWindowFrame()) {
|
||||||
|
// CUSTOM WINDOW FRAME
|
||||||
|
QVBoxLayout *layout = new QVBoxLayout;
|
||||||
|
layout->setMargin(1);
|
||||||
|
this->setLayout(layout);
|
||||||
|
{
|
||||||
|
QHBoxLayout *buttons = this->titlebarBox = new QHBoxLayout;
|
||||||
|
buttons->setMargin(0);
|
||||||
|
layout->addLayout(buttons);
|
||||||
|
|
||||||
|
// title
|
||||||
|
QLabel *titleLabel = new QLabel("Chatterino");
|
||||||
|
buttons->addWidget(titleLabel);
|
||||||
|
this->titleLabel = titleLabel;
|
||||||
|
|
||||||
|
// buttons
|
||||||
|
RippleEffectLabel *min = new RippleEffectLabel;
|
||||||
|
min->getLabel().setText("min");
|
||||||
|
min->setFixedSize(46, 30);
|
||||||
|
RippleEffectLabel *max = new RippleEffectLabel;
|
||||||
|
max->setFixedSize(46, 30);
|
||||||
|
max->getLabel().setText("max");
|
||||||
|
RippleEffectLabel *exit = new RippleEffectLabel;
|
||||||
|
exit->setFixedSize(46, 30);
|
||||||
|
exit->getLabel().setText("exit");
|
||||||
|
|
||||||
|
this->minButton = min;
|
||||||
|
this->maxButton = max;
|
||||||
|
this->exitButton = exit;
|
||||||
|
|
||||||
|
this->widgets.push_back(min);
|
||||||
|
this->widgets.push_back(max);
|
||||||
|
this->widgets.push_back(exit);
|
||||||
|
|
||||||
|
buttons->addStretch(1);
|
||||||
|
buttons->addWidget(min);
|
||||||
|
buttons->addWidget(max);
|
||||||
|
buttons->addWidget(exit);
|
||||||
|
}
|
||||||
|
this->layoutBase = new QWidget(this);
|
||||||
|
this->widgets.push_back(this->layoutBase);
|
||||||
|
layout->addWidget(this->layoutBase);
|
||||||
|
}
|
||||||
|
|
||||||
|
// DPI
|
||||||
auto dpi = util::getWindowDpi(this->winId());
|
auto dpi = util::getWindowDpi(this->winId());
|
||||||
|
|
||||||
if (dpi) {
|
if (dpi) {
|
||||||
|
@ -49,6 +112,40 @@ void BaseWindow::init()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QWidget *BaseWindow::getLayoutContainer()
|
||||||
|
{
|
||||||
|
if (this->enableCustomFrame) {
|
||||||
|
return this->layoutBase;
|
||||||
|
} else {
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool BaseWindow::hasCustomWindowFrame()
|
||||||
|
{
|
||||||
|
#ifdef Q_OS_WIN
|
||||||
|
return this->enableCustomFrame;
|
||||||
|
#else
|
||||||
|
return false;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void BaseWindow::refreshTheme()
|
||||||
|
{
|
||||||
|
QPalette palette;
|
||||||
|
palette.setColor(QPalette::Background, this->themeManager.windowBg);
|
||||||
|
palette.setColor(QPalette::Foreground, this->themeManager.windowText);
|
||||||
|
this->setPalette(palette);
|
||||||
|
}
|
||||||
|
|
||||||
|
void BaseWindow::addTitleBarButton(const QString &text)
|
||||||
|
{
|
||||||
|
RippleEffectLabel *label = new RippleEffectLabel;
|
||||||
|
label->getLabel().setText(text);
|
||||||
|
this->widgets.push_back(label);
|
||||||
|
this->titlebarBox->insertWidget(2, label);
|
||||||
|
}
|
||||||
|
|
||||||
void BaseWindow::changeEvent(QEvent *)
|
void BaseWindow::changeEvent(QEvent *)
|
||||||
{
|
{
|
||||||
TooltipWidget::getInstance()->hide();
|
TooltipWidget::getInstance()->hide();
|
||||||
|
@ -64,26 +161,156 @@ bool BaseWindow::nativeEvent(const QByteArray &eventType, void *message, long *r
|
||||||
{
|
{
|
||||||
MSG *msg = reinterpret_cast<MSG *>(message);
|
MSG *msg = reinterpret_cast<MSG *>(message);
|
||||||
|
|
||||||
// WM_DPICHANGED
|
switch (msg->message) {
|
||||||
if (msg->message == 0x02E0) {
|
case WM_DPICHANGED: {
|
||||||
qDebug() << "dpi changed";
|
qDebug() << "dpi changed";
|
||||||
int dpi = HIWORD(msg->wParam);
|
int dpi = HIWORD(msg->wParam);
|
||||||
|
|
||||||
float oldDpiMultiplier = this->dpiMultiplier;
|
float oldDpiMultiplier = this->dpiMultiplier;
|
||||||
this->dpiMultiplier = dpi / 96.f;
|
this->dpiMultiplier = dpi / 96.f;
|
||||||
float scale = this->dpiMultiplier / oldDpiMultiplier;
|
float scale = this->dpiMultiplier / oldDpiMultiplier;
|
||||||
|
|
||||||
this->dpiMultiplierChanged(oldDpiMultiplier, this->dpiMultiplier);
|
this->dpiMultiplierChanged(oldDpiMultiplier, this->dpiMultiplier);
|
||||||
|
|
||||||
this->resize(static_cast<int>(this->width() * scale),
|
this->resize(static_cast<int>(this->width() * scale),
|
||||||
static_cast<int>(this->height() * scale));
|
static_cast<int>(this->height() * scale));
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
}
|
||||||
|
case WM_NCCALCSIZE: {
|
||||||
|
if (this->hasCustomWindowFrame()) {
|
||||||
|
// this kills the window frame and title bar we added with
|
||||||
|
// WS_THICKFRAME and WS_CAPTION
|
||||||
|
*result = 0;
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return QWidget::nativeEvent(eventType, message, result);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case WM_NCHITTEST: {
|
||||||
|
if (this->hasCustomWindowFrame()) {
|
||||||
|
*result = 0;
|
||||||
|
const LONG border_width = 8; // in pixels
|
||||||
|
RECT winrect;
|
||||||
|
GetWindowRect((HWND)winId(), &winrect);
|
||||||
|
|
||||||
|
long x = GET_X_LPARAM(msg->lParam);
|
||||||
|
long y = GET_Y_LPARAM(msg->lParam);
|
||||||
|
|
||||||
|
bool resizeWidth = minimumWidth() != maximumWidth();
|
||||||
|
bool resizeHeight = minimumHeight() != maximumHeight();
|
||||||
|
|
||||||
|
if (resizeWidth) {
|
||||||
|
// left border
|
||||||
|
if (x >= winrect.left && x < winrect.left + border_width) {
|
||||||
|
*result = HTLEFT;
|
||||||
|
}
|
||||||
|
// right border
|
||||||
|
if (x < winrect.right && x >= winrect.right - border_width) {
|
||||||
|
*result = HTRIGHT;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (resizeHeight) {
|
||||||
|
// bottom border
|
||||||
|
if (y < winrect.bottom && y >= winrect.bottom - border_width) {
|
||||||
|
*result = HTBOTTOM;
|
||||||
|
}
|
||||||
|
// top border
|
||||||
|
if (y >= winrect.top && y < winrect.top + border_width) {
|
||||||
|
*result = HTTOP;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (resizeWidth && resizeHeight) {
|
||||||
|
// bottom left corner
|
||||||
|
if (x >= winrect.left && x < winrect.left + border_width &&
|
||||||
|
y < winrect.bottom && y >= winrect.bottom - border_width) {
|
||||||
|
*result = HTBOTTOMLEFT;
|
||||||
|
}
|
||||||
|
// bottom right corner
|
||||||
|
if (x < winrect.right && x >= winrect.right - border_width &&
|
||||||
|
y < winrect.bottom && y >= winrect.bottom - border_width) {
|
||||||
|
*result = HTBOTTOMRIGHT;
|
||||||
|
}
|
||||||
|
// top left corner
|
||||||
|
if (x >= winrect.left && x < winrect.left + border_width && y >= winrect.top &&
|
||||||
|
y < winrect.top + border_width) {
|
||||||
|
*result = HTTOPLEFT;
|
||||||
|
}
|
||||||
|
// top right corner
|
||||||
|
if (x < winrect.right && x >= winrect.right - border_width &&
|
||||||
|
y >= winrect.top && y < winrect.top + border_width) {
|
||||||
|
*result = HTTOPRIGHT;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (*result == 0) {
|
||||||
|
bool client = false;
|
||||||
|
|
||||||
|
QPoint point(x - winrect.left, y - winrect.top);
|
||||||
|
for (QWidget *widget : this->widgets) {
|
||||||
|
if (widget->geometry().contains(point)) {
|
||||||
|
client = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (client) {
|
||||||
|
*result = HTCLIENT;
|
||||||
|
} else {
|
||||||
|
*result = HTCAPTION;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
qDebug() << *result;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return QWidget::nativeEvent(eventType, message, result);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
} // end case WM_NCHITTEST
|
||||||
|
case WM_CLOSE: {
|
||||||
|
if (this->enableCustomFrame) {
|
||||||
|
return close();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
return QWidget::nativeEvent(eventType, message, result);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return QWidget::nativeEvent(eventType, message, result);
|
void BaseWindow::showEvent(QShowEvent *)
|
||||||
} // namespace widgets
|
{
|
||||||
|
if (this->isVisible() && this->hasCustomWindowFrame()) {
|
||||||
|
SetWindowLongPtr((HWND)this->winId(), GWL_STYLE,
|
||||||
|
WS_POPUP | WS_CAPTION | WS_THICKFRAME | WS_MAXIMIZEBOX | WS_MINIMIZEBOX);
|
||||||
|
|
||||||
|
const MARGINS shadow = {1, 1, 1, 1};
|
||||||
|
DwmExtendFrameIntoClientArea((HWND)this->winId(), &shadow);
|
||||||
|
|
||||||
|
SetWindowPos((HWND)this->winId(), 0, 0, 0, 0, 0,
|
||||||
|
SWP_FRAMECHANGED | SWP_NOMOVE | SWP_NOSIZE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void BaseWindow::paintEvent(QPaintEvent *event)
|
||||||
|
{
|
||||||
|
BaseWidget::paintEvent(event);
|
||||||
|
|
||||||
|
if (this->hasCustomWindowFrame()) {
|
||||||
|
QPainter painter(this);
|
||||||
|
|
||||||
|
bool windowFocused = this->window() == QApplication::activeWindow();
|
||||||
|
|
||||||
|
if (windowFocused) {
|
||||||
|
painter.setPen(this->themeManager.tabs.selected.backgrounds.regular.color());
|
||||||
|
} else {
|
||||||
|
painter.setPen(this->themeManager.tabs.selected.backgrounds.unfocused.color());
|
||||||
|
}
|
||||||
|
painter.drawRect(0, 0, this->width() - 1, this->height() - 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
} // namespace widgets
|
} // namespace widgets
|
||||||
|
|
|
@ -2,26 +2,47 @@
|
||||||
|
|
||||||
#include "basewidget.hpp"
|
#include "basewidget.hpp"
|
||||||
|
|
||||||
|
class QHBoxLayout;
|
||||||
|
|
||||||
namespace chatterino {
|
namespace chatterino {
|
||||||
namespace widgets {
|
namespace widgets {
|
||||||
|
|
||||||
class BaseWindow : public BaseWidget
|
class BaseWindow : public BaseWidget
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
explicit BaseWindow(singletons::ThemeManager &_themeManager, QWidget *parent);
|
explicit BaseWindow(singletons::ThemeManager &_themeManager, QWidget *parent,
|
||||||
explicit BaseWindow(BaseWidget *parent);
|
bool enableCustomFrame = false);
|
||||||
explicit BaseWindow(QWidget *parent = nullptr);
|
explicit BaseWindow(BaseWidget *parent, bool enableCustomFrame = false);
|
||||||
|
explicit BaseWindow(QWidget *parent = nullptr, bool enableCustomFrame = false);
|
||||||
|
|
||||||
|
QWidget *getLayoutContainer();
|
||||||
|
bool hasCustomWindowFrame();
|
||||||
|
void addTitleBarButton(const QString &text);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
#ifdef USEWINSDK
|
#ifdef USEWINSDK
|
||||||
|
virtual void showEvent(QShowEvent *);
|
||||||
virtual bool nativeEvent(const QByteArray &eventType, void *message, long *result) override;
|
virtual bool nativeEvent(const QByteArray &eventType, void *message, long *result) override;
|
||||||
|
virtual void paintEvent(QPaintEvent *event) override;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
virtual void changeEvent(QEvent *) override;
|
virtual void changeEvent(QEvent *) override;
|
||||||
virtual void leaveEvent(QEvent *) override;
|
virtual void leaveEvent(QEvent *) override;
|
||||||
|
|
||||||
|
virtual void refreshTheme() override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void init();
|
void init();
|
||||||
|
|
||||||
|
bool enableCustomFrame;
|
||||||
|
|
||||||
|
QHBoxLayout *titlebarBox;
|
||||||
|
QWidget *titleLabel;
|
||||||
|
QWidget *minButton;
|
||||||
|
QWidget *maxButton;
|
||||||
|
QWidget *exitButton;
|
||||||
|
QWidget *layoutBase;
|
||||||
|
std::vector<QWidget *> widgets;
|
||||||
};
|
};
|
||||||
} // namespace widgets
|
} // namespace widgets
|
||||||
} // namespace chatterino
|
} // namespace chatterino
|
||||||
|
|
|
@ -15,7 +15,7 @@ namespace widgets {
|
||||||
class RippleEffectLabel : public RippleEffectButton
|
class RippleEffectLabel : public RippleEffectButton
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
explicit RippleEffectLabel(BaseWidget *parent, int spacing = 6);
|
explicit RippleEffectLabel(BaseWidget *parent = nullptr, int spacing = 6);
|
||||||
|
|
||||||
SignalLabel &getLabel()
|
SignalLabel &getLabel()
|
||||||
{
|
{
|
||||||
|
|
|
@ -24,6 +24,7 @@ namespace widgets {
|
||||||
|
|
||||||
Notebook::Notebook(Window *parent, bool _showButtons, const std::string &settingPrefix)
|
Notebook::Notebook(Window *parent, bool _showButtons, const std::string &settingPrefix)
|
||||||
: BaseWidget(parent)
|
: BaseWidget(parent)
|
||||||
|
, parentWindow(parent)
|
||||||
, settingRoot(fS("{}/notebook", settingPrefix))
|
, settingRoot(fS("{}/notebook", settingPrefix))
|
||||||
, addButton(this)
|
, addButton(this)
|
||||||
, settingsButton(this)
|
, settingsButton(this)
|
||||||
|
@ -196,14 +197,15 @@ void Notebook::performLayout(bool animated)
|
||||||
|
|
||||||
int x = 0, y = 0;
|
int x = 0, y = 0;
|
||||||
float scale = this->getDpiMultiplier();
|
float scale = this->getDpiMultiplier();
|
||||||
|
bool customFrame = this->parentWindow->hasCustomWindowFrame();
|
||||||
|
|
||||||
if (!showButtons || settings.hidePreferencesButton) {
|
if (!this->showButtons || settings.hidePreferencesButton || customFrame) {
|
||||||
this->settingsButton.hide();
|
this->settingsButton.hide();
|
||||||
} else {
|
} else {
|
||||||
this->settingsButton.show();
|
this->settingsButton.show();
|
||||||
x += settingsButton.width();
|
x += settingsButton.width();
|
||||||
}
|
}
|
||||||
if (!showButtons || settings.hideUserButton) {
|
if (!this->showButtons || settings.hideUserButton || customFrame) {
|
||||||
this->userButton.hide();
|
this->userButton.hide();
|
||||||
} else {
|
} else {
|
||||||
this->userButton.move(x, 0);
|
this->userButton.move(x, 0);
|
||||||
|
@ -211,7 +213,8 @@ void Notebook::performLayout(bool animated)
|
||||||
x += userButton.width();
|
x += userButton.width();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!showButtons || (settings.hideUserButton && settings.hidePreferencesButton)) {
|
if (customFrame || !this->showButtons ||
|
||||||
|
(settings.hideUserButton && settings.hidePreferencesButton)) {
|
||||||
x += (int)(scale * 2);
|
x += (int)(scale * 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -57,6 +57,8 @@ public slots:
|
||||||
void addPageButtonClicked();
|
void addPageButtonClicked();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
Window *parentWindow;
|
||||||
|
|
||||||
QList<SplitContainer *> pages;
|
QList<SplitContainer *> pages;
|
||||||
|
|
||||||
NotebookButton addButton;
|
NotebookButton addButton;
|
||||||
|
|
|
@ -18,7 +18,7 @@ namespace widgets {
|
||||||
|
|
||||||
Window::Window(const QString &windowName, singletons::ThemeManager &_themeManager,
|
Window::Window(const QString &windowName, singletons::ThemeManager &_themeManager,
|
||||||
bool _isMainWindow)
|
bool _isMainWindow)
|
||||||
: BaseWindow(_themeManager, nullptr)
|
: BaseWindow(_themeManager, nullptr, true)
|
||||||
, settingRoot(fS("/windows/{}", windowName))
|
, settingRoot(fS("/windows/{}", windowName))
|
||||||
, windowGeometry(this->settingRoot)
|
, windowGeometry(this->settingRoot)
|
||||||
, dpi(this->getDpiMultiplier())
|
, dpi(this->getDpiMultiplier())
|
||||||
|
@ -34,6 +34,11 @@ Window::Window(const QString &windowName, singletons::ThemeManager &_themeManage
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if (this->hasCustomWindowFrame()) {
|
||||||
|
this->addTitleBarButton("Preferences");
|
||||||
|
this->addTitleBarButton("User");
|
||||||
|
}
|
||||||
|
|
||||||
QVBoxLayout *layout = new QVBoxLayout(this);
|
QVBoxLayout *layout = new QVBoxLayout(this);
|
||||||
|
|
||||||
// add titlebar
|
// add titlebar
|
||||||
|
@ -42,7 +47,7 @@ Window::Window(const QString &windowName, singletons::ThemeManager &_themeManage
|
||||||
// }
|
// }
|
||||||
|
|
||||||
layout->addWidget(&this->notebook);
|
layout->addWidget(&this->notebook);
|
||||||
setLayout(layout);
|
this->getLayoutContainer()->setLayout(layout);
|
||||||
|
|
||||||
// set margin
|
// set margin
|
||||||
// if (SettingsManager::getInstance().useCustomWindowFrame.get()) {
|
// if (SettingsManager::getInstance().useCustomWindowFrame.get()) {
|
||||||
|
@ -139,14 +144,6 @@ void Window::closeEvent(QCloseEvent *)
|
||||||
this->closed();
|
this->closed();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Window::refreshTheme()
|
|
||||||
{
|
|
||||||
QPalette palette;
|
|
||||||
palette.setColor(QPalette::Background,
|
|
||||||
this->themeManager.tabs.regular.backgrounds.regular.color());
|
|
||||||
this->setPalette(palette);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Window::loadGeometry()
|
void Window::loadGeometry()
|
||||||
{
|
{
|
||||||
bool doSetGeometry = false;
|
bool doSetGeometry = false;
|
||||||
|
|
|
@ -63,8 +63,6 @@ private:
|
||||||
|
|
||||||
float dpi;
|
float dpi;
|
||||||
|
|
||||||
virtual void refreshTheme() override;
|
|
||||||
|
|
||||||
void loadGeometry();
|
void loadGeometry();
|
||||||
|
|
||||||
Notebook notebook;
|
Notebook notebook;
|
||||||
|
|
Loading…
Reference in a new issue