[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