1
0
Fork 0
mirror of https://git.jami.net/savoirfairelinux/jami-client-qt.git synced 2025-04-21 21:52:03 +02:00
jami-client-qt/src/app/ViewCoordinator.qml
Sébastien Blin 84150e8977 misc: bump copyright to 2024
Change-Id: I8d5f968fbedbc884c91416246049a0ef4cd652eb
2024-01-03 09:54:49 -05:00

210 lines
7.5 KiB
QML

/*
* Copyright (C) 2024 Savoir-faire Linux Inc.
*
* 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 3 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, see <https://www.gnu.org/licenses/>.
*/
import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
import net.jami.Constants 1.1
import net.jami.Models 1.1
import "commoncomponents"
QtObject {
id: root
required property QtObject viewManager
signal initialized
function requestAppWindowWizardView() {
viewCoordinator.present("WizardView");
}
// A map of view names to file paths for QML files that define each view.
property variant resources: {
"SidePanel": "mainview/components/SidePanel.qml",
"WelcomePage": "mainview/components/WelcomePage.qml",
"ConversationView": "mainview/ConversationView.qml",
"NewSwarmPage": "mainview/components/NewSwarmPage.qml",
"WizardView": "wizardview/WizardView.qml",
"AccountMigrationView": "AccountMigrationView.qml",
"SettingsView": "settingsview/SettingsView.qml",
"SettingsSidePanel": "settingsview/SettingsSidePanel.qml"
}
// The `main` view of the application window.
property StackView rootView
property var currentViewName: rootView && rootView.currentItem && rootView.currentItem.objectName || null
function init(mainStackView) {
rootView = Qt.createQmlObject(`import QtQuick; import QtQuick.Controls
StackView { anchors.fill: parent }`, mainStackView);
initialized();
}
function deinit() {
viewManager.destroyAllViews();
if (rootView)
rootView.destroy();
}
// Finds a view and gets its index within the StackView it's in.
function getStackIndex(viewName) {
for (const [key, value] of Object.entries(viewManager.views)) {
if (value.objectName === viewName) {
return value.StackView.index;
}
}
return -1;
}
// Create, present, and return a dialog object.
function presentDialog(parent, path, props = {}) {
// Open the dialog once the object is created
return viewManager.createUniqueView(path, parent, function (obj) {
const doneCb = function () {
viewManager.destroyView(path);
};
if (obj.closed !== undefined) {
obj.closed.connect(doneCb);
} else {
if (obj.accepted !== undefined) {
obj.accepted.connect(doneCb);
}
if (obj.rejected !== undefined) {
obj.rejected.connect(doneCb);
}
}
obj.open();
}, props);
}
// Present a view by name.
function present(viewName, props) {
const path = resources[viewName];
// Check if the current view should inhibit the presentation of this view.
if (rootView.currentItem && rootView.currentItem.inhibits.includes(viewName)) {
print("inhibiting view:", viewName);
return;
}
// If the view already exists in the StackView, the function will attempt
// to navigate to its StackView position by dismissing elevated views.
if (rootView.find(function (item) {
return item.objectName === viewName;
}, StackView.DontLoad)) {
const viewIndex = getStackIndex(viewName);
for (var i = (rootView.depth - 1); i > viewIndex; i--) {
dismissObj(rootView.get(i, StackView.DontLoad));
}
return;
}
if (!viewManager.createView(path, rootView, function (view) {
// push the view onto the stack if it's not already there
if (rootView.currentItem !== view) {
rootView.push(view, StackView.Immediate);
}
if (!view.managed)
view.presented();
}, props)) {
print("could not create view:", viewName);
}
}
// Dismiss by object.
function dismissObj(obj) {
// Check if it makes sense to remove this view at all.
if (obj.StackView.view !== rootView || !viewManager.viewCount()) {
return;
}
// If we are dismissing a view that is not at the top of the stack,
// we need to store each of the views on top into a temporary stack
// and then restore them after the view is dismissed.
const viewIndex = obj.StackView.index;
var tempStack = [];
for (var i = (rootView.depth - 1); i > viewIndex; i--) {
var item = rootView.pop(StackView.Immediate);
tempStack.push(item);
}
// And we define a function to restore and resolve the views.
var resolveStack = () => {
for (var i = 0; i < tempStack.length; i++) {
rootView.push(tempStack[i], StackView.Immediate);
}
if (rootView.depth > 0)
rootView.currentItem.presented();
};
// Now we can dismiss the view at the top of the stack.
const depth = rootView.depth;
if (obj === rootView.get(depth - 1, StackView.DontLoad)) {
var view;
if (rootView.depth === 1) {
view = rootView.currentItem;
rootView.clear();
} else
view = rootView.pop(StackView.Immediate);
if (!view) {
print("could not pop view:", obj.objectName);
resolveStack();
return;
}
// If the view is managed, we can destroy it, otherwise, it can
// be reused and destroyed by it's parent.
if (view.managed) {
var objectName = view ? view.objectName : obj.objectName;
if (!viewManager.destroyView(resources[objectName])) {
print("could not destroy view:", objectName);
}
} else
view.dismissed();
}
resolveStack();
}
// Dismiss a view by name or the top view if unspecified.
function dismiss(viewName = undefined) {
if (!rootView || rootView.depth === 0)
return;
if (viewName !== undefined) {
const depth = rootView.depth;
for (var i = (depth - 1); i >= 0; i--) {
const view = rootView.get(i, StackView.DontLoad);
if (view.objectName === viewName) {
dismissObj(view);
return;
}
}
return;
} else {
dismissObj(rootView.currentItem);
}
}
function getView(viewName) {
return viewManager.getView(viewName);
}
// Load a view without presenting it.
function preload(viewName) {
if (!viewManager.createView(resources[viewName], null)) {
console.log("Failed to load view: " + viewName);
}
}
}