From 1ef15ae73da349473e43f0a0198f5005c9c0663f Mon Sep 17 00:00:00 2001 From: Skycoder42 Date: Thu, 22 Feb 2018 13:34:17 +0100 Subject: [PATCH] completed tabbar sample (quick) --- .../mvvmcore/SampleCore/drawerviewmodel.cpp | 5 ++ examples/mvvmcore/SampleCore/tabviewmodel.cpp | 35 ++++++++++++++ examples/mvvmcore/SampleCore/tabviewmodel.h | 25 ++++++++++ examples/mvvmquick/SampleQuick/SampleView.qml | 7 --- .../mvvmquick/SampleQuick/TabItemView.qml | 14 ++++++ examples/mvvmquick/SampleQuick/TabView.qml | 46 +++++++++++-------- examples/mvvmquick/SampleQuick/main.cpp | 1 + examples/mvvmquick/SampleQuick/qml.qrc | 1 + src/imports/mvvmquick/InputDialog.qml | 9 ++-- src/imports/mvvmquick/PresentingStackView.qml | 2 + src/mvvmquick/quickpresenter.cpp | 30 +++++++----- 11 files changed, 135 insertions(+), 40 deletions(-) create mode 100644 examples/mvvmquick/SampleQuick/TabItemView.qml diff --git a/examples/mvvmcore/SampleCore/drawerviewmodel.cpp b/examples/mvvmcore/SampleCore/drawerviewmodel.cpp index 7cb2ba9..72dfed7 100644 --- a/examples/mvvmcore/SampleCore/drawerviewmodel.cpp +++ b/examples/mvvmcore/SampleCore/drawerviewmodel.cpp @@ -1,12 +1,14 @@ #include "drawerviewmodel.h" #include "sampleviewmodel.h" +#include "tabviewmodel.h" DrawerViewModel::DrawerViewModel(QObject *parent) : ViewModel(parent), _navModel(new QStandardItemModel(0, 1, this)) { _navModel->appendRow(new QStandardItem(tr("Main Sample"))); + _navModel->appendRow(new QStandardItem(tr("Tab Sample"))); } DrawerViewModel::~DrawerViewModel() @@ -25,6 +27,9 @@ void DrawerViewModel::open(int index) case 0: show(); break; + case 1: + show(); + break; default: break; } diff --git a/examples/mvvmcore/SampleCore/tabviewmodel.cpp b/examples/mvvmcore/SampleCore/tabviewmodel.cpp index 2381aa5..930c6a4 100644 --- a/examples/mvvmcore/SampleCore/tabviewmodel.cpp +++ b/examples/mvvmcore/SampleCore/tabviewmodel.cpp @@ -1,4 +1,5 @@ #include "tabviewmodel.h" +#include TabViewModel::TabViewModel(QObject *parent) : ViewModel(parent) @@ -8,3 +9,37 @@ TabViewModel::~TabViewModel() { qInfo(Q_FUNC_INFO); } + +void TabViewModel::addTab() +{ + QtMvvm::getInput(tr("New Tab"), tr("Enter a tab title:"), this, [this](QString res, bool ok) { + if(ok) { + show({ + {QStringLiteral("title"), res} + }); + } + }); +} + + + +TabItemViewModel::TabItemViewModel(QObject *parent) : + ViewModel(parent), + _title(tr("No Title")) +{} + +TabItemViewModel::~TabItemViewModel() +{ + qInfo(Q_FUNC_INFO); +} + +QString TabItemViewModel::title() const +{ + return _title; +} + +void TabItemViewModel::onInit(const QVariantHash ¶ms) +{ + _title = params.value(QStringLiteral("title"), _title).toString(); + emit titleChanged(_title); +} diff --git a/examples/mvvmcore/SampleCore/tabviewmodel.h b/examples/mvvmcore/SampleCore/tabviewmodel.h index b1c8c46..1634fa5 100644 --- a/examples/mvvmcore/SampleCore/tabviewmodel.h +++ b/examples/mvvmcore/SampleCore/tabviewmodel.h @@ -10,6 +10,31 @@ class TabViewModel : public QtMvvm::ViewModel public: Q_INVOKABLE explicit TabViewModel(QObject *parent = nullptr); ~TabViewModel(); + +public Q_SLOTS: + void addTab(); +}; + +class TabItemViewModel : public QtMvvm::ViewModel +{ + Q_OBJECT + + Q_PROPERTY(QString title READ title NOTIFY titleChanged) + +public: + Q_INVOKABLE explicit TabItemViewModel(QObject *parent = nullptr); + ~TabItemViewModel(); + + QString title() const; + +Q_SIGNALS: + void titleChanged(QString title); + +protected: + void onInit(const QVariantHash ¶ms) override; + +private: + QString _title; }; #endif // TABVIEWMODEL_H diff --git a/examples/mvvmquick/SampleQuick/SampleView.qml b/examples/mvvmquick/SampleQuick/SampleView.qml index 6c7de83..9f9e323 100644 --- a/examples/mvvmquick/SampleQuick/SampleView.qml +++ b/examples/mvvmquick/SampleQuick/SampleView.qml @@ -18,13 +18,6 @@ Page { onMenuButtonClicked: QuickPresenter.toggleDrawer() moreMenu: Menu { - MenuItem { - text: qsTr("Show Tabs") - onTriggered: viewModel.showTabs() - } - - MenuSeparator {} - MenuItem { text: qsTr("Another Input") onTriggered: viewModel.getInput() diff --git a/examples/mvvmquick/SampleQuick/TabItemView.qml b/examples/mvvmquick/SampleQuick/TabItemView.qml new file mode 100644 index 0000000..b97f0dc --- /dev/null +++ b/examples/mvvmquick/SampleQuick/TabItemView.qml @@ -0,0 +1,14 @@ +import QtQuick 2.10 +import QtQuick.Controls 2.3 +import de.skycoder42.QtMvvm.Core 1.0 +import de.skycoder42.QtMvvm.Quick 1.0 +import de.skycoder42.QtMvvm.Sample 1.0 + +Pane { + property TabItemViewModel viewModel: null + + Switch { + anchors.centerIn: parent + text: viewModel.title + } +} diff --git a/examples/mvvmquick/SampleQuick/TabView.qml b/examples/mvvmquick/SampleQuick/TabView.qml index 8207677..5070bf7 100644 --- a/examples/mvvmquick/SampleQuick/TabView.qml +++ b/examples/mvvmquick/SampleQuick/TabView.qml @@ -20,13 +20,11 @@ Page { tabBar: TabBar { id: tabBar - currentIndex: swipe.currentIndex + currentIndex: 0 TabButton { - text: "Test 1" - } - TabButton { - text: "Test 2" + text: "+" + onClicked: viewModel.addTab(); } } } @@ -37,23 +35,33 @@ Page { id: swipe anchors.fill: parent currentIndex: bar.tabBarItem.currentIndex + } - Pane { - id: firstPage + Component { + id: _newTab + TabButton { + property TabItemViewModel viewModel: null - Switch { - anchors.centerIn: parent - checked: true - text: qsTr("Click me!") - } + text: viewModel.title + onClicked: swipe.setCurrentIndex(bar.tabBarItem.currentIndex) } - Pane { - id: secondPage + } - Switch { - anchors.centerIn: parent - text: qsTr("Click me, too!") - } - } + function presentTab(item) { + console.log("here"); + var tabBar = bar.tabBarItem; + tabBar.insertItem(tabBar.count - 1, _newTab.createObject(tabBar, {viewModel: item.viewModel})); + item.parent = swipe; + swipe.addItem(item); + tabBar.setCurrentIndex(tabBar.count - 2); + return true; + } + + function afterPop() { + var tabBar = bar.tabBarItem; + while(tabBar.count > 0) + tabBar.takeItem(0).destroy(); + while(swipe.count > 0) + swipe.takeItem(0).destroy(); } } diff --git a/examples/mvvmquick/SampleQuick/main.cpp b/examples/mvvmquick/SampleQuick/main.cpp index e5ff898..2805ed1 100644 --- a/examples/mvvmquick/SampleQuick/main.cpp +++ b/examples/mvvmquick/SampleQuick/main.cpp @@ -33,6 +33,7 @@ int main(int argc, char *argv[]) qmlRegisterUncreatableType("de.skycoder42.QtMvvm.Sample", 1, 0, "ResultViewModel", QStringLiteral("ViewModels cannot be created")); qmlRegisterUncreatableType("de.skycoder42.QtMvvm.Sample", 1, 0, "DrawerViewModel", QStringLiteral("ViewModels cannot be created")); qmlRegisterUncreatableType("de.skycoder42.QtMvvm.Sample", 1, 0, "TabViewModel", QStringLiteral("ViewModels cannot be created")); + qmlRegisterUncreatableType("de.skycoder42.QtMvvm.Sample", 1, 0, "TabItemViewModel", QStringLiteral("ViewModels cannot be created")); QtMvvm::QuickPresenter::registerAsPresenter(); diff --git a/examples/mvvmquick/SampleQuick/qml.qrc b/examples/mvvmquick/SampleQuick/qml.qrc index 67c1e17..fcca30b 100644 --- a/examples/mvvmquick/SampleQuick/qml.qrc +++ b/examples/mvvmquick/SampleQuick/qml.qrc @@ -7,5 +7,6 @@ ResultView.qml DrawerView.qml TabView.qml + TabItemView.qml diff --git a/src/imports/mvvmquick/InputDialog.qml b/src/imports/mvvmquick/InputDialog.qml index ab42077..c115bd1 100644 --- a/src/imports/mvvmquick/InputDialog.qml +++ b/src/imports/mvvmquick/InputDialog.qml @@ -45,9 +45,12 @@ MsgBoxBase { Layout.fillHeight: true Layout.fillWidth: true - onLoaded: msgResult.result = Qt.binding(function() { - return item.inputValue; - }) + onLoaded: { + msgResult.result = Qt.binding(function() { + return item.inputValue; + }) + item.forceActiveFocus(); + } } } diff --git a/src/imports/mvvmquick/PresentingStackView.qml b/src/imports/mvvmquick/PresentingStackView.qml index 5869870..5a36e1b 100644 --- a/src/imports/mvvmquick/PresentingStackView.qml +++ b/src/imports/mvvmquick/PresentingStackView.qml @@ -65,6 +65,8 @@ StackView { function clearWaitingItems() { _clearItems.forEach(function(item) { + if(typeof item.afterPop == "function") + item.afterPop(); item.destroy(); }); _clearItems = []; diff --git a/src/mvvmquick/quickpresenter.cpp b/src/mvvmquick/quickpresenter.cpp index 4dec0aa..cd38264 100644 --- a/src/mvvmquick/quickpresenter.cpp +++ b/src/mvvmquick/quickpresenter.cpp @@ -1,6 +1,8 @@ #include "quickpresenter.h" #include "quickpresenter_p.h" +#include + #include #include #include @@ -90,26 +92,32 @@ QUrl QuickPresenter::findViewUrl(const QMetaObject *viewModelType) if(lIndex > 0) cName.truncate(lIndex); + QUrl resUrl; + auto shortest = std::numeric_limits::max(); for(auto dir : qAsConst(d->searchDirs)) { QDir searchDir(dir, QStringLiteral("%1*.qml").arg(QString::fromLatin1(cName)), QDir::NoSort, QDir::Files | QDir::NoDotAndDotDot | QDir::Readable); QDirIterator iterator(searchDir, QDirIterator::Subdirectories); - if(iterator.hasNext()) { + while(iterator.hasNext()) { iterator.next(); - QUrl resUrl; - if(dir.startsWith(QStringLiteral(":"))) { - resUrl.setScheme(QStringLiteral("qrc")); - resUrl.setPath(iterator.filePath().mid(1)); //skip the beginning colon - } else - resUrl = QUrl::fromLocalFile(iterator.filePath()); - logDebug() << "Found URL for viewmodel" - << viewModelType->className() - << "as:" << resUrl; - return resUrl; + if(iterator.fileName().size() < shortest) { + if(dir.startsWith(QStringLiteral(":"))) { + resUrl.clear(); + resUrl.setScheme(QStringLiteral("qrc")); + resUrl.setPath(iterator.filePath().mid(1)); //skip the beginning colon + } else + resUrl = QUrl::fromLocalFile(iterator.filePath()); + } } } + if(resUrl.isValid()) { + logDebug() << "Found URL for viewmodel" + << viewModelType->className() + << "as:" << resUrl; + return resUrl; + } } currentMeta = currentMeta->superClass();