Mercurial > hg > svgui
changeset 1580:a2ff9c01889e
Merge from branch background-mode
author | Chris Cannam |
---|---|
date | Fri, 24 Jan 2020 15:11:08 +0000 |
parents | 5f6fdd525158 (current diff) 85f04c956f03 (diff) |
children | 11660e0c896f 01a41a37bd26 |
files | |
diffstat | 5 files changed, 177 insertions(+), 53 deletions(-) [+] |
line wrap: on
line diff
--- a/layer/ColourDatabase.cpp Wed Jan 15 13:58:33 2020 +0000 +++ b/layer/ColourDatabase.cpp Fri Jan 24 15:11:08 2020 +0000 @@ -88,17 +88,44 @@ } int -ColourDatabase::getNearbyColourIndex(QColor col) const +ColourDatabase::getNearbyColourIndex(QColor col, WithBackgroundMode mode) const { - int index = 0; + int index = -1; int closestIndex = -1; - int closestDistance = 0; + double closestDistance = 0; for (auto &c: m_colours) { - int distance = - std::abs(col.red() - c.colour.red()) + - std::abs(col.green() - c.colour.green()) + - std::abs(col.blue() - c.colour.blue()); + + ++index; + + if (mode == WithDarkBackground && !c.darkbg) { +#ifdef DEBUG_COLOUR_DATABASE + SVDEBUG << "getNearbyColourIndex: dark background requested, skipping " << c.colour.name() << endl; +#endif + continue; + } + if (mode == WithLightBackground && c.darkbg) { +#ifdef DEBUG_COLOUR_DATABASE + SVDEBUG << "getNearbyColourIndex: light background requested, skipping " << c.colour.name() << endl; +#endif + continue; + } + + // This distance formula is "one of the better low-cost + // approximations" according to + // https://en.wikipedia.org/w/index.php?title=Color_difference&oldid=936888327 + + double r1 = col.red(), r2 = c.colour.red(); + double g1 = col.green(), g2 = c.colour.green(); + double b1 = col.blue(), b2 = c.colour.blue(); + + double rav = (r1 + r2) / 2.0; + double rterm = (2.0 + rav / 256.0) * (r1 - r2) * (r1 - r2); + double gterm = 4.0 * (g1 - g2) * (g1 - g2); + double bterm = (2.0 + (255 - rav) / 256.0) * (b1 - b2) * (b1 - b2); + + double distance = sqrt(rterm + gterm + bterm); + #ifdef DEBUG_COLOUR_DATABASE SVDEBUG << "getNearbyColourIndex: comparing " << c.colour.name() << " to " << col.name() << ": distance = " << distance << endl; @@ -110,7 +137,6 @@ SVDEBUG << "(this is the best so far)" << endl; #endif } - ++index; } #ifdef DEBUG_COLOUR_DATABASE
--- a/layer/ColourDatabase.h Wed Jan 15 13:58:33 2020 +0000 +++ b/layer/ColourDatabase.h Fri Jan 24 15:11:08 2020 +0000 @@ -71,13 +71,20 @@ */ bool haveColour(QColor c) const; + enum WithBackgroundMode { + WithAnyBackground, + WithDarkBackground, + WithLightBackground + }; + /** * Return the index of the colour in the database that is closest - * to the given one, by some simplistic measure (Manhattan - * distance in RGB space). This always returns some valid index, - * unless the database is empty, in which case it returns -1. + * to the given one, by some simple measure. This always returns + * some valid index, unless the database is empty, in which case + * it returns -1. */ - int getNearbyColourIndex(QColor c) const; + int getNearbyColourIndex(QColor c, + WithBackgroundMode mode = WithAnyBackground) const; /** * Add a colour to the database, with the associated name. Return @@ -110,9 +117,9 @@ /** * Return a colour that contrasts with the one at index c, - * according to some simplistic algorithm. The returned colour is - * not necessarily in the database; pass it to - * getNearbyColourIndex if you need one that is. + * according to some simple algorithm. The returned colour is not + * necessarily in the database; pass it to getNearbyColourIndex if + * you need one that is. */ QColor getContrastingColour(int c) const;
--- a/view/ViewManager.cpp Wed Jan 15 13:58:33 2020 +0000 +++ b/view/ViewManager.cpp Fri Jan 24 15:11:08 2020 +0000 @@ -22,8 +22,11 @@ #include "View.h" #include "Overview.h" +#include "system/System.h" + #include <QSettings> #include <QApplication> +#include <QStyleFactory> #include <iostream> @@ -72,20 +75,11 @@ settings.endGroup(); if (getGlobalDarkBackground()) { -/* - cerr << "dark palette:" << endl; - cerr << "window = " << QApplication::palette().color(QPalette::Window).name() << endl; - cerr << "windowtext = " << QApplication::palette().color(QPalette::WindowText).name() << endl; - cerr << "base = " << QApplication::palette().color(QPalette::Base).name() << endl; - cerr << "alternatebase = " << QApplication::palette().color(QPalette::AlternateBase).name() << endl; - cerr << "text = " << QApplication::palette().color(QPalette::Text).name() << endl; - cerr << "button = " << QApplication::palette().color(QPalette::Button).name() << endl; - cerr << "buttontext = " << QApplication::palette().color(QPalette::ButtonText).name() << endl; - cerr << "brighttext = " << QApplication::palette().color(QPalette::BrightText).name() << endl; - cerr << "light = " << QApplication::palette().color(QPalette::Light).name() << endl; - cerr << "dark = " << QApplication::palette().color(QPalette::Dark).name() << endl; - cerr << "mid = " << QApplication::palette().color(QPalette::Mid).name() << endl; -*/ + // i.e. widgets are already dark; create a light palette in + // case we are asked to switch to it, but don't create a dark + // one because it will be assigned from the actual application + // palette if we switch + m_lightPalette = QPalette(QColor("#000000"), // WindowText QColor("#dddfe4"), // Button QColor("#ffffff"), // Light @@ -95,32 +89,48 @@ QColor("#ffffff"), // BrightText QColor("#ffffff"), // Base QColor("#efefef")); // Window - + + m_lightPalette.setColor(QPalette::Highlight, Qt::darkBlue); + if (!OSReportsDarkThemeActive()) { + int r, g, b; + if (OSQueryAccentColour(r, g, b)) { + m_lightPalette.setColor(QPalette::Highlight, QColor(r, g, b)); + } + } } else { -/* - cerr << "light palette:" << endl; - cerr << "window = " << QApplication::palette().color(QPalette::Window).name() << endl; - cerr << "windowtext = " << QApplication::palette().color(QPalette::WindowText).name() << endl; - cerr << "base = " << QApplication::palette().color(QPalette::Base).name() << endl; - cerr << "alternatebase = " << QApplication::palette().color(QPalette::AlternateBase).name() << endl; - cerr << "text = " << QApplication::palette().color(QPalette::Text).name() << endl; - cerr << "button = " << QApplication::palette().color(QPalette::Button).name() << endl; - cerr << "buttontext = " << QApplication::palette().color(QPalette::ButtonText).name() << endl; - cerr << "brighttext = " << QApplication::palette().color(QPalette::BrightText).name() << endl; - cerr << "light = " << QApplication::palette().color(QPalette::Light).name() << endl; - cerr << "dark = " << QApplication::palette().color(QPalette::Dark).name() << endl; - cerr << "mid = " << QApplication::palette().color(QPalette::Mid).name() << endl; -*/ - m_darkPalette = QPalette(QColor("#ffffff"), // WindowText + // i.e. widgets are currently light; create a dark palette in + // case we are asked to switch to it, but don't create a light + // one because it will be assigned from the actual application + // palette if we switch + + m_darkPalette = QPalette(QColor("#f0f0f0"), // WindowText QColor("#3e3e3e"), // Button QColor("#808080"), // Light QColor("#1e1e1e"), // Dark QColor("#404040"), // Mid - QColor("#ffffff"), // Text + QColor("#f0f0f0"), // Text QColor("#ffffff"), // BrightText QColor("#000000"), // Base QColor("#202020")); // Window + + m_darkPalette.setColor(QPalette::Highlight, QColor(25, 130, 220)); + if (OSReportsDarkThemeActive()) { + int r, g, b; + if (OSQueryAccentColour(r, g, b)) { + m_darkPalette.setColor(QPalette::Highlight, QColor(r, g, b)); + } + } + + m_darkPalette.setColor(QPalette::Link, QColor(50, 175, 255)); + m_darkPalette.setColor(QPalette::LinkVisited, QColor(50, 175, 255)); + + m_darkPalette.setColor(QPalette::Disabled, QPalette::WindowText, + QColor("#808080")); + m_darkPalette.setColor(QPalette::Disabled, QPalette::Text, + QColor("#808080")); + m_darkPalette.setColor(QPalette::Disabled, QPalette::Shadow, + QColor("#000000")); } } @@ -792,13 +802,44 @@ m_lightPalette = QApplication::palette(); } -#ifndef Q_OS_MAC +#ifdef Q_OS_MAC + return; +#endif + if (dark) { + +#ifdef Q_OS_WIN32 + // The Windows Vista style doesn't use the palette for many of + // its controls. They can be styled with stylesheets, but that + // takes a lot of fiddly and fragile custom bits. Easier and + // more reliable to switch to a non-Vista style which does use + // the palette. + + QStyle *plainWindowsStyle = QStyleFactory::create("windows"); + if (!plainWindowsStyle) { + SVCERR << "Failed to load plain Windows style" << endl; + } else { + qApp->setStyle(plainWindowsStyle); + } +#endif + QApplication::setPalette(m_darkPalette); + } else { + +#ifdef Q_OS_WIN32 + // Switch back to Vista style + + QStyle *fancyWindowsStyle = QStyleFactory::create("windowsvista"); + if (!fancyWindowsStyle) { + SVCERR << "Failed to load fancy Windows style" << endl; + } else { + qApp->setStyle(fancyWindowsStyle); + } +#endif + QApplication::setPalette(m_lightPalette); } -#endif } bool
--- a/widgets/ColourComboBox.cpp Wed Jan 15 13:58:33 2020 +0000 +++ b/widgets/ColourComboBox.cpp Fri Jan 24 15:11:08 2020 +0000 @@ -38,15 +38,29 @@ connect(this, SIGNAL(activated(int)), this, SLOT(comboActivated(int))); connect(ColourDatabase::getInstance(), SIGNAL(colourDatabaseChanged()), this, SLOT(rebuild())); - - if (count() < 20 && count() > maxVisibleItems()) { - setMaxVisibleItems(count()); - } } void -ColourComboBox::comboActivated(int index) +ColourComboBox::includeUnsetEntry(QString entry) { + m_unsetEntry = entry; + + rebuild(); + + blockSignals(true); + int ix = currentIndex(); + setCurrentIndex(ix + 1); + blockSignals(false); +} + +void +ColourComboBox::comboActivated(int comboIndex) +{ + int index = comboIndex; + if (m_unsetEntry != "") { + index = comboIndex - 1; // so index is the colour index + } + if (!m_withAddNewColourEntry || index < int(ColourDatabase::getInstance()->getColourCount())) { emit colourChanged(index); @@ -81,6 +95,10 @@ clear(); + if (m_unsetEntry != "") { + addItem(m_unsetEntry); + } + int size = (QFontMetrics(QFont()).height() * 2) / 3; if (size < 12) size = 12; @@ -95,6 +113,12 @@ } setCurrentIndex(ix); + + if (count() < 18) { + setMaxVisibleItems(count()); + } else { + setMaxVisibleItems(10); + } blockSignals(false); }
--- a/widgets/ColourComboBox.h Wed Jan 15 13:58:33 2020 +0000 +++ b/widgets/ColourComboBox.h Fri Jan 24 15:11:08 2020 +0000 @@ -29,7 +29,32 @@ public: ColourComboBox(bool withAddNewColourEntry, QWidget *parent = 0); + /** + * Add an entry at the top of the combo for "no colour selected", + * with the given label. + */ + void includeUnsetEntry(QString label); + + /** + * Get the current colour index. This is the same as + * QComboBox::currentIndex() if there is no unset entry, or 1 less + * than it if includeUnsetEntry() has been used. So if there is an + * unset entry, and it is selected, this returns -1. + */ + int getCurrentColourIndex() const { + int index = currentIndex(); + if (m_unsetEntry == "") { + return index; + } else { + return index - 1; + } + } + signals: + /** + * Emitted when the current index is changed. The argument is the + * value returned by getCurrentColourIndex() + */ void colourChanged(int colourIndex); private slots: @@ -38,6 +63,7 @@ private: bool m_withAddNewColourEntry; + QString m_unsetEntry; }; #endif