From 53ce7c557f68c541a2a0867bbb77fe0d96a445e5 Mon Sep 17 00:00:00 2001 From: Toast Date: Thu, 27 Mar 2025 00:40:34 +0100 Subject: [PATCH 1/9] Add new countdown action --- src/Main.qml | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/Main.qml b/src/Main.qml index 07fa36d..1644f35 100644 --- a/src/Main.qml +++ b/src/Main.qml @@ -21,6 +21,18 @@ Kirigami.ApplicationWindow { // This can also be set to an id of a Kirigami.Page pageStack.initialPage: Kirigami.ScrollablePage { title: i18nc("@title", "Countdown") + actions: [ + Kirigami.Action { + id: addAction + icon.name: "list-add-symbolic" + text: i18nc("@action:button", "Add countdown") + onTriggered: countdownModel.append({ + name: "New countdown", + description: "This was added with the add countdown button", + date: 1000 + }) + } + ] Kirigami.CardsListView { id: cardsView model: countdownModel From 728d931fcd6083c8f5c1bcca11a7aae77de459c3 Mon Sep 17 00:00:00 2001 From: Toast Date: Thu, 27 Mar 2025 01:08:47 +0100 Subject: [PATCH 2/9] Remove qt nag --- src/main.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main.cpp b/src/main.cpp index 570244c..ba49d54 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -15,7 +15,7 @@ int main(int argc, char *argv[]) QApplication::setOrganizationName(QStringLiteral("Toast")); QApplication::setOrganizationDomain(QStringLiteral("toast003.xyz")); QApplication::setApplicationName(QStringLiteral("Kirigami Testing")); - QApplication::setDesktopFileName(QStringLiteral("xyz.toast003.kirigami-testing.desktop")); + QApplication::setDesktopFileName(QStringLiteral("xyz.toast003.kirigami-testing")); QApplication::setStyle(QStringLiteral("breeze")); if (qEnvironmentVariableIsEmpty("QT_QUICK_CONTROLS_STYLE")) { From 60c5a9ec91fbcd4b3e55ff6d6384ce756fe0fe88 Mon Sep 17 00:00:00 2001 From: Toast Date: Thu, 27 Mar 2025 01:08:56 +0100 Subject: [PATCH 3/9] Add global drawer --- src/Main.qml | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/Main.qml b/src/Main.qml index 1644f35..bb202bb 100644 --- a/src/Main.qml +++ b/src/Main.qml @@ -17,6 +17,18 @@ Kirigami.ApplicationWindow { // and provides additional context for the translators title: i18nc("@title:window", "Day countdown") + globalDrawer: Kirigami.GlobalDrawer { + isMenu: true + actions: [ + Kirigami.Action { + text: i18n("Quit") + icon.name: "application-exit-symbolic" + shortcut: StandardKey.Quit + onTriggered: Qt.quit() + } + ] + } + // Set the first page that will be loaded when the app opens // This can also be set to an id of a Kirigami.Page pageStack.initialPage: Kirigami.ScrollablePage { From 8882908df1c2cd4db07a68c1bd75f9c6b91ff379 Mon Sep 17 00:00:00 2001 From: Toast Date: Thu, 27 Mar 2025 01:57:36 +0100 Subject: [PATCH 4/9] Increase window size --- src/Main.qml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Main.qml b/src/Main.qml index bb202bb..eaa9940 100644 --- a/src/Main.qml +++ b/src/Main.qml @@ -9,8 +9,8 @@ Kirigami.ApplicationWindow { // Unique identifier to reference this object id: root - width: 400 - height: 300 + width: 600 + height: 400 // Window title // i18nc() makes a string translatable From 426cd746b2f91edfbdb85c57071600938d18273d Mon Sep 17 00:00:00 2001 From: Toast Date: Thu, 27 Mar 2025 02:10:45 +0100 Subject: [PATCH 5/9] Add new countdown dialog --- src/Main.qml | 67 ++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 62 insertions(+), 5 deletions(-) diff --git a/src/Main.qml b/src/Main.qml index eaa9940..47ae50e 100644 --- a/src/Main.qml +++ b/src/Main.qml @@ -38,11 +38,7 @@ Kirigami.ApplicationWindow { id: addAction icon.name: "list-add-symbolic" text: i18nc("@action:button", "Add countdown") - onTriggered: countdownModel.append({ - name: "New countdown", - description: "This was added with the add countdown button", - date: 1000 - }) + onTriggered: addDialog.open() } ] Kirigami.CardsListView { @@ -114,4 +110,65 @@ Kirigami.ApplicationWindow { } } } + + Kirigami.Dialog { + id: addDialog + title: i18nc("@title:window", "Add countdown") + standardButtons: Kirigami.Dialog.Ok | Kirigami.Dialog.Cancel + padding: Kirigami.Units.largeSpacing + preferredWidth: Kirigami.Units.gridUnit * 20 + + Kirigami.FormLayout { + Controls.TextField { + id: nameField + Kirigami.FormData.label: i18nc("@label:textbox", "Name*:") + onAccepted: descriptionField.forceActiveFocus() + } + Controls.TextField { + id: descriptionField + Kirigami.FormData.label: i18nc("@label:textbox", "Description:") + placeholderText: i18n("Optional") + onAccepted: dateField.forceActiveFocus() + } + Controls.TextField { + id: dateField + Kirigami.FormData.label: i18nc("@label:textbox", "ISO Date*:") + inputMask: "D999-99-99" + onAccepted: addDialog.onAccepted() + } + Controls.Label { + text: "* = required fields" + } + } + + Component.onCompleted: { + const button = standardButton(Kirigami.Dialog.Ok); + button.enabled = Qt.binding(() => requiredFieldsFilled()); + } + + function requiredFieldsFilled() { + return (nameField.text !== "" && dateField.acceptableInput); + } + + function appendDataToModel() { + countdownModel.append({ + name: nameField.text, + description: descriptionField.text, + date: new Date(dateField.text) + }); + } + function clearFieldsAndClose() { + nameField.text = ""; + descriptionField.text = ""; + dateField.text = ""; + addDialog.close(); + } + + onAccepted: { + if (!addDialog.requiredFieldsFilled()) + return; + appendDataToModel(); + clearFieldsAndClose(); + } + } } From 4d11c9070961eebad78e1fa2f194c8960bda67d0 Mon Sep 17 00:00:00 2001 From: Toast Date: Thu, 27 Mar 2025 02:11:31 +0100 Subject: [PATCH 6/9] Remove placeholder countdowns --- src/Main.qml | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/src/Main.qml b/src/Main.qml index 47ae50e..382bf71 100644 --- a/src/Main.qml +++ b/src/Main.qml @@ -50,17 +50,6 @@ Kirigami.ApplicationWindow { ListModel { id: countdownModel - - ListElement { - name: "Japan trip!" - description: ":D" - date: 131 - } - ListElement { - name: "My birthday!" - description: "Pls give money" - date: 61 - } } Component { From d3ea32dfca3a4f139ce72ead681e6d52649ed93a Mon Sep 17 00:00:00 2001 From: Toast Date: Thu, 27 Mar 2025 02:11:53 +0100 Subject: [PATCH 7/9] Calculate days remaining from stored date --- src/Main.qml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Main.qml b/src/Main.qml index 382bf71..e5bf2fe 100644 --- a/src/Main.qml +++ b/src/Main.qml @@ -72,7 +72,7 @@ Kirigami.ApplicationWindow { Kirigami.Heading { Layout.fillWidth: true level: 1 - text: date + text: i18n("%1 days", Math.round((date-Date.now())/86400000)) } ColumnLayout { Kirigami.Heading { From 92359188c06b386cf6b48929d6558832fed2dd9c Mon Sep 17 00:00:00 2001 From: Toast Date: Thu, 27 Mar 2025 02:15:32 +0100 Subject: [PATCH 8/9] Add missing parameters This fixes some ugly layout bugs --- src/Main.qml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Main.qml b/src/Main.qml index e5bf2fe..d8477b4 100644 --- a/src/Main.qml +++ b/src/Main.qml @@ -70,13 +70,13 @@ Kirigami.ApplicationWindow { columns: root.wideScreen ? 4 : 2 Kirigami.Heading { - Layout.fillWidth: true level: 1 text: i18n("%1 days", Math.round((date-Date.now())/86400000)) } ColumnLayout { Kirigami.Heading { Layout.fillWidth: true + level: 2 text: name } Kirigami.Separator { From 0d0f9d9bfd8fd2b42cca33693a64d0b7bd9d4902 Mon Sep 17 00:00:00 2001 From: Toast Date: Thu, 27 Mar 2025 02:38:18 +0100 Subject: [PATCH 9/9] Extract components to different files --- src/CMakeLists.txt | 3 + src/Main.qml | 110 +-------------------------- src/components/AddDialog.qml | 64 ++++++++++++++++ src/components/CMakeLists.txt | 16 ++++ src/components/CountdownDelegate.qml | 49 ++++++++++++ 5 files changed, 135 insertions(+), 107 deletions(-) create mode 100644 src/components/AddDialog.qml create mode 100644 src/components/CMakeLists.txt create mode 100644 src/components/CountdownDelegate.qml diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index ff599cd..ba15ea0 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -25,6 +25,9 @@ target_link_libraries(kirigami-testing KF6::I18n KF6::CoreAddons KF6::IconThemes + kirigami-testing-components ) install(TARGETS kirigami-testing ${KDE_INSTALL_TARGETS_DEFAULT_ARGS}) + +add_subdirectory(components) diff --git a/src/Main.qml b/src/Main.qml index d8477b4..ffd9b14 100644 --- a/src/Main.qml +++ b/src/Main.qml @@ -3,6 +3,7 @@ import QtQuick import QtQuick.Layouts import QtQuick.Controls as Controls import org.kde.kirigami as Kirigami +import xyz.toast003.kirigamiTesting.components // Provides basic features needed for all kirigami applications Kirigami.ApplicationWindow { @@ -44,7 +45,7 @@ Kirigami.ApplicationWindow { Kirigami.CardsListView { id: cardsView model: countdownModel - delegate: countdownDelegate + delegate: CountdownDelegate {} } } @@ -52,112 +53,7 @@ Kirigami.ApplicationWindow { id: countdownModel } - Component { - id: countdownDelegate - Kirigami.AbstractCard { - contentItem: Item { - implicitWidth: delegateLayout.implicitWidth - implicitHeight: delegateLayout.implicitHeight - GridLayout { - id: delegateLayout - anchors { - left: parent.left - top: parent.top - right: parent.right - } - rowSpacing: Kirigami.Units.largeSpacing - columnSpacing: Kirigami.Units.largeSpacing - columns: root.wideScreen ? 4 : 2 - - Kirigami.Heading { - level: 1 - text: i18n("%1 days", Math.round((date-Date.now())/86400000)) - } - ColumnLayout { - Kirigami.Heading { - Layout.fillWidth: true - level: 2 - text: name - } - Kirigami.Separator { - Layout.fillWidth: true - visible: description.length > 0 - } - Controls.Label { - Layout.fillWidth: true - wrapMode: Text.WordWrap - text: description - visible: description.length > 0 - } - } - Controls.Button { - Layout.alignment: Qt.AlignRight - Layout.columnSpan: 2 - text: i18n("Edit") - } - } - } - } - } - - Kirigami.Dialog { + AddDialog { id: addDialog - title: i18nc("@title:window", "Add countdown") - standardButtons: Kirigami.Dialog.Ok | Kirigami.Dialog.Cancel - padding: Kirigami.Units.largeSpacing - preferredWidth: Kirigami.Units.gridUnit * 20 - - Kirigami.FormLayout { - Controls.TextField { - id: nameField - Kirigami.FormData.label: i18nc("@label:textbox", "Name*:") - onAccepted: descriptionField.forceActiveFocus() - } - Controls.TextField { - id: descriptionField - Kirigami.FormData.label: i18nc("@label:textbox", "Description:") - placeholderText: i18n("Optional") - onAccepted: dateField.forceActiveFocus() - } - Controls.TextField { - id: dateField - Kirigami.FormData.label: i18nc("@label:textbox", "ISO Date*:") - inputMask: "D999-99-99" - onAccepted: addDialog.onAccepted() - } - Controls.Label { - text: "* = required fields" - } - } - - Component.onCompleted: { - const button = standardButton(Kirigami.Dialog.Ok); - button.enabled = Qt.binding(() => requiredFieldsFilled()); - } - - function requiredFieldsFilled() { - return (nameField.text !== "" && dateField.acceptableInput); - } - - function appendDataToModel() { - countdownModel.append({ - name: nameField.text, - description: descriptionField.text, - date: new Date(dateField.text) - }); - } - function clearFieldsAndClose() { - nameField.text = ""; - descriptionField.text = ""; - dateField.text = ""; - addDialog.close(); - } - - onAccepted: { - if (!addDialog.requiredFieldsFilled()) - return; - appendDataToModel(); - clearFieldsAndClose(); - } } } diff --git a/src/components/AddDialog.qml b/src/components/AddDialog.qml new file mode 100644 index 0000000..b730bfa --- /dev/null +++ b/src/components/AddDialog.qml @@ -0,0 +1,64 @@ +import QtQuick +import QtQuick.Controls as Controls +import org.kde.kirigami as Kirigami + +Kirigami.Dialog { + id: addDialog + title: i18nc("@title:window", "Add countdown") + standardButtons: Kirigami.Dialog.Ok | Kirigami.Dialog.Cancel + padding: Kirigami.Units.largeSpacing + preferredWidth: Kirigami.Units.gridUnit * 20 + + Kirigami.FormLayout { + Controls.TextField { + id: nameField + Kirigami.FormData.label: i18nc("@label:textbox", "Name*:") + onAccepted: descriptionField.forceActiveFocus() + } + Controls.TextField { + id: descriptionField + Kirigami.FormData.label: i18nc("@label:textbox", "Description:") + placeholderText: i18n("Optional") + onAccepted: dateField.forceActiveFocus() + } + Controls.TextField { + id: dateField + Kirigami.FormData.label: i18nc("@label:textbox", "ISO Date*:") + inputMask: "D999-99-99" + onAccepted: addDialog.onAccepted() + } + Controls.Label { + text: "* = required fields" + } + } + + Component.onCompleted: { + const button = standardButton(Kirigami.Dialog.Ok); + button.enabled = Qt.binding(() => requiredFieldsFilled()); + } + + function requiredFieldsFilled() { + return (nameField.text !== "" && dateField.acceptableInput); + } + + function appendDataToModel() { + countdownModel.append({ + name: nameField.text, + description: descriptionField.text, + date: new Date(dateField.text) + }); + } + function clearFieldsAndClose() { + nameField.text = ""; + descriptionField.text = ""; + dateField.text = ""; + addDialog.close(); + } + + onAccepted: { + if (!addDialog.requiredFieldsFilled()) + return; + appendDataToModel(); + clearFieldsAndClose(); + } +} diff --git a/src/components/CMakeLists.txt b/src/components/CMakeLists.txt new file mode 100644 index 0000000..61c0bc7 --- /dev/null +++ b/src/components/CMakeLists.txt @@ -0,0 +1,16 @@ +add_library(kirigami-testing-components) + +ecm_add_qml_module(kirigami-testing-components + URI "xyz.toast003.kirigamiTesting.components" + GENERATE_PLUGIN_SOURCE +) + +ecm_target_qml_sources(kirigami-testing-components + SOURCES + AddDialog.qml + CountdownDelegate.qml +) + +ecm_finalize_qml_module(kirigami-testing-components) + +install(TARGETS kirigami-testing-components ${KDE_INSTALL_TARGETS_DEFAULT_ARGS}) diff --git a/src/components/CountdownDelegate.qml b/src/components/CountdownDelegate.qml new file mode 100644 index 0000000..2084d22 --- /dev/null +++ b/src/components/CountdownDelegate.qml @@ -0,0 +1,49 @@ +import QtQuick +import QtQuick.Layouts +import QtQuick.Controls as Controls +import org.kde.kirigami as Kirigami + +Kirigami.AbstractCard { + contentItem: Item { + implicitWidth: delegateLayout.implicitWidth + implicitHeight: delegateLayout.implicitHeight + GridLayout { + id: delegateLayout + anchors { + left: parent.left + top: parent.top + right: parent.right + } + rowSpacing: Kirigami.Units.largeSpacing + columnSpacing: Kirigami.Units.largeSpacing + columns: root.wideScreen ? 4 : 2 + + Kirigami.Heading { + level: 1 + text: i18n("%1 days", Math.round((date - Date.now()) / 86400000)) + } + ColumnLayout { + Kirigami.Heading { + Layout.fillWidth: true + level: 2 + text: name + } + Kirigami.Separator { + Layout.fillWidth: true + visible: description.length > 0 + } + Controls.Label { + Layout.fillWidth: true + wrapMode: Text.WordWrap + text: description + visible: description.length > 0 + } + } + Controls.Button { + Layout.alignment: Qt.AlignRight + Layout.columnSpan: 2 + text: i18n("Edit") + } + } + } +}