From b716801165e303c6ca7faf8010f997081c6adbd4 Mon Sep 17 00:00:00 2001 From: Joshua Goins Date: Sat, 19 Aug 2023 10:30:52 -0400 Subject: [PATCH] Switch to the new FormCard API for most of the user interface --- launcher/ui/Pages/LoginPage.qml | 203 +++---- launcher/ui/Pages/NewsPage.qml | 100 ++-- launcher/ui/Settings/AccountSettings.qml | 382 ++++++------ .../ui/Settings/CompatibilityToolSetup.qml | 73 +-- launcher/ui/Settings/DeveloperSettings.qml | 75 ++- launcher/ui/Settings/GeneralSettings.qml | 37 +- launcher/ui/Settings/ProfileSettings.qml | 556 ++++++++++-------- launcher/ui/Settings/SettingsPage.qml | 243 ++++---- 8 files changed, 876 insertions(+), 793 deletions(-) diff --git a/launcher/ui/Pages/LoginPage.qml b/launcher/ui/Pages/LoginPage.qml index 029b616..fa6799b 100644 --- a/launcher/ui/Pages/LoginPage.qml +++ b/launcher/ui/Pages/LoginPage.qml @@ -6,7 +6,7 @@ import QtQuick.Window 2.15 import org.kde.kirigami 2.20 as Kirigami import QtQuick.Controls 2.15 as Controls import QtQuick.Layouts 1.15 -import org.kde.kirigamiaddons.labs.mobileform 0.1 as MobileForm +import org.kde.kirigamiaddons.formcard 1.0 as FormCard import zone.xiv.astra 1.0 Controls.Control { @@ -51,155 +51,142 @@ Controls.Control { contentItem: ColumnLayout { width: parent.width - MobileForm.FormCard { - Layout.topMargin: Kirigami.Units.largeSpacing + + FormCard.FormCard { Layout.fillWidth: true - contentItem: ColumnLayout { - spacing: 0 - MobileForm.FormCardHeader { - title: i18n("Current Profile") - } + FormCard.FormButtonDelegate { + text: i18n("Current Profile") + description: page.profile.name - MobileForm.FormButtonDelegate { - text: page.profile.name + Controls.Menu { + id: profileMenu - Controls.Menu { - id: profileMenu + Repeater { + model: LauncherCore.profileManager - Repeater { - model: LauncherCore.profileManager + Controls.MenuItem { + required property var profile Controls.MenuItem { - required property var profile + text: profile.name - Controls.MenuItem { - text: profile.name - - onClicked: { - page.profile = profile - profileMenu.close() - } + onClicked: { + page.profile = profile + profileMenu.close() } } } } - - onClicked: profileMenu.popup() } + + onClicked: profileMenu.popup() } } - MobileForm.FormCard { - Layout.topMargin: Kirigami.Units.largeSpacing + FormCard.FormCard { Layout.fillWidth: true - contentItem: ColumnLayout { - spacing: 0 - MobileForm.FormCardHeader { - title: i18n("Login") + FormCard.FormButtonDelegate { + text: i18n("Current Account") + description: page.profile.account.name + + leading: Kirigami.Avatar + { + source: page.profile.account.avatarUrl } - MobileForm.FormButtonDelegate { - text: page.profile.account.name + leadingPadding: Kirigami.Units.largeSpacing * 2 - leading: Kirigami.Avatar - { - source: page.profile.account.avatarUrl - } + Controls.Menu { + id: accountMenu - leadingPadding: Kirigami.Units.largeSpacing * 2 + Repeater { + model: LauncherCore.accountManager - Controls.Menu { - id: accountMenu - - Repeater { - model: LauncherCore.accountManager + Controls.MenuItem { + required property var account Controls.MenuItem { - required property var account + text: account.name + icon.name: account.avatarUrl.length === 0 ? "actor" : "" + icon.source: account.avatarUrl - Controls.MenuItem { - text: account.name - icon.name: account.avatarUrl.length === 0 ? "actor" : "" - icon.source: account.avatarUrl - - onClicked: { - page.profile.account = account - accountMenu.close() - } + onClicked: { + page.profile.account = account + accountMenu.close() } } } } - - onClicked: accountMenu.popup() } - MobileForm.FormDelegateSeparator { - } + onClicked: accountMenu.popup() + } - MobileForm.FormTextFieldDelegate { - id: usernameField - label: page.profile.account.isSapphire ? i18n("Username") : i18n("Square Enix ID") - text: page.profile.account.name - enabled: false - } + FormCard.FormDelegateSeparator { + } - MobileForm.FormDelegateSeparator { - } + FormCard.FormTextFieldDelegate { + id: usernameField + label: page.profile.account.isSapphire ? i18n("Username") : i18n("Square Enix ID") + text: page.profile.account.name + enabled: false + } - MobileForm.FormTextFieldDelegate { - id: passwordField - label: page.profile.account.isSapphire ? i18n("Password") : i18n("Square Enix Password") - echoMode: TextInput.Password - focus: true - onAccepted: { - if (otpField.visible) { - otpField.clicked(); - } else { - loginButton.clicked(); - } - } - text: page.profile.account.rememberPassword ? "abcdefg" : "" - } + FormCard.FormDelegateSeparator { + } - MobileForm.FormDelegateSeparator { - } - - MobileForm.FormTextFieldDelegate { - id: otpField - label: i18n("One-time Password") - visible: page.profile.account.useOTP - onAccepted: loginButton.clicked() - } - - MobileForm.FormDelegateSeparator {} - - MobileForm.FormButtonDelegate { - id: loginButton - - text: i18n("Log In") - icon.name: "unlock" - enabled: page.isLoginValid - onClicked: { - LauncherCore.login(page.profile, usernameField.text, passwordField.text, otpField.text) - pageStack.layers.push('qrc:/ui/Pages/StatusPage.qml') + FormCard.FormTextFieldDelegate { + id: passwordField + label: page.profile.account.isSapphire ? i18n("Password") : i18n("Square Enix Password") + echoMode: TextInput.Password + focus: true + onAccepted: { + if (otpField.visible) { + otpField.clicked(); + } else { + loginButton.clicked(); } } + text: page.profile.account.rememberPassword ? "abcdefg" : "" + } - MobileForm.FormDelegateSeparator { - visible: forgotPasswordButton.visible + FormCard.FormDelegateSeparator { + } + + FormCard.FormTextFieldDelegate { + id: otpField + label: i18n("One-time Password") + visible: page.profile.account.useOTP + onAccepted: loginButton.clicked() + } + + FormCard.FormDelegateSeparator {} + + FormCard.FormButtonDelegate { + id: loginButton + + text: i18n("Log In") + icon.name: "unlock" + enabled: page.isLoginValid + onClicked: { + LauncherCore.login(page.profile, usernameField.text, passwordField.text, otpField.text) + pageStack.layers.push('qrc:/ui/Pages/StatusPage.qml') } + } - MobileForm.FormButtonDelegate { - id: forgotPasswordButton + FormCard.FormDelegateSeparator { + visible: forgotPasswordButton.visible + } - text: i18n("Forgot ID or Password") - icon.name: "dialog-password" - visible: !page.profile.account.isSapphire - onClicked: applicationWindow().openUrl('https://secure.square-enix.com/account/app/svc/reminder') - } + FormCard.FormButtonDelegate { + id: forgotPasswordButton + + text: i18n("Forgot ID or Password") + icon.name: "dialog-password" + visible: !page.profile.account.isSapphire + onClicked: applicationWindow().openUrl('https://secure.square-enix.com/account/app/svc/reminder') } } } diff --git a/launcher/ui/Pages/NewsPage.qml b/launcher/ui/Pages/NewsPage.qml index f3d8dc6..a4472ef 100644 --- a/launcher/ui/Pages/NewsPage.qml +++ b/launcher/ui/Pages/NewsPage.qml @@ -6,7 +6,7 @@ import QtQuick.Window 2.15 import org.kde.kirigami 2.20 as Kirigami import QtQuick.Controls 2.15 as Controls import QtQuick.Layouts 1.15 -import org.kde.kirigamiaddons.labs.mobileform 0.1 as MobileForm +import org.kde.kirigamiaddons.formcard 1.0 as FormCard import QtGraphicalEffects 1.0 import zone.xiv.astra 1.0 @@ -83,84 +83,80 @@ Controls.Control { } } - MobileForm.FormCard { - Layout.topMargin: Kirigami.Units.largeSpacing + FormCard.FormHeader { + title: i18n("News") + + Layout.fillWidth: true + maximumWidth: layout.maximumWidth + } + + FormCard.FormCard { Layout.fillWidth: true Layout.alignment: Qt.AlignHCenter | Qt.AlignTop maximumWidth: layout.maximumWidth visible: LauncherCore.headline !== null - contentItem: ColumnLayout { - spacing: 0 + Repeater { + model: LauncherCore.headline !== null ? LauncherCore.headline.news : undefined - MobileForm.FormCardHeader { - title: i18n("News") - } + FormCard.FormButtonDelegate { + text: modelData.title + description: Qt.formatDate(modelData.date) - Repeater { - model: LauncherCore.headline !== null ? LauncherCore.headline.news : undefined - - MobileForm.FormButtonDelegate { - text: modelData.title - description: Qt.formatDate(modelData.date) - - onClicked: applicationWindow().openUrl(modelData.url) - onHoveredChanged: { - if (hovered) { - applicationWindow().hoverLinkIndicator.text = modelData.url; - } else { - applicationWindow().hoverLinkIndicator.text = ""; - } + onClicked: applicationWindow().openUrl(modelData.url) + onHoveredChanged: { + if (hovered) { + applicationWindow().hoverLinkIndicator.text = modelData.url; + } else { + applicationWindow().hoverLinkIndicator.text = ""; } } } + } - MobileForm.FormTextDelegate { - description: i18n("No news.") - visible: LauncherCore.headline !== null ? LauncherCore.headline.failedToLoad : false - } + FormCard.FormTextDelegate { + description: i18n("No news.") + visible: LauncherCore.headline !== null ? LauncherCore.headline.failedToLoad : false } } - MobileForm.FormCard { - Layout.topMargin: Kirigami.Units.largeSpacing + FormCard.FormHeader { + title: i18n("Topics") + + Layout.fillWidth: true + maximumWidth: layout.maximumWidth + } + + FormCard.FormCard { Layout.fillWidth: true Layout.alignment: Qt.AlignHCenter | Qt.AlignTop maximumWidth: layout.maximumWidth visible: LauncherCore.headline !== null - contentItem: ColumnLayout { - spacing: 0 + Repeater { + model: LauncherCore.headline !== null ? LauncherCore.headline.topics : undefined - MobileForm.FormCardHeader { - title: i18n("Topics") - } + FormCard.FormButtonDelegate { + text: modelData.title + description: Qt.formatDate(modelData.date) - Repeater { - model: LauncherCore.headline !== null ? LauncherCore.headline.topics : undefined - - MobileForm.FormButtonDelegate { - text: modelData.title - description: Qt.formatDate(modelData.date) - - hoverEnabled: true - onClicked: applicationWindow().openUrl(modelData.url) - onHoveredChanged: { - if (hovered) { - applicationWindow().hoverLinkIndicator.text = modelData.url; - } else { - applicationWindow().hoverLinkIndicator.text = ""; - } + hoverEnabled: true + onClicked: applicationWindow().openUrl(modelData.url) + onHoveredChanged: { + if (hovered) { + applicationWindow().hoverLinkIndicator.text = modelData.url; + } else { + applicationWindow().hoverLinkIndicator.text = ""; } } } + } - MobileForm.FormTextDelegate { - description: i18n("No topics.") - visible: LauncherCore.headline !== null ? LauncherCore.headline.failedToLoad : false - } + FormCard.FormTextDelegate { + description: i18n("No topics.") + visible: LauncherCore.headline !== null ? LauncherCore.headline.failedToLoad : false } } diff --git a/launcher/ui/Settings/AccountSettings.qml b/launcher/ui/Settings/AccountSettings.qml index f428c94..f9bcc13 100644 --- a/launcher/ui/Settings/AccountSettings.qml +++ b/launcher/ui/Settings/AccountSettings.qml @@ -6,202 +6,228 @@ import QtQuick.Window 2.15 import org.kde.kirigami 2.20 as Kirigami import QtQuick.Controls 2.15 as Controls import QtQuick.Layouts 1.15 -import org.kde.kirigamiaddons.labs.mobileform 0.1 as MobileForm +import org.kde.kirigamiaddons.formcard 1.0 as FormCard import zone.xiv.astra 1.0 -Kirigami.ScrollablePage { +FormCard.FormCardPage { id: page property var account title: i18n("Account Settings") - ColumnLayout { - width: parent.width + FormCard.FormHeader { + title: i18n("General") + } - MobileForm.FormCard { - Layout.topMargin: Kirigami.Units.largeSpacing - Layout.fillWidth: true - contentItem: ColumnLayout { - spacing: 0 + FormCard.FormCard { + Layout.fillWidth: true - MobileForm.FormCardHeader { - title: i18n("General") - } + FormCard.FormTextFieldDelegate { + id: usernameDelegate - - MobileForm.FormTextFieldDelegate { - label: i18n("Username") - text: page.account.name - onTextChanged: page.account.name = text - } - - MobileForm.FormDelegateSeparator {} - - MobileForm.FormComboBoxDelegate { - text: i18n("Language") - model: ["Japanese", "English", "German", "French"] - currentIndex: page.account.language - onCurrentIndexChanged: page.account.language = currentIndex - } - - MobileForm.FormDelegateSeparator {} - - MobileForm.FormComboBoxDelegate { - text: i18n("Account type") - model: ["Square Enix", "Sapphire"] - currentIndex: page.account.isSapphire ? 1 : 0 - onCurrentIndexChanged: page.account.isSapphire = (currentIndex === 1) - } - - MobileForm.FormDelegateSeparator {} - - MobileForm.FormComboBoxDelegate { - id: licenseField - text: i18n("License") - description: i18n("If the account holds multiple licenses, choose the preferred one.") - model: ["Windows", "Steam", "macOS"] - currentIndex: page.account.license - onCurrentIndexChanged: page.account.license = currentIndex - visible: !page.account.isSapphire - } - - MobileForm.FormDelegateSeparator { - visible: licenseField.visible - } - - MobileForm.FormCheckDelegate { - id: freeTrialField - text: i18n("Free trial") - checked: page.account.isFreeTrial - onCheckedChanged: page.account.isFreeTrial = checked - visible: !page.account.isSapphire - } - - MobileForm.FormDelegateSeparator { - visible: freeTrialField.visible - } - - MobileForm.FormCheckDelegate { - id: needOTPField - - text: i18n("Needs a one-time password") - checked: page.account.useOTP - onCheckedChanged: page.account.useOTP = checked - visible: !page.account.isSapphire - } - - MobileForm.FormDelegateSeparator { - visible: needOTPField.visible - } - - MobileForm.FormTextFieldDelegate { - label: i18n("Lobby URL") - text: page.account.lobbyUrl - onTextChanged: page.account.lobbyUrl = text - visible: page.account.isSapphire - placeholderText: "neolobby0X.ffxiv.com" - } - - MobileForm.FormDelegateSeparator {} - - MobileForm.FormButtonDelegate { - text: i18n("Set Lodestone Character") - description: i18n("Associate a character's avatar with this account.") - icon.name: "actor" - Kirigami.PromptDialog { - id: lodestoneDialog - title: i18n("Enter Lodestone Id") - - standardButtons: Kirigami.Dialog.Ok | Kirigami.Dialog.Cancel - - onAccepted: page.account.lodestoneId = lodestoneIdField.text - - Controls.TextField { - id: lodestoneIdField - text: page.account.lodestoneId - placeholderText: qsTr("123456...") - } - } - - onClicked: lodestoneDialog.open() - } - } + label: i18n("Username") + text: page.account.name + onTextChanged: page.account.name = text } - MobileForm.FormCard { - Layout.topMargin: Kirigami.Units.largeSpacing - Layout.fillWidth: true - contentItem: ColumnLayout { - spacing: 0 - - MobileForm.FormCardHeader { - title: i18n("Login") - } - - MobileForm.FormCheckDelegate { - text: i18n("Remember password") - checked: page.account.rememberPassword - onCheckedChanged: page.account.rememberPassword = checked - } - - MobileForm.FormDelegateSeparator {} - - MobileForm.FormCheckDelegate { - id: generateOTPField - - text: i18n("Automatically generate one-time passwords") - checked: page.account.rememberOTP - onCheckedChanged: page.account.rememberOTP = checked - enabled: page.account.useOTP - visible: !page.account.isSapphire - } - - MobileForm.FormDelegateSeparator { - visible: generateOTPField.visible - } - - MobileForm.FormButtonDelegate { - text: i18n("Enter OTP Secret") - icon.name: "list-add-symbolic" - enabled: page.account.rememberOTP - visible: generateOTPField.visible - Kirigami.PromptDialog { - id: otpDialog - title: i18n("Enter OTP Secret") - - standardButtons: Kirigami.Dialog.Ok | Kirigami.Dialog.Cancel - - onAccepted: page.account.setOTPSecret(otpSecretField.text) - - Controls.TextField { - id: otpSecretField - placeholderText: qsTr("ABCD EFGH...") - } - } - - onClicked: otpDialog.open() - } - } + FormCard.FormDelegateSeparator { + above: usernameDelegate + below: languageDelegate } - MobileForm.FormCard { - Layout.topMargin: Kirigami.Units.largeSpacing - Layout.fillWidth: true - contentItem: ColumnLayout { - spacing: 0 + FormCard.FormComboBoxDelegate { + id: languageDelegate - MobileForm.FormButtonDelegate { - text: i18n("Delete Account") - description: !enabled ? i18n("Cannot delete the only account.") : "" - icon.name: "delete" - enabled: LauncherCore.accountManager.canDelete(page.account) - onClicked: { - LauncherCore.accountManager.deleteAccount(page.account) - applicationWindow().pageStack.layers.pop() - } + text: i18n("Language") + model: ["Japanese", "English", "German", "French"] + currentIndex: page.account.language + onCurrentIndexChanged: page.account.language = currentIndex + } + + FormCard.FormDelegateSeparator { + above: languageDelegate + below: accountTypeDelegate + } + + FormCard.FormComboBoxDelegate { + id: accountTypeDelegate + + text: i18n("Account type") + model: ["Square Enix", "Sapphire"] + currentIndex: page.account.isSapphire ? 1 : 0 + onCurrentIndexChanged: page.account.isSapphire = (currentIndex === 1) + } + + FormCard.FormDelegateSeparator { + above: accountTypeDelegate + below: licenseField + } + + FormCard.FormComboBoxDelegate { + id: licenseField + + text: i18n("License") + description: i18n("If the account holds multiple licenses, choose the preferred one.") + model: ["Windows", "Steam", "macOS"] + currentIndex: page.account.license + onCurrentIndexChanged: page.account.license = currentIndex + visible: !page.account.isSapphire + } + + FormCard.FormDelegateSeparator { + above: licenseField + below: freeTrialField + + visible: licenseField.visible + } + + FormCard.FormCheckDelegate { + id: freeTrialField + text: i18n("Free trial") + checked: page.account.isFreeTrial + onCheckedChanged: page.account.isFreeTrial = checked + visible: !page.account.isSapphire + } + + FormCard.FormDelegateSeparator { + above: freeTrialField + below: needOTPField + + visible: freeTrialField.visible + } + + FormCard.FormCheckDelegate { + id: needOTPField + + text: i18n("Needs a one-time password") + checked: page.account.useOTP + onCheckedChanged: page.account.useOTP = checked + visible: !page.account.isSapphire + } + + FormCard.FormDelegateSeparator { + above: needOTPField + below: lobbyURLDelegate + + visible: needOTPField.visible + } + + FormCard.FormTextFieldDelegate { + id: lobbyURLDelegate + + label: i18n("Lobby URL") + text: page.account.lobbyUrl + onTextChanged: page.account.lobbyUrl = text + visible: page.account.isSapphire + placeholderText: "neolobby0X.ffxiv.com" + } + + FormCard.FormDelegateSeparator { + above: lobbyURLDelegate + below: lodestoneDelegate + } + + FormCard.FormButtonDelegate { + id: lodestoneDelegate + + text: i18n("Set Lodestone Character") + description: i18n("Associate a character's avatar with this account.") + icon.name: "actor" + Kirigami.PromptDialog { + id: lodestoneDialog + title: i18n("Enter Lodestone Id") + + standardButtons: Kirigami.Dialog.Ok | Kirigami.Dialog.Cancel + + onAccepted: page.account.lodestoneId = lodestoneIdField.text + + Controls.TextField { + id: lodestoneIdField + text: page.account.lodestoneId + placeholderText: qsTr("123456...") } } + + onClicked: lodestoneDialog.open() + } + } + + FormCard.FormHeader { + title: i18n("Login") + } + + FormCard.FormCard { + Layout.fillWidth: true + + FormCard.FormCheckDelegate { + id: rememberPasswordDelegate + + text: i18n("Remember password") + checked: page.account.rememberPassword + onCheckedChanged: page.account.rememberPassword = checked + } + + FormCard.FormDelegateSeparator { + above: rememberPasswordDelegate + below: generateOTPField + } + + FormCard.FormCheckDelegate { + id: generateOTPField + + text: i18n("Automatically generate one-time passwords") + checked: page.account.rememberOTP + onCheckedChanged: page.account.rememberOTP = checked + enabled: page.account.useOTP + visible: !page.account.isSapphire + } + + FormCard.FormDelegateSeparator { + above: generateOTPField + below: otpSecretDelegate + + visible: generateOTPField.visible + } + + FormCard.FormButtonDelegate { + id: otpSecretDelegate + + text: i18n("Enter OTP Secret") + icon.name: "list-add-symbolic" + enabled: page.account.rememberOTP + visible: generateOTPField.visible + Kirigami.PromptDialog { + id: otpDialog + title: i18n("Enter OTP Secret") + + standardButtons: Kirigami.Dialog.Ok | Kirigami.Dialog.Cancel + + onAccepted: page.account.setOTPSecret(otpSecretField.text) + + Controls.TextField { + id: otpSecretField + placeholderText: qsTr("ABCD EFGH...") + } + } + + onClicked: otpDialog.open() + } + } + + FormCard.FormCard { + Layout.topMargin: Kirigami.Units.largeSpacing + Layout.fillWidth: true + + FormCard.FormButtonDelegate { + text: i18n("Delete Account") + description: !enabled ? i18n("Cannot delete the only account.") : "" + icon.name: "delete" + enabled: LauncherCore.accountManager.canDelete(page.account) + onClicked: { + LauncherCore.accountManager.deleteAccount(page.account) + applicationWindow().pageStack.layers.pop() + } } } } \ No newline at end of file diff --git a/launcher/ui/Settings/CompatibilityToolSetup.qml b/launcher/ui/Settings/CompatibilityToolSetup.qml index 520ca7d..4421579 100644 --- a/launcher/ui/Settings/CompatibilityToolSetup.qml +++ b/launcher/ui/Settings/CompatibilityToolSetup.qml @@ -6,59 +6,60 @@ import QtQuick.Window 2.15 import org.kde.kirigami 2.20 as Kirigami import QtQuick.Controls 2.15 as Controls import QtQuick.Layouts 1.15 -import org.kde.kirigamiaddons.labs.mobileform 0.1 as MobileForm +import org.kde.kirigamiaddons.formcard 1.0 as FormCard import zone.xiv.astra 1.0 -Kirigami.Page { +FormCard.FormCardPage { id: page property var installer: null title: i18n("Install Compatibility Tool") - ColumnLayout { - width: parent.width - MobileForm.FormCard { - Layout.topMargin: Kirigami.Units.largeSpacing - Layout.fillWidth: true - contentItem: ColumnLayout { - spacing: 0 + FormCard.FormHeader { + title: i18n("Compatibility Tool") + } - MobileForm.FormCardHeader { - title: i18n("Compatibility Tool") - } + FormCard.FormCard { + Layout.fillWidth: true - MobileForm.FormTextDelegate { - text: i18n("Press the button below to install the compatibility tool for Steam.") - } + FormCard.FormTextDelegate { + text: i18n("Press the button below to install the compatibility tool for Steam.") + } - MobileForm.FormDelegateSeparator {} + FormCard.FormDelegateSeparator { + below: installToolButton + } - MobileForm.FormButtonDelegate { - text: i18n("Install Tool") - icon.name: "install" - onClicked: { - page.installer = LauncherCore.createCompatInstaller(); - page.installer.installCompatibilityTool(); - } - } + FormCard.FormButtonDelegate { + id: installToolButton - MobileForm.FormDelegateSeparator {} + text: i18n("Install Tool") + icon.name: "install" + onClicked: { + page.installer = LauncherCore.createCompatInstaller(); + page.installer.installCompatibilityTool(); + } + } - MobileForm.FormButtonDelegate { - text: i18n("Remove Tool") - icon.name: "delete" - onClicked: { - page.installer = LauncherCore.createCompatInstaller(); - page.installer.removeCompatibilityTool(); - } - } + FormCard.FormDelegateSeparator { + above: installToolButton + below: removeToolButton + } + + FormCard.FormButtonDelegate { + id: removeToolButton + + text: i18n("Remove Tool") + icon.name: "delete" + onClicked: { + page.installer = LauncherCore.createCompatInstaller(); + page.installer.removeCompatibilityTool(); } } } - Kirigami.PromptDialog { - id: errorDialog + property Kirigami.PromptDialog errorDialog: Kirigami.PromptDialog { title: i18n("Install error") showCloseButton: false @@ -68,7 +69,7 @@ Kirigami.Page { onRejected: applicationWindow().pageStack.layers.pop() } - Connections { + data: Connections { enabled: page.installer !== null target: page.installer diff --git a/launcher/ui/Settings/DeveloperSettings.qml b/launcher/ui/Settings/DeveloperSettings.qml index d6efd20..37b7d73 100644 --- a/launcher/ui/Settings/DeveloperSettings.qml +++ b/launcher/ui/Settings/DeveloperSettings.qml @@ -6,7 +6,7 @@ import QtQuick.Window 2.15 import org.kde.kirigami 2.20 as Kirigami import QtQuick.Controls 2.15 as Controls import QtQuick.Layouts 1.15 -import org.kde.kirigamiaddons.labs.mobileform 0.1 as MobileForm +import org.kde.kirigamiaddons.formcard 1.0 as FormCard import zone.xiv.astra 1.0 import "../Components" @@ -16,40 +16,55 @@ Kirigami.ScrollablePage { title: i18n("Developer Settings") - ColumnLayout { - width: parent.width + FormCard.FormCard { + Layout.fillWidth: true - MobileForm.FormCard { - Layout.topMargin: Kirigami.Units.largeSpacing - Layout.fillWidth: true - contentItem: ColumnLayout { - spacing: 0 + FormCard.FormCheckDelegate { + id: keepPatchesDelegate - MobileForm.FormCheckDelegate { - text: i18n("Keep Patches") - description: i18n("Do not delete patches after they're used. Astra will not redownload patch data, if found.") - checked: LauncherCore.keepPatches - onCheckedChanged: LauncherCore.keepPatches = checked - } + text: i18n("Keep Patches") + description: i18n("Do not delete patches after they're used. Astra will not redownload patch data, if found.") + checked: LauncherCore.keepPatches + onCheckedChanged: LauncherCore.keepPatches = checked + } - MobileForm.FormTextFieldDelegate { - label: i18n("Dalamud Distribution Server") - text: LauncherCore.dalamudDistribServer - onTextChanged: LauncherCore.dalamudDistribServer = text - } + FormCard.FormDelegateSeparator { + above: keepPatchesDelegate + below: dalamudServerDelegate + } - MobileForm.FormTextFieldDelegate { - label: i18n("SE Main Server") - text: LauncherCore.squareEnixServer - onTextChanged: LauncherCore.squareEnixServer = text - } + FormCard.FormTextFieldDelegate { + id: dalamudServerDelegate - MobileForm.FormTextFieldDelegate { - label: i18n("SE Login Server") - text: LauncherCore.squareEnixLoginServer - onTextChanged: LauncherCore.squareEnixLoginServer = text - } - } + label: i18n("Dalamud Distribution Server") + text: LauncherCore.dalamudDistribServer + onTextChanged: LauncherCore.dalamudDistribServer = text + } + + FormCard.FormDelegateSeparator { + above: dalamudServerDelegate + below: mainServerDelegate + } + + FormCard.FormTextFieldDelegate { + id: mainServerDelegate + + label: i18n("SE Main Server") + text: LauncherCore.squareEnixServer + onTextChanged: LauncherCore.squareEnixServer = text + } + + FormCard.FormDelegateSeparator { + above: mainServerDelegate + below: loginServerDelegate + } + + FormCard.FormTextFieldDelegate { + id: loginServerDelegate + + label: i18n("SE Login Server") + text: LauncherCore.squareEnixLoginServer + onTextChanged: LauncherCore.squareEnixLoginServer = text } } } \ No newline at end of file diff --git a/launcher/ui/Settings/GeneralSettings.qml b/launcher/ui/Settings/GeneralSettings.qml index b0d5446..0cb2662 100644 --- a/launcher/ui/Settings/GeneralSettings.qml +++ b/launcher/ui/Settings/GeneralSettings.qml @@ -6,31 +6,28 @@ import QtQuick.Window 2.15 import org.kde.kirigami 2.20 as Kirigami import QtQuick.Controls 2.15 as Controls import QtQuick.Layouts 1.15 -import org.kde.kirigamiaddons.labs.mobileform 0.1 as MobileForm +import org.kde.kirigamiaddons.formcard 1.0 as FormCard import zone.xiv.astra 1.0 -MobileForm.FormCard { - Layout.topMargin: Kirigami.Units.largeSpacing - Layout.fillWidth: true - contentItem: ColumnLayout { - spacing: 0 +FormCard.FormCard { + FormCard.FormCheckDelegate { + id: closeAstraDelegate - MobileForm.FormCardHeader { - title: i18n("General") - } + text: i18n("Close Astra when game is launched") + checked: LauncherCore.closeWhenLaunched + onCheckedChanged: LauncherCore.closeWhenLaunched = checked + } - MobileForm.FormCheckDelegate { - text: i18n("Close Astra when game is launched") - checked: LauncherCore.closeWhenLaunched - onCheckedChanged: LauncherCore.closeWhenLaunched = checked - } + FormCard.FormDelegateSeparator { + above: closeAstraDelegate + below: showNewsDelegate + } - MobileForm.FormDelegateSeparator {} + FormCard.FormCheckDelegate { + id: showNewsDelegate - MobileForm.FormCheckDelegate { - text: i18n("Enable and show news") - checked: LauncherCore.showNews - onCheckedChanged: LauncherCore.showNews = checked - } + text: i18n("Enable and show news") + checked: LauncherCore.showNews + onCheckedChanged: LauncherCore.showNews = checked } } \ No newline at end of file diff --git a/launcher/ui/Settings/ProfileSettings.qml b/launcher/ui/Settings/ProfileSettings.qml index 2dddded..60140f6 100644 --- a/launcher/ui/Settings/ProfileSettings.qml +++ b/launcher/ui/Settings/ProfileSettings.qml @@ -6,290 +6,334 @@ import QtQuick.Window 2.15 import org.kde.kirigami 2.20 as Kirigami import QtQuick.Controls 2.15 as Controls import QtQuick.Layouts 1.15 -import org.kde.kirigamiaddons.labs.mobileform 0.1 as MobileForm +import org.kde.kirigamiaddons.formcard 1.0 as FormCard import zone.xiv.astra 1.0 import "../Components" -Kirigami.ScrollablePage { +FormCard.FormCardPage { id: page property var profile title: i18n("Profile Settings") - ColumnLayout { - width: parent.width + FormCard.FormHeader { + title: i18n("General") + } - MobileForm.FormCard { - Layout.topMargin: Kirigami.Units.largeSpacing - Layout.fillWidth: true - contentItem: ColumnLayout { - spacing: 0 + FormCard.FormCard { + Layout.fillWidth: true - MobileForm.FormCardHeader { - title: i18n("General") - } + FormCard.FormTextFieldDelegate { + id: nameDelegate - MobileForm.FormTextFieldDelegate { - label: i18n("Name") - text: page.profile.name - onTextChanged: page.profile.name = text - } - - MobileForm.FormDelegateSeparator {} - - FormFolderDelegate { - text: i18n("Game Path") - folder: page.profile.gamePath - } - - MobileForm.FormDelegateSeparator {} - - MobileForm.FormComboBoxDelegate { - text: i18n("DirectX Version") - model: ["DirectX 11", "DirectX 9"] - currentIndex: page.profile.directx9Enabled ? 1 : 0 - onCurrentIndexChanged: page.profile.directx9Enabled = (currentIndex === 1) - } - - MobileForm.FormDelegateSeparator {} - - MobileForm.FormCheckDelegate { - text: i18n("Encrypt Game Arguments") - checked: page.profile.argumentsEncrypted - onCheckedChanged: page.profile.argumentsEncrypted = checked - } - - MobileForm.FormDelegateSeparator {} - - MobileForm.FormCheckDelegate { - text: i18n("Enable Watchdog") - description: i18n("Gives real-time queue updates. X11 only.") - checked: page.profile.watchdogEnabled - onCheckedChanged: page.profile.watchdogEnabled = checked - enabled: false - visible: false - } - - MobileForm.FormDelegateSeparator { - visible: false - } - - MobileForm.FormTextDelegate { - description: page.profile.expansionVersionText - } - } + label: i18n("Name") + text: page.profile.name + onTextChanged: page.profile.name = text } - MobileForm.FormCard { - Layout.topMargin: Kirigami.Units.largeSpacing - Layout.fillWidth: true - contentItem: ColumnLayout { - spacing: 0 - - MobileForm.FormCardHeader { - title: i18n("Wine") - } - - MobileForm.FormComboBoxDelegate { - text: i18n("Wine Type") - model: ["System", "Custom"] - currentIndex: page.profile.wineType - onCurrentIndexChanged: page.profile.wineType = currentIndex - enabled: !LauncherCore.isSteam - } - - MobileForm.FormDelegateSeparator {} - - FormFileDelegate { - text: i18n("Wine Path") - file: page.profile.winePath - enabled: !LauncherCore.isSteam && page.profile.wineType !== Profile.System - } - - MobileForm.FormDelegateSeparator {} - - FormFolderDelegate { - text: i18n("Wine Prefix Path") - folder: page.profile.winePrefixPath - enabled: !LauncherCore.isSteam - } - - MobileForm.FormDelegateSeparator {} - - MobileForm.FormTextDelegate { - description: page.profile.wineVersionText - } - } + FormCard.FormDelegateSeparator { + above: nameDelegate + below: gamePathDelegate } - MobileForm.FormCard { - Layout.topMargin: Kirigami.Units.largeSpacing - Layout.fillWidth: true - contentItem: ColumnLayout { - spacing: 0 + FormFolderDelegate { + id: gamePathDelegate - MobileForm.FormCardHeader { - title: i18n("Tools") - } + text: i18n("Game Path") + folder: page.profile.gamePath + } - MobileForm.FormCheckDelegate { - text: i18n("Enable ESync") - description: i18n("Could improve game performance, but requires a patched Wine and kernel.") - checked: page.profile.esyncEnabled - onCheckedChanged: page.profile.esyncEnabled = checked - } + FormCard.FormDelegateSeparator { + above: gamePathDelegate + below: directXDelegate + } - MobileForm.FormDelegateSeparator {} + FormCard.FormComboBoxDelegate { + id: directXDelegate - MobileForm.FormCheckDelegate { - text: i18n("Enable Gamescope") - description: i18n("A micro-compositor that uses Wayland to create a nested session.\nIf you use fullscreen mode, it may improve input handling.") - checked: page.profile.gamescopeEnabled - onCheckedChanged: page.profile.gamescopeEnabled = checked - visible: false - enabled: false - } + text: i18n("DirectX Version") + model: ["DirectX 11", "DirectX 9"] + currentIndex: page.profile.directx9Enabled ? 1 : 0 + onCurrentIndexChanged: page.profile.directx9Enabled = (currentIndex === 1) + } - MobileForm.FormDelegateSeparator { - visible: false - } + FormCard.FormDelegateSeparator { + above: directXDelegate + below: encryptArgDelegate + } - MobileForm.FormButtonDelegate { - text: i18n("Configure Gamescope...") - icon.name: "configure" - enabled: false - visible: false - Kirigami.PromptDialog { - id: gamescopeSettingsDialog - title: i18n("Configure Gamescope") + FormCard.FormCheckDelegate { + id: encryptArgDelegate - Kirigami.FormLayout { - Controls.CheckBox { - Kirigami.FormData.label: "Fullscreen:" - checked: page.profile.gamescopeFullscreen - onCheckedChanged: page.profile.gamescopeFullscreen = checked - } - Controls.CheckBox { - Kirigami.FormData.label: "Borderless:" - checked: page.profile.gamescopeBorderless - onCheckedChanged: page.profile.gamescopeBorderless = checked - } - Controls.SpinBox { - Kirigami.FormData.label: "Width:" - to: 4096 - value: page.profile.gamescopeWidth - onValueModified: page.profile.gamescopeWidth = value - } - Controls.SpinBox { - Kirigami.FormData.label: "Height:" - to: 4096 - value: page.profile.gamescopeHeight - onValueModified: page.profile.gamescopeHeight = value - } - Controls.SpinBox { - Kirigami.FormData.label: "Refresh Rate:" - to: 512 - value: page.profile.gamescopeRefreshRate - onValueModified: page.profile.gamescopeRefreshRate = value - } - } + text: i18n("Encrypt Game Arguments") + checked: page.profile.argumentsEncrypted + onCheckedChanged: page.profile.argumentsEncrypted = checked + } + + FormCard.FormDelegateSeparator { + above: encryptArgDelegate + below: enableWatchdogDelegate + } + + FormCard.FormCheckDelegate { + id: enableWatchdogDelegate + + text: i18n("Enable Watchdog") + description: i18n("Gives real-time queue updates. X11 only.") + checked: page.profile.watchdogEnabled + onCheckedChanged: page.profile.watchdogEnabled = checked + enabled: false + visible: false + } + + FormCard.FormDelegateSeparator { + visible: false + } + + FormCard.FormTextDelegate { + description: page.profile.expansionVersionText + } + } + + FormCard.FormHeader { + title: i18n("Wine") + } + + FormCard.FormCard { + Layout.fillWidth: true + + FormCard.FormComboBoxDelegate { + id: wineTypeDelegate + + text: i18n("Wine Type") + model: ["System", "Custom"] + currentIndex: page.profile.wineType + onCurrentIndexChanged: page.profile.wineType = currentIndex + enabled: !LauncherCore.isSteam + } + + FormCard.FormDelegateSeparator { + above: wineTypeDelegate + below: winePathDelegate + } + + FormFileDelegate { + id: winePathDelegate + + text: i18n("Wine Path") + file: page.profile.winePath + enabled: !LauncherCore.isSteam && page.profile.wineType !== Profile.System + } + + FormCard.FormDelegateSeparator { + above: winePathDelegate + below: winePrefixPathDelegate + } + + FormFolderDelegate { + id: winePrefixPathDelegate + + text: i18n("Wine Prefix Path") + folder: page.profile.winePrefixPath + enabled: !LauncherCore.isSteam + } + + FormCard.FormDelegateSeparator { + above: winePrefixPathDelegate + } + + FormCard.FormTextDelegate { + description: page.profile.wineVersionText + } + } + + FormCard.FormHeader { + title: i18n("Tools") + } + + FormCard.FormCard { + Layout.fillWidth: true + + FormCard.FormCheckDelegate { + id: esyncDelegate + + text: i18n("Enable ESync") + description: i18n("Could improve game performance, but requires a patched Wine and kernel.") + checked: page.profile.esyncEnabled + onCheckedChanged: page.profile.esyncEnabled = checked + } + + FormCard.FormDelegateSeparator { + above: esyncDelegate + below: gamemodeDelegate + } + + FormCard.FormCheckDelegate { + text: i18n("Enable Gamescope") + description: i18n("A micro-compositor that uses Wayland to create a nested session.\nIf you use fullscreen mode, it may improve input handling.") + checked: page.profile.gamescopeEnabled + onCheckedChanged: page.profile.gamescopeEnabled = checked + visible: false + enabled: false + } + + FormCard.FormDelegateSeparator { + visible: false + } + + FormCard.FormButtonDelegate { + text: i18n("Configure Gamescope...") + icon.name: "configure" + enabled: false + visible: false + Kirigami.PromptDialog { + id: gamescopeSettingsDialog + title: i18n("Configure Gamescope") + + Kirigami.FormLayout { + Controls.CheckBox { + Kirigami.FormData.label: "Fullscreen:" + checked: page.profile.gamescopeFullscreen + onCheckedChanged: page.profile.gamescopeFullscreen = checked } - - onClicked: gamescopeSettingsDialog.open() - } - - MobileForm.FormDelegateSeparator { - visible: false - } - - MobileForm.FormCheckDelegate { - text: i18n("Enable Gamemode") - description: i18n("A special game performance tool, that tunes your CPU scheduler among other things.") - checked: page.profile.gamemodeEnabled - onCheckedChanged: page.profile.gamemodeEnabled = checked - } - } - } - - MobileForm.FormCard { - Layout.topMargin: Kirigami.Units.largeSpacing - Layout.fillWidth: true - contentItem: ColumnLayout { - spacing: 0 - - MobileForm.FormCardHeader { - title: i18n("Dalamud") - } - - MobileForm.FormCheckDelegate { - text: i18n("Enable Dalamud") - description: i18n("Dalamud extends the game with useful plugins, but use at your own risk.") - checked: page.profile.dalamudEnabled - onCheckedChanged: page.profile.dalamudEnabled = checked - } - - MobileForm.FormDelegateSeparator {} - - MobileForm.FormComboBoxDelegate { - text: i18n("Update Channel") - model: ["Stable", "Staging", ".NET 5"] - currentIndex: page.profile.dalamudChannel - onCurrentIndexChanged: page.profile.dalamudChannel = currentIndex - enabled: page.profile.dalamudEnabled - } - - MobileForm.FormDelegateSeparator {} - - MobileForm.FormComboBoxDelegate { - text: i18n("Injection Method") - description: "It shouldn't be nessecary to change this setting, unless you're running into issues injecting Dalamud." - model: ["Entrypoint", "DLL Injection"] - enabled: page.profile.dalamudEnabled - } - - MobileForm.FormDelegateSeparator {} - - MobileForm.FormSpinBoxDelegate { - label: i18n("Injection Delay") - enabled: page.profile.dalamudEnabled - } - - MobileForm.FormDelegateSeparator {} - - MobileForm.FormCheckDelegate { - text: i18n("Opt Out of Automatic Marketboard Collection") - checked: page.profile.dalamudOptOut - onCheckedChanged: page.profile.dalamudOptOut = checked - enabled: page.profile.dalamudEnabled - } - - MobileForm.FormDelegateSeparator {} - - MobileForm.FormTextDelegate { - description: page.profile.dalamudVersionText - } - } - } - - MobileForm.FormCard { - Layout.topMargin: Kirigami.Units.largeSpacing - Layout.fillWidth: true - contentItem: ColumnLayout { - spacing: 0 - - MobileForm.FormButtonDelegate { - text: i18n("Delete Profile") - description: !enabled ? i18n("Cannot delete the only profile.") : "" - icon.name: "delete" - enabled: LauncherCore.profileManager.canDelete(page.profile) - onClicked: { - LauncherCore.profileManager.deleteProfile(page.profile) - applicationWindow().pageStack.layers.pop() + Controls.CheckBox { + Kirigami.FormData.label: "Borderless:" + checked: page.profile.gamescopeBorderless + onCheckedChanged: page.profile.gamescopeBorderless = checked + } + Controls.SpinBox { + Kirigami.FormData.label: "Width:" + to: 4096 + value: page.profile.gamescopeWidth + onValueModified: page.profile.gamescopeWidth = value + } + Controls.SpinBox { + Kirigami.FormData.label: "Height:" + to: 4096 + value: page.profile.gamescopeHeight + onValueModified: page.profile.gamescopeHeight = value + } + Controls.SpinBox { + Kirigami.FormData.label: "Refresh Rate:" + to: 512 + value: page.profile.gamescopeRefreshRate + onValueModified: page.profile.gamescopeRefreshRate = value } } } + + onClicked: gamescopeSettingsDialog.open() + } + + FormCard.FormDelegateSeparator { + visible: false + } + + FormCard.FormCheckDelegate { + id: gamemodeDelegate + + text: i18n("Enable Gamemode") + description: i18n("A special game performance tool, that tunes your CPU scheduler among other things.") + checked: page.profile.gamemodeEnabled + onCheckedChanged: page.profile.gamemodeEnabled = checked + } + } + + FormCard.FormHeader { + title: i18n("Dalamud") + } + + FormCard.FormCard { + Layout.fillWidth: true + + FormCard.FormCheckDelegate { + id: enableDalamudDelegate + + text: i18n("Enable Dalamud") + description: i18n("Dalamud extends the game with useful plugins, but use at your own risk.") + checked: page.profile.dalamudEnabled + onCheckedChanged: page.profile.dalamudEnabled = checked + } + + FormCard.FormDelegateSeparator { + above: enableDalamudDelegate + below: dalamudChannelDelegate + } + + FormCard.FormComboBoxDelegate { + id: dalamudChannelDelegate + + text: i18n("Update Channel") + model: ["Stable", "Staging", ".NET 5"] + currentIndex: page.profile.dalamudChannel + onCurrentIndexChanged: page.profile.dalamudChannel = currentIndex + enabled: page.profile.dalamudEnabled + } + + FormCard.FormDelegateSeparator { + above: dalamudChannelDelegate + below: dalamudInjectDelegate + } + + FormCard.FormComboBoxDelegate { + id: dalamudInjectDelegate + + text: i18n("Injection Method") + description: "It shouldn't be nessecary to change this setting, unless you're running into issues injecting Dalamud." + model: ["Entrypoint", "DLL Injection"] + enabled: page.profile.dalamudEnabled + } + + FormCard.FormDelegateSeparator { + above: dalamudInjectDelegate + below: dalamudDelayDelegate + } + + FormCard.FormSpinBoxDelegate { + id: dalamudDelayDelegate + + label: i18n("Injection Delay") + enabled: page.profile.dalamudEnabled + } + + FormCard.FormDelegateSeparator { + above: dalamudDelayDelegate + below: dalamudOptOutDelegate + } + + FormCard.FormCheckDelegate { + id: dalamudOptOutDelegate + + text: i18n("Opt Out of Automatic Marketboard Collection") + checked: page.profile.dalamudOptOut + onCheckedChanged: page.profile.dalamudOptOut = checked + enabled: page.profile.dalamudEnabled + } + + FormCard.FormDelegateSeparator { + above: dalamudOptOutDelegate + } + + FormCard.FormTextDelegate { + description: page.profile.dalamudVersionText + } + } + + FormCard.FormCard { + Layout.topMargin: Kirigami.Units.largeSpacing + Layout.fillWidth: true + + FormCard.FormButtonDelegate { + text: i18n("Delete Profile") + description: !enabled ? i18n("Cannot delete the only profile.") : "" + icon.name: "delete" + enabled: LauncherCore.profileManager.canDelete(page.profile) + onClicked: { + LauncherCore.profileManager.deleteProfile(page.profile) + applicationWindow().pageStack.layers.pop() + } } } } \ No newline at end of file diff --git a/launcher/ui/Settings/SettingsPage.qml b/launcher/ui/Settings/SettingsPage.qml index 3d887ce..1f62b1e 100644 --- a/launcher/ui/Settings/SettingsPage.qml +++ b/launcher/ui/Settings/SettingsPage.qml @@ -6,138 +6,155 @@ import QtQuick.Window 2.15 import org.kde.kirigami 2.20 as Kirigami import QtQuick.Controls 2.15 as Controls import QtQuick.Layouts 1.15 -import org.kde.kirigamiaddons.labs.mobileform 0.1 as MobileForm +import org.kde.kirigamiaddons.formcard 1.0 as FormCard import zone.xiv.astra 1.0 -Kirigami.ScrollablePage { +FormCard.FormCardPage { id: page title: i18n("Settings") - ColumnLayout { - width: parent.width + FormCard.FormHeader { + title: i18n("General") + } - GeneralSettings {} + GeneralSettings { + Layout.fillWidth: true + } - MobileForm.FormCard { - Layout.topMargin: Kirigami.Units.largeSpacing - Layout.fillWidth: true - contentItem: ColumnLayout { - spacing: 0 + FormCard.FormHeader { + title: i18n("Profiles") + } - MobileForm.FormCardHeader { - title: i18n("Profiles") - } + FormCard.FormCard { + Layout.fillWidth: true - Repeater { - model: LauncherCore.profileManager + Repeater { + model: LauncherCore.profileManager - MobileForm.FormButtonDelegate { - required property var profile + FormCard.FormButtonDelegate { + required property var profile - text: profile.name - onClicked: applicationWindow().pageStack.layers.push('qrc:/ui/Settings/ProfileSettings.qml', { - profile: profile - }) - } - } - - MobileForm.FormDelegateSeparator {} - - MobileForm.FormButtonDelegate { - text: i18n("Add Profile") - icon.name: "list-add" - onClicked: { - applicationWindow().currentSetupProfile = LauncherCore.profileManager.addProfile() - applicationWindow().checkSetup() - } - } + text: profile.name + onClicked: applicationWindow().pageStack.layers.push('qrc:/ui/Settings/ProfileSettings.qml', { + profile: profile + }) } } - MobileForm.FormCard { - Layout.topMargin: Kirigami.Units.largeSpacing - Layout.fillWidth: true - contentItem: ColumnLayout { - spacing: 0 - - MobileForm.FormCardHeader { - title: i18n("Accounts") - } - - Repeater { - model: LauncherCore.accountManager - - MobileForm.FormButtonDelegate { - required property var account - - text: account.name - - leading: Kirigami.Avatar - { - source: account.avatarUrl - } - - leadingPadding: Kirigami.Units.largeSpacing * 2 - - onClicked: applicationWindow().pageStack.layers.push('qrc:/ui/Settings/AccountSettings.qml', { - account: account - }) - } - } - - MobileForm.FormDelegateSeparator {} - - MobileForm.FormButtonDelegate { - text: i18n("Add Square Enix Account") - icon.name: "list-add-symbolic" - onClicked: pageStack.layers.push('qrc:/ui/Setup/AddSquareEnix.qml') - } - - MobileForm.FormDelegateSeparator {} - - MobileForm.FormButtonDelegate { - text: i18n("Add Sapphire Account") - icon.name: "list-add-symbolic" - onClicked: pageStack.layers.push('qrc:/ui/Setup/AddSapphire.qml') - } - } + FormCard.FormDelegateSeparator { + below: addProfileButton } - MobileForm.FormCard { - Layout.topMargin: Kirigami.Units.largeSpacing - Layout.fillWidth: true - contentItem: ColumnLayout { - spacing: 0 - Component { - id: aboutPage - MobileForm.AboutPage { - aboutData: About - } - } + FormCard.FormButtonDelegate { + id: addProfileButton - MobileForm.FormButtonDelegate { - text: i18n("Setup Compatibility Tool") - icon.name: "install" - onClicked: applicationWindow().pageStack.layers.push('qrc:/ui/Settings/CompatibilityToolSetup.qml') - } - - MobileForm.FormDelegateSeparator {} - - MobileForm.FormButtonDelegate { - text: i18n("Developer Settings") - icon.name: "configure" - onClicked: applicationWindow().pageStack.layers.push('qrc:/ui/Settings/DeveloperSettings.qml') - } - - MobileForm.FormDelegateSeparator {} - - MobileForm.FormButtonDelegate { - text: i18n("About Astra") - icon.name: "help-about-symbolic" - onClicked: applicationWindow().pageStack.layers.push(aboutPage) - } + text: i18n("Add Profile") + icon.name: "list-add" + onClicked: { + applicationWindow().currentSetupProfile = LauncherCore.profileManager.addProfile() + applicationWindow().checkSetup() } } } + + FormCard.FormHeader { + title: i18n("Accounts") + } + + FormCard.FormCard { + Layout.fillWidth: true + + Repeater { + model: LauncherCore.accountManager + + FormCard.FormButtonDelegate { + required property var account + + text: account.name + + leading: Kirigami.Avatar + { + source: account.avatarUrl + } + + leadingPadding: Kirigami.Units.largeSpacing * 2 + + onClicked: applicationWindow().pageStack.layers.push('qrc:/ui/Settings/AccountSettings.qml', { + account: account + }) + } + } + + FormCard.FormDelegateSeparator { + below: addSquareEnixButton + } + + FormCard.FormButtonDelegate { + id: addSquareEnixButton + + text: i18n("Add Square Enix Account") + icon.name: "list-add-symbolic" + onClicked: pageStack.layers.push('qrc:/ui/Setup/AddSquareEnix.qml') + } + + FormCard.FormDelegateSeparator { + above: addSquareEnixButton + below: addSapphireButton + } + + FormCard.FormButtonDelegate { + id: addSapphireButton + + text: i18n("Add Sapphire Account") + icon.name: "list-add-symbolic" + onClicked: pageStack.layers.push('qrc:/ui/Setup/AddSapphire.qml') + } + } + + FormCard.FormCard { + Layout.fillWidth: true + + FormCard.FormButtonDelegate { + id: setupCompatToolButton + + text: i18n("Setup Compatibility Tool") + icon.name: "install" + onClicked: applicationWindow().pageStack.layers.push('qrc:/ui/Settings/CompatibilityToolSetup.qml') + } + + FormCard.FormDelegateSeparator { + above: setupCompatToolButton + below: developerSettingsButton + } + + FormCard.FormButtonDelegate { + id: developerSettingsButton + + text: i18n("Developer Settings") + icon.name: "configure" + onClicked: applicationWindow().pageStack.layers.push('qrc:/ui/Settings/DeveloperSettings.qml') + } + + FormCard.FormDelegateSeparator { + above: developerSettingsButton + below: aboutButton + } + + FormCard.FormButtonDelegate { + id: aboutButton + + text: i18n("About Astra") + icon.name: "help-about-symbolic" + + Component { + id: aboutPage + FormCard.AboutPage { + aboutData: About + } + } + + onClicked: applicationWindow().pageStack.layers.push(aboutPage) + } + } } \ No newline at end of file