diff --git a/app/CMakeLists.txt b/app/CMakeLists.txt index 24d636302..cf3e9aa9e 100644 --- a/app/CMakeLists.txt +++ b/app/CMakeLists.txt @@ -15,7 +15,6 @@ set(lattedock-app_SRCS plasma/extended/screenpool.cpp plasma/extended/theme.cpp settings/settingsdialog.cpp - settings/sortedactivitiesmodel.cpp settings/universalsettings.cpp settings/delegates/activitycmbboxdelegate.cpp settings/delegates/checkboxdelegate.cpp diff --git a/app/settings/sortedactivitiesmodel.cpp b/app/settings/sortedactivitiesmodel.cpp deleted file mode 100644 index 6f473c1c6..000000000 --- a/app/settings/sortedactivitiesmodel.cpp +++ /dev/null @@ -1,434 +0,0 @@ -/* - * Copyright (C) 2016 Ivan Cukic - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2, - * or (at your option) any later version, as published by the Free - * Software Foundation - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details - * - * You should have received a copy of the GNU General Public - * License along with this program; if not, write to the - * Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#include "sortedactivitiesmodel.h" - -// local -#include "../../liblatte2/commontools.h" - -// C++ -#include - -// Qt -#include -#include -#include -#include -#include -#include - -// KDE -#include -#include -#include -#include -#include - -// Plasma -#include - -#define PLASMACONFIG "plasma-org.kde.plasma.desktop-appletsrc" - -namespace { - -class BackgroundCache: public QObject -{ -public: - BackgroundCache() - : initialized(false) - , plasmaConfig(KSharedConfig::openConfig(PLASMACONFIG)) { - using namespace std::placeholders; - - const auto configFile = QStandardPaths::writableLocation( - QStandardPaths::GenericConfigLocation) + - QLatin1Char('/') + PLASMACONFIG; - - KDirWatch::self()->addFile(configFile); - - connect(KDirWatch::self(), &KDirWatch::dirty, this, &BackgroundCache::settingsFileChanged); - connect(KDirWatch::self(), &KDirWatch::created, this, &BackgroundCache::settingsFileChanged); - } - - void settingsFileChanged(const QString &file) { - if (!file.endsWith(PLASMACONFIG)) { - return; - } - - if (initialized) { - plasmaConfig->reparseConfiguration(); - reload(); - } - } - - void subscribe(SortedActivitiesModel *model) { - if (!initialized) { - reload(); - } - - models << model; - } - - void unsubscribe(SortedActivitiesModel *model) { - models.removeAll(model); - - if (models.isEmpty()) { - initialized = false; - forActivity.clear(); - } - } - - QString backgroundFromConfig(const KConfigGroup &config) const { - auto wallpaperPlugin = config.readEntry("wallpaperplugin"); - auto wallpaperConfig = config.group("Wallpaper").group(wallpaperPlugin).group("General"); - - if (wallpaperConfig.hasKey("Image")) { - // Trying for the wallpaper - auto wallpaper = wallpaperConfig.readEntry("Image", QString()); - - if (!wallpaper.isEmpty()) { - return wallpaper; - } - } - - if (wallpaperConfig.hasKey("Color")) { - auto backgroundColor = wallpaperConfig.readEntry("Color", QColor(0, 0, 0)); - return backgroundColor.name(); - } - - return QString(); - } - - void reload() { - auto newForActivity = forActivity; - QHash lastScreenForActivity; - - // contains activities for which the wallpaper - // has updated - QStringList changedActivities; - - // Contains activities not covered by any containment - QStringList ghostActivities = forActivity.keys(); - - // Traversing through all containments in search for - // containments that define activities in plasma - for (const auto &containmentId : plasmaConfigContainments().groupList()) { - const auto containment = plasmaConfigContainments().group(containmentId); - const auto lastScreen = containment.readEntry("lastScreen", 0); - const auto activity = containment.readEntry("activityId", QString()); - - // Ignore the containment if the activity is not defined - if (activity.isEmpty()) continue; - - // If we have already found the same activity from another - // containment, we are using the new one only if - // the previous one was a color and not a proper wallpaper, - // or if the screen ID is closer to zero - const bool processed = !ghostActivities.contains(activity) && - newForActivity.contains(activity) && - (lastScreenForActivity[activity] < lastScreen); - - // qDebug() << "GREPME Searching containment " << containmentId - // << "for the wallpaper of the " << activity << " activity - " - // << "currently, we think that the wallpaper is " << processed << (processed ? newForActivity[activity] : QString()) - // << "last screen is" << lastScreen - // ; - - if (processed && - newForActivity[activity][0] != '#') continue; - - // Marking the current activity as processed - ghostActivities.removeAll(activity); - - const auto returnedBackground = backgroundFromConfig(containment); - - QString background = returnedBackground; - - if (background.startsWith("file://")) { - background = returnedBackground.mid(7); - } - - // qDebug() << " GREPME Found wallpaper: " << background; - - if (background.isEmpty()) continue; - - // If we got this far and we already had a new wallpaper for - // this activity, it means we now have a better one - bool foundBetterWallpaper = changedActivities.contains(activity); - - if (foundBetterWallpaper || newForActivity[activity] != background) { - if (!foundBetterWallpaper) { - changedActivities << activity; - } - - // qDebug() << " GREPME Setting: " << activity << " = " << background << "," << lastScreen; - - newForActivity[activity] = background; - lastScreenForActivity[activity] = lastScreen; - } - } - - initialized = true; - - // Removing the activities from the list if we haven't found them - // while traversing through the containments - for (const auto &activity : ghostActivities) { - newForActivity.remove(activity); - } - - // If we have detected the changes, lets notify everyone - if (!changedActivities.isEmpty()) { - forActivity = newForActivity; - - for (auto model : models) { - model->onBackgroundsUpdated(changedActivities); - } - } - } - - KConfigGroup plasmaConfigContainments() { - return plasmaConfig->group("Containments"); - } - - QHash forActivity; - QList models; - - bool initialized; - KSharedConfig::Ptr plasmaConfig; -}; - -static BackgroundCache &backgrounds() -{ - // If you convert this to a shared pointer, - // fix the connections to KDirWatcher - static BackgroundCache cache; - return cache; -} - -} - -SortedActivitiesModel::SortedActivitiesModel(const QVector &states, QObject *parent) - : QSortFilterProxyModel(parent) - , m_activitiesModel(new KActivities::ActivitiesModel(states, this)) - , m_activities(new KActivities::Consumer(this)) -{ - setSourceModel(m_activitiesModel); - - setDynamicSortFilter(true); - setSortRole(KActivities::ActivitiesModel::ActivityId); - sort(0, Qt::DescendingOrder); - - backgrounds().subscribe(this); -} - -SortedActivitiesModel::~SortedActivitiesModel() -{ - backgrounds().unsubscribe(this); -} - -bool SortedActivitiesModel::inhibitUpdates() const -{ - return m_inhibitUpdates; -} - -void SortedActivitiesModel::setInhibitUpdates(bool inhibitUpdates) -{ - if (m_inhibitUpdates != inhibitUpdates) { - m_inhibitUpdates = inhibitUpdates; - emit inhibitUpdatesChanged(m_inhibitUpdates); - - setDynamicSortFilter(!inhibitUpdates); - } -} - -/*QHash SortedActivitiesModel::roleNames() const -{ - if (!sourceModel()) return QHash(); - - auto roleNames = sourceModel()->roleNames(); - - roleNames[LastTimeUsed] = "lastTimeUsed"; - roleNames[LastTimeUsedString] = "lastTimeUsedString"; - roleNames[WindowCount] = "windowCount"; - roleNames[HasWindows] = "hasWindows"; - - return roleNames; -}*/ - -QVariant SortedActivitiesModel::data(const QModelIndex &index, int role) const -{ - if (role == KActivities::ActivitiesModel::ActivityBackground) { - const auto activity = activityIdForIndex(index); - - return backgrounds().forActivity[activity]; - - } else { - return QSortFilterProxyModel::data(index, role); - } -} - -QString SortedActivitiesModel::activityIdForIndex(const QModelIndex &index) const -{ - return data(index, KActivities::ActivitiesModel::ActivityId).toString(); -} - -QString SortedActivitiesModel::activityIdForRow(int row) const -{ - return activityIdForIndex(index(row, 0)); -} - -int SortedActivitiesModel::rowForActivityId(const QString &activity) const -{ - int position = -1; - - for (int row = 0; row < rowCount(); ++row) { - if (activity == activityIdForRow(row)) { - position = row; - } - } - - return position; -} - -QString SortedActivitiesModel::relativeActivity(int relative) const -{ - const auto currentActivity = m_activities->currentActivity(); - - if (!sourceModel()) return QString(); - - const auto currentRowCount = sourceModel()->rowCount(); - - //x % 0 is undefined in c++ - if (currentRowCount == 0) { - return QString(); - } - - int currentActivityRow = 0; - - for (; currentActivityRow < currentRowCount; currentActivityRow++) { - if (activityIdForRow(currentActivityRow) == currentActivity) break; - } - - currentActivityRow = currentActivityRow + relative; - - //wrap to within bounds for both positive and negative currentActivityRows - currentActivityRow = (currentRowCount + (currentActivityRow % currentRowCount)) % currentRowCount; - - return activityIdForRow(currentActivityRow); -} - -void SortedActivitiesModel::onCurrentActivityChanged(const QString ¤tActivity) -{ - if (m_previousActivity == currentActivity) return; - - const int previousActivityRow = rowForActivityId(m_previousActivity); -// emit rowChanged(previousActivityRow); - - m_previousActivity = currentActivity; - - const int currentActivityRow = rowForActivityId(m_previousActivity); - // emit rowChanged(currentActivityRow); -} - -void SortedActivitiesModel::onBackgroundsUpdated(const QStringList &activities) -{ - for (const auto &activity : activities) { - const int row = rowForActivityId(activity); - emit rowChanged(row, { KActivities::ActivitiesModel::ActivityBackground }); - } -} - - -void SortedActivitiesModel::rowChanged(int row, const QVector &roles) -{ - if (row == -1) return; - - emit dataChanged(index(row, 0), index(row, 0), roles); -} - -float SortedActivitiesModel::luminasFromFile(QString imageFile, int edge) -{ - QImage image(imageFile); - - Plasma::Types::Location location = static_cast(edge); - - if (m_luminasCache.keys().contains(imageFile)) { - if (m_luminasCache[imageFile].keys().contains(location)) { - return m_luminasCache[imageFile].value(location); - } - } - - if (image.format() != QImage::Format_Invalid) { - int maskHeight = (0.08 * image.height()); - int maskWidth = (0.05 * image.width()); - - float areaLumin = -1000; - - int firstRow = 0; - int firstColumn = 0; - int endRow = 0; - int endColumn = 0; - - if (location == Plasma::Types::TopEdge) { - firstRow = 0; - endRow = maskHeight; - firstColumn = 0; - endColumn = image.width() - 1; - } else if (location == Plasma::Types::BottomEdge) { - firstRow = image.height() - maskHeight - 1; - endRow = image.height() - 1; - firstColumn = 0; - endColumn = image.width() - 1; - } else if (location == Plasma::Types::LeftEdge) { - firstRow = 0; - endRow = image.height() - 1; - firstColumn = 0; - endColumn = maskWidth; - } else if (location == Plasma::Types::RightEdge) { - firstRow = 0; - endRow = image.height() - 1; - firstColumn = image.width() - 1 - maskWidth; - endColumn = image.width() - 1; - } - - for (int row = firstRow; row < endRow; ++row) { - QRgb *line = (QRgb *)image.scanLine(row); - - for (int col = firstColumn; col < endColumn ; ++col) { - QRgb pixelData = line[col]; - float pixelLuminosity = Latte::colorLumina(pixelData); - - areaLumin = (areaLumin == -1000) ? pixelLuminosity : (areaLumin + pixelLuminosity); - } - } - - float areaSize = (endRow - firstRow) * (endColumn - firstColumn); - areaLumin = areaLumin / areaSize; - - if (!m_luminasCache.keys().contains(imageFile)) { - m_luminasCache[imageFile] = EdgesHash(); - } - - m_luminasCache[imageFile].insert(location, areaLumin); - - return areaLumin; - } - - //! didn't find anything - return -1000; -} diff --git a/app/settings/sortedactivitiesmodel.h b/app/settings/sortedactivitiesmodel.h deleted file mode 100644 index 9e1a51907..000000000 --- a/app/settings/sortedactivitiesmodel.h +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Copyright (C) 2016 Ivan Cukic - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2, - * or (at your option) any later version, as published by the Free - * Software Foundation - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details - * - * You should have received a copy of the GNU General Public - * License along with this program; if not, write to the - * Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#ifndef SORTED_ACTIVITIES_MODEL -#define SORTED_ACTIVITIES_MODEL - -// Qt -#include - -// Plasma -#include - -// KDE -#include -#include -#include - -typedef QHash EdgesHash; - -class SortedActivitiesModel : public QSortFilterProxyModel -{ - Q_OBJECT - - Q_PROPERTY(bool inhibitUpdates READ inhibitUpdates WRITE setInhibitUpdates NOTIFY inhibitUpdatesChanged) - -public: - SortedActivitiesModel(const QVector &states, QObject *parent = nullptr); - ~SortedActivitiesModel() override; - - QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; - - float luminasFromFile(QString imageFile, int edge); - QString relativeActivity(int relative) const; - -protected: - /*enum AdditionalRoles { - LastTimeUsed = KActivities::ActivitiesModel::UserRole, - LastTimeUsedString = KActivities::ActivitiesModel::UserRole + 1, - WindowCount = KActivities::ActivitiesModel::UserRole + 2, - HasWindows = KActivities::ActivitiesModel::UserRole + 3 - };*/ - -public Q_SLOTS: - bool inhibitUpdates() const; - void setInhibitUpdates(bool sortByLastUsedTime); - - void onBackgroundsUpdated(const QStringList &changedBackgrounds); - void onCurrentActivityChanged(const QString ¤tActivity); - - QString activityIdForRow(int row) const; - QString activityIdForIndex(const QModelIndex &index) const; - int rowForActivityId(const QString &activity) const; - - void rowChanged(int row, const QVector &roles); - -Q_SIGNALS: - void inhibitUpdatesChanged(bool inhibitUpdates); - -private: - bool m_inhibitUpdates; - - QString m_previousActivity; - - KActivities::ActivitiesModel *m_activitiesModel = nullptr; - KActivities::Consumer *m_activities = nullptr; - - //! screen aware backgrounds: activity id, screen name, backgroundfile - QHash> m_backgrounds; - - //! image file and luminas per edge - QHash m_luminasCache; -}; - -#endif // SORTED_ACTIVITIES_MODEL diff --git a/app/settings/universalsettings.cpp b/app/settings/universalsettings.cpp index d360396ed..0f1113cfb 100644 --- a/app/settings/universalsettings.cpp +++ b/app/settings/universalsettings.cpp @@ -22,7 +22,6 @@ // local #include "layoutmanager.h" -#include "sortedactivitiesmodel.h" // Qt #include @@ -64,10 +63,6 @@ UniversalSettings::~UniversalSettings() { saveConfig(); cleanupSettings(); - - if (m_runningActivitiesModel) { - m_runningActivitiesModel->deleteLater(); - } } void UniversalSettings::initGlobalShortcutsWatcher() @@ -157,9 +152,6 @@ void UniversalSettings::load() //! load configuration loadConfig(); - //! connections with other classes - connect(m_corona->layoutManager(), &LayoutManager::viewColorizerChanged, this, &UniversalSettings::reconsiderActivitiesModel); - //! load global shortcuts badges at startup initGlobalShortcutsWatcher(); parseGlobalShortcuts(); @@ -491,56 +483,6 @@ QString UniversalSettings::trademarkIconPath() return m_corona->kPackage().filePath("trademark"); } -QAbstractItemModel *UniversalSettings::runningActivitiesModel() const -{ - return m_runningActivitiesModel; -} - -void UniversalSettings::setRunningActivitiesModel(SortedActivitiesModel *model) -{ - if (m_runningActivitiesModel == model) { - return; - } - - if (m_runningActivitiesModel) { - m_runningActivitiesModel->deleteLater(); - } - - m_runningActivitiesModel = model; - - emit runningActivitiesModelChanged(); -} - -void UniversalSettings::enableActivitiesModel() -{ - if (!m_runningActivitiesModel) { - setRunningActivitiesModel(new SortedActivitiesModel({KActivities::Info::Running, KActivities::Info::Stopping}, this)); - } -} - -void UniversalSettings::disableActivitiesModel() -{ - if (m_runningActivitiesModel) { - setRunningActivitiesModel(nullptr); - } -} - -void UniversalSettings::reconsiderActivitiesModel() -{ - if (m_corona->layoutManager()->hasColorizer()) { - enableActivitiesModel(); - } else { - disableActivitiesModel(); - } -} - -float UniversalSettings::luminasFromFile(QString imageFile, int edge) -{ - enableActivitiesModel(); - - return m_runningActivitiesModel->luminasFromFile(imageFile, edge); -} - QQmlListProperty UniversalSettings::screens() { return QQmlListProperty(this, nullptr, &countScreens, &atScreens); diff --git a/app/settings/universalsettings.h b/app/settings/universalsettings.h index 8a8b09595..7c27f3c97 100644 --- a/app/settings/universalsettings.h +++ b/app/settings/universalsettings.h @@ -36,8 +36,6 @@ #include #include -class SortedActivitiesModel; - namespace Latte { class LayoutManager; @@ -57,8 +55,6 @@ class UniversalSettings : public QObject Q_PROPERTY(Latte::Types::MouseSensitivity mouseSensitivity READ mouseSensitivity WRITE setMouseSensitivity NOTIFY mouseSensitivityChanged) - Q_PROPERTY(QAbstractItemModel *runningActivitiesModel READ runningActivitiesModel NOTIFY runningActivitiesModelChanged) - Q_PROPERTY(QQmlListProperty screens READ screens) public: @@ -108,9 +104,6 @@ public: Types::MouseSensitivity mouseSensitivity() const; void setMouseSensitivity(Types::MouseSensitivity sensitivity); - QAbstractItemModel *runningActivitiesModel() const; - void setRunningActivitiesModel(SortedActivitiesModel *model); - QQmlListProperty screens(); static int countScreens(QQmlListProperty *property); //! is needed by screens() static QScreen *atScreens(QQmlListProperty *property, int index); //! is needed by screens() @@ -119,8 +112,6 @@ public slots: Q_INVOKABLE QString splitterIconPath(); Q_INVOKABLE QString trademarkIconPath(); - Q_INVOKABLE float luminasFromFile(QString imageFile, int edge); - signals: void autostartChanged(); void badgesForActivateChanged(); @@ -133,7 +124,6 @@ signals: void launchersChanged(); void layoutsMemoryUsageChanged(); void mouseSensitivityChanged(); - void runningActivitiesModelChanged(); void screenTrackerIntervalChanged(); void showInfoWindowChanged(); void versionChanged(); @@ -142,13 +132,10 @@ private slots: void loadConfig(); void saveConfig(); - void reconsiderActivitiesModel(); void shortcutsFileChanged(const QString &file); private: void cleanupSettings(); - void enableActivitiesModel(); - void disableActivitiesModel(); void initGlobalShortcutsWatcher(); //! access user set global shortcuts for activate entries @@ -181,8 +168,6 @@ private: Types::LayoutsMemoryUsage m_memoryUsage; Types::MouseSensitivity m_mouseSensitivity{Types::HighSensitivity}; - SortedActivitiesModel *m_runningActivitiesModel{nullptr}; - QPointer m_corona; KConfigGroup m_universalGroup; diff --git a/containment/package/contents/code/ColorizerTools.js b/containment/package/contents/code/ColorizerTools.js index 4a6880714..0f30cc866 100644 --- a/containment/package/contents/code/ColorizerTools.js +++ b/containment/package/contents/code/ColorizerTools.js @@ -18,6 +18,16 @@ */ +function colorBrightness(color) { + return colorBrightnessFromRGB(color.r * 255, color.g * 255, color.b * 255) +} + +// formula for brightness according to: +// https://www.w3.org/TR/AERT/#color-contrast +function colorBrightnessFromRGB(r, g, b) { + return (r * 299 + g * 587 + b * 114) / 1000 +} + function colorLuminas(color) { return colorLuminasFromRGB(color.r, color.g, color.b) } diff --git a/containment/package/contents/ui/Ruler.qml b/containment/package/contents/ui/Ruler.qml index 235176677..3267cf8eb 100644 --- a/containment/package/contents/ui/Ruler.qml +++ b/containment/package/contents/ui/Ruler.qml @@ -28,6 +28,8 @@ import org.kde.plasma.components 2.0 as PlasmaComponents import org.kde.latte 0.2 as Latte +import "../code/ColorizerTools.js" as ColorizerTools + Item{ id: rulerItem @@ -123,38 +125,8 @@ Item{ } } - - // formula for luminance according to: - // https://www.w3.org/TR/2008/REC-WCAG20-20081211/#relativeluminancedef - property real textColorRs: { - var color = textColor.r; - if (color <= 0.03928) { - return color / 12.92; - } else { - return Math.pow( ((color + 0.055) / 1.055), 2.4 ); - } - } - - property real textColorGs: { - var color = textColor.g; - if (color <= 0.03928) { - return color / 12.92; - } else { - return Math.pow( ((color + 0.055) / 1.055), 2.4 ); - } - } - - property real textColorBs: { - var color = textColor.b; - if (color <= 0.03928) { - return color / 12.92; - } else { - return Math.pow( ((color + 0.055) / 1.055), 2.4 ); - } - } - - readonly property real textColorLuma: 0.2126*textColorRs + 0.7152*textColorGs + 0.0722*textColorBs - readonly property bool textColorIsDark: textColorLuma < 0.6 + readonly property real textColorBrightness: ColorizerTools.colorBrightness(textColor) + readonly property bool textColorIsDark: textColorBrightness < 127.5 readonly property color textColor: latteView && latteView.managedLayout ? latteView.managedLayout.textColor : "#D7E3FF" Behavior on width { diff --git a/containment/package/contents/ui/colorizer/Manager.qml b/containment/package/contents/ui/colorizer/Manager.qml index abc6b1b90..2e456aadc 100644 --- a/containment/package/contents/ui/colorizer/Manager.qml +++ b/containment/package/contents/ui/colorizer/Manager.qml @@ -35,9 +35,10 @@ Loader{ || !Latte.WindowSystem.compositingActive readonly property bool forceSolidnessAndColorize: forceSolidness && forceColorizeFromActiveWindowScheme - readonly property real themeBackgroundColorLuma: ColorizerTools.colorLuminas(theme.backgroundColor) - readonly property real themeTextColorLuma: ColorizerTools.colorLuminas(theme.textColor) - readonly property color minimizedDotColor: themeTextColorLuma > 0.6 ? Qt.darker(theme.textColor, 1.7) : Qt.lighter(theme.textColor, 7) + readonly property real themeBackgroundColorBrightness: ColorizerTools.colorBrightness(theme.backgroundColor) + readonly property real themeTextColorBrightness: ColorizerTools.colorBrightness(theme.textColor) + + readonly property color minimizedDotColor: themeTextColorBrightness > 127.5 ? Qt.darker(theme.textColor, 1.7) : Qt.lighter(theme.textColor, 7) property bool mustBeShown: active && (!forceSolidPanel || forceSolidnessAndColorize) //! when forceSemiTransparentPanel is enabled because of snapped or maximized etc. windows @@ -47,7 +48,7 @@ Loader{ && (plasmoid.configuration.solidBackgroundForMaximized || plasmoid.configuration.backgroundOnlyOnMaximized) && !root.editMode && Latte.WindowSystem.compositingActive - property real currentBackgroundLuminas: item ? item.currentLuminas : -1000 + property real currentBackgroundBrightness: item ? item.currentBrightness : -1000 property QtObject applyTheme: { if (forceSolidnessAndColorize && latteView.visibility.touchingWindowScheme) { @@ -55,7 +56,7 @@ Loader{ } if (themeExtended) { - if (currentBackgroundLuminas > 0.5) { + if (currentBackgroundBrightness > 127.5) { return themeExtended.lightTheme; } else { return themeExtended.darkTheme; @@ -99,6 +100,6 @@ Loader{ location: plasmoid.location screenName: latteView && latteView.positioner ? latteView.positioner.currentScreenName : "" - onCurrentLuminasChanged: console.log("CURRENT LUMINAS !!! " + currentLuminas); + onCurrentBrightnessChanged: console.log("CURRENT Brightness !!! " + currentBrightness); } } diff --git a/liblatte2/backgroundtracker.cpp b/liblatte2/backgroundtracker.cpp index dcc6cd493..d4508db27 100644 --- a/liblatte2/backgroundtracker.cpp +++ b/liblatte2/backgroundtracker.cpp @@ -58,9 +58,9 @@ void BackgroundTracker::setLocation(int location) emit locationChanged(); } -float BackgroundTracker::currentLuminas() const +float BackgroundTracker::currentBrightness() const { - return m_luminas; + return m_brightness; } QString BackgroundTracker::activity() const @@ -108,9 +108,9 @@ void BackgroundTracker::update() return; } - m_luminas = m_cache->luminasFor(m_activity, m_screenName, m_location); + m_brightness = m_cache->brightnessFor(m_activity, m_screenName, m_location); - emit currentLuminasChanged(); + emit currentBrightnessChanged(); } } diff --git a/liblatte2/backgroundtracker.h b/liblatte2/backgroundtracker.h index 23ed71c92..2439e100e 100644 --- a/liblatte2/backgroundtracker.h +++ b/liblatte2/backgroundtracker.h @@ -35,7 +35,7 @@ class BackgroundTracker: public QObject Q_PROPERTY(int location READ location WRITE setLocation NOTIFY locationChanged) - Q_PROPERTY(float currentLuminas READ currentLuminas NOTIFY currentLuminasChanged) + Q_PROPERTY(float currentBrightness READ currentBrightness NOTIFY currentBrightnessChanged) Q_PROPERTY(QString activity READ activity WRITE setActivity NOTIFY activityChanged) Q_PROPERTY(QString screenName READ screenName WRITE setScreenName NOTIFY screenNameChanged) @@ -47,7 +47,7 @@ public: int location() const; void setLocation(int location); - float currentLuminas() const; + float currentBrightness() const; QString activity() const; void setActivity(QString id); @@ -57,7 +57,7 @@ public: signals: void activityChanged(); - void currentLuminasChanged(); + void currentBrightnessChanged(); void locationChanged(); void screenNameChanged(); @@ -67,7 +67,7 @@ private slots: private: // local - float m_luminas{-1000}; + float m_brightness{-1000}; PlasmaExtended::BackgroundCache *m_cache{nullptr}; // Qt diff --git a/liblatte2/commontools.cpp b/liblatte2/commontools.cpp index bcf9a3e48..c97b56c01 100644 --- a/liblatte2/commontools.cpp +++ b/liblatte2/commontools.cpp @@ -25,6 +25,24 @@ namespace Latte { +float colorBrightness(QColor color) +{ + return colorBrightness(color.red(), color.green(), color.blue()); +} + +float colorBrightness(QRgb rgb) +{ + return colorBrightness(qRed(rgb), qGreen(rgb), qBlue(rgb)); +} + +float colorBrightness(float r, float g, float b) +{ + float brightness = (r * 299 + g * 587 + b * 114) / 1000; + + return brightness; +} + + float colorLumina(QRgb rgb) { float r = (float)(qRed(rgb)) / 255; diff --git a/liblatte2/commontools.h b/liblatte2/commontools.h index f4852075b..bb70e7716 100644 --- a/liblatte2/commontools.h +++ b/liblatte2/commontools.h @@ -23,6 +23,10 @@ namespace Latte { +float colorBrightness(QColor color); +float colorBrightness(QRgb rgb); +float colorBrightness(float r, float g, float b); + float colorLumina(QColor color); float colorLumina(QRgb rgb); float colorLumina(float r, float g, float b); diff --git a/liblatte2/plasma/extended/backgroundcache.cpp b/liblatte2/plasma/extended/backgroundcache.cpp index ffd31fa95..1101306a6 100644 --- a/liblatte2/plasma/extended/backgroundcache.cpp +++ b/liblatte2/plasma/extended/backgroundcache.cpp @@ -175,28 +175,28 @@ QString BackgroundCache::background(QString activity, QString screen) } } -float BackgroundCache::luminasFor(QString activity, QString screen, Plasma::Types::Location location) +float BackgroundCache::brightnessFor(QString activity, QString screen, Plasma::Types::Location location) { QString assignedBackground = background(activity, screen); if (!assignedBackground.isEmpty()) { - return luminasFromFile(assignedBackground, location); + return brightnessFromFile(assignedBackground, location); } return -1000; } -float BackgroundCache::luminasFromFile(QString imageFile, Plasma::Types::Location location) +float BackgroundCache::brightnessFromFile(QString imageFile, Plasma::Types::Location location) { - if (m_luminasCache.keys().contains(imageFile)) { - if (m_luminasCache[imageFile].keys().contains(location)) { - return m_luminasCache[imageFile].value(location); + if (m_brightnessCache.keys().contains(imageFile)) { + if (m_brightnessCache[imageFile].keys().contains(location)) { + return m_brightnessCache[imageFile].value(location); } } //! if it is a color if (imageFile.startsWith("#")) { - return Latte::colorLumina(QColor(imageFile)); + return Latte::colorBrightness(QColor(imageFile)); } //! if it is a local image @@ -206,7 +206,7 @@ float BackgroundCache::luminasFromFile(QString imageFile, Plasma::Types::Locatio int maskHeight = (0.08 * image.height()); int maskWidth = (0.05 * image.width()); - float areaLumin = -1000; + float areaBrightness = -1000; int firstRow = 0; int firstColumn = 0; @@ -240,22 +240,22 @@ float BackgroundCache::luminasFromFile(QString imageFile, Plasma::Types::Locatio for (int col = firstColumn; col < endColumn ; ++col) { QRgb pixelData = line[col]; - float pixelLuminosity = Latte::colorLumina(pixelData); + float pixelBrightness = Latte::colorBrightness(pixelData); - areaLumin = (areaLumin == -1000) ? pixelLuminosity : (areaLumin + pixelLuminosity); + areaBrightness = (areaBrightness == -1000) ? pixelBrightness : (areaBrightness + pixelBrightness); } } float areaSize = (endRow - firstRow) * (endColumn - firstColumn); - areaLumin = areaLumin / areaSize; + areaBrightness = areaBrightness / areaSize; - if (!m_luminasCache.keys().contains(imageFile)) { - m_luminasCache[imageFile] = EdgesHash(); + if (!m_brightnessCache.keys().contains(imageFile)) { + m_brightnessCache[imageFile] = EdgesHash(); } - m_luminasCache[imageFile].insert(location, areaLumin); + m_brightnessCache[imageFile].insert(location, areaBrightness); - return areaLumin; + return areaBrightness; } //! didn't find anything diff --git a/liblatte2/plasma/extended/backgroundcache.h b/liblatte2/plasma/extended/backgroundcache.h index 02e628f15..e0023660a 100644 --- a/liblatte2/plasma/extended/backgroundcache.h +++ b/liblatte2/plasma/extended/backgroundcache.h @@ -47,7 +47,7 @@ public: static BackgroundCache *self(); ~BackgroundCache() override; - float luminasFor(QString activity, QString screen, Plasma::Types::Location location); + float brightnessFor(QString activity, QString screen, Plasma::Types::Location location); QString background(QString activity, QString screen); @@ -62,7 +62,7 @@ private: BackgroundCache(QObject *parent = nullptr); bool isDesktopContainment(const KConfigGroup &containment) const; - float luminasFromFile(QString imageFile, Plasma::Types::Location location); + float brightnessFromFile(QString imageFile, Plasma::Types::Location location); QString backgroundFromConfig(const KConfigGroup &config) const; private: @@ -72,8 +72,8 @@ private: //! screen aware backgrounds: activity id, screen name, backgroundfile QHash> m_backgrounds; - //! image file and luminas per edge - QHash m_luminasCache; + //! image file and brightness per edge + QHash m_brightnessCache; KSharedConfig::Ptr m_plasmaConfig; }; diff --git a/plasmoid/package/contents/code/ColorizerTools.js b/plasmoid/package/contents/code/ColorizerTools.js index 4a6880714..f409bffac 100644 --- a/plasmoid/package/contents/code/ColorizerTools.js +++ b/plasmoid/package/contents/code/ColorizerTools.js @@ -17,6 +17,15 @@ * along with this program. If not, see . */ +function colorBrightness(color) { + return colorBrightnessFromRGB(color.r * 255, color.g * 255, color.b * 255); +} + +// formula for brightness according to: +// https://www.w3.org/TR/AERT/#color-contrast +function colorBrightnessFromRGB(r, g, b) { + return (r * 299 + g * 587 + b * 114) / 1000 +} function colorLuminas(color) { return colorLuminasFromRGB(color.r, color.g, color.b) diff --git a/plasmoid/package/contents/ui/main.qml b/plasmoid/package/contents/ui/main.qml index ee9474dde..9f7f3d583 100644 --- a/plasmoid/package/contents/ui/main.qml +++ b/plasmoid/package/contents/ui/main.qml @@ -94,13 +94,13 @@ Item { property int widthMargins: root.vertical ? thickMargin : iconMargin property int heightMargins: !root.vertical ? thickMargin : iconMargin - property real textColorLuma: ColorizerTools.colorLuminas(theme.textColor) + property real textColorBrightness: ColorizerTools.colorBrightness(theme.textColor) property color minimizedDotColor: { if (latteView) { return latteView.minimizedDotColor; } - return textColorLuma > 0.6 ? Qt.darker(theme.textColor, 1.7) : Qt.lighter(theme.textColor, 7) + return textColorBrightness > 127.5 ? Qt.darker(theme.textColor, 1.7) : Qt.lighter(theme.textColor, 7) } //a small badgers record (id,value)