[vlc-devel] [RFC 56/82] qt: provide component to help navigation between QML views

Pierre Lamot pierre at videolabs.io
Fri Feb 1 14:02:00 CET 2019


  this class allows to navigate between view and to keep track of the
  history navigation.

  views are defined as a page name and a property set, they might have
  another view nested.

  views can be expressed as a dictionnary

  { view: "mainView", viewProperties: {
      "prop1" : "val1",
      "view" : { "subView" }
      "viewProperties" : { "subprop": "subval" }
      }
  }

  or as a list, considering "view" and "viewProperties" are reserved key to express subviews

  [ "mainView", {"prop1": "val1"}, "subView", {"subprop" : "subVal"} ]
---
 modules/gui/qt/Makefile.am                    |  3 +
 .../gui/qt/components/navigation_history.cpp  | 68 ++++++++++++++++++
 .../gui/qt/components/navigation_history.hpp  | 72 +++++++++++++++++++
 3 files changed, 143 insertions(+)
 create mode 100644 modules/gui/qt/components/navigation_history.cpp
 create mode 100644 modules/gui/qt/components/navigation_history.hpp

diff --git a/modules/gui/qt/Makefile.am b/modules/gui/qt/Makefile.am
index 6f435c55e3..4096f192c5 100644
--- a/modules/gui/qt/Makefile.am
+++ b/modules/gui/qt/Makefile.am
@@ -85,6 +85,8 @@ libqt_plugin_la_SOURCES = \
 	gui/qt/components/extended_panels.hpp \
 	gui/qt/components/info_panels.cpp gui/qt/components/info_panels.hpp \
 	gui/qt/components/info_widgets.cpp gui/qt/components/info_widgets.hpp \
+	gui/qt/components/navigation_history.cpp \
+	gui/qt/components/navigation_history.hpp \
 	gui/qt/components/player_controler.cpp gui/qt/components/player_controler.hpp gui/qt/components/player_controler_p.hpp \
 	gui/qt/components/preferences_widgets.cpp \
 	gui/qt/components/preferences_widgets.hpp \
@@ -254,6 +256,7 @@ nodist_libqt_plugin_la_SOURCES = \
 	gui/qt/components/simple_preferences.moc.cpp \
 	gui/qt/components/open_panels.moc.cpp \
 	gui/qt/components/interface_widgets.moc.cpp \
+	gui/qt/components/navigation_history.moc.cpp \
 	gui/qt/components/controller.moc.cpp \
 	gui/qt/components/controller_widget.moc.cpp \
 	gui/qt/components/custom_menus.moc.cpp \
diff --git a/modules/gui/qt/components/navigation_history.cpp b/modules/gui/qt/components/navigation_history.cpp
new file mode 100644
index 0000000000..39a428a7d9
--- /dev/null
+++ b/modules/gui/qt/components/navigation_history.cpp
@@ -0,0 +1,68 @@
+#include "navigation_history.hpp"
+#include <QDebug>
+
+NavigationHistory::NavigationHistory(QObject *parent) : QObject(parent)
+{
+
+}
+
+QVariant NavigationHistory::getCurrent()
+{
+
+    return m_history.back();
+}
+
+bool NavigationHistory::isEmpty()
+{
+    return m_history.count() < 1;
+}
+
+void NavigationHistory::push(QVariantMap item, PostAction postAction)
+{
+    //m_history.push_back(VariantToPropertyMap(item));
+    m_history.push_back(item);
+    if (m_history.count() == 2)
+        emit emptyChanged(true);
+    if (postAction == PostAction::Go)
+        emit currentChanged(m_history.back());
+}
+
+static void pushListRec(QVariantMap& itemMap, QVariantList::const_iterator it, QVariantList::const_iterator end )
+{
+    if (it == end)
+        return;
+    if(it->canConvert<QString>())
+    {
+        itemMap["view"] = it->toString();
+        QVariantMap subMap;
+        pushListRec(subMap, ++it, end);
+        itemMap["viewProperties"] = subMap;
+    }
+    else if ( it->canConvert<QVariantMap>() )
+    {
+        itemMap.unite( it->toMap() );
+        pushListRec(itemMap, ++it, end);
+    }
+}
+
+void NavigationHistory::push(QVariantList itemList, NavigationHistory::PostAction postAction)
+{
+    QVariantMap itemMap;
+    pushListRec(itemMap, itemList.cbegin(), itemList.cend());
+    push(itemMap, postAction);
+}
+
+void NavigationHistory::pop(PostAction postAction)
+{
+    if (m_history.count() == 1)
+        return;
+
+    //delete m_history.back();
+    m_history.pop_back();
+
+    if (m_history.count() == 1) {
+        emit emptyChanged(true);
+    }
+    if (postAction == PostAction::Go)
+        emit currentChanged(m_history.back());
+}
diff --git a/modules/gui/qt/components/navigation_history.hpp b/modules/gui/qt/components/navigation_history.hpp
new file mode 100644
index 0000000000..36d8c4a8ce
--- /dev/null
+++ b/modules/gui/qt/components/navigation_history.hpp
@@ -0,0 +1,72 @@
+#ifndef NAVIGATION_HISTORY_HPP
+#define NAVIGATION_HISTORY_HPP
+
+#include <QObject>
+#include <QList>
+#include <QtQml/QQmlPropertyMap>
+
+class NavigationHistory : public QObject
+{
+    Q_OBJECT
+public:
+    Q_PROPERTY(QVariant current READ getCurrent NOTIFY currentChanged)
+    Q_PROPERTY(bool empty READ isEmpty NOTIFY emptyChanged)
+
+    enum class PostAction{
+        Stay,
+        Go
+    };
+    Q_ENUM(PostAction)
+
+public:
+    explicit NavigationHistory(QObject *parent = nullptr);
+
+    QVariant getCurrent();
+    bool isEmpty();
+
+signals:
+    void currentChanged(QVariant current);
+    void emptyChanged(bool empty);
+
+public slots:
+    /**
+     * Push a
+     *
+     * \code
+     * push({
+     *   view: "foo", //push the view foo
+     *   viewProperties: {
+     *      view : "bar",  //the sub view "bar"
+     *      viewProperties: {
+     *         baz: "plop" //the property baz will be set in the view "bar"
+     *      }
+     *   }
+     * }, History.Go)
+     * \endcode
+     */
+    Q_INVOKABLE void push( QVariantMap, PostAction = PostAction::Stay );
+
+    /**
+     * provide a short version of the history push({k:v}), wich implicitly create a dictonnary tree from the input list
+     *
+     * List items are interpreted as
+     *   * strings will push a dict with "view" key to the value of the string and
+     *     a "viewProperties" dict configured with the tail of the list
+     *
+     *   * dict: values will be added to the current viewProperty
+     *
+     * example:
+     * \code
+     * //push the view foo, then bar, set baz to plop in the view "bar"
+     *  push(["foo", "bar", {baz: "plop"} ], History.Go)
+     * \endcode
+     */
+    Q_INVOKABLE void push(QVariantList itemList, PostAction = PostAction::Stay );
+    //pop the last page
+    void pop( PostAction = PostAction::Stay );
+
+private:
+    QVariantList m_history;
+};
+
+#endif // NAVIGATION_HISTORY_HPP
-- 
2.19.1



More information about the vlc-devel mailing list