From dae1a56691841cbc37d597c5da59bfbc91e1e1a9 Mon Sep 17 00:00:00 2001 From: Filippo Scognamiglio Date: Wed, 30 Jun 2021 08:33:31 +0200 Subject: [PATCH] Migrate from QtQuick.Controls 1.x to QtQuick.Controls 2.x. Updated QMLTermWidget submodule. --- app/main.cpp | 3 + app/qml/AboutDialog.qml | 34 +- app/qml/ApplicationSettings.qml | 3 +- app/qml/CheckableSlider.qml | 7 +- app/qml/ColorButton.qml | 3 +- app/qml/Components/SizedLabel.qml | 12 +- app/qml/Glossy.qml | 21 - app/qml/InsertNameDialog.qml | 2 +- app/qml/PreprocessedTerminal.qml | 29 +- app/qml/SettingsAdvancedTab.qml | 203 ++++----- app/qml/SettingsEffectsTab.qml | 119 +++--- app/qml/SettingsGeneralTab.qml | 385 +++++++++--------- app/qml/SettingsTerminalTab.qml | 246 ++++++----- app/qml/SettingsWindow.qml | 60 +-- app/qml/SimpleSlider.qml | 6 +- app/qml/main.qml | 12 +- app/qml/menus/FullContextMenu.qml | 72 ++++ app/qml/menus/ShortContextMenu.qml | 28 ++ .../WindowMenu.qml} | 33 +- app/qml/resources.qrc | 5 +- qmltermwidget | 2 +- 21 files changed, 682 insertions(+), 603 deletions(-) delete mode 100644 app/qml/Glossy.qml create mode 100644 app/qml/menus/FullContextMenu.qml create mode 100644 app/qml/menus/ShortContextMenu.qml rename app/qml/{CRTMainMenuBar.qml => menus/WindowMenu.qml} (53%) diff --git a/app/main.cpp b/app/main.cpp index 749a777..c58679e 100644 --- a/app/main.cpp +++ b/app/main.cpp @@ -79,6 +79,9 @@ int main(int argc, char *argv[]) app.setWindowIcon(QIcon(":../icons/32x32/cool-retro-term.png")); #endif + app.setOrganizationName("cool-retro-term"); + app.setOrganizationDomain("cool-retro-term"); + // Manage command line arguments from the cpp side QStringList args = app.arguments(); diff --git a/app/qml/AboutDialog.qml b/app/qml/AboutDialog.qml index 79d4936..cec04e8 100644 --- a/app/qml/AboutDialog.qml +++ b/app/qml/AboutDialog.qml @@ -1,5 +1,5 @@ import QtQuick 2.2 -import QtQuick.Controls 1.1 +import QtQuick.Controls 2.2 import QtQuick.Layouts 1.1 import QtQuick.Window 2.0 @@ -86,24 +86,28 @@ Window{ } Component{ id: licenseComponent - TextArea{ + ScrollView { anchors.fill: parent - readOnly: true - text: "Copyright (c) 2013 Filippo Scognamiglio \n\n" + - "https://github.com/Swordfish90/cool-retro-term\n\n" + + clip: true + TextArea{ + readOnly: true + wrapMode: TextEdit.Wrap + text: "Copyright (c) 2013 Filippo Scognamiglio \n\n" + + "https://github.com/Swordfish90/cool-retro-term\n\n" + - "cool-retro-term is free software: you can redistribute it and/or modify " + - "it under the terms of the GNU General Public License as published by " + - "the Free Software Foundation, either version 3 of the License, or " + - "(at your option) any later version.\n\n" + + "cool-retro-term is free software: you can redistribute it and/or modify " + + "it under the terms of the GNU General Public License as published by " + + "the Free Software Foundation, either version 3 of the License, or " + + "(at your option) any later version.\n\n" + - "This program is distributed in the hope that it will be useful, " + - "but WITHOUT ANY WARRANTY; without even the implied warranty of " + - "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the " + - "GNU General Public License for more details.\n\n" + + "This program is distributed in the hope that it will be useful, " + + "but WITHOUT ANY WARRANTY; without even the implied warranty of " + + "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the " + + "GNU General Public License for more details.\n\n" + - "You should have received a copy of the GNU General Public License " + - "along with this program. If not, see ." + "You should have received a copy of the GNU General Public License " + + "along with this program. If not, see ." + } } } } diff --git a/app/qml/ApplicationSettings.qml b/app/qml/ApplicationSettings.qml index d7a3866..96ccad2 100644 --- a/app/qml/ApplicationSettings.qml +++ b/app/qml/ApplicationSettings.qml @@ -19,7 +19,7 @@ *******************************************************************************/ import QtQuick 2.2 -import QtQuick.Controls 1.0 +import QtQuick.Controls 2.0 import "utils.js" as Utils @@ -336,6 +336,7 @@ QtObject{ _margin = settings.margin !== undefined ? settings.margin : _margin; + handleFontChanged(); } diff --git a/app/qml/CheckableSlider.qml b/app/qml/CheckableSlider.qml index 3548a9c..d2d55a3 100644 --- a/app/qml/CheckableSlider.qml +++ b/app/qml/CheckableSlider.qml @@ -19,7 +19,7 @@ *******************************************************************************/ import QtQuick 2.2 -import QtQuick.Controls 1.1 +import QtQuick.Controls 2.0 import QtQuick.Layouts 1.1 import "Components" @@ -28,8 +28,8 @@ RowLayout { property alias name: check.text property double value - property alias min_value: slider.minimumValue - property alias max_value: slider.maximumValue + property alias min_value: slider.from + property alias max_value: slider.to property alias stepSize: slider.stepSize signal newValue(real newValue); @@ -67,7 +67,6 @@ RowLayout { } } SizedLabel { - Layout.fillHeight: true text: Math.round(((value - min_value) / (max_value - min_value)) * 100) + "%" } } diff --git a/app/qml/ColorButton.qml b/app/qml/ColorButton.qml index 3b9e1b9..1a3eeaf 100644 --- a/app/qml/ColorButton.qml +++ b/app/qml/ColorButton.qml @@ -42,8 +42,7 @@ Item { anchors.fill: parent radius: 10 color: rootItem.color - border.color: "black" - Glossy {} + Rectangle { anchors.fill: parent anchors.margins: parent.height * 0.25 diff --git a/app/qml/Components/SizedLabel.qml b/app/qml/Components/SizedLabel.qml index 23a38b6..f289adb 100644 --- a/app/qml/Components/SizedLabel.qml +++ b/app/qml/Components/SizedLabel.qml @@ -20,16 +20,14 @@ import QtQuick 2.0 -import QtQuick.Controls 1.0 +import QtQuick.Controls 2.0 +import QtQuick.Layouts 1.0 // This component is simply a label with a predefined size. // Used to improve alignment. -Item { - property alias text: textfield.text +Label { + id: textfield + Layout.minimumWidth: appSettings.labelWidth width: appSettings.labelWidth - Label{ - id: textfield - anchors { right: parent.right; verticalCenter: parent.verticalCenter } - } } diff --git a/app/qml/Glossy.qml b/app/qml/Glossy.qml deleted file mode 100644 index 3ac9c14..0000000 --- a/app/qml/Glossy.qml +++ /dev/null @@ -1,21 +0,0 @@ -import QtQuick 2.2 - -Rectangle { - anchors.centerIn: parent - width: parent.width - parent.border.width - height: parent.height - parent.border.width - radius:parent.radius - parent.border.width/2 - smooth: true - - border.width: parent.border.width/2 - border.color: "#22FFFFFF" - - gradient: Gradient { - GradientStop { position: 0; color: "#88FFFFFF" } - GradientStop { position: .1; color: "#55FFFFFF" } - GradientStop { position: .5; color: "#33FFFFFF" } - GradientStop { position: .501; color: "#11000000" } - GradientStop { position: .8; color: "#11FFFFFF" } - GradientStop { position: 1; color: "#55FFFFFF" } - } -} diff --git a/app/qml/InsertNameDialog.qml b/app/qml/InsertNameDialog.qml index 22d31f7..fc316b3 100644 --- a/app/qml/InsertNameDialog.qml +++ b/app/qml/InsertNameDialog.qml @@ -20,7 +20,7 @@ import QtQuick 2.2 import QtQuick.Window 2.0 -import QtQuick.Controls 1.1 +import QtQuick.Controls 2.0 import QtQuick.Layouts 1.1 import QtQuick.Dialogs 1.1 diff --git a/app/qml/PreprocessedTerminal.qml b/app/qml/PreprocessedTerminal.qml index cb8698c..d9f4b5c 100644 --- a/app/qml/PreprocessedTerminal.qml +++ b/app/qml/PreprocessedTerminal.qml @@ -19,10 +19,11 @@ *******************************************************************************/ import QtQuick 2.2 -import QtQuick.Controls 1.1 +import QtQuick.Controls 2.0 import QMLTermWidget 1.0 +import "menus" import "utils.js" as Utils Item{ @@ -156,31 +157,23 @@ Item{ Component.onCompleted: { appSettings.terminalFontChanged.connect(handleFontChanged); appSettings.initializedSettings.connect(startSession); + appSettings.handleFontChanged() } } + Component { - id: linuxContextMenu - Menu{ - id: contextmenu - MenuItem { action: copyAction } - MenuItem { action: pasteAction } - MenuSeparator { visible: !appSettings.showMenubar } - MenuItem { action: showsettingsAction ; visible: !appSettings.showMenubar} - MenuSeparator { visible: !appSettings.showMenubar } - CRTMainMenuBar { visible: !appSettings.showMenubar } - } + id: shortContextMenu + ShortContextMenu { } } + Component { - id: osxContextMenu - Menu{ - id: contextmenu - MenuItem{action: copyAction} - MenuItem{action: pasteAction} - } + id: fullContextMenu + FullContextMenu { } } + Loader { id: menuLoader - sourceComponent: (Qt.platform.os === "osx" ? osxContextMenu : linuxContextMenu) + sourceComponent: (Qt.platform.os === "osx" || appSettings.showMenubar ? shortContextMenu : fullContextMenu) } property alias contextmenu: menuLoader.item diff --git a/app/qml/SettingsAdvancedTab.qml b/app/qml/SettingsAdvancedTab.qml index c0d486a..1ca7899 100644 --- a/app/qml/SettingsAdvancedTab.qml +++ b/app/qml/SettingsAdvancedTab.qml @@ -19,127 +19,128 @@ *******************************************************************************/ import QtQuick 2.2 -import QtQuick.Controls 1.1 +import QtQuick.Controls 2.0 import QtQuick.Layouts 1.1 +import QtQml 2.0 import "Components" -Tab{ - ColumnLayout{ - anchors.fill: parent +ColumnLayout{ + GroupBox{ + Layout.fillWidth: true + title: qsTr("Command") - GroupBox{ - Layout.fillWidth: true - title: qsTr("Command") - ColumnLayout { - anchors.fill: parent - CheckBox{ - id: useCustomCommand - text: qsTr("Use custom command instead of shell at startup") - checked: appSettings.useCustomCommand - onCheckedChanged: appSettings.useCustomCommand = checked - } - // Workaround for QTBUG-31627 for pre 5.3.0 - Binding{ - target: useCustomCommand - property: "checked" - value: appSettings.useCustomCommand - } - TextField{ - id: customCommand - Layout.fillWidth: true - text: appSettings.customCommand - enabled: useCustomCommand.checked - onEditingFinished: appSettings.customCommand = text + ColumnLayout { + anchors.fill: parent + CheckBox{ + id: useCustomCommand + text: qsTr("Use custom command instead of shell at startup") + checked: appSettings.useCustomCommand + onCheckedChanged: appSettings.useCustomCommand = checked + } + // Workaround for QTBUG-31627 for pre 5.3.0 + Binding{ + target: useCustomCommand + property: "checked" + value: appSettings.useCustomCommand + } + TextField{ + id: customCommand + Layout.fillWidth: true + text: appSettings.customCommand + enabled: useCustomCommand.checked + onEditingFinished: appSettings.customCommand = text - // Save text even if user forgets to press enter or unfocus - function saveSetting() { - appSettings.customCommand = text; - } - Component.onCompleted: settings_window.closing.connect(saveSetting) + // Save text even if user forgets to press enter or unfocus + function saveSetting() { + appSettings.customCommand = text; } + Component.onCompleted: settings_window.closing.connect(saveSetting) } } + } - GroupBox{ - title: qsTr("Performance") - Layout.fillWidth: true - GridLayout{ - anchors.fill: parent - rows: 2 - columns: 3 + GroupBox{ + title: qsTr("Performance") + Layout.fillWidth: true + GridLayout{ + anchors.fill: parent + columns: 4 - Label{text: qsTr("Effects FPS")} - Slider{ - Layout.fillWidth: true - id: fpsSlider - onValueChanged: { - if (enabled) { - appSettings.fps = value !== 60 ? value + 1 : 0; - } - } - stepSize: 1 - enabled: false - Component.onCompleted: { - minimumValue = 0; - maximumValue = 60; - value = appSettings.fps !== 0 ? appSettings.fps - 1 : 60; - enabled = true; + Label{text: qsTr("Effects FPS")} + Slider{ + Layout.fillWidth: true + Layout.columnSpan: 2 + id: fpsSlider + onValueChanged: { + if (enabled) { + appSettings.fps = value !== 60 ? value + 1 : 0; } } + stepSize: 1 + enabled: false + Component.onCompleted: { + from = 0; + to = 60; + value = appSettings.fps !== 0 ? appSettings.fps - 1 : 60; + enabled = true; + } + } - SizedLabel{text: appSettings.fps !== 0 ? appSettings.fps : qsTr("Max")} - Label{text: qsTr("Texture Quality")} - Slider{ - Layout.fillWidth: true - id: txtslider - onValueChanged: if (enabled) appSettings.windowScaling = value; - stepSize: 0.05 - enabled: false - Component.onCompleted: { - minimumValue = 0.25 //Without this value gets set to 0.5 - value = appSettings.windowScaling; - enabled = true; - } + Label{text: appSettings.fps !== 0 ? appSettings.fps : qsTr("Max")} + Label{text: qsTr("Texture Quality")} + Slider{ + id: txtslider + Layout.fillWidth: true + Layout.columnSpan: 2 + onValueChanged: if (enabled) appSettings.windowScaling = value; + stepSize: 0.05 + enabled: false + Component.onCompleted: { + from = 0.25 //Without this value gets set to 0.5 + value = appSettings.windowScaling; + enabled = true; } - SizedLabel{text: Math.round(txtslider.value * 100) + "%"} + } + Label{text: Math.round(txtslider.value * 100) + "%"} - Label{text: qsTr("Bloom Quality")} - Slider{ - Layout.fillWidth: true - id: bloomSlider - onValueChanged: if (enabled) appSettings.bloomQuality = value; - stepSize: 0.05 - enabled: false - Component.onCompleted: { - minimumValue = 0.25 - value = appSettings.bloomQuality; - enabled = true; - } + Label{text: qsTr("Bloom Quality")} + Slider{ + Layout.fillWidth: true + Layout.columnSpan: 2 + id: bloomSlider + onValueChanged: if (enabled) appSettings.bloomQuality = value; + stepSize: 0.05 + enabled: false + Component.onCompleted: { + from = 0.25 + value = appSettings.bloomQuality; + enabled = true; } - SizedLabel{text: Math.round(bloomSlider.value * 100) + "%"} + } + Label{text: Math.round(bloomSlider.value * 100) + "%"} - Label{text: qsTr("BurnIn Quality")} - Slider{ - Layout.fillWidth: true - id: burnInSlider - onValueChanged: if (enabled) appSettings.burnInQuality = value; - stepSize: 0.05 - enabled: false - Component.onCompleted: { - minimumValue = 0.25 - value = appSettings.burnInQuality; - enabled = true; - } - } - SizedLabel{text: Math.round(burnInSlider.value * 100) + "%"} - CheckBox{ - Layout.columnSpan: 2 - text: qsTr("Burnin optimization (Might display timing artifacts)") - checked: appSettings.useFastBurnIn - onCheckedChanged: appSettings.useFastBurnIn = checked + Label{text: qsTr("BurnIn Quality")} + Slider{ + Layout.fillWidth: true + id: burnInSlider + Layout.columnSpan: 2 + onValueChanged: if (enabled) appSettings.burnInQuality = value; + stepSize: 0.05 + enabled: false + Component.onCompleted: { + from = 0.25 + value = appSettings.burnInQuality; + enabled = true; } } + Label{text: Math.round(burnInSlider.value * 100) + "%"} + CheckBox{ + Layout.columnSpan: 2 + text: qsTr("Burnin optimization (Might display timing artifacts)") + checked: appSettings.useFastBurnIn + onCheckedChanged: appSettings.useFastBurnIn = checked + } } } } diff --git a/app/qml/SettingsEffectsTab.qml b/app/qml/SettingsEffectsTab.qml index c14ede2..e51299b 100644 --- a/app/qml/SettingsEffectsTab.qml +++ b/app/qml/SettingsEffectsTab.qml @@ -19,72 +19,69 @@ *******************************************************************************/ import QtQuick 2.2 -import QtQuick.Controls 1.1 +import QtQuick.Controls 2.0 import QtQuick.Layouts 1.1 -Tab{ - ColumnLayout{ - anchors.fill: parent - spacing: 2 +ColumnLayout{ + spacing: 2 - GroupBox{ - title: qsTr("Effects") - Layout.fillWidth: true + GroupBox{ + title: qsTr("Effects") + Layout.fillWidth: true - ColumnLayout { - anchors.fill: parent + ColumnLayout { + anchors.fill: parent - CheckableSlider{ - name: qsTr("Bloom") - onNewValue: appSettings.bloom = newValue - value: appSettings.bloom - } - CheckableSlider{ - name: qsTr("BurnIn") - onNewValue: appSettings.burnIn = newValue - value: appSettings.burnIn - } - CheckableSlider{ - name: qsTr("Static Noise") - onNewValue: appSettings.staticNoise = newValue - value: appSettings.staticNoise - } - CheckableSlider{ - name: qsTr("Jitter") - onNewValue: appSettings.jitter = newValue - value: appSettings.jitter - } - CheckableSlider{ - name: qsTr("Glow Line") - onNewValue: appSettings.glowingLine = newValue; - value: appSettings.glowingLine - } - CheckableSlider{ - name: qsTr("Screen Curvature") - onNewValue: appSettings.screenCurvature = newValue; - value: appSettings.screenCurvature; - } - CheckableSlider{ - name: qsTr("Ambient Light") - onNewValue: appSettings.ambientLight = newValue; - value: appSettings.ambientLight - enabled: appSettings.framesIndex !== 0 - } - CheckableSlider{ - name: qsTr("Flickering") - onNewValue: appSettings.flickering = newValue; - value: appSettings.flickering; - } - CheckableSlider{ - name: qsTr("Horizontal Sync") - onNewValue: appSettings.horizontalSync = newValue; - value: appSettings.horizontalSync; - } - CheckableSlider{ - name: qsTr("RGB Shift") - onNewValue: appSettings.rbgShift = newValue; - value: appSettings.rbgShift; - } + CheckableSlider{ + name: qsTr("Bloom") + onNewValue: appSettings.bloom = newValue + value: appSettings.bloom + } + CheckableSlider{ + name: qsTr("BurnIn") + onNewValue: appSettings.burnIn = newValue + value: appSettings.burnIn + } + CheckableSlider{ + name: qsTr("Static Noise") + onNewValue: appSettings.staticNoise = newValue + value: appSettings.staticNoise + } + CheckableSlider{ + name: qsTr("Jitter") + onNewValue: appSettings.jitter = newValue + value: appSettings.jitter + } + CheckableSlider{ + name: qsTr("Glow Line") + onNewValue: appSettings.glowingLine = newValue; + value: appSettings.glowingLine + } + CheckableSlider{ + name: qsTr("Screen Curvature") + onNewValue: appSettings.screenCurvature = newValue; + value: appSettings.screenCurvature; + } + CheckableSlider{ + name: qsTr("Ambient Light") + onNewValue: appSettings.ambientLight = newValue; + value: appSettings.ambientLight + enabled: appSettings.framesIndex !== 0 + } + CheckableSlider{ + name: qsTr("Flickering") + onNewValue: appSettings.flickering = newValue; + value: appSettings.flickering; + } + CheckableSlider{ + name: qsTr("Horizontal Sync") + onNewValue: appSettings.horizontalSync = newValue; + value: appSettings.horizontalSync; + } + CheckableSlider{ + name: qsTr("RGB Shift") + onNewValue: appSettings.rbgShift = newValue; + value: appSettings.rbgShift; } } } diff --git a/app/qml/SettingsGeneralTab.qml b/app/qml/SettingsGeneralTab.qml index 9efaedb..bd46a1f 100644 --- a/app/qml/SettingsGeneralTab.qml +++ b/app/qml/SettingsGeneralTab.qml @@ -19,216 +19,217 @@ *******************************************************************************/ import QtQuick 2.2 -import QtQuick.Controls 1.1 +import QtQuick.Controls 2.4 import QtQuick.Layouts 1.1 import QtQuick.Dialogs 1.1 -Tab{ - ColumnLayout{ - anchors.fill: parent - GroupBox{ - Layout.fillWidth: true - Layout.fillHeight: true - title: qsTr("Profile") - RowLayout { - anchors.fill: parent - TableView { - id: profilesView +ColumnLayout{ + GroupBox{ + Layout.fillWidth: true + title: qsTr("Profile") + RowLayout { + anchors.fill: parent + ListView { + id: profilesView + Layout.fillWidth: true + Layout.fillHeight: true + model: appSettings.profilesList + delegate: Rectangle { + width: label.width + height: label.height + color: (index == profilesView.currentIndex) ? palette.highlight : palette.base + Label { + id: label + text: appSettings.profilesList.get(index).text + MouseArea { + anchors.fill: parent + onClicked: profilesView.currentIndex = index + onDoubleClicked: appSettings.loadProfile(index) + } + } + } + } + ColumnLayout { + Layout.fillHeight: true + Layout.fillWidth: false + Button{ Layout.fillWidth: true + text: qsTr("Save") + onClicked: { + insertname.profileName = ""; + insertname.show() + } + } + Button{ + Layout.fillWidth: true + property alias currentIndex: profilesView.currentIndex + enabled: currentIndex >= 0 + text: qsTr("Load") + onClicked: { + var index = currentIndex; + if (index >= 0) + appSettings.loadProfile(index); + } + } + Button{ + Layout.fillWidth: true + text: qsTr("Remove") + property alias currentIndex: profilesView.currentIndex + + enabled: currentIndex >= 0 && !appSettings.profilesList.get(currentIndex).builtin + onClicked: { + appSettings.profilesList.remove(currentIndex); + profilesView.selection.clear(); + + // TODO This is a very ugly workaround. The view didn't update on Qt 5.3.2. + profilesView.model = 0; + profilesView.model = appSettings.profilesList; + } + } + Item { + // Spacing Layout.fillHeight: true - model: appSettings.profilesList - headerVisible: false - TableViewColumn { - title: qsTr("Profile") - role: "text" - width: parent.width * 0.5 - } - onActivated: { - appSettings.loadProfile(row); - } } - ColumnLayout { - Layout.fillHeight: true - Layout.fillWidth: false - Button{ - Layout.fillWidth: true - text: qsTr("Save") - onClicked: { - insertname.profileName = ""; - insertname.show() - } + Button{ + Layout.fillWidth: true + text: qsTr("Import") + onClicked: { + fileDialog.selectExisting = true; + fileDialog.callBack = function (url) {loadFile(url);}; + fileDialog.open(); } - Button{ - Layout.fillWidth: true - property alias currentIndex: profilesView.currentRow - enabled: currentIndex >= 0 - text: qsTr("Load") - onClicked: { - var index = profilesView.currentRow; - if (index >= 0) - appSettings.loadProfile(index); - } - } - Button{ - Layout.fillWidth: true - text: qsTr("Remove") - property alias currentIndex: profilesView.currentRow + function loadFile(url) { + try { + if (appSettings.verbose) + console.log("Loading file: " + url); - enabled: currentIndex >= 0 && !appSettings.profilesList.get(currentIndex).builtin - onClicked: { - appSettings.profilesList.remove(currentIndex); - profilesView.selection.clear(); + var profileObject = JSON.parse(fileIO.read(url)); + var name = profileObject.name; - // TODO This is a very ugly workaround. The view didn't update on Qt 5.3.2. - profilesView.model = 0; - profilesView.model = appSettings.profilesList; - } - } - Item { - // Spacing - Layout.fillHeight: true - } - Button{ - Layout.fillWidth: true - text: qsTr("Import") - onClicked: { - fileDialog.selectExisting = true; - fileDialog.callBack = function (url) {loadFile(url);}; - fileDialog.open(); - } - function loadFile(url) { - try { - if (appSettings.verbose) - console.log("Loading file: " + url); + if (!name) + throw "Profile doesn't have a name"; - var profileObject = JSON.parse(fileIO.read(url)); - var name = profileObject.name; + var version = profileObject.version !== undefined ? profileObject.version : 1; + if (version !== appSettings.profileVersion) + throw "This profile is not supported on this version of CRT."; - if (!name) - throw "Profile doesn't have a name"; + delete profileObject.name; - var version = profileObject.version !== undefined ? profileObject.version : 1; - if (version !== appSettings.profileVersion) - throw "This profile is not supported on this version of CRT."; - - delete profileObject.name; - - appSettings.appendCustomProfile(name, JSON.stringify(profileObject)); - } catch (err) { - messageDialog.text = qsTr(err) - messageDialog.open(); - } - } - } - Button{ - property alias currentIndex: profilesView.currentRow - - Layout.fillWidth: true - - text: qsTr("Export") - enabled: currentIndex >= 0 && !appSettings.profilesList.get(currentIndex).builtin - onClicked: { - fileDialog.selectExisting = false; - fileDialog.callBack = function (url) {storeFile(url);}; - fileDialog.open(); - } - function storeFile(url) { - try { - var urlString = url.toString(); - - // Fix the extension if it's missing. - var extension = urlString.substring(urlString.length - 5, urlString.length); - var urlTail = (extension === ".json" ? "" : ".json"); - url += urlTail; - - if (true) - console.log("Storing file: " + url); - - var profileObject = appSettings.profilesList.get(currentIndex); - var profileSettings = JSON.parse(profileObject.obj_string); - profileSettings["name"] = profileObject.text; - profileSettings["version"] = appSettings.profileVersion; - - var result = fileIO.write(url, JSON.stringify(profileSettings, undefined, 2)); - if (!result) - throw "The file could not be written."; - } catch (err) { - console.log(err); - messageDialog.text = qsTr("There has been an error storing the file.") - messageDialog.open(); - } + appSettings.appendCustomProfile(name, JSON.stringify(profileObject)); + } catch (err) { + messageDialog.text = qsTr(err) + messageDialog.open(); } } } - } - } + Button{ + property alias currentIndex: profilesView.currentIndex - GroupBox{ - title: qsTr("Screen") - Layout.fillWidth: true - GridLayout{ - anchors.fill: parent - columns: 2 - Label{ text: qsTr("Brightness") } - SimpleSlider{ - onValueChanged: appSettings.brightness = value - value: appSettings.brightness + Layout.fillWidth: true + + text: qsTr("Export") + enabled: currentIndex >= 0 && !appSettings.profilesList.get(currentIndex).builtin + onClicked: { + fileDialog.selectExisting = false; + fileDialog.callBack = function (url) {storeFile(url);}; + fileDialog.open(); + } + function storeFile(url) { + try { + var urlString = url.toString(); + + // Fix the extension if it's missing. + var extension = urlString.substring(urlString.length - 5, urlString.length); + var urlTail = (extension === ".json" ? "" : ".json"); + url += urlTail; + + if (true) + console.log("Storing file: " + url); + + var profileObject = appSettings.profilesList.get(currentIndex); + var profileSettings = JSON.parse(profileObject.obj_string); + profileSettings["name"] = profileObject.text; + profileSettings["version"] = appSettings.profileVersion; + + var result = fileIO.write(url, JSON.stringify(profileSettings, undefined, 2)); + if (!result) + throw "The file could not be written."; + } catch (err) { + console.log(err); + messageDialog.text = qsTr("There has been an error storing the file.") + messageDialog.open(); + } + } } - Label{ text: qsTr("Contrast") } - SimpleSlider{ - onValueChanged: appSettings.contrast = value - value: appSettings.contrast - } - Label{ text: qsTr("Margin") } - SimpleSlider{ - onValueChanged: appSettings._margin = value - value: appSettings._margin - } - Label{ text: qsTr("Opacity") } - SimpleSlider{ - onValueChanged: appSettings.windowOpacity = value - value: appSettings.windowOpacity - } - } - } - - // DIALOGS //////////////////////////////////////////////////////////////// - InsertNameDialog{ - id: insertname - onNameSelected: { - appSettings.appendCustomProfile(name, appSettings.composeProfileString()); - } - } - MessageDialog { - id: messageDialog - title: qsTr("File Error") - onAccepted: { - messageDialog.close(); - } - } - Loader { - property var callBack - property bool selectExisting: false - id: fileDialog - - sourceComponent: FileDialog{ - nameFilters: ["Json files (*.json)"] - selectMultiple: false - selectFolder: false - selectExisting: fileDialog.selectExisting - onAccepted: callBack(fileUrl); - } - - onSelectExistingChanged: reload() - - function open() { - item.open(); - } - - function reload() { - active = false; - active = true; } } } + + GroupBox{ + title: qsTr("Screen") + Layout.fillWidth: true + GridLayout{ + anchors.fill: parent + columns: 2 + Label{ text: qsTr("Brightness") } + SimpleSlider{ + onValueChanged: appSettings.brightness = value + value: appSettings.brightness + } + Label{ text: qsTr("Contrast") } + SimpleSlider{ + onValueChanged: appSettings.contrast = value + value: appSettings.contrast + } + Label{ text: qsTr("Margin") } + SimpleSlider{ + onValueChanged: appSettings._margin = value + value: appSettings._margin + } + Label{ text: qsTr("Opacity") } + SimpleSlider{ + onValueChanged: appSettings.windowOpacity = value + value: appSettings.windowOpacity + } + } + } + + // DIALOGS //////////////////////////////////////////////////////////////// + InsertNameDialog{ + id: insertname + onNameSelected: { + appSettings.appendCustomProfile(name, appSettings.composeProfileString()); + } + } + MessageDialog { + id: messageDialog + title: qsTr("File Error") + onAccepted: { + messageDialog.close(); + } + } + Loader { + property var callBack + property bool selectExisting: false + id: fileDialog + + sourceComponent: FileDialog{ + nameFilters: ["Json files (*.json)"] + selectMultiple: false + selectFolder: false + selectExisting: fileDialog.selectExisting + onAccepted: callBack(fileUrl); + } + + onSelectExistingChanged: reload() + + function open() { + item.open(); + } + + function reload() { + active = false; + active = true; + } + } } diff --git a/app/qml/SettingsTerminalTab.qml b/app/qml/SettingsTerminalTab.qml index 914a90c..ba5a0b6 100644 --- a/app/qml/SettingsTerminalTab.qml +++ b/app/qml/SettingsTerminalTab.qml @@ -19,154 +19,142 @@ *******************************************************************************/ import QtQuick 2.2 -import QtQuick.Controls 1.1 +import QtQuick.Controls 2.1 import QtQuick.Layouts 1.1 +import QtQml 2.0 import "Components" -Tab{ - ColumnLayout{ - anchors.fill: parent +ColumnLayout{ - GroupBox{ - title: qsTr("Font") - Layout.fillWidth: true - GridLayout{ - anchors.fill: parent - columns: 2 - Label { text: qsTr("Rasterization") } - ComboBox { - id: rasterizationBox + GroupBox{ + title: qsTr("Font") + Layout.fillWidth: true + GridLayout{ + anchors.fill: parent + columns: 2 + Label { text: qsTr("Rasterization") } + ComboBox { + id: rasterizationBox - property string selectedElement: model[currentIndex] + property string selectedElement: model[currentIndex] - Layout.fillWidth: true - model: [qsTr("Default"), qsTr("Scanlines"), qsTr("Pixels")] - currentIndex: appSettings.rasterization - onCurrentIndexChanged: { - appSettings.rasterization = currentIndex - } + Layout.fillWidth: true + model: [qsTr("Default"), qsTr("Scanlines"), qsTr("Pixels")] + currentIndex: appSettings.rasterization + onCurrentIndexChanged: { + appSettings.rasterization = currentIndex } - Label{ text: qsTr("Name") } - ComboBox{ - id: fontChanger - Layout.fillWidth: true - model: appSettings.fontlist - onActivated: { - var name = appSettings.fontlist.get(index).name; - appSettings.fontNames[appSettings.rasterization] = name; - appSettings.handleFontChanged(); - } - function updateIndex(){ - var name = appSettings.fontNames[appSettings.rasterization]; - var index = appSettings.getIndexByName(name); - if (index !== undefined) - currentIndex = index; - } - Connections{ - target: appSettings - onTerminalFontChanged: fontChanger.updateIndex(); - } - Component.onCompleted: updateIndex(); + } + Label{ text: qsTr("Name") } + ComboBox{ + id: fontChanger + Layout.fillWidth: true + model: appSettings.fontlist + textRole: "text" + onActivated: { + var name = appSettings.fontlist.get(index).name; + appSettings.fontNames[appSettings.rasterization] = name; + appSettings.handleFontChanged(); } - Label{ text: qsTr("Scaling") } - RowLayout{ - Layout.fillWidth: true - Slider{ - Layout.fillWidth: true - id: fontScalingChanger - onValueChanged: if(enabled) appSettings.fontScaling = value - stepSize: 0.05 - enabled: false // Another trick to fix initial bad behavior. - Component.onCompleted: { - minimumValue = appSettings.minimumFontScaling; - maximumValue = appSettings.maximumFontScaling; - value = appSettings.fontScaling; - enabled = true; - } - Connections{ - target: appSettings - onFontScalingChanged: fontScalingChanger.value = appSettings.fontScaling; - } - } - SizedLabel{ - text: Math.round(fontScalingChanger.value * 100) + "%" - } + function updateIndex(){ + var name = appSettings.fontNames[appSettings.rasterization]; + var index = appSettings.getIndexByName(name); + if (index !== undefined) + currentIndex = index; } - Label{ text: qsTr("Font Width") } - RowLayout{ + Connections{ + target: appSettings + onTerminalFontChanged: fontChanger.updateIndex(); + } + Component.onCompleted: updateIndex(); + } + Label{ text: qsTr("Scaling") } + RowLayout{ + Layout.fillWidth: true + Slider{ Layout.fillWidth: true - Slider{ - Layout.fillWidth: true - id: widthChanger - onValueChanged: appSettings.fontWidth = value; - value: appSettings.fontWidth - stepSize: 0.05 - Component.onCompleted: { - // This is needed to avoid unnecessary chnaged events. - minimumValue = 0.5; - maximumValue = 1.5; - } - } - SizedLabel{ - text: Math.round(widthChanger.value * 100) + "%" - } + id: fontScalingChanger + onValueChanged: appSettings.fontScaling = value + value: appSettings.fontScaling + stepSize: 0.05 + from: appSettings.minimumFontScaling; + to: appSettings.maximumFontScaling; + } + SizedLabel{ + text: Math.round(fontScalingChanger.value * 100) + "%" + } + } + Label{ text: qsTr("Font Width") } + RowLayout{ + Layout.fillWidth: true + Slider{ + Layout.fillWidth: true + id: widthChanger + onValueChanged: appSettings.fontWidth = value; + value: appSettings.fontWidth + stepSize: 0.05 + from: 0.5 + to: 1.5 + } + SizedLabel{ + text: Math.round(widthChanger.value * 100) + "%" } } } - GroupBox{ - title: qsTr("Cursor") - Layout.fillWidth: true - ColumnLayout { - anchors.fill: parent - CheckBox{ - id: blinkingCursor - text: qsTr("Blinking Cursor") - checked: appSettings.blinkingCursor - onCheckedChanged: appSettings.blinkingCursor = checked - } - Binding{ - target: blinkingCursor - property: "checked" - value: appSettings.blinkingCursor - } + } + GroupBox{ + title: qsTr("Cursor") + Layout.fillWidth: true + ColumnLayout { + anchors.fill: parent + CheckBox{ + id: blinkingCursor + text: qsTr("Blinking Cursor") + checked: appSettings.blinkingCursor + onCheckedChanged: appSettings.blinkingCursor = checked + } + Binding{ + target: blinkingCursor + property: "checked" + value: appSettings.blinkingCursor } } - GroupBox{ - title: qsTr("Colors") - Layout.fillWidth: true + } + GroupBox{ + title: qsTr("Colors") + Layout.fillWidth: true + ColumnLayout{ + anchors.fill: parent ColumnLayout{ - anchors.fill: parent - ColumnLayout{ - Layout.fillWidth: true - CheckableSlider{ - name: qsTr("Chroma Color") - onNewValue: appSettings.chromaColor = newValue - value: appSettings.chromaColor - } - CheckableSlider{ - name: qsTr("Saturation Color") - onNewValue: appSettings.saturationColor = newValue - value: appSettings.saturationColor - enabled: appSettings.chromaColor !== 0 - } + Layout.fillWidth: true + CheckableSlider{ + name: qsTr("Chroma Color") + onNewValue: appSettings.chromaColor = newValue + value: appSettings.chromaColor } - RowLayout{ + CheckableSlider{ + name: qsTr("Saturation Color") + onNewValue: appSettings.saturationColor = newValue + value: appSettings.saturationColor + enabled: appSettings.chromaColor !== 0 + } + } + RowLayout{ + Layout.fillWidth: true + ColorButton{ + name: qsTr("Font") + height: 50 Layout.fillWidth: true - ColorButton{ - name: qsTr("Font") - height: 50 - Layout.fillWidth: true - onColorSelected: appSettings._fontColor = color; - color: appSettings._fontColor - } - ColorButton{ - name: qsTr("Background") - height: 50 - Layout.fillWidth: true - onColorSelected: appSettings._backgroundColor = color; - color: appSettings._backgroundColor - } + onColorSelected: appSettings._fontColor = color; + color: appSettings._fontColor + } + ColorButton{ + name: qsTr("Background") + height: 50 + Layout.fillWidth: true + onColorSelected: appSettings._backgroundColor = color; + color: appSettings._backgroundColor } } } diff --git a/app/qml/SettingsWindow.qml b/app/qml/SettingsWindow.qml index 78a0031..3ce63dc 100644 --- a/app/qml/SettingsWindow.qml +++ b/app/qml/SettingsWindow.qml @@ -19,46 +19,50 @@ *******************************************************************************/ import QtQuick 2.2 -import QtQuick.Controls 1.1 +import QtQuick.Controls 2.1 import QtQuick.Window 2.1 -import QtQuick.Layouts 1.1 +import QtQuick.Layouts 1.3 import QtQuick.Dialogs 1.1 Window { id: settings_window title: qsTr("Settings") - width: 580 - height: 400 + width: 800 + height: 600 property int tabmargins: 15 - TabView{ - id: tabView - anchors.fill: parent - anchors.margins: 10 - SettingsGeneralTab { - id: generalTab - title: qsTr("General") - anchors.fill: parent - anchors.margins: tabmargins + TabBar { + id: bar + width: parent.width + TabButton { + text: qsTr("General") } - SettingsTerminalTab { - id: terminalTab - title: qsTr("Terminal") - anchors.fill: parent - anchors.margins: tabmargins + TabButton { + text: qsTr("Terminal") } - SettingsEffectsTab { - id: effectsTab - title: qsTr("Effects") - anchors.fill: parent - anchors.margins: tabmargins + TabButton { + text: qsTr("Effects") } - SettingsAdvancedTab { - id: performanceTab - title: qsTr("Advanced") - anchors.fill: parent - anchors.margins: tabmargins + TabButton { + text: qsTr("Advanced") } } + + StackLayout { + anchors { + top: bar.bottom + left: parent.left + right: parent.right + bottom: parent.bottom + margins: tabmargins + } + + currentIndex: bar.currentIndex + + SettingsGeneralTab { } + SettingsTerminalTab { } + SettingsEffectsTab { } + SettingsAdvancedTab { } + } } diff --git a/app/qml/SimpleSlider.qml b/app/qml/SimpleSlider.qml index 44d3608..003460f 100644 --- a/app/qml/SimpleSlider.qml +++ b/app/qml/SimpleSlider.qml @@ -19,7 +19,7 @@ *******************************************************************************/ import QtQuick 2.2 -import QtQuick.Controls 1.1 +import QtQuick.Controls 2.0 import QtQuick.Layouts 1.1 import "Components" @@ -27,8 +27,8 @@ import "Components" RowLayout { property alias value: slider.value property alias stepSize: slider.stepSize - property alias minimumValue: slider.minimumValue - property alias maximumValue: slider.maximumValue + property alias minimumValue: slider.from + property alias maximumValue: slider.to property real maxMultiplier: 100 id: setting_component diff --git a/app/qml/main.qml b/app/qml/main.qml index 99d8522..a1fe125 100644 --- a/app/qml/main.qml +++ b/app/qml/main.qml @@ -20,8 +20,9 @@ import QtQuick 2.2 import QtQuick.Window 2.1 -import QtQuick.Controls 1.1 -import QtGraphicalEffects 1.0 +import QtQuick.Controls 2.3 + +import "menus" ApplicationWindow{ id: terminalWindow @@ -37,8 +38,6 @@ ApplicationWindow{ // Load saved window geometry and show the window Component.onCompleted: { - appSettings.handleFontChanged(); - x = appSettings.x y = appSettings.y width = appSettings.width @@ -55,11 +54,9 @@ ApplicationWindow{ property bool fullscreen: appSettings.fullscreen onFullscreenChanged: visibility = (fullscreen ? Window.FullScreen : Window.Windowed) - //Workaround: Without __contentItem a ugly thin border is visible. - menuBar: CRTMainMenuBar{ + menuBar: WindowMenu { id: mainMenu visible: (Qt.platform.os === "osx" || appSettings.showMenubar) - __contentItem.visible: mainMenu.visible } property string wintitle: appSettings.wintitle @@ -136,7 +133,6 @@ ApplicationWindow{ } TerminalContainer{ id: terminalContainer - y: appSettings.showMenubar ? 0 : -2 // Workaroud to hide the margin in the menubar. width: parent.width height: (parent.height + Math.abs(y)) } diff --git a/app/qml/menus/FullContextMenu.qml b/app/qml/menus/FullContextMenu.qml new file mode 100644 index 0000000..1b75320 --- /dev/null +++ b/app/qml/menus/FullContextMenu.qml @@ -0,0 +1,72 @@ +/******************************************************************************* +* Copyright (c) 2013-2021 "Filippo Scognamiglio" +* https://github.com/Swordfish90/cool-retro-term +* +* This file is part of cool-retro-term. +* +* cool-retro-term is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program. If not, see . +*******************************************************************************/ + +import QtQuick 2.2 +import QtQuick.Controls 2.3 + +Menu{ + id: contextmenu + MenuItem { action: copyAction } + MenuItem { action: pasteAction } + MenuItem { action: showsettingsAction } + + MenuSeparator { } + + Menu { + title: qsTr("File") + MenuItem { + action: quitAction + } + } + Menu { + title: qsTr("Edit") + MenuItem {action: copyAction} + MenuItem {action: pasteAction} + MenuSeparator { } + MenuItem {action: showsettingsAction} + } + Menu{ + title: qsTr("View") + MenuItem {action: fullscreenAction; visible: fullscreenAction.enabled} + MenuItem {action: showMenubarAction; visible: showMenubarAction.enabled} + MenuItem {action: zoomIn} + MenuItem {action: zoomOut} + } + Menu{ + id: profilesMenu + title: qsTr("Profiles") + Instantiator{ + model: appSettings.profilesList + delegate: MenuItem { + text: model.text + onTriggered: { + appSettings.loadProfileString(obj_string); + appSettings.handleFontChanged(); + } + } + onObjectAdded: profilesMenu.insertItem(index, object) + onObjectRemoved: profilesMenu.removeItem(object) + } + } + Menu{ + title: qsTr("Help") + MenuItem {action: showAboutAction} + } +} diff --git a/app/qml/menus/ShortContextMenu.qml b/app/qml/menus/ShortContextMenu.qml new file mode 100644 index 0000000..ea711ca --- /dev/null +++ b/app/qml/menus/ShortContextMenu.qml @@ -0,0 +1,28 @@ +/******************************************************************************* +* Copyright (c) 2013-2021 "Filippo Scognamiglio" +* https://github.com/Swordfish90/cool-retro-term +* +* This file is part of cool-retro-term. +* +* cool-retro-term is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program. If not, see . +*******************************************************************************/ + +import QtQuick 2.2 +import QtQuick.Controls 2.3 + +Menu{ + id: contextmenu + MenuItem { action: copyAction } + MenuItem { action: pasteAction } +} diff --git a/app/qml/CRTMainMenuBar.qml b/app/qml/menus/WindowMenu.qml similarity index 53% rename from app/qml/CRTMainMenuBar.qml rename to app/qml/menus/WindowMenu.qml index be5423e..6154f1f 100644 --- a/app/qml/CRTMainMenuBar.qml +++ b/app/qml/menus/WindowMenu.qml @@ -1,35 +1,51 @@ +/******************************************************************************* +* Copyright (c) 2013-2021 "Filippo Scognamiglio" +* https://github.com/Swordfish90/cool-retro-term +* +* This file is part of cool-retro-term. +* +* cool-retro-term is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program. If not, see . +*******************************************************************************/ + import QtQuick 2.2 -import QtQuick.Controls 1.1 +import QtQuick.Controls 2.3 MenuBar { id: defaultMenuBar - property bool visible: true + visible: appSettings.showMenubar + Menu { title: qsTr("File") - visible: defaultMenuBar.visible MenuItem {action: quitAction} } Menu { title: qsTr("Edit") - visible: defaultMenuBar.visible && appSettings.showMenubar MenuItem {action: copyAction} MenuItem {action: pasteAction} - MenuSeparator{visible: Qt.platform.os !== "osx"} + MenuSeparator { } MenuItem {action: showsettingsAction} } Menu{ title: qsTr("View") - visible: defaultMenuBar.visible MenuItem {action: fullscreenAction; visible: fullscreenAction.enabled} MenuItem {action: showMenubarAction; visible: showMenubarAction.enabled} - MenuSeparator{visible: showMenubarAction.enabled} MenuItem {action: zoomIn} MenuItem {action: zoomOut} } Menu{ id: profilesMenu title: qsTr("Profiles") - visible: defaultMenuBar.visible Instantiator{ model: appSettings.profilesList delegate: MenuItem { @@ -45,7 +61,6 @@ MenuBar { } Menu{ title: qsTr("Help") - visible: defaultMenuBar.visible MenuItem {action: showAboutAction} } } diff --git a/app/qml/resources.qrc b/app/qml/resources.qrc index 8df465f..ac04e1d 100644 --- a/app/qml/resources.qrc +++ b/app/qml/resources.qrc @@ -12,7 +12,6 @@ TimeManager.qml SimpleSlider.qml ColorButton.qml - Glossy.qml AboutDialog.qml InsertNameDialog.qml SettingsEffectsTab.qml @@ -22,7 +21,6 @@ fonts/1977-apple2/PrintChar21.ttf fonts/1971-ibm-3278/3270Medium.ttf Storage.qml - CRTMainMenuBar.qml SettingsAdvancedTab.qml TerminalContainer.qml images/crt256.png @@ -44,5 +42,8 @@ fonts/modern-terminus/TerminusTTF-4.46.0.ttf NewTerminalFrame.qml SlowBurnIn.qml + menus/WindowMenu.qml + menus/FullContextMenu.qml + menus/ShortContextMenu.qml diff --git a/qmltermwidget b/qmltermwidget index 59f967d..5c47d1f 160000 --- a/qmltermwidget +++ b/qmltermwidget @@ -1 +1 @@ -Subproject commit 59f967d5e1f6e9ce8e1632d9405422b071d93d30 +Subproject commit 5c47d1f49455394226e0e595f79c148f0c098006