dark/light mode & accent color

This commit is contained in:
Hane 2024-11-26 17:11:01 +01:00
commit 60890cecad
9 changed files with 178 additions and 44 deletions

View file

@ -653,7 +653,7 @@ Overseer::Overseer() : epsc(this){
} }
void Overseer::populateSystemValues() { void Overseer::populateSystemValues() {
updateDarkMode(); updateColors();
} }
void Overseer::openControlPanel() { void Overseer::openControlPanel() {
@ -688,7 +688,7 @@ ProcessedNativeEvent Overseer::processTopLevelWindowMessage(void* msg) {
switch(message->message) { switch(message->message) {
case WM_SETTINGCHANGE: case WM_SETTINGCHANGE:
if(!wcscmp(((wchar_t*)message->lParam), L"ImmersiveColorSet")) if(!wcscmp(((wchar_t*)message->lParam), L"ImmersiveColorSet"))
return updateDarkMode(); return updateColors();
break; break;
default: default:
return ProcessedNativeEvent::NONE; return ProcessedNativeEvent::NONE;
@ -699,23 +699,36 @@ ProcessedNativeEvent Overseer::processTopLevelWindowMessage(void* msg) {
#endif #endif
} }
ProcessedNativeEvent Overseer::updateDarkMode(){ ProcessedNativeEvent Overseer::updateColors() {
// DwmGetColorizationColor( WM_DWMCOLORIZATIONCOLORCHANGED // DwmGetColorizationColor( WM_DWMCOLORIZATIONCOLORCHANGED
DWORD value = 0; DWORD value = 0;
DWORD size = sizeof(DWORD); DWORD size = sizeof(DWORD);
LSTATUS result; LSTATUS result;
//Theme bg color
result = RegGetValueW(HKEY_CURRENT_USER, L"Software\\Microsoft\\Windows\\CurrentVersion\\Themes\\Personalize", L"AppsUseLightTheme", RRF_RT_REG_DWORD, nullptr, &value, &size); result = RegGetValueW(HKEY_CURRENT_USER, L"Software\\Microsoft\\Windows\\CurrentVersion\\Themes\\Personalize", L"AppsUseLightTheme", RRF_RT_REG_DWORD, nullptr, &value, &size);
this->lightMode = (bool)value; this->lightMode = (bool)value;
return ProcessedNativeEvent::LIGHT_MODE;
//Accent color
result = RegGetValueW(HKEY_CURRENT_USER, L"Software\\Microsoft\\Windows\\DWM", L"ColorizationColor", RRF_RT_REG_DWORD, nullptr, &value, &size);
if (result == ERROR_SUCCESS) {
this->accentColor = value;
} else this->accentColor = 0xffffffff;
return ProcessedNativeEvent::COLORS;
} }
bool Overseer::isLightMode() { bool Overseer::isLightMode() {
return this->lightMode; return this->lightMode;
} }
uint32_t Overseer::getAccentColor() {
return this->accentColor;
}
NGuid Overseer::getGuid() { NGuid Overseer::getGuid() {
return guid; return guid;
} }

View file

@ -113,8 +113,9 @@ class Overseer {
void populateSystemValues(); void populateSystemValues();
void openControlPanel(); void openControlPanel();
ProcessedNativeEvent processTopLevelWindowMessage(void* msg); ProcessedNativeEvent processTopLevelWindowMessage(void* msg);
ProcessedNativeEvent updateDarkMode(); ProcessedNativeEvent updateColors();
bool isLightMode(); bool isLightMode();
uint32_t getAccentColor();
std::vector<Endpoint*> getPlaybackEndpoints(); std::vector<Endpoint*> getPlaybackEndpoints();
std::vector<Endpoint*> getCaptureEndpoints(); std::vector<Endpoint*> getCaptureEndpoints();
@ -138,6 +139,7 @@ class Overseer {
NGuid guid; NGuid guid;
bool lightMode; bool lightMode;
uint32_t accentColor;
IMMDeviceEnumerator *deviceEnumerator; IMMDeviceEnumerator *deviceEnumerator;
EndpointSituationCallback epsc; EndpointSituationCallback epsc;

View file

@ -221,6 +221,10 @@ bool OverseerHandler::isLightMode() {
return this->os->isLightMode(); return this->os->isLightMode();
} }
uint32_t OverseerHandler::getAccentColor() {
return this->os->getAccentColor();
}
std::vector<Endpoint*> OverseerHandler::getPlaybackEndpoints() { std::vector<Endpoint*> OverseerHandler::getPlaybackEndpoints() {
return this->os->getPlaybackEndpoints(); return this->os->getPlaybackEndpoints();
} }

View file

@ -101,6 +101,7 @@ public:
void openControlPanel(); void openControlPanel();
ProcessedNativeEvent processTopLevelWindowMessage(void* msg); ProcessedNativeEvent processTopLevelWindowMessage(void* msg);
bool isLightMode(); bool isLightMode();
uint32_t getAccentColor();
//void setChangeFrontDefaultsFunction(std::function<void(Roles, std::wstring)> changeFrontDefaults); //void setChangeFrontDefaultsFunction(std::function<void(Roles, std::wstring)> changeFrontDefaults);
//void changeFrontDefaultsCallback(Roles role, std::wstring endpointId); //void changeFrontDefaultsCallback(Roles role, std::wstring endpointId);

View file

@ -38,7 +38,7 @@
enum ProcessedNativeEvent { enum ProcessedNativeEvent {
NONE = 0, NONE = 0,
LIGHT_MODE = (1 << 0), COLORS = (1 << 0),
}; };
enum AudioChannel { enum AudioChannel {

View file

@ -7,19 +7,27 @@ bool DarkModeEventFilter::nativeEventFilter(const QByteArray &eventType, void *m
if (eventType == "windows_generic_MSG") { if (eventType == "windows_generic_MSG") {
ProcessedNativeEvent event = osh->processTopLevelWindowMessage(message); ProcessedNativeEvent event = osh->processTopLevelWindowMessage(message);
switch(event) { switch(event) {
case LIGHT_MODE: case COLORS:
StylingHelper::setBackgroundColor(osh->isLightMode()); StylingHelper::setBackgroundColor(osh->isLightMode());
//Update accent color across entire app
{
uint32_t color = osh->getAccentColor();
uint8_t r, g, b, a;
if (StylingHelper::argbToDiscreteValues(osh->getAccentColor(), &r, &g, &b, &a)) {
const QWidgetList topLevelWidgets = QApplication::topLevelWidgets();
for (QWidget *widget : topLevelWidgets) {
if(qobject_cast<MainWindow*>(widget)) {
((MainWindow*)widget)->updateColor(r, g, b, a);
}
}
}
}
return true; return true;
break; break;
default: default:
break; break;
} }
/*
* if ([event type] == NSKeyDown) {
* // Handle key event
* qDebug() << QString::fromNSString([event characters]);
* }
*/
} }
return false; return false;
} }
@ -124,8 +132,8 @@ void MeterSlider::paintEvent(QPaintEvent *event) {
sliderComplex2.subControls |= QStyle::SC_SliderTickmarks; sliderComplex2.subControls |= QStyle::SC_SliderTickmarks;
QPainter painter(this); QPainter painter(this);
QStyle* stle = QApplication::style(); QStyle* style = QApplication::style();
stle->drawComplexControl((QStyle::ComplexControl)CC_MeterSlider, &sliderComplex2, &painter, this); style->drawComplexControl((QStyle::ComplexControl)CC_MeterSlider, &sliderComplex2, &painter, this);
//Q_D(QSlider); //Q_D(QSlider);
@ -252,6 +260,13 @@ QRect MainWindow::setSizePosition(QScreen* screen, int width, int height) {
} }
} }
void MainWindow::updateColor(uint8_t r, uint8_t g, uint8_t b, uint8_t a) {
QColor color(r, g, b, a);
QPalette pal = QPalette(color);
pal.setColor(QPalette::Highlight, color);
scrollArea->verticalScrollBar()->setPalette(pal);
}
void MainWindow::compose() { void MainWindow::compose() {
//todo: invalidate layout when adding sessions with window open //todo: invalidate layout when adding sessions with window open
//We need dynamically added child widgets to expand so that we know their height //We need dynamically added child widgets to expand so that we know their height
@ -1022,6 +1037,10 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) {
scrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded); scrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);
scrollArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); scrollArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
scrollArea->setContentsMargins(QMargins(0, 0, 0, 0)); scrollArea->setContentsMargins(QMargins(0, 0, 0, 0));
//ScrollBarFocusFilter focusFilter = new ScrollBarFocusFilter(this);
scrollArea->verticalScrollBar()->installEventFilter(this);
scrollArea->horizontalScrollBar()->installEventFilter(this);
//scrollArea->verticalScrollBar()->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Preferred); //scrollArea->verticalScrollBar()->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Preferred);
//scrollArea->verticalScrollBar()->setSingleStep(1); //scrollArea->verticalScrollBar()->setSingleStep(1);
@ -1071,6 +1090,13 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) {
} }
}); });
/*
* Set accent color
*/
uint8_t a, r, g, b;
if (StylingHelper::argbToDiscreteValues(osh->getAccentColor(), &r, &g, &b, &a))
this->updateColor(r, g, b, a);
/* /*
* Set of function callback definitons for EndpointSituationCallback * Set of function callback definitons for EndpointSituationCallback
*/ */
@ -1090,6 +1116,50 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) {
} }
bool MainWindow::eventFilter(QObject *object, QEvent *event) {
//QScrollBar* widgetCast = qobject_cast<QScrollBar*>(object);
if (object == scrollArea->verticalScrollBar()) {
[[maybe_unused]] QEvent::Type tipo = event->type();
if (event->type() == QHoverEvent::HoverEnter) {
log_debugcpp("Hover event: ");
log_debugcpp("\tGlobal pos: "
+ std::to_string(((QHoverEvent*)event)->globalPosition().x())
+ ", "
+ std::to_string(((QHoverEvent*)event)->globalPosition().y()));
log_debugcpp("\tNewWid pos: "
+ std::to_string(((QHoverEvent*)event)->position().x())
+ ", "
+ std::to_string(((QHoverEvent*)event)->position().y()));
log_debugcpp("\tOldWid pos: "
+ std::to_string(((QHoverEvent*)event)->oldPos().x())
+ ", "
+ std::to_string(((QHoverEvent*)event)->oldPos().y()));
}
if (event->type() == QScrollEvent::ScrollFinished) {
QHoverEvent* hoverEvent = new QHoverEvent(QEvent::HoverEnter,
scrollArea->verticalScrollBar()->mapFromGlobal(QCursor::pos()),
QCursor::pos(),
scrollArea->verticalScrollBar()->mapFromGlobal(QCursor::pos()));
log_debugcpp("ScrollFinished event: ");
log_debugcpp("\tGlobal pos: "
+ std::to_string(QCursor::pos().x())
+ ", "
+ std::to_string(QCursor::pos().y()));
log_debugcpp("\tWidget pos: "
+ std::to_string(scrollArea->verticalScrollBar()->mapFromGlobal(QCursor::pos()).x())
+ ", "
+ std::to_string(scrollArea->verticalScrollBar()->mapFromGlobal(QCursor::pos()).y()));
QCoreApplication::instance()->postEvent(scrollArea->verticalScrollBar(), hoverEvent);
/*
* QCoreApplication::instance()->postEvent(this, new CustomWidgetEvent<SessionHandler*>((QEvent::Type)CustomQEvent::SessionWidgetObsolete, sessionHandler));
*/
//scrollArea->setFocus(Qt::MouseFocusReason);
return false;
}}
return false;
}
void MainWindow::flushRoleChanges() { void MainWindow::flushRoleChanges() {
//TODO: bucket list deque //TODO: bucket list deque
std::pair<Roles, std::wstring> change = roleBucketList.front(); std::pair<Roles, std::wstring> change = roleBucketList.front();

View file

@ -182,6 +182,7 @@ public:
MainWindow(QWidget *parent = nullptr); MainWindow(QWidget *parent = nullptr);
void reloadEndpointWidgets(); void reloadEndpointWidgets();
void compose(); void compose();
void updateColor(uint8_t r, uint8_t g, uint8_t b, uint8_t a);
protected: protected:
void closeEvent(QCloseEvent *event) override; void closeEvent(QCloseEvent *event) override;
@ -200,6 +201,7 @@ private slots:
private: private:
//std::vector<EndpointHandler*> *ephs; //std::vector<EndpointHandler*> *ephs;
bool eventFilter(QObject *object, QEvent *event);
void flushRoleChanges(); void flushRoleChanges();
void changeFrontDefaults(Roles role, EndpointWidget* newDef, EndpointWidget* oldDef); void changeFrontDefaults(Roles role, EndpointWidget* newDef, EndpointWidget* oldDef);

View file

@ -78,6 +78,29 @@ namespace StylingHelper {
QGuiApplication::setPalette(pal); QGuiApplication::setPalette(pal);
} }
static inline void setAccentColor(bool lightMode) {
//QApplication* app = (QApplication*)QApplication::instance();
QPalette pal = QGuiApplication::palette();
if(lightMode) {
pal.setColor(QPalette::Window, Qt::white);
pal.setColor(QPalette::WindowText, Qt::black);
} else {
pal.setColor(QPalette::Window, Qt::black);
pal.setColor(QPalette::WindowText, Qt::white);
}
QGuiApplication::setPalette(pal);
}
static inline bool argbToDiscreteValues(uint32_t color, uint8_t *r, uint8_t *g, uint8_t *b, uint8_t *a) {
if(!r || !g || !b || !a) return false;
*a = (color >> 24) & 0xFF;
*r = (color >> 16) & 0xFF;
*g = (color >> 8) & 0xFF;
*b = color & 0xFF;
return true;
}
static inline QLatin1String operator""_L1(const char* ch, uint64_t) { static inline QLatin1String operator""_L1(const char* ch, uint64_t) {
return QLatin1String(ch); return QLatin1String(ch);
} }

View file

@ -6,6 +6,7 @@
using namespace StylingHelper; using namespace StylingHelper;
class MixerStyle : public QProxyStyle { class MixerStyle : public QProxyStyle {
public: public:
using QProxyStyle::QProxyStyle; using QProxyStyle::QProxyStyle;
@ -448,8 +449,8 @@ public:
//QColor arrowColor = QColor(188,143,143,100); //QColor arrowColor = QColor(188,143,143,100);
arrowColor.setAlpha(160); arrowColor.setAlpha(160);
const QColor bgColor = backgroundColor(option->palette, widget); const QColor appBgColor = QGuiApplication::palette().window().color();
const bool isDarkBg = bgColor.red() < 128 && bgColor.green() < 128 && bgColor.blue() < 128; const bool isDarkBg = appBgColor.red() < 128 && appBgColor.green() < 128 && appBgColor.blue() < 128;
if (transient) { if (transient) {
if (horizontal) { if (horizontal) {
@ -482,10 +483,10 @@ public:
gradient.setColorAt(0.9, buttonColor.darker(105)); gradient.setColorAt(0.9, buttonColor.darker(105));
gradient.setColorAt(1, buttonColor.darker(107)); gradient.setColorAt(1, buttonColor.darker(107));
} else { } else {
gradient.setColorAt(0, bgColor.lighter(157)); gradient.setColorAt(0, appBgColor.lighter(157));
gradient.setColorAt(0.1, bgColor.lighter(155)); gradient.setColorAt(0.1, appBgColor.lighter(155));
gradient.setColorAt(0.9, bgColor.lighter(155)); gradient.setColorAt(0.9, appBgColor.lighter(155));
gradient.setColorAt(1, bgColor.lighter(157)); gradient.setColorAt(1, appBgColor.lighter(157));
} }
painter->save(); painter->save();
@ -505,23 +506,27 @@ public:
} }
QRect pixmapRect = scrollBarSlider; QRect pixmapRect = scrollBarSlider;
QLinearGradient gradient(pixmapRect.center().x(), pixmapRect.top(), QColor highlightColor = option->palette.highlight().color();
pixmapRect.center().x(), pixmapRect.bottom()); /*
if (!horizontal) * QLinearGradient gradient(pixmapRect.center().x(), pixmapRect.top(),
gradient = QLinearGradient(pixmapRect.left(), pixmapRect.center().y(), * pixmapRect.center().x(), pixmapRect.bottom());
pixmapRect.right(), pixmapRect.center().y()); * if (!horizontal)
* gradient = QLinearGradient(pixmapRect.left(), pixmapRect.center().y(),
* pixmapRect.right(), pixmapRect.center().y());
*/
QLinearGradient highlightedGradient = gradient; //QLinearGradient highlightedGradient = gradient;
QColor midColor2 = mergedColors(gradientStartColor, gradientStopColor, 40); QColor heldColor = 0xc4e3d7e0;//Qt::gray;//osh->isLightMode() ? Qt::white : Qt::black;
gradient.setColorAt(0, calculateButtonColor(option->palette).lighter(108)); //gradient.setColorAt(0, option->palette.highlight().color());
gradient.setColorAt(1, calculateButtonColor(option->palette)); //gradient.setColorAt(1, option->palette.highlight().color());
highlightedGradient.setColorAt(0, gradientStartColor.darker(102)); //highlightedGradient.setColorAt(0, gradientStartColor.darker(102));
highlightedGradient.setColorAt(1, gradientStopColor.lighter(102)); //highlightedGradient.setColorAt(1, gradientStopColor.lighter(102));
// Paint slider // Paint slider
if (scrollBar->subControls & SC_ScrollBarSlider) { if (scrollBar->subControls & SC_ScrollBarSlider) {
log_debugcpp("Final scrollbar paint if");
if (transient) { if (transient) {
QRect rect = scrollBarSlider.adjusted(horizontal ? 1 : 2, horizontal ? 2 : 1, -1, -1); QRect rect = scrollBarSlider.adjusted(horizontal ? 1 : 2, horizontal ? 2 : 1, -1, -1);
painter->setPen(Qt::NoPen); painter->setPen(Qt::NoPen);
@ -535,14 +540,20 @@ public:
} else { } else {
QRect pixmapRect = scrollBarSlider; QRect pixmapRect = scrollBarSlider;
painter->setPen(QPen(alphaOutline)); painter->setPen(QPen(alphaOutline));
if (option->state & State_Sunken && scrollBar->activeSubControls & SC_ScrollBarSlider) if (option->state & State_Sunken
painter->setBrush(midColor2); && scrollBar->activeSubControls & SC_ScrollBarSlider)
else if (option->state & State_MouseOver && scrollBar->activeSubControls & SC_ScrollBarSlider) painter->setBrush(heldColor);
painter->setBrush(highlightedGradient); else if (option->state & State_MouseOver
else if (!isDarkBg) && scrollBar->activeSubControls & SC_ScrollBarSlider) {
painter->setBrush(gradient); painter->setBrush(highlightColor);
else }
painter->setBrush(midColor2); else //if (!isDarkBg)
if(!isDarkBg)
painter->setBrush(Qt::black);
else painter->setBrush(Qt::white);
//else
// painter->setBrush(heldColor);
painter->drawRoundedRect(pixmapRect.adjusted(horizontal ? -1 : 0, horizontal ? 0 : -1, horizontal ? 0 : -1, horizontal ? -1 : 0), 5, 5); painter->drawRoundedRect(pixmapRect.adjusted(horizontal ? -1 : 0, horizontal ? 0 : -1, horizontal ? 0 : -1, horizontal ? -1 : 0), 5, 5);
@ -675,6 +686,13 @@ private:
return gradient; return gradient;
} }
QColor highlightedOutline(const QPalette &pal) const {
QColor highlightedOutline = highlight(pal);//.darker(25);//QColor(Qt::green);
if (highlightedOutline.value() > 160)
highlightedOutline.setHsl(highlightedOutline.hue(), highlightedOutline.saturation(), 160);
return highlightedOutline;
}
QColor calculateButtonColor(const QPalette &pal) const { QColor calculateButtonColor(const QPalette &pal) const {
QColor buttonColor = pal.button().color(); QColor buttonColor = pal.button().color();
int val = qGray(buttonColor.rgb()); int val = qGray(buttonColor.rgb());
@ -835,3 +853,4 @@ private:
*/ */
//void MixerStyle:: //void MixerStyle::