diff options
Diffstat (limited to 'examples/quickcontrols2/ios')
37 files changed, 1022 insertions, 0 deletions
diff --git a/examples/quickcontrols2/ios/todolist/AppSettings.qml b/examples/quickcontrols2/ios/todolist/AppSettings.qml new file mode 100644 index 0000000000..c732b9fbc8 --- /dev/null +++ b/examples/quickcontrols2/ios/todolist/AppSettings.qml @@ -0,0 +1,14 @@ +// Copyright (C) 2022 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only + +pragma Singleton + +import Qt.labs.settings + +Settings { + // The properties here are given default values to account for the first run of the application. + // After the application has run once, future values will come from the stored settings. + property bool showDoneTasks: true + property int maxTasks: 30 + property int fontSize: 18 +} diff --git a/examples/quickcontrols2/ios/todolist/CMakeLists.txt b/examples/quickcontrols2/ios/todolist/CMakeLists.txt new file mode 100644 index 0000000000..413ea6ad97 --- /dev/null +++ b/examples/quickcontrols2/ios/todolist/CMakeLists.txt @@ -0,0 +1,84 @@ +cmake_minimum_required(VERSION 3.18) +project(todolist LANGUAGES CXX) + +set(CMAKE_AUTOMOC ON) + +if(NOT DEFINED INSTALL_EXAMPLESDIR) + set(INSTALL_EXAMPLESDIR "examples") +endif() + +set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/todolist") + +find_package(Qt6 COMPONENTS Gui Qml Quick QuickControls2) + +qt_add_executable(todolist + src/main.cpp +) + +set_target_properties(todolist PROPERTIES + WIN32_EXECUTABLE TRUE + MACOSX_BUNDLE TRUE +) + +target_link_libraries(todolist PUBLIC + Qt${QT_VERSION_MAJOR}::Core + Qt${QT_VERSION_MAJOR}::Gui + Qt${QT_VERSION_MAJOR}::Qml + Qt${QT_VERSION_MAJOR}::Quick + Qt${QT_VERSION_MAJOR}::QuickControls2 +) + +set_source_files_properties(AppSettings.qml PROPERTIES + QT_QML_SINGLETON_TYPE TRUE +) + +set_source_files_properties(Database.qml PROPERTIES + QT_QML_SINGLETON_TYPE TRUE +) + +qt_add_qml_module(todolist + URI App + VERSION 1.0 + QML_FILES + AppSettings.qml + Database.qml + FontSizePage.qml + HomePage.qml + MaxTasksPage.qml + NavBar.qml + ProjectPage.qml + SettingsPage.qml + ToggleCompletedTasksPage.qml + main.qml + RESOURCES + images/back.png + images/back@2x.png + images/back@3x.png + images/back-white.png + images/back-white@2x.png + images/back-white@3x.png + images/close.png + images/close@2x.png + images/close@3x.png + images/close-white.png + images/close-white@2x.png + images/close-white@3x.png + images/plus-math.png + images/plus-math@2x.png + images/plus-math@3x.png + images/settings.png + images/settings@2x.png + images/settings@3x.png + images/add-new.png + images/add-new@2x.png + images/add-new@3x.png + NO_RESOURCE_TARGET_PATH +) + +set_property(GLOBAL PROPERTY XCODE_EMIT_EFFECTIVE_PLATFORM_NAME ON) + +install(TARGETS todolist + RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}" + BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}" + LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}" +) diff --git a/examples/quickcontrols2/ios/todolist/Database.qml b/examples/quickcontrols2/ios/todolist/Database.qml new file mode 100644 index 0000000000..31bbd8c1e7 --- /dev/null +++ b/examples/quickcontrols2/ios/todolist/Database.qml @@ -0,0 +1,161 @@ +// Copyright (C) 2022 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only + +pragma Singleton + +import QtQml +import QtQuick.LocalStorage + +QtObject { + id: root + + property var _db + + function _database() { + if (_db) + return _db + + try { + let db = LocalStorage.openDatabaseSync("ToDoList", "1.0", "ToDoList application database") + + db.transaction(function (tx) { + tx.executeSql(`CREATE TABLE IF NOT EXISTS projects ( + project_id INTEGER PRIMARY KEY AUTOINCREMENT, + project_name TEXT NOT NULL CHECK(project_name != ''), + project_note TEXT + )`); + }) + + db.transaction(function (tx) { + tx.executeSql(`CREATE TABLE IF NOT EXISTS tasks ( + task_id INTEGER PRIMARY KEY AUTOINCREMENT, + task_name TEXT CHECK(task_name != ''), + done INTEGER, + project_id, + FOREIGN KEY(project_id) REFERENCES projects(project_id) + )`); + }) + + _db = db + } catch (error) { + console.log("Error opening database: " + error) + }; + + return _db + } + + function getProjects() { + let projects = [] + root._database().transaction(function (tx) { + let results = tx.executeSql('SELECT * FROM projects') + for (let i = 0; i < results.rows.length; i++) { + let projectRow = results.rows.item(i) + let projectId = projectRow.project_id + let completedTasks = Math.max(countDoneTasksByProject(projectId).rows.length, 0) + let totalTasks = Math.max(countTaskByProject(projectId).rows.length, 0) + projects.push({ + "projectName": projectRow.project_name, + "projectId": projectId, + "projectNote": projectRow.project_note ?? "", + "completedTasks": completedTasks, + "totalTasks": totalTasks + }) + } + }) + return projects + } + + function newProject(projectName) { + let results + root._database().transaction(function (tx) { + results = tx.executeSql("INSERT INTO projects (project_name) VALUES(?)", [projectName]) + }) + return results + } + + function updateProjectNote(projectId, projectNote) { + root._database().transaction(function (tx) { + tx.executeSql("UPDATE projects set project_note=? WHERE project_id=?", [projectNote, projectId]) + }) + } + + function updateProjectName(projectId, projectName) { + root._database().transaction(function (tx) { + tx.executeSql("UPDATE projects set project_name=? WHERE project_id=?", [projectName, projectId]) + }) + } + + function deleteProject(projectId) { + root._database().transaction(function (tx) { + deleteAllTasks(projectId) + tx.executeSql("DELETE FROM projects WHERE project_id = ?", [projectId]) + }) + } + + function getTaskByProject(projectId) { + if (!projectId) + return + + let tasks = [] + root._database().transaction(function (tx) { + let results = tx.executeSql("SELECT * FROM tasks WHERE project_id = " + [projectId] + " ORDER BY done") + for (let i = 0; i < results.rows.length; i++) { + let row = results.rows.item(i) + tasks.push({ + "taskId": row.task_id, + "taskName": row.task_name, + "done": row.done === 1 ? true : false + }) + } + }) + return tasks + } + + function countTaskByProject(projectId) { + let results + root._database().transaction(function (tx) { + results = tx.executeSql('SELECT task_id FROM tasks WHERE project_id =' + [projectId]) + }) + return results + } + + function countDoneTasksByProject(projectId) { + let results + root._database().transaction(function (tx) { + results = tx.executeSql("SELECT task_id FROM tasks WHERE project_id =" + [projectId] + " AND done = 1") + }) + return results + } + + function newTask(projectId, taskName) { + let results + root._database().transaction(function (tx) { + results = tx.executeSql("INSERT INTO tasks (task_name, done, project_id) VALUES(?, 0, ?)", [taskName, projectId]) + }) + return results + } + + function updateTaskName(taskId, taskName) { + root._database().transaction(function (tx) { + tx.executeSql("UPDATE tasks set task_name=? WHERE task_id=?", [taskName, taskId]) + }) + } + + function updateDoneState(taskId, doneState) { + root._database().transaction(function (tx) { + tx.executeSql("UPDATE tasks set done=? WHERE task_id=?", [doneState, taskId]) + }) + } + + function deleteAllTasks(projectId) { + root._database().transaction(function (tx) { + tx.executeSql("DELETE FROM tasks WHERE project_id =" + projectId) + }) + } + + function deleteTask(taskId) { + root._database().transaction(function (tx) { + tx.executeSql("DELETE FROM tasks WHERE task_id = ?", [taskId]) + }) + } +} diff --git a/examples/quickcontrols2/ios/todolist/FontSizePage.qml b/examples/quickcontrols2/ios/todolist/FontSizePage.qml new file mode 100644 index 0000000000..2b0e5b16db --- /dev/null +++ b/examples/quickcontrols2/ios/todolist/FontSizePage.qml @@ -0,0 +1,44 @@ +// Copyright (C) 2022 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only + +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts + +Page { + Frame { + width: parent.width - 60 + anchors.centerIn: parent + topPadding: 12 + bottomPadding: 12 + + RowLayout { + anchors.fill: parent + spacing: 12 + + Label { + text: qsTr("A") + font.pointSize: 15 + font.weight: 400 + } + + Slider { + snapMode: Slider.SnapAlways + stepSize: 1 + from: 15 + value: AppSettings.fontSize + to: 21 + + Layout.fillWidth: true + + onMoved: AppSettings.fontSize = value + } + + Label { + text: qsTr("A") + font.pointSize: 21 + font.weight: 400 + } + } + } +} diff --git a/examples/quickcontrols2/ios/todolist/HomePage.qml b/examples/quickcontrols2/ios/todolist/HomePage.qml new file mode 100644 index 0000000000..4df6f90b7a --- /dev/null +++ b/examples/quickcontrols2/ios/todolist/HomePage.qml @@ -0,0 +1,168 @@ +// Copyright (C) 2022 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only + +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts +import QtQuick.LocalStorage +import QtQuick.Controls.iOS + +Page { + id: root + + header: Label { + text: qsTr("Projects") + font.pointSize: AppSettings.fontSize + 20 + font.styleName: "Semibold" + leftPadding: 30 + topPadding: 20 + bottomPadding: 20 + } + + ListView { + id: projectListView + anchors.fill: parent + clip: true + + model: ListModel { + id: projectsModel + + Component.onCompleted: { + let projects = Database.getProjects() + for (let project of projects) + append(project) + } + } + + delegate: SwipeDelegate { + id: projectDelegate + width: ListView.view.width + height: projectContent.implicitHeight + + required property int index + required property int projectId + required property string projectName + required property int completedTasks + required property int totalTasks + + swipe.right: Rectangle { + width: 50 + height: parent.height + color: "red" + anchors.right: parent.right + + SwipeDelegate.onClicked: { + Database.deleteProject(projectDelegate.projectId) + projectsModel.remove(projectDelegate.index, 1) + } + + Image { + source: IOS.theme === IOS.Dark ? "images/close-white.png" + : "images/close.png" + width: 20 + height: 20 + anchors.centerIn: parent + } + } + + Column { + id: projectContent + topPadding: 8 + bottomPadding: 10 + leftPadding: 30 + + Label { + text: completedTasks + " / " + totalTasks + font.pointSize: AppSettings.fontSize + } + + Label { + id: project + text: projectName + font.pointSize: AppSettings.fontSize + font.styleName: "Semibold" + } + } + + Connections { + target: projectDelegate + function onClicked() { + let project = projectsModel.get(index) + root.StackView.view.push("ProjectPage.qml", { + "projectsModel": projectsModel, + "projectId": project.projectId, + "projectName": project.projectName, + "projectIndex": index, + "projectNote": project.projectNote, + "completedTasks": project.completedTasks, + "totalTasks": project.totalTasks + }) + } + } + } + } + + Popup { + id: newProjectPopup + anchors.centerIn: parent + height: 200 + modal: true + + ColumnLayout { + anchors.fill: parent + + Label { + text: qsTr("Project Name") + font.pointSize: AppSettings.fontSize + 2.0 + font.bold: true + + Layout.alignment: Qt.AlignHCenter + } + + TextField { + id: newProjectTextField + placeholderText: qsTr("Enter project name") + font.pointSize: AppSettings.fontSize + + Layout.fillWidth: true + Layout.leftMargin: 10 + Layout.rightMargin: 10 + } + + Button { + id: createProjectButton + text: qsTr("Create project") + flat: true + font.pointSize: AppSettings.fontSize + enabled: newProjectTextField.length > 0 + + Layout.alignment: Qt.AlignHCenter + + onClicked: { + let results = Database.newProject(newProjectTextField.text) + projectsModel.append({ + projectId: parseInt(results.insertId), + projectName: newProjectTextField.text, + totalTasks: 0, + completedTasks: 0, + projectNote: "" + }) + newProjectTextField.text = "" + newProjectPopup.close() + } + } + } + } + + footer: ToolBar { + ToolButton { + anchors.right: parent.right + anchors.rightMargin: 5 + text: qsTr("New project") + font.pointSize: AppSettings.fontSize - 2 + icon.source: "images/add-new.png" + + onClicked: newProjectPopup.open() + } + } +} diff --git a/examples/quickcontrols2/ios/todolist/MaxTasksPage.qml b/examples/quickcontrols2/ios/todolist/MaxTasksPage.qml new file mode 100644 index 0000000000..509a460357 --- /dev/null +++ b/examples/quickcontrols2/ios/todolist/MaxTasksPage.qml @@ -0,0 +1,36 @@ +// Copyright (C) 2022 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only + +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts + +Page { + ColumnLayout { + width: parent.width + anchors.verticalCenter: parent.verticalCenter + + Label { + id: maxTasksText + horizontalAlignment: Text.AlignHCenter + wrapMode: Text.Wrap + text: qsTr("Choose the maximum amount of tasks each project can have.") + font.pointSize: AppSettings.fontSize + + Layout.fillWidth: true + } + + SpinBox { + id: maxTasksSpinbox + editable: true + from: 5 + value: AppSettings.maxTasks + to: 30 + + Layout.alignment: Qt.AlignHCenter + Layout.topMargin: 10 + + onValueModified: AppSettings.maxTasks = maxTasksSpinbox.value + } + } +} diff --git a/examples/quickcontrols2/ios/todolist/NavBar.qml b/examples/quickcontrols2/ios/todolist/NavBar.qml new file mode 100644 index 0000000000..4f57353dca --- /dev/null +++ b/examples/quickcontrols2/ios/todolist/NavBar.qml @@ -0,0 +1,44 @@ +// Copyright (C) 2022 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only + +import QtQuick +import QtQuick.Controls + +ToolBar { + id: root + width: parent.width + + required property StackView stackView + + ToolButton { + enabled: root.stackView.depth >= 2 + anchors.left: parent.left + anchors.leftMargin: 5 + visible: root.stackView.depth >= 2 + anchors.verticalCenter: parent.verticalCenter + display: AbstractButton.TextBesideIcon + text: root.stackView.depth > 2 ? qsTr("Back") : qsTr("Home") + font.pointSize: AppSettings.fontSize + icon.source: "images/back.png" + icon.height: 20 + icon.width: 20 + + onClicked: root.stackView.pop() + } + + ToolButton { + anchors.right: parent.right + anchors.rightMargin: 5 + icon.source: "images/settings.png" + icon.height: 20 + icon.width: 20 + visible: { + // Force the binding to re-evaluate so that the title check is run each time the page changes. + root.stackView.currentItem + !root.stackView.find((item, index) => { return item.title === "settingsPage" }) + } + + onClicked: root.stackView.push("SettingsPage.qml") + } +} + diff --git a/examples/quickcontrols2/ios/todolist/ProjectPage.qml b/examples/quickcontrols2/ios/todolist/ProjectPage.qml new file mode 100644 index 0000000000..ca86ea521a --- /dev/null +++ b/examples/quickcontrols2/ios/todolist/ProjectPage.qml @@ -0,0 +1,239 @@ +// Copyright (C) 2022 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only + +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts +import QtQuick.Controls.iOS + +Page { + id: root + + required property int projectIndex + required property int projectId + required property string projectName + required property string projectNote + + required property int completedTasks + required property int totalTasks + + required property ListModel projectsModel + + header: ColumnLayout { + id: titleRow + spacing: 4 + + TextField { + id: projectNameLabel + Layout.fillWidth: true + text: root.projectName + font.pointSize: AppSettings.fontSize + 10 + font.styleName: "Bold" + padding: 0 + background: null + wrapMode: TextField.Wrap + + Layout.topMargin: 10 + Layout.leftMargin: 20 + Layout.rightMargin: 20 + + onEditingFinished: { + Database.updateProjectName(root.projectId, text) + projectsModel.setProperty(projectIndex, "projectName", projectNameLabel.text) + } + } + + Label { + text: root.completedTasks + " / " + root.totalTasks + Layout.leftMargin: 20 + } + + ProgressBar { + id: progressBar + from: 0 + value: root.completedTasks + to: root.totalTasks + Layout.leftMargin: 20 + } + } + + ColumnLayout { + anchors.fill: parent + + TextArea { + id: textArea + leftPadding: 15 + rightPadding: 15 + bottomPadding: 10 + topPadding: 10 + font.pointSize: AppSettings.fontSize + placeholderText: qsTr("Write a note...") + text: root.projectNote + wrapMode: TextArea.Wrap + + Layout.fillWidth: true + Layout.preferredHeight: 80 + Layout.topMargin: 20 + + onEditingFinished: { + Database.updateProjectNote(root.projectId, text) + projectsModel.setProperty(projectIndex, "projectNote", textArea.text) + } + } + + ListView { + id: taskListView + model: taskModel + clip: true + + Layout.fillWidth: true + Layout.fillHeight: true + Layout.topMargin: 20 + + ListModel { + id: taskModel + + Component.onCompleted: { + let tasks = Database.getTaskByProject(projectId) + for (let task of tasks) + append(task) + } + } + + delegate: CheckDelegate { + id: taskList + width: taskListView.width + height: visible ? 40 : 0 + checked: done + visible: !done || (done && AppSettings.showDoneTasks) + + required property bool done + required property int taskId + required property string taskName + required property int index + + onClicked: { + Database.updateDoneState(taskId, checked ? 1 : 0) + taskModel.setProperty(index, "done", checked) + root.completedTasks = Math.max(Database.countDoneTasksByProject(root.projectId).rows.length, 0) + root.totalTasks = Math.max(Database.countTaskByProject(root.projectId).rows.length, 0) + root.projectsModel.setProperty(projectIndex, "completedTasks", root.completedTasks) + } + + TextField { + id: taskNameLabel + text: taskList.taskName + anchors.left: deleteTaskButton.right + anchors.leftMargin: 10 + padding: 0 + font.pointSize: AppSettings.fontSize + anchors.verticalCenter: parent.verticalCenter + background: null + + onEditingFinished: { + Database.updateTaskName(taskList.taskId, taskNameLabel.text) + taskModel.setProperty(index, "taskName", taskNameLabel.text) + } + } + + Button { + id: deleteTaskButton + anchors.left: parent.left + width: 15 + height: 15 + flat: true + topPadding: 0 + bottomPadding: 0 + rightPadding: 0 + leftPadding: 0 + anchors.leftMargin: 10 + anchors.verticalCenter: parent.verticalCenter + icon.source: "images/close.png" + icon.color: IOS.theme === IOS.Dark ? "white" : "black" + + onClicked: { + Database.deleteTask(taskList.taskId) + taskModel.remove(index, 1) + root.totalTasks-- + if (taskList.done) + root.completedTasks-- + } + } + } + } + + Popup { + id: addTaskPopup + parent: root + anchors.centerIn: parent + height: 200 + modal: true + focus: true + + ColumnLayout { + anchors.fill: parent + + Label { + text: qsTr("Add New Task") + font.pointSize: AppSettings.fontSize + 2.0 + font.bold: true + + Layout.alignment: Qt.AlignHCenter + } + + TextField { + id: newTaskNameTextField + placeholderText: qsTr("Enter task name") + font.pointSize: AppSettings.fontSize + + Layout.fillWidth: true + Layout.leftMargin: 10 + Layout.rightMargin: 10 + Layout.alignment: Qt.AlignHCenter + } + + Button { + text: qsTr("Add task") + flat: true + font.pointSize: AppSettings.fontSize + enabled: newTaskNameTextField.length > 0 + + Layout.alignment: Qt.AlignHCenter + + onClicked: { + const result = Database.newTask(root.projectId, newTaskNameTextField.text) + taskModel.append({ + "taskId": parseInt(result.insertId), + "taskName": newTaskNameTextField.text, "done": false + }) + root.projectsModel.setProperty(projectIndex, "totalTasks", taskListView.count) + newTaskNameTextField.text = "" + root.totalTasks++ + addTaskPopup.close() + } + } + } + } + + Label { + text: qsTr("Task limit reached.") + Layout.alignment: Qt.AlignHCenter + Layout.bottomMargin: 20 + font.pointSize: AppSettings.fontSize + visible: taskListView.count >= AppSettings.maxTasks + } + } + + footer: ToolBar { + ToolButton { + anchors.right: parent.right + anchors.rightMargin: 5 + text: qsTr("New task") + font.pointSize: AppSettings.fontSize - 2 + icon.source: "images/add-new.png" + enabled: taskListView.count < AppSettings.maxTasks + + onClicked: addTaskPopup.open() + } + } +} diff --git a/examples/quickcontrols2/ios/todolist/SettingsPage.qml b/examples/quickcontrols2/ios/todolist/SettingsPage.qml new file mode 100644 index 0000000000..85e8ed2125 --- /dev/null +++ b/examples/quickcontrols2/ios/todolist/SettingsPage.qml @@ -0,0 +1,68 @@ +// Copyright (C) 2022 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only + +import QtQuick +import QtQuick.Controls +import QtQuick.Controls.iOS + +Page { + title: "settingsPage" + + property bool showDoneTasks: true + + header: Label { + text: qsTr("Settings") + font.pointSize: AppSettings.fontSize + 20 + font.styleName: "Semibold" + leftPadding: 20 + topPadding: 20 + } + + ListView { + anchors.fill: parent + topMargin: 20 + model: listModel + clip: true + + ListModel { + id: listModel + ListElement { + setting: qsTr("Font size") + page: "FontSize" + } + + ListElement { + setting: qsTr("Maximum number of tasks per project") + page: "MaxTasks" + } + + ListElement { + setting: qsTr("Show completed tasks") + page: "ToggleCompletedTasks" + } + } + + delegate: ItemDelegate { + width: parent.width + text: setting + font.pointSize: AppSettings.fontSize + + onClicked: stackView.push(page + "Page.qml") + + required property string setting + required property string page + + Image { + source: IOS.theme === IOS.Dark ? "images/back-white.png" + : "images/back.png" + width: 20 + height: 20 + anchors.right: parent.right + anchors.rightMargin: 10 + fillMode: Image.PreserveAspectFit + anchors.verticalCenter: parent.verticalCenter + mirror: true + } + } + } +} diff --git a/examples/quickcontrols2/ios/todolist/ToggleCompletedTasksPage.qml b/examples/quickcontrols2/ios/todolist/ToggleCompletedTasksPage.qml new file mode 100644 index 0000000000..df2145866a --- /dev/null +++ b/examples/quickcontrols2/ios/todolist/ToggleCompletedTasksPage.qml @@ -0,0 +1,34 @@ +// Copyright (C) 2022 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only + +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts + +Page { + ColumnLayout { + width: parent.width + anchors.verticalCenter: parent.verticalCenter + + Label { + id: toggleText + horizontalAlignment: Text.AlignHCenter + wrapMode: Text.Wrap + text: toggleTasksSwitch.checked ? qsTr("Completed tasks will be shown.") + : qsTr("Completed tasks will be hidden.") + font.pointSize: AppSettings.fontSize + + Layout.fillWidth: true + } + + Switch { + id: toggleTasksSwitch + checked: AppSettings.showDoneTasks + + Layout.alignment: Qt.AlignHCenter + Layout.topMargin: 10 + + onClicked: AppSettings.showDoneTasks = checked + } + } +} diff --git a/examples/quickcontrols2/ios/todolist/doc/images/qtquickcontrols2-todolist.png b/examples/quickcontrols2/ios/todolist/doc/images/qtquickcontrols2-todolist.png Binary files differnew file mode 100644 index 0000000000..5be7190a43 --- /dev/null +++ b/examples/quickcontrols2/ios/todolist/doc/images/qtquickcontrols2-todolist.png diff --git a/examples/quickcontrols2/ios/todolist/doc/src/qtquickcontrols2-todolist.qdoc b/examples/quickcontrols2/ios/todolist/doc/src/qtquickcontrols2-todolist.qdoc new file mode 100644 index 0000000000..12e2d4fca5 --- /dev/null +++ b/examples/quickcontrols2/ios/todolist/doc/src/qtquickcontrols2-todolist.qdoc @@ -0,0 +1,22 @@ +// Copyright (C) 2022 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only + +/*! + \example ios/todolist + \keyword Qt Quick Controls - To Do List + \title Qt Quick Controls - To Do List + \keyword Qt Quick Controls 2 - To Do List + \ingroup qtquickcontrols2-examples + \brief To do list application for iOS. + + This example demonstrates how to create a simple to do list application for + iOS using the \l {iOS Style}. + + \image qtquickcontrols2-todolist.png + + The example also shows how an in-memory SQL database can be created and + used purely through QML, without needing C++, through the use of + \l {Qt Quick Local Storage QML Types}{LocalStorage}. + + \include examples-run.qdocinc +*/ diff --git a/examples/quickcontrols2/ios/todolist/images/add-new.png b/examples/quickcontrols2/ios/todolist/images/add-new.png Binary files differnew file mode 100644 index 0000000000..2e60e48a2d --- /dev/null +++ b/examples/quickcontrols2/ios/todolist/images/add-new.png diff --git a/examples/quickcontrols2/ios/todolist/images/add-new@2x.png b/examples/quickcontrols2/ios/todolist/images/add-new@2x.png Binary files differnew file mode 100644 index 0000000000..edb8b62847 --- /dev/null +++ b/examples/quickcontrols2/ios/todolist/images/add-new@2x.png diff --git a/examples/quickcontrols2/ios/todolist/images/add-new@3x.png b/examples/quickcontrols2/ios/todolist/images/add-new@3x.png Binary files differnew file mode 100644 index 0000000000..b5b9b6a5d6 --- /dev/null +++ b/examples/quickcontrols2/ios/todolist/images/add-new@3x.png diff --git a/examples/quickcontrols2/ios/todolist/images/back-white.png b/examples/quickcontrols2/ios/todolist/images/back-white.png Binary files differnew file mode 100644 index 0000000000..503bdf4d48 --- /dev/null +++ b/examples/quickcontrols2/ios/todolist/images/back-white.png diff --git a/examples/quickcontrols2/ios/todolist/images/back-white@2x.png b/examples/quickcontrols2/ios/todolist/images/back-white@2x.png Binary files differnew file mode 100644 index 0000000000..e201ec6d5b --- /dev/null +++ b/examples/quickcontrols2/ios/todolist/images/back-white@2x.png diff --git a/examples/quickcontrols2/ios/todolist/images/back-white@3x.png b/examples/quickcontrols2/ios/todolist/images/back-white@3x.png Binary files differnew file mode 100644 index 0000000000..eb8b7ffc68 --- /dev/null +++ b/examples/quickcontrols2/ios/todolist/images/back-white@3x.png diff --git a/examples/quickcontrols2/ios/todolist/images/back.png b/examples/quickcontrols2/ios/todolist/images/back.png Binary files differnew file mode 100644 index 0000000000..94580efd7f --- /dev/null +++ b/examples/quickcontrols2/ios/todolist/images/back.png diff --git a/examples/quickcontrols2/ios/todolist/images/back@2x.png b/examples/quickcontrols2/ios/todolist/images/back@2x.png Binary files differnew file mode 100644 index 0000000000..b5cf424e91 --- /dev/null +++ b/examples/quickcontrols2/ios/todolist/images/back@2x.png diff --git a/examples/quickcontrols2/ios/todolist/images/back@3x.png b/examples/quickcontrols2/ios/todolist/images/back@3x.png Binary files differnew file mode 100644 index 0000000000..50d5102f4e --- /dev/null +++ b/examples/quickcontrols2/ios/todolist/images/back@3x.png diff --git a/examples/quickcontrols2/ios/todolist/images/close-white.png b/examples/quickcontrols2/ios/todolist/images/close-white.png Binary files differnew file mode 100644 index 0000000000..72163067a6 --- /dev/null +++ b/examples/quickcontrols2/ios/todolist/images/close-white.png diff --git a/examples/quickcontrols2/ios/todolist/images/close-white@2x.png b/examples/quickcontrols2/ios/todolist/images/close-white@2x.png Binary files differnew file mode 100644 index 0000000000..54828e84d1 --- /dev/null +++ b/examples/quickcontrols2/ios/todolist/images/close-white@2x.png diff --git a/examples/quickcontrols2/ios/todolist/images/close-white@3x.png b/examples/quickcontrols2/ios/todolist/images/close-white@3x.png Binary files differnew file mode 100644 index 0000000000..dd67cf1b69 --- /dev/null +++ b/examples/quickcontrols2/ios/todolist/images/close-white@3x.png diff --git a/examples/quickcontrols2/ios/todolist/images/close.png b/examples/quickcontrols2/ios/todolist/images/close.png Binary files differnew file mode 100644 index 0000000000..eba32b637d --- /dev/null +++ b/examples/quickcontrols2/ios/todolist/images/close.png diff --git a/examples/quickcontrols2/ios/todolist/images/close@2x.png b/examples/quickcontrols2/ios/todolist/images/close@2x.png Binary files differnew file mode 100644 index 0000000000..72cf76317a --- /dev/null +++ b/examples/quickcontrols2/ios/todolist/images/close@2x.png diff --git a/examples/quickcontrols2/ios/todolist/images/close@3x.png b/examples/quickcontrols2/ios/todolist/images/close@3x.png Binary files differnew file mode 100644 index 0000000000..6cb2ea58d9 --- /dev/null +++ b/examples/quickcontrols2/ios/todolist/images/close@3x.png diff --git a/examples/quickcontrols2/ios/todolist/images/plus-math.png b/examples/quickcontrols2/ios/todolist/images/plus-math.png Binary files differnew file mode 100644 index 0000000000..b0d182d23e --- /dev/null +++ b/examples/quickcontrols2/ios/todolist/images/plus-math.png diff --git a/examples/quickcontrols2/ios/todolist/images/plus-math@2x.png b/examples/quickcontrols2/ios/todolist/images/plus-math@2x.png Binary files differnew file mode 100644 index 0000000000..112a132084 --- /dev/null +++ b/examples/quickcontrols2/ios/todolist/images/plus-math@2x.png diff --git a/examples/quickcontrols2/ios/todolist/images/plus-math@3x.png b/examples/quickcontrols2/ios/todolist/images/plus-math@3x.png Binary files differnew file mode 100644 index 0000000000..ca513d200b --- /dev/null +++ b/examples/quickcontrols2/ios/todolist/images/plus-math@3x.png diff --git a/examples/quickcontrols2/ios/todolist/images/settings.png b/examples/quickcontrols2/ios/todolist/images/settings.png Binary files differnew file mode 100644 index 0000000000..600981fb35 --- /dev/null +++ b/examples/quickcontrols2/ios/todolist/images/settings.png diff --git a/examples/quickcontrols2/ios/todolist/images/settings@2x.png b/examples/quickcontrols2/ios/todolist/images/settings@2x.png Binary files differnew file mode 100644 index 0000000000..80541aa028 --- /dev/null +++ b/examples/quickcontrols2/ios/todolist/images/settings@2x.png diff --git a/examples/quickcontrols2/ios/todolist/images/settings@3x.png b/examples/quickcontrols2/ios/todolist/images/settings@3x.png Binary files differnew file mode 100644 index 0000000000..48c2b2a8c0 --- /dev/null +++ b/examples/quickcontrols2/ios/todolist/images/settings@3x.png diff --git a/examples/quickcontrols2/ios/todolist/main.qml b/examples/quickcontrols2/ios/todolist/main.qml new file mode 100644 index 0000000000..a0067643f1 --- /dev/null +++ b/examples/quickcontrols2/ios/todolist/main.qml @@ -0,0 +1,32 @@ +// Copyright (C) 2022 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only + +import QtQuick +import QtQuick.Window +import QtQuick.Controls + +ApplicationWindow { + width: 390 + height: 844 + visible: true + title: "To Do List" + + header: NavBar { + stackView: stackView + } + + Flickable { + width: parent.width + height: parent.height + flickableDirection: Flickable.VerticalFlick + boundsBehavior: Flickable.StopAtBounds + + ScrollIndicator.vertical: ScrollIndicator {} + + StackView { + id: stackView + anchors.fill: parent + initialItem: HomePage {} + } + } +} diff --git a/examples/quickcontrols2/ios/todolist/qmldir b/examples/quickcontrols2/ios/todolist/qmldir new file mode 100644 index 0000000000..e0c443110e --- /dev/null +++ b/examples/quickcontrols2/ios/todolist/qmldir @@ -0,0 +1,2 @@ +singleton Database 1.0 Database.qml +singleton AppSettings 1.0 AppSettings.qml diff --git a/examples/quickcontrols2/ios/todolist/src/main.cpp b/examples/quickcontrols2/ios/todolist/src/main.cpp new file mode 100644 index 0000000000..1db4f7ae37 --- /dev/null +++ b/examples/quickcontrols2/ios/todolist/src/main.cpp @@ -0,0 +1,32 @@ +// Copyright (C) 2022 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only + +#include <QGuiApplication> +#include <QQmlApplicationEngine> +#include <QtQml/qqmlextensionplugin.h> +#include <QtQuickControls2/qquickstyle.h> + +int main(int argc, char *argv[]) +{ + QGuiApplication app(argc, argv); + + QQuickStyle::setStyle("iOS"); + + QQmlApplicationEngine engine; + const QUrl url(u"qrc:/main.qml"_qs); + QObject::connect( + &engine, &QQmlApplicationEngine::objectCreated, &app, + [url](QObject *obj, const QUrl &objUrl) { + if (!obj && url == objUrl) + QCoreApplication::exit(-1); + }, + Qt::QueuedConnection); + + engine.addImportPath(":/"); + + engine.load(url); + if (engine.rootObjects().isEmpty()) + return -1; + + return app.exec(); +} diff --git a/examples/quickcontrols2/ios/todolist/todolist.pro b/examples/quickcontrols2/ios/todolist/todolist.pro new file mode 100644 index 0000000000..d77d718a62 --- /dev/null +++ b/examples/quickcontrols2/ios/todolist/todolist.pro @@ -0,0 +1,42 @@ +TEMPLATE = app +TARGET = todolist +QT += quick quickcontrols2 + +SOURCES += src/main.cpp + +RESOURCES += \ + images/back.png \ + images/back@2x.png \ + images/back@3x.png \ + images/back-white.png \ + images/back-white@2x.png \ + images/back-white@3x.png \ + images/close.png \ + images/close@2x.png \ + images/close@3x.png \ + images/close-white.png \ + images/close-white@2x.png \ + images/close-white@3x.png \ + images/plus-math.png \ + images/plus-math@2x.png \ + images/plus-math@3x.png \ + images/settings.png \ + images/settings@2x.png \ + images/settings@3x.png \ + images/add-new.png \ + images/add-new@2x.png \ + images/add-new@3x.png \ + main.qml \ + AppSettings.qml \ + Database.qml \ + FontSizePage.qml \ + HomePage.qml \ + MaxTasksPage.qml \ + NavBar.qml \ + ProjectPage.qml \ + SettingsPage.qml \ + ToggleCompletedTasksPage.qml \ + qmldir + +target.path = $$[QT_INSTALL_EXAMPLES]/quickcontrols2/ios/todolist +INSTALLS += target |