diff --git a/src/back/backlasses.cpp b/src/back/backlasses.cpp index 970d79f..e51c011 100644 --- a/src/back/backlasses.cpp +++ b/src/back/backlasses.cpp @@ -653,7 +653,7 @@ Overseer::Overseer() : epsc(this){ } void Overseer::populateSystemValues() { - updateDarkMode(); + updateColors(); } void Overseer::openControlPanel() { @@ -688,7 +688,7 @@ ProcessedNativeEvent Overseer::processTopLevelWindowMessage(void* msg) { switch(message->message) { case WM_SETTINGCHANGE: if(!wcscmp(((wchar_t*)message->lParam), L"ImmersiveColorSet")) - return updateDarkMode(); + return updateColors(); break; default: return ProcessedNativeEvent::NONE; @@ -699,23 +699,36 @@ ProcessedNativeEvent Overseer::processTopLevelWindowMessage(void* msg) { #endif } -ProcessedNativeEvent Overseer::updateDarkMode(){ +ProcessedNativeEvent Overseer::updateColors() { // DwmGetColorizationColor( WM_DWMCOLORIZATIONCOLORCHANGED DWORD value = 0; DWORD size = sizeof(DWORD); 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); 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() { return this->lightMode; } +uint32_t Overseer::getAccentColor() { + return this->accentColor; +} + NGuid Overseer::getGuid() { return guid; } diff --git a/src/back/backlasses.h b/src/back/backlasses.h index 9edc779..f5fba61 100644 --- a/src/back/backlasses.h +++ b/src/back/backlasses.h @@ -113,8 +113,9 @@ class Overseer { void populateSystemValues(); void openControlPanel(); ProcessedNativeEvent processTopLevelWindowMessage(void* msg); - ProcessedNativeEvent updateDarkMode(); + ProcessedNativeEvent updateColors(); bool isLightMode(); + uint32_t getAccentColor(); std::vector getPlaybackEndpoints(); std::vector getCaptureEndpoints(); @@ -138,6 +139,7 @@ class Overseer { NGuid guid; bool lightMode; + uint32_t accentColor; IMMDeviceEnumerator *deviceEnumerator; EndpointSituationCallback epsc; diff --git a/src/cont/contclasses.cpp b/src/cont/contclasses.cpp index 75df484..71f981d 100644 --- a/src/cont/contclasses.cpp +++ b/src/cont/contclasses.cpp @@ -221,6 +221,10 @@ bool OverseerHandler::isLightMode() { return this->os->isLightMode(); } +uint32_t OverseerHandler::getAccentColor() { + return this->os->getAccentColor(); +} + std::vector OverseerHandler::getPlaybackEndpoints() { return this->os->getPlaybackEndpoints(); } diff --git a/src/cont/contclasses.h b/src/cont/contclasses.h index cb3230a..e3ebab6 100644 --- a/src/cont/contclasses.h +++ b/src/cont/contclasses.h @@ -101,6 +101,7 @@ public: void openControlPanel(); ProcessedNativeEvent processTopLevelWindowMessage(void* msg); bool isLightMode(); + uint32_t getAccentColor(); //void setChangeFrontDefaultsFunction(std::function changeFrontDefaults); //void changeFrontDefaultsCallback(Roles role, std::wstring endpointId); diff --git a/src/global.h b/src/global.h index 9cecbfd..4d684a9 100644 --- a/src/global.h +++ b/src/global.h @@ -37,8 +37,8 @@ //INIT BACK enum ProcessedNativeEvent { - NONE = 0, - LIGHT_MODE = (1 << 0), + NONE = 0, + COLORS = (1 << 0), }; enum AudioChannel { diff --git a/src/qt/qtclasses.cpp b/src/qt/qtclasses.cpp index 835daff..48660f1 100644 --- a/src/qt/qtclasses.cpp +++ b/src/qt/qtclasses.cpp @@ -7,19 +7,27 @@ bool DarkModeEventFilter::nativeEventFilter(const QByteArray &eventType, void *m if (eventType == "windows_generic_MSG") { ProcessedNativeEvent event = osh->processTopLevelWindowMessage(message); switch(event) { - case LIGHT_MODE: + case COLORS: 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(widget)) { + ((MainWindow*)widget)->updateColor(r, g, b, a); + } + } + } + } return true; break; default: break; } - /* - * if ([event type] == NSKeyDown) { - * // Handle key event - * qDebug() << QString::fromNSString([event characters]); - * } - */ } return false; } @@ -124,8 +132,8 @@ void MeterSlider::paintEvent(QPaintEvent *event) { sliderComplex2.subControls |= QStyle::SC_SliderTickmarks; QPainter painter(this); - QStyle* stle = QApplication::style(); - stle->drawComplexControl((QStyle::ComplexControl)CC_MeterSlider, &sliderComplex2, &painter, this); + QStyle* style = QApplication::style(); + style->drawComplexControl((QStyle::ComplexControl)CC_MeterSlider, &sliderComplex2, &painter, this); //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() { //todo: invalidate layout when adding sessions with window open //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->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); 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()->setSingleStep(1); @@ -1070,6 +1089,13 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) { this->recentlyClosedTimer->start(); } }); + + /* + * 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 @@ -1090,6 +1116,50 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) { } +bool MainWindow::eventFilter(QObject *object, QEvent *event) { + //QScrollBar* widgetCast = qobject_cast(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((QEvent::Type)CustomQEvent::SessionWidgetObsolete, sessionHandler)); + */ + //scrollArea->setFocus(Qt::MouseFocusReason); + return false; + }} + return false; +} + void MainWindow::flushRoleChanges() { //TODO: bucket list deque std::pair change = roleBucketList.front(); diff --git a/src/qt/qtclasses.h b/src/qt/qtclasses.h index 3b60cff..349b2d3 100644 --- a/src/qt/qtclasses.h +++ b/src/qt/qtclasses.h @@ -182,6 +182,7 @@ public: MainWindow(QWidget *parent = nullptr); void reloadEndpointWidgets(); void compose(); + void updateColor(uint8_t r, uint8_t g, uint8_t b, uint8_t a); protected: void closeEvent(QCloseEvent *event) override; @@ -200,6 +201,7 @@ private slots: private: //std::vector *ephs; + bool eventFilter(QObject *object, QEvent *event); void flushRoleChanges(); void changeFrontDefaults(Roles role, EndpointWidget* newDef, EndpointWidget* oldDef); diff --git a/src/qt/qtcommon.h b/src/qt/qtcommon.h index afd7929..b059504 100644 --- a/src/qt/qtcommon.h +++ b/src/qt/qtcommon.h @@ -77,6 +77,29 @@ namespace StylingHelper { } 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) { return QLatin1String(ch); diff --git a/src/qt/qtvisuals.h b/src/qt/qtvisuals.h index 3095c45..0db58e8 100644 --- a/src/qt/qtvisuals.h +++ b/src/qt/qtvisuals.h @@ -6,6 +6,7 @@ using namespace StylingHelper; class MixerStyle : public QProxyStyle { + public: using QProxyStyle::QProxyStyle; @@ -448,8 +449,8 @@ public: //QColor arrowColor = QColor(188,143,143,100); arrowColor.setAlpha(160); - const QColor bgColor = backgroundColor(option->palette, widget); - const bool isDarkBg = bgColor.red() < 128 && bgColor.green() < 128 && bgColor.blue() < 128; + const QColor appBgColor = QGuiApplication::palette().window().color(); + const bool isDarkBg = appBgColor.red() < 128 && appBgColor.green() < 128 && appBgColor.blue() < 128; if (transient) { if (horizontal) { @@ -482,17 +483,17 @@ public: gradient.setColorAt(0.9, buttonColor.darker(105)); gradient.setColorAt(1, buttonColor.darker(107)); } else { - gradient.setColorAt(0, bgColor.lighter(157)); - gradient.setColorAt(0.1, bgColor.lighter(155)); - gradient.setColorAt(0.9, bgColor.lighter(155)); - gradient.setColorAt(1, bgColor.lighter(157)); + gradient.setColorAt(0, appBgColor.lighter(157)); + gradient.setColorAt(0.1, appBgColor.lighter(155)); + gradient.setColorAt(0.9, appBgColor.lighter(155)); + gradient.setColorAt(1, appBgColor.lighter(157)); } - + painter->save(); //painter->fillRect(rect, gradient); painter->setPen(Qt::NoPen); painter->setPen(alphaOutline); - + QColor subtleEdge = alphaOutline; subtleEdge.setAlpha(40); painter->setPen(subtleEdge); @@ -505,23 +506,27 @@ public: } QRect pixmapRect = scrollBarSlider; - QLinearGradient gradient(pixmapRect.center().x(), pixmapRect.top(), - pixmapRect.center().x(), pixmapRect.bottom()); - if (!horizontal) - gradient = QLinearGradient(pixmapRect.left(), pixmapRect.center().y(), - pixmapRect.right(), pixmapRect.center().y()); + QColor highlightColor = option->palette.highlight().color(); + /* + * QLinearGradient gradient(pixmapRect.center().x(), pixmapRect.top(), + * pixmapRect.center().x(), pixmapRect.bottom()); + * 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); - gradient.setColorAt(0, calculateButtonColor(option->palette).lighter(108)); - gradient.setColorAt(1, calculateButtonColor(option->palette)); - - highlightedGradient.setColorAt(0, gradientStartColor.darker(102)); - highlightedGradient.setColorAt(1, gradientStopColor.lighter(102)); + QColor heldColor = 0xc4e3d7e0;//Qt::gray;//osh->isLightMode() ? Qt::white : Qt::black; + //gradient.setColorAt(0, option->palette.highlight().color()); + //gradient.setColorAt(1, option->palette.highlight().color()); + + //highlightedGradient.setColorAt(0, gradientStartColor.darker(102)); + //highlightedGradient.setColorAt(1, gradientStopColor.lighter(102)); // Paint slider if (scrollBar->subControls & SC_ScrollBarSlider) { + log_debugcpp("Final scrollbar paint if"); if (transient) { QRect rect = scrollBarSlider.adjusted(horizontal ? 1 : 2, horizontal ? 2 : 1, -1, -1); painter->setPen(Qt::NoPen); @@ -535,14 +540,20 @@ public: } else { QRect pixmapRect = scrollBarSlider; painter->setPen(QPen(alphaOutline)); - if (option->state & State_Sunken && scrollBar->activeSubControls & SC_ScrollBarSlider) - painter->setBrush(midColor2); - else if (option->state & State_MouseOver && scrollBar->activeSubControls & SC_ScrollBarSlider) - painter->setBrush(highlightedGradient); - else if (!isDarkBg) - painter->setBrush(gradient); - else - painter->setBrush(midColor2); + if (option->state & State_Sunken + && scrollBar->activeSubControls & SC_ScrollBarSlider) + painter->setBrush(heldColor); + else if (option->state & State_MouseOver + && scrollBar->activeSubControls & SC_ScrollBarSlider) { + painter->setBrush(highlightColor); + } + 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); @@ -675,6 +686,13 @@ private: 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 buttonColor = pal.button().color(); int val = qGray(buttonColor.rgb()); @@ -835,3 +853,4 @@ private: */ //void MixerStyle:: +