[vlc-commits] [Git][videolan/vlc][master] 3 commits: qt: Create control_list_filter
Jean-Baptiste Kempf (@jbk)
gitlab at videolan.org
Fri Mar 11 10:33:46 UTC 2022
Jean-Baptiste Kempf pushed to branch master at VideoLAN / VLC
Commits:
026b9db3 by Benjamin Arnaud at 2022-03-11T09:41:32+00:00
qt: Create control_list_filter
- - - - -
50df9c28 by Benjamin Arnaud at 2022-03-11T09:41:32+00:00
qml/PlayerControlLayout: Add ControlListFilter(s) to hide unnecessary buttons
fix #26607
- - - - -
dcc4520c by Benjamin Arnaud at 2022-03-11T09:41:32+00:00
qml/ControlLayout: Update keyboard navigation implementation
Our prior implementation couldn't handle a model invalidate() properly and ended up corrupting
the keyboard navigation.
- - - - -
7 changed files:
- modules/gui/qt/Makefile.am
- modules/gui/qt/maininterface/mainui.cpp
- + modules/gui/qt/player/control_list_filter.cpp
- + modules/gui/qt/player/control_list_filter.hpp
- modules/gui/qt/player/qml/ControlLayout.qml
- modules/gui/qt/player/qml/PlayerControlLayout.qml
- po/POTFILES.in
Changes:
=====================================
modules/gui/qt/Makefile.am
=====================================
@@ -228,6 +228,8 @@ libqt_plugin_la_SOURCES = \
gui/qt/player/player_controller.cpp gui/qt/player/player_controller.hpp gui/qt/player/player_controller_p.hpp \
gui/qt/player/player_controlbar_model.cpp gui/qt/player/player_controlbar_model.hpp \
gui/qt/player/control_list_model.cpp gui/qt/player/control_list_model.hpp \
+ gui/qt/player/control_list_filter.cpp \
+ gui/qt/player/control_list_filter.hpp \
gui/qt/playlist/media.hpp \
gui/qt/playlist/playlist_common.cpp \
gui/qt/playlist/playlist_common.hpp \
@@ -424,6 +426,7 @@ nodist_libqt_plugin_la_SOURCES = \
gui/qt/player/player_controller.moc.cpp \
gui/qt/player/player_controlbar_model.moc.cpp \
gui/qt/player/control_list_model.moc.cpp \
+ gui/qt/player/control_list_filter.moc.cpp \
gui/qt/playlist/playlist_common.moc.cpp \
gui/qt/playlist/playlist_controller.moc.cpp \
gui/qt/playlist/playlist_item.moc.cpp \
=====================================
modules/gui/qt/maininterface/mainui.cpp
=====================================
@@ -22,6 +22,7 @@
#include "player/player_controller.hpp"
#include "player/player_controlbar_model.hpp"
#include "player/control_list_model.hpp"
+#include "player/control_list_filter.hpp"
#include "dialogs/toolbar/controlbar_profile_model.hpp"
#include "dialogs/toolbar/controlbar_profile.hpp"
@@ -255,6 +256,7 @@ void MainUI::registerQMLTypes()
qmlRegisterUncreatableType<ControlbarProfile>(uri, versionMajor, versionMinor, "ControlbarProfile", "");
qmlRegisterUncreatableType<PlayerControlbarModel>(uri, versionMajor, versionMinor, "PlayerControlbarModel", "");
qmlRegisterUncreatableType<ControlListModel>( uri, versionMajor, versionMinor, "ControlListModel", "" );
+ qmlRegisterType<ControlListFilter>(uri, versionMajor, versionMinor, "ControlListFilter");
qmlRegisterSingletonType(uri, versionMajor, versionMinor, "PlayerListModel", PlayerControlbarModel::getPlaylistIdentifierListModel);
qmlRegisterType<StringListMenu>( uri, versionMajor, versionMinor, "StringListMenu" );
=====================================
modules/gui/qt/player/control_list_filter.cpp
=====================================
@@ -0,0 +1,93 @@
+/*****************************************************************************
+ * Copyright (C) 2022 VLC authors and VideoLAN
+ *
+ * Authors: Benjamin Arnaud <bunjee at omega.gg>
+ *
+ * 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
+ * the Free Software Foundation; either version 2 of the License, or
+ * ( at your option ) any later version.
+ *
+ * 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 "control_list_filter.hpp"
+
+// Player includes
+#include "player_controller.hpp"
+#include "control_list_model.hpp"
+
+// Ctor / dtor
+
+/* explicit */ ControlListFilter::ControlListFilter(QObject * parent)
+ : QSortFilterProxyModel(parent) {}
+
+// QAbstractProxyModel reimplementation
+
+void ControlListFilter::setSourceModel(QAbstractItemModel * sourceModel) /* override */
+{
+ assert(sourceModel->inherits("ControlListModel"));
+
+ QSortFilterProxyModel::setSourceModel(sourceModel);
+}
+
+// Protected QSortFilterProxyModel reimplementation
+
+bool ControlListFilter::filterAcceptsRow(int source_row, const QModelIndex &) const /* override */
+{
+ QAbstractItemModel * model = sourceModel();
+
+ if (model == nullptr || m_player == nullptr)
+ return true;
+
+ QVariant variant = model->data(model->index(source_row, 0), ControlListModel::ID_ROLE);
+
+ if (variant.isValid() == false)
+ return true;
+
+ ControlListModel::ControlType type
+ = static_cast<ControlListModel::ControlType> (variant.toInt());
+
+ // NOTE: These controls are completely hidden when the current media does not support them.
+ if (type == ControlListModel::TELETEXT_BUTTONS)
+ {
+ return m_player->isTeletextAvailable();
+ }
+ else if (type == ControlListModel::DVD_MENUS_BUTTON)
+ {
+ return m_player->hasMenu();
+ }
+
+ return true;
+}
+
+// Properties
+
+PlayerController * ControlListFilter::player()
+{
+ return m_player;
+}
+
+void ControlListFilter::setPlayer(PlayerController * player)
+{
+ if (m_player == player) return;
+
+ if (m_player)
+ disconnect(m_player, nullptr, this, nullptr);
+
+ m_player = player;
+
+ connect(player, &PlayerController::teletextAvailableChanged, this, &ControlListFilter::invalidate);
+ connect(player, &PlayerController::hasMenuChanged, this, &ControlListFilter::invalidate);
+
+ invalidate();
+
+ emit playerChanged();
+}
=====================================
modules/gui/qt/player/control_list_filter.hpp
=====================================
@@ -0,0 +1,56 @@
+/*****************************************************************************
+ * Copyright (C) 2022 VLC authors and VideoLAN
+ *
+ * Authors: Benjamin Arnaud <bunjee at omega.gg>
+ *
+ * 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
+ * the Free Software Foundation; either version 2 of the License, or
+ * ( at your option ) any later version.
+ *
+ * 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 CONTROLLISTFILTER_HPP
+#define CONTROLLISTFILTER_HPP
+
+// Qt includes
+#include <QSortFilterProxyModel>
+
+// Forward declarations
+class PlayerController;
+
+class ControlListFilter : public QSortFilterProxyModel
+{
+ Q_OBJECT
+
+ Q_PROPERTY(PlayerController * player READ player WRITE setPlayer NOTIFY playerChanged)
+
+public:
+ explicit ControlListFilter(QObject * parent = nullptr);
+
+public: // QAbstractProxyModel reimplementation
+ void setSourceModel(QAbstractItemModel * sourceModel) override;
+
+protected: // QSortFilterProxyModel reimplementation
+ bool filterAcceptsRow(int source_row, const QModelIndex & source_parent) const override;
+
+signals:
+ void playerChanged();
+
+public: // Properties
+ PlayerController * player();
+ void setPlayer(PlayerController * player);
+
+private: // Variables
+ PlayerController * m_player = nullptr;
+};
+
+#endif // CONTROLLISTFILTER_HPP
=====================================
modules/gui/qt/player/qml/ControlLayout.qml
=====================================
@@ -92,7 +92,13 @@ FocusScope {
Repeater {
id: repeater
+ // NOTE: We apply the 'navigation chain' after adding the item.
+ onItemAdded: item.applyNavigation()
+
onItemRemoved: {
+ // NOTE: We update the 'navigation chain' after removing the item.
+ item.removeNavigation()
+
item.recoverFocus(index)
}
@@ -129,23 +135,7 @@ FocusScope {
value: (loader.x + minimumWidth <= rowLayout.width)
}
- function buildFocusChain() {
- // rebuild the focus chain:
- if (typeof repeater === "undefined")
- return
-
- var rightItem = repeater.itemAt(index + 1)
- var leftItem = repeater.itemAt(index - 1)
-
- item.Navigation.rightItem = !!rightItem ? rightItem.item : null
- item.Navigation.leftItem = !!leftItem ? leftItem.item : null
- }
-
- Component.onCompleted: {
- repeater.countChanged.connect(loader.buildFocusChain)
- repeater.modelChanged.connect(loader.buildFocusChain)
- repeater.countChanged.connect(controlLayout._handleFocus)
- }
+ Component.onCompleted: repeater.countChanged.connect(controlLayout._handleFocus)
onActiveFocusChanged: {
if (activeFocus && (!!item && !item.focus)) {
@@ -190,6 +180,47 @@ FocusScope {
item.visible = Qt.binding(function() { return loader.visible })
}
+ function applyNavigation() {
+ var itemLeft = repeater.itemAt(index - 1)
+ var itemRight = repeater.itemAt(index + 1)
+
+ if (itemLeft) {
+ var componentLeft = itemLeft.item;
+
+ item.Navigation.leftItem = componentLeft
+
+ componentLeft.Navigation.rightItem = item
+ }
+
+ if (itemRight) {
+ var componentRight = itemRight.item;
+
+ item.Navigation.rightItem = componentRight
+
+ componentRight.Navigation.leftItem = item
+ }
+ }
+
+ function removeNavigation() {
+ var itemLeft = repeater.itemAt(index - 1)
+
+ // NOTE: The current item was removed from the repeater so we test against the
+ // same index.
+ var itemRight = repeater.itemAt(index)
+
+ if (itemLeft) {
+ if (itemRight) {
+ itemLeft.item.Navigation.rightItem = itemRight.item
+ itemRight.item.Navigation.leftItem = itemLeft.item
+ }
+ else
+ itemLeft.item.Navigation.rightItem = null
+ }
+ else if (itemRight) {
+ itemRight.item.Navigation.leftItem = null
+ }
+ }
+
function _focusIfFocusable(_loader) {
if (!!_loader && !!_loader.item && _loader.item.focus) {
if (item.focusReason !== undefined)
=====================================
modules/gui/qt/player/qml/PlayerControlLayout.qml
=====================================
@@ -68,7 +68,11 @@ FocusScope {
focus: true
sourceComponent: ControlLayout {
- model: playerControlLayout.model.left
+ model: ControlListFilter {
+ sourceModel: playerControlLayout.model.left
+
+ player: Player
+ }
Navigation.parentItem: playerControlLayout
Navigation.rightItem: layoutLoader_center.item
@@ -95,7 +99,11 @@ FocusScope {
: implicitWidth
sourceComponent: ControlLayout {
- model: playerControlLayout.model.center
+ model: ControlListFilter {
+ sourceModel: playerControlLayout.model.center
+
+ player: Player
+ }
Navigation.parentItem: playerControlLayout
Navigation.leftItem: layoutLoader_left.item
@@ -123,7 +131,11 @@ FocusScope {
&& !!playerControlLayout.model.right
sourceComponent: ControlLayout {
- model: playerControlLayout.model.right
+ model: ControlListFilter {
+ sourceModel: playerControlLayout.model.right
+
+ player: Player
+ }
rightAligned: true
=====================================
po/POTFILES.in
=====================================
@@ -817,6 +817,8 @@ modules/gui/qt/util/validators.cpp
modules/gui/qt/util/validators.hpp
modules/gui/qt/player/player_controlbar_model.cpp
modules/gui/qt/player/player_controlbar_model.hpp
+modules/gui/qt/player/control_list_filter.cpp
+modules/gui/qt/player/control_list_filter.hpp
modules/gui/qt/dialogs/dialogs/qml/CustomDialog.qml
modules/gui/qt/dialogs/dialogs/qml/Dialogs.qml
modules/gui/qt/dialogs/dialogs/qml/WindowDialog.qml
View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/b5923a21d65d4e33dcc498a204a0ecc82437153e...dcc4520cd9257fdcc77582e18853e6f46ddb4a07
--
View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/b5923a21d65d4e33dcc498a204a0ecc82437153e...dcc4520cd9257fdcc77582e18853e6f46ddb4a07
You're receiving this email because of your account on code.videolan.org.
VideoLAN code repository instance
More information about the vlc-commits
mailing list