[vlc-commits] [Git][videolan/vlc][master] 2 commits: qt: update ColorSchemeModel implementation

Jean-Baptiste Kempf (@jbk) gitlab at videolan.org
Fri Jul 23 09:46:37 UTC 2021



Jean-Baptiste Kempf pushed to branch master at VideoLAN / VLC


Commits:
d2c7abb6 by Prince Gupta at 2021-07-23T09:09:32+00:00
qt: update ColorSchemeModel implementation

* Identify Color Scheme via enum
* Move available color scheme defination to cpp side

This is done to introduce "auto" color scheme

- - - - -
9cec201b by Prince Gupta at 2021-07-23T09:09:32+00:00
qt: introduce auto color scheme on windows

new "auto" color scheme automatically switches between "day" and
"night" color scheme based on system settings

available color schemes -

on windows: auto, day, night

other: system, day, night

Closes #25590

- - - - -


6 changed files:

- modules/gui/qt/dialogs/preferences/simple_preferences.cpp
- modules/gui/qt/maininterface/main_interface.cpp
- modules/gui/qt/maininterface/mainui.cpp
- modules/gui/qt/style/VLCColors.qml
- modules/gui/qt/util/color_scheme_model.cpp
- modules/gui/qt/util/color_scheme_model.hpp


Changes:

=====================================
modules/gui/qt/dialogs/preferences/simple_preferences.cpp
=====================================
@@ -852,10 +852,11 @@ SPrefsPanel::SPrefsPanel( qt_intf_t *_p_intf, QWidget *_parent,
             m_resetters.push_back(std::make_unique<PropertyResetter>(ui.pinVideoControlsCheckbox, "checked"));
             QObject::connect( ui.pinVideoControlsCheckbox, &QCheckBox::stateChanged, p_intf->p_mi, &MainInterface::setPinVideoControls );
 
-            ui.colorSchemeComboBox->insertItems(0, p_intf->p_mi->getColorScheme()->stringList());
-            ui.colorSchemeComboBox->setCurrentText( p_intf->p_mi->getColorScheme()->getCurrent() );
+            ui.colorSchemeComboBox->setModel( p_intf->p_mi->getColorScheme() );
+            ui.colorSchemeComboBox->setCurrentText( p_intf->p_mi->getColorScheme()->currentText() );
             m_resetters.push_back(std::make_unique<PropertyResetter>( ui.colorSchemeComboBox, "currentIndex" ));
-            QObject::connect( ui.colorSchemeComboBox, &QComboBox::currentTextChanged, p_intf->p_mi->getColorScheme(), &ColorSchemeModel::setCurrent );
+            QObject::connect( ui.colorSchemeComboBox, QOverload<int>::of(&QComboBox::currentIndexChanged)
+                              , p_intf->p_mi->getColorScheme(), &ColorSchemeModel::setCurrentIndex );
 
             const float intfScaleFloatFactor = 100.f;
             const auto updateIntfUserScaleFactorFromControls =


=====================================
modules/gui/qt/maininterface/main_interface.cpp
=====================================
@@ -150,12 +150,12 @@ MainInterface::MainInterface(qt_intf_t *_p_intf , QWidget* parent, Qt::WindowFla
     playlistVisible  = getSettings()->value( "MainWindow/playlist-visible", false ).toBool();
     playlistWidthFactor = getSettings()->value( "MainWindow/playlist-width-factor", 4.0 ).toDouble();
     m_gridView = getSettings()->value( "MainWindow/grid-view", true).toBool();
-    QString currentColorScheme = getSettings()->value( "MainWindow/color-scheme", "system").toString();
     m_showRemainingTime = getSettings()->value( "MainWindow/ShowRemainingTime", false ).toBool();
     m_pinVideoControls = getSettings()->value("MainWindow/pin-video-controls", false ).toBool();
 
     m_colorScheme = new ColorSchemeModel(this);
-    m_colorScheme->setCurrent(currentColorScheme);
+    const auto currentColorScheme = static_cast<ColorSchemeModel::ColorScheme>(getSettings()->value( "MainWindow/color-scheme", ColorSchemeModel::System ).toInt());
+    m_colorScheme->setCurrentScheme(currentColorScheme);
 
     /* Controlbar Profile Model Creation */
     m_controlbarProfileModel = new ControlbarProfileModel(p_intf, this);
@@ -253,7 +253,7 @@ MainInterface::~MainInterface()
     settings->setValue( "playlist-width-factor", playlistWidthFactor);
 
     settings->setValue( "grid-view", m_gridView );
-    settings->setValue( "color-scheme", m_colorScheme->getCurrent() );
+    settings->setValue( "color-scheme", m_colorScheme->currentScheme() );
     /* Save the stackCentralW sizes */
     settings->endGroup();
 


=====================================
modules/gui/qt/maininterface/mainui.cpp
=====================================
@@ -170,6 +170,7 @@ void MainUI::registerQMLTypes()
 {
     qRegisterMetaType<VLCTick>();
     qmlRegisterUncreatableType<VLCTick>("org.videolan.vlc", 0, 1, "VLCTick", "");
+    qmlRegisterUncreatableType<ColorSchemeModel>("org.videolan.vlc", 0, 1, "ColorSchemeModel", "");
 
     qRegisterMetaType<QmlInputItem>();
 


=====================================
modules/gui/qt/style/VLCColors.qml
=====================================
@@ -17,6 +17,8 @@
  *****************************************************************************/
 import QtQuick 2.11
 
+import org.videolan.vlc 0.1
+
 Item {
     id: colors_id
 
@@ -168,16 +170,23 @@ Item {
 
     property color seekpoint: "red";
 
-    property var colorSchemes: mainInterface.colorScheme
-    Component.onCompleted:  {
-        mainInterface.colorScheme.setAvailableColorSchemes(["system", "day", "night"])
-    }
-
     property color windowCSDButtonDarkBg:  "#80484848"
     property color windowCSDButtonLightBg: "#80DADADA"
     property color windowCSDButtonBg: isThemeDark ? windowCSDButtonDarkBg : windowCSDButtonLightBg
 
-    state: mainInterface.colorScheme.current
+    state: {
+        switch (mainInterface.colorScheme.scheme) {
+        case ColorSchemeModel.System:
+            return "system"
+        case ColorSchemeModel.Day:
+            return "day"
+        case ColorSchemeModel.Night:
+            return "night"
+        default:
+            console.assert(false, "Unknown color scheme")
+        }
+    }
+
     states: [
         //other styles are provided for testing purpose
         State {


=====================================
modules/gui/qt/util/color_scheme_model.cpp
=====================================
@@ -1,5 +1,5 @@
 /*****************************************************************************
- * Copyright (C) 2020 the VideoLAN team
+ * Copyright (C) 2021 the VideoLAN team
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -18,89 +18,227 @@
 
 #include "color_scheme_model.hpp"
 
-ColorSchemeModel::ColorSchemeModel(QObject* parent)
-    : QStringListModel(parent)
+#include "qt.hpp"
+
+
+#ifdef Q_OS_WIN
+
+#include <QAbstractNativeEventFilter>
+#include <QApplication>
+#include <QSettings>
+
+#include <qt_windows.h>
+
+namespace
 {
+    const char *WIN_THEME_SETTING_PATH = "HKEY_CURRENT_USER\\Software\\Microsoft\\Windows\\CurrentVersion\\Themes\\Personalize";
+    const char *WIN_THEME_SETTING_LIGHT_THEME_KEY = "AppsUseLightTheme";
 }
 
-void ColorSchemeModel::setAvailableColorSchemes(const QStringList& colorSchemeList)
+class ColorSchemeModel::WinColorSchemeList
+        : public ColorSchemeModel::SchemeList
+        , public QAbstractNativeEventFilter
 {
-    setStringList(colorSchemeList);
-
-    //indexOf return -1 on "not found", wich will generate an invalid index
-    int position = colorSchemeList.indexOf(m_current);
-
-    QPersistentModelIndex oldIndex = m_checkedItem;
-    m_checkedItem = index(position);
-    if (oldIndex.isValid())
-        emit dataChanged(oldIndex, oldIndex);
-    if (m_checkedItem.isValid())
-        emit dataChanged(m_checkedItem, m_checkedItem);
-    else
+public:
+    static bool canDetectTheme()
+    {
+        QSettings settings(QLatin1String {WIN_THEME_SETTING_PATH}, QSettings::NativeFormat);
+        return settings.contains(WIN_THEME_SETTING_LIGHT_THEME_KEY);
+    }
+
+    WinColorSchemeList(ColorSchemeModel *colorSchemeModel)
+        : m_colorSchemeModel {colorSchemeModel}
+        , m_settings(QLatin1String {WIN_THEME_SETTING_PATH}, QSettings::NativeFormat)
+        , m_items {{qtr("Auto"), ColorScheme::Auto}, {qtr("Day"), ColorScheme::Day}, {qtr("Night"), ColorScheme::Night}}
+    {
+        qApp->installNativeEventFilter(this);
+    }
+
+    ~WinColorSchemeList()
+    {
+        qApp->removeNativeEventFilter(this);
+    }
+
+    ColorScheme scheme(int i) const override
     {
-        m_current = QString{};
-        emit currentChanged(m_current);
+        if (m_items.at(i).scheme == ColorScheme::Auto)
+            return m_settings.value(WIN_THEME_SETTING_LIGHT_THEME_KEY).toBool()
+                    ? ColorScheme::Day : ColorScheme::Night;
+
+        return m_items.at(i).scheme;
     }
+
+    QString text(int i) const override
+    {
+        return m_items.at(i).text;
+    }
+
+    int size() const override
+    {
+        return m_items.size();
+    }
+
+    bool nativeEventFilter(const QByteArray &, void *message, long *) override
+    {
+        MSG* msg = static_cast<MSG*>( message );
+        if ( msg->message == WM_SETTINGCHANGE
+             && !lstrcmp( LPCTSTR( msg->lParam ), L"ImmersiveColorSet" ) )
+        {
+            m_colorSchemeModel->indexChanged(0);
+        }
+        return false;
+    }
+
+private:
+    struct Item
+    {
+        QString text;
+        ColorScheme scheme;
+    };
+
+    ColorSchemeModel *m_colorSchemeModel;
+    QSettings m_settings;
+    const QVector<Item> m_items;
+};
+
+#endif
+
+class ColorSchemeModel::DefaultSchemeList : public ColorSchemeModel::SchemeList
+{
+public:
+    DefaultSchemeList()
+        : m_items {{qtr("System"), ColorScheme::System}, {qtr("Day"), ColorScheme::Day}, {qtr("Night"), ColorScheme::Night}}
+    {
+    }
+
+    ColorScheme scheme(int i) const override
+    {
+        return m_items.at(i).scheme;
+    }
+
+    QString text(int i) const override
+    {
+        return m_items.at(i).text;
+    }
+
+    int size() const override
+    {
+        return m_items.size();
+    }
+
+private:
+    struct Item
+    {
+        QString text;
+        ColorScheme scheme;
+    };
+
+    const QVector<Item> m_items;
+};
+
+std::unique_ptr<ColorSchemeModel::SchemeList> ColorSchemeModel::createList(ColorSchemeModel *parent)
+{
+#ifdef Q_OS_WIN
+    if (WinColorSchemeList::canDetectTheme)
+        return std::make_unique<WinColorSchemeList>(parent);
+#endif
+    Q_UNUSED(parent);
+    return std::make_unique<DefaultSchemeList>();
 }
 
-Qt::ItemFlags ColorSchemeModel::flags (const QModelIndex & index) const
+ColorSchemeModel::ColorSchemeModel(QObject* parent)
+    : QAbstractListModel(parent)
+    , m_list {createList(this)}
+    , m_currentIndex {0}
 {
-    Qt::ItemFlags defaultFlags = QStringListModel::flags(index);
-    if (index.isValid()){
+}
+
+int ColorSchemeModel::rowCount(const QModelIndex &) const
+{
+    return m_list->size();
+}
+
+Qt::ItemFlags ColorSchemeModel::flags (const QModelIndex &index) const
+{
+    Qt::ItemFlags defaultFlags = QAbstractListModel::flags(index);
+    if (index.isValid())
         return defaultFlags | Qt::ItemIsUserCheckable;
-    }
     return defaultFlags;
 }
 
-
-bool ColorSchemeModel::setData(const QModelIndex &index,
-                                const QVariant &value, int role)
+QVariant ColorSchemeModel::data(const QModelIndex &index, const int role) const
 {
-    if(!index.isValid())
-        return false;
+    if (!checkIndex(index, CheckIndexOption::IndexIsValid))
+        return QVariant {};
 
-    if (role != Qt::CheckStateRole)
-        return QStringListModel::setData(index, value, role);
+    if (role == Qt::CheckStateRole)
+        return m_currentIndex == index.row() ? Qt::Checked : Qt::Unchecked;
 
-    if (value.type() != QVariant::Bool || value.toBool() == false)
-        return false;
+    if (role == Qt::DisplayRole)
+        return m_list->text(index.row());
 
-    if (index != m_checkedItem) {
-        QPersistentModelIndex oldIndex = m_checkedItem;
-        m_checkedItem = index;
-        if (oldIndex.isValid())
-            emit dataChanged(oldIndex, oldIndex);
-        emit dataChanged(m_checkedItem, m_checkedItem);
-        m_current = data(index, Qt::DisplayRole).toString();
-        emit currentChanged(m_current);
+    return QVariant {};
+}
+
+bool ColorSchemeModel::setData(const QModelIndex &index,
+                               const QVariant &value, const int role)
+{
+    if (role == Qt::CheckStateRole
+            && checkIndex(index, CheckIndexOption::IndexIsValid)
+            && index.row() != m_currentIndex
+            && value.type() == QVariant::Bool
+            && value.toBool())
+    {
+        setCurrentIndex(index.row());
+        return true;
     }
 
-    return true;
+    return false;
 }
 
-void ColorSchemeModel::setCurrent(const QString& current)
+int ColorSchemeModel::currentIndex() const
 {
-    //indexOf return -1 on "not found", wich will generate an invalid index
-    int position = stringList().indexOf(current);
-
-    QPersistentModelIndex oldIndex = m_checkedItem;
-    m_checkedItem = index(position);
-    if (oldIndex.isValid())
-        emit dataChanged(oldIndex, oldIndex);
-    if (m_checkedItem.isValid())
-        emit dataChanged(m_checkedItem, m_checkedItem);
-
-    m_current = current;
-    emit currentChanged(m_current);
+    return m_currentIndex;
 }
 
-QVariant ColorSchemeModel::data(const QModelIndex &index, int role) const
+void ColorSchemeModel::setCurrentIndex(const int newIndex)
 {
-    if (!index.isValid())
-        return QVariant();
+    if (m_currentIndex == newIndex)
+        return;
+
+    assert(newIndex >= 0 && newIndex < m_list->size());
+    const auto oldIndex = this->index(m_currentIndex);
+    m_currentIndex = newIndex;
+    emit dataChanged(index(m_currentIndex), index(m_currentIndex), {Qt::CheckStateRole});
+    emit dataChanged(oldIndex, oldIndex, {Qt::CheckStateRole});
+    emit currentChanged();
+}
 
-    if(role == Qt::CheckStateRole)
-        return m_checkedItem == index ? Qt::Checked : Qt::Unchecked;
+QString ColorSchemeModel::currentText() const
+{
+    return m_list->text(m_currentIndex);
+}
 
-    return QStringListModel::data(index, role);
+void ColorSchemeModel::setCurrentScheme(const ColorScheme scheme)
+{
+    for (int i = 0; i < m_list->size(); ++i)
+    {
+        if (m_list->scheme(i) == scheme)
+        {
+            setCurrentIndex(i);
+            break;
+        }
+    }
+}
+
+ColorSchemeModel::ColorScheme ColorSchemeModel::currentScheme() const
+{
+    return m_list->scheme(m_currentIndex);
+}
+
+void ColorSchemeModel::indexChanged(const int i)
+{
+    emit dataChanged(index(i), index(i));
+    if (i == m_currentIndex)
+        emit currentChanged();
 }


=====================================
modules/gui/qt/util/color_scheme_model.hpp
=====================================
@@ -19,32 +19,66 @@
 #ifndef COLORSCHEMEMODEL_HPP
 #define COLORSCHEMEMODEL_HPP
 
-#include <QStringListModel>
+#include <QAbstractListModel>
 
-class ColorSchemeModel : public QStringListModel
+#include <memory>
+
+class ColorSchemeModel : public QAbstractListModel
 {
     Q_OBJECT
-    Q_PROPERTY(QString current READ getCurrent WRITE setCurrent NOTIFY currentChanged)
+    Q_PROPERTY(QString current READ currentText NOTIFY currentChanged)
+    Q_PROPERTY(ColorScheme scheme READ currentScheme WRITE setCurrentScheme NOTIFY currentChanged)
+
 public:
-    explicit ColorSchemeModel(QObject* parent = nullptr);
+    enum ColorScheme
+    {
+        System,
+        Day,
+        Night,
+
+        Auto
+    };
+
+    Q_ENUM(ColorScheme);
 
-    Q_INVOKABLE void setAvailableColorSchemes(const QStringList& colorSchemeList);
+    explicit ColorSchemeModel(QObject* parent = nullptr);
 
+    virtual int rowCount(const QModelIndex& parent) const override;
     virtual Qt::ItemFlags flags (const QModelIndex& index) const override;
     virtual QVariant data(const QModelIndex &index, int role) const override;
     virtual bool setData(const QModelIndex &index, const QVariant &value, int role) override;
 
-    inline QString getCurrent() const { return m_current; }
-    void setCurrent(const QString& );
+    int currentIndex() const;
+    void setCurrentIndex(int newIndex);
+
+    QString currentText() const;
+
+    void setCurrentScheme(ColorScheme scheme);
+    ColorScheme currentScheme() const;
 
 signals:
-    void currentChanged(const QString& colorScheme);
+    void currentChanged();
 
 private:
-    QString               m_current;
-    QPersistentModelIndex m_checkedItem;
+    class SchemeList
+    {
+    public:
+        virtual ~SchemeList() = default;
+        virtual ColorScheme scheme(int i) const = 0;
+        virtual QString text(int i) const = 0;
+        virtual int size() const = 0;
+    };
+
+    class DefaultSchemeList;
+    class WinColorSchemeList;
+
+    static std::unique_ptr<SchemeList> createList(ColorSchemeModel *parent);
 
+    // \internal used by SchemeList to notify scheme changed
+    void indexChanged(int i);
 
+    const std::unique_ptr<SchemeList> m_list;
+    int m_currentIndex;
 };
 
 #endif // COLORSCHEMEMODEL_HPP



View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/81204466970a80c8b26a42ac70820bd162b638a2...9cec201b268515251e950ad5a040113c2507982a

-- 
View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/81204466970a80c8b26a42ac70820bd162b638a2...9cec201b268515251e950ad5a040113c2507982a
You're receiving this email because of your account on code.videolan.org.




More information about the vlc-commits mailing list