diff --git a/app/qml/AboutDialog.qml b/app/qml/AboutDialog.qml index cec04e8..22becce 100644 --- a/app/qml/AboutDialog.qml +++ b/app/qml/AboutDialog.qml @@ -1,9 +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.2 import QtQuick.Layouts 1.1 import QtQuick.Window 2.0 -Window{ +Window { id: dialogwindow title: qsTr("About") width: 600 @@ -11,16 +30,19 @@ Window{ modality: Qt.ApplicationModal - ColumnLayout{ + ColumnLayout { anchors.fill: parent anchors.margins: 15 spacing: 15 Text { Layout.alignment: Qt.AlignHCenter text: "cool-retro-term" - font {bold: true; pointSize: 18} + font { + bold: true + pointSize: 18 + } } - Loader{ + Loader { id: mainContent Layout.fillHeight: true Layout.fillWidth: true @@ -41,32 +63,33 @@ Window{ } } ] - Component.onCompleted: mainContent.state = "Default"; + Component.onCompleted: mainContent.state = "Default" } - Item{ + Item { Layout.fillWidth: true height: childrenRect.height - Button{ + Button { anchors.left: parent.left text: qsTr("License") onClicked: { - mainContent.state == "Default" ? mainContent.state = "License" : mainContent.state = "Default" + mainContent.state == "Default" ? mainContent.state + = "License" : mainContent.state = "Default" } } - Button{ + Button { anchors.right: parent.right text: qsTr("Close") - onClicked: dialogwindow.close(); + onClicked: dialogwindow.close() } } } // MAIN COMPONENTS //////////////////////////////////////////////////////// - Component{ + Component { id: defaultComponent - ColumnLayout{ + ColumnLayout { anchors.fill: parent spacing: 10 - Image{ + Image { Layout.fillWidth: true Layout.fillHeight: true Layout.alignment: Qt.AlignHCenter @@ -74,39 +97,36 @@ Window{ source: "images/crt256.png" smooth: true } - Text{ + Text { Layout.alignment: Qt.AlignCenter horizontalAlignment: Text.AlignHCenter - text: appSettings.version + "\n" + - qsTr("Author: ") + "Filippo Scognamiglio\n" + - qsTr("Email: ") + "flscogna@gmail.com\n" + - qsTr("Source: ") + "https://github.com/Swordfish90/cool-retro-term\n" + text: appSettings.version + "\n" + qsTr( + "Author: ") + "Filippo Scognamiglio\n" + qsTr( + "Email: ") + "flscogna@gmail.com\n" + qsTr( + "Source: ") + "https://github.com/Swordfish90/cool-retro-term\n" } } } - Component{ + Component { id: licenseComponent ScrollView { anchors.fill: parent clip: true - TextArea{ + 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" + - - "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 ." + text: "Copyright (c) 2013-2021 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" + + "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 ." } } } diff --git a/app/qml/ApplicationSettings.qml b/app/qml/ApplicationSettings.qml index 96ccad2..d8a1d70 100644 --- a/app/qml/ApplicationSettings.qml +++ b/app/qml/ApplicationSettings.qml @@ -1,5 +1,5 @@ /******************************************************************************* -* Copyright (c) 2013 "Filippo Scognamiglio" +* Copyright (c) 2013-2021 "Filippo Scognamiglio" * https://github.com/Swordfish90/cool-retro-term * * This file is part of cool-retro-term. @@ -17,18 +17,16 @@ * 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.0 import "utils.js" as Utils -QtObject{ +QtObject { readonly property string version: appVersion readonly property int profileVersion: 2 // STATIC CONSTANTS //////////////////////////////////////////////////////// - readonly property real screenCurvatureSize: 0.4 readonly property real minimumFontScaling: 0.25 readonly property real maximumFontScaling: 2.50 @@ -37,7 +35,6 @@ QtObject{ readonly property real maxBurnInFadeTime: 1600 // GENERAL SETTINGS /////////////////////////////////////////////////////// - property int x: 100 property int y: 100 property int width: 1024 @@ -61,10 +58,9 @@ QtObject{ property bool blinkingCursor: false - onWindowScalingChanged: handleFontChanged(); + onWindowScalingChanged: handleFontChanged() // PROFILE SETTINGS /////////////////////////////////////////////////////// - property real windowOpacity: 1.0 property real ambientLight: 0.2 property real contrast: 0.80 @@ -75,9 +71,16 @@ QtObject{ property string _backgroundColor: "#000000" property string _fontColor: "#ff8100" - property string saturatedColor: Utils.mix(Utils.strToColor("#FFFFFF"), Utils.strToColor(_fontColor), saturationColor * 0.5) - property color fontColor: Utils.mix(Utils.strToColor(saturatedColor), Utils.strToColor(_backgroundColor), 0.7 + (contrast * 0.3)) - property color backgroundColor: Utils.mix(Utils.strToColor(_backgroundColor), Utils.strToColor(saturatedColor), 0.7 + (contrast * 0.3)) + property string saturatedColor: Utils.mix(Utils.strToColor("#FFFFFF"), + Utils.strToColor(_fontColor), + saturationColor * 0.5) + property color fontColor: Utils.mix(Utils.strToColor(saturatedColor), + Utils.strToColor(_backgroundColor), + 0.7 + (contrast * 0.3)) + property color backgroundColor: Utils.mix(Utils.strToColor( + _backgroundColor), + Utils.strToColor(saturatedColor), + 0.7 + (contrast * 0.3)) property real staticNoise: 0.12 property real screenCurvature: 0.3 @@ -96,16 +99,21 @@ QtObject{ property real rbgShift: 0.0 property real _margin: 0.5 + property real _frameMargin: 0.5 + property real margin: Utils.lint(1.0, 20.0, _margin) + property real frameMargin: Utils.lint(1.0, 50.0, _frameMargin) + + property real totalMargin: frameMargin + margin readonly property int no_rasterization: 0 readonly property int scanline_rasterization: 1 readonly property int pixel_rasterization: 2 + readonly property int subpixel_rasterization: 3 property int rasterization: no_rasterization // FONTS ////////////////////////////////////////////////////////////////// - readonly property real baseFontScaling: 0.75 property real fontScaling: 1.0 property real totalFontScaling: baseFontScaling * fontScaling @@ -119,168 +127,198 @@ QtObject{ signal terminalFontChanged(string fontFamily, int pixelSize, int lineSpacing, real screenScaling, real fontWidth) - signal initializedSettings() + signal initializedSettings - property Loader fontManager: Loader{ + property Loader fontManager: Loader { states: [ - State { when: rasterization == no_rasterization - PropertyChanges {target: fontManager; source: "Fonts.qml" } }, - State { when: rasterization == scanline_rasterization - PropertyChanges {target: fontManager; source: "FontScanlines.qml" } }, - State { when: rasterization == pixel_rasterization; - PropertyChanges {target: fontManager; source: "FontPixels.qml" } } + State { + when: rasterization == no_rasterization + PropertyChanges { + target: fontManager + source: "Fonts.qml" + } + }, + State { + when: rasterization == scanline_rasterization + PropertyChanges { + target: fontManager + source: "FontScanlines.qml" + } + }, + State { + when: rasterization == pixel_rasterization + PropertyChanges { + target: fontManager + source: "FontPixels.qml" + } + }, + State { + when: rasterization == subpixel_rasterization + PropertyChanges { + target: fontManager + source: "FontPixels.qml" + } + } ] onLoaded: handleFontChanged() } - property FontLoader fontLoader: FontLoader { } + property FontLoader fontLoader: FontLoader {} - onTotalFontScalingChanged: handleFontChanged(); - onFontWidthChanged: handleFontChanged(); + onTotalFontScalingChanged: handleFontChanged() + onFontWidthChanged: handleFontChanged() function getIndexByName(name) { for (var i = 0; i < fontlist.count; i++) { - var requestedName = fontlist.get(i).name; + var requestedName = fontlist.get(i).name if (name === requestedName) - return i; + return i } - return 0; // If the font is not available default to 0. + return 0 // If the font is not available default to 0. } - function incrementScaling(){ - fontScaling = Math.min(fontScaling + 0.05, maximumFontScaling); - handleFontChanged(); + function incrementScaling() { + fontScaling = Math.min(fontScaling + 0.05, maximumFontScaling) + handleFontChanged() } - function decrementScaling(){ - fontScaling = Math.max(fontScaling - 0.05, minimumFontScaling); - handleFontChanged(); + function decrementScaling() { + fontScaling = Math.max(fontScaling - 0.05, minimumFontScaling) + handleFontChanged() } - function handleFontChanged(){ - if (!fontManager.item) return; + function handleFontChanged() { + if (!fontManager.item) + return - var index = getIndexByName(fontNames[rasterization]); - if (index === undefined) return; + var index = getIndexByName(fontNames[rasterization]) + if (index === undefined) + return - fontManager.item.selectedFontIndex = index; - fontManager.item.scaling = totalFontScaling; + fontManager.item.selectedFontIndex = index + fontManager.item.scaling = totalFontScaling - var fontSource = fontManager.item.source; - var pixelSize = fontManager.item.pixelSize; - var lineSpacing = fontManager.item.lineSpacing; - var screenScaling = fontManager.item.screenScaling; - var fontWidth = fontManager.item.defaultFontWidth * appSettings.fontWidth; - var fontFamily = fontManager.item.family; - var isSystemFont = fontManager.item.isSystemFont; + var fontSource = fontManager.item.source + var pixelSize = fontManager.item.pixelSize + var lineSpacing = fontManager.item.lineSpacing + var screenScaling = fontManager.item.screenScaling + var fontWidth = fontManager.item.defaultFontWidth * appSettings.fontWidth + var fontFamily = fontManager.item.family + var isSystemFont = fontManager.item.isSystemFont - lowResolutionFont = fontManager.item.lowResolutionFont; + lowResolutionFont = fontManager.item.lowResolutionFont if (!isSystemFont) { - fontLoader.source = fontSource; - fontFamily = fontLoader.name; + fontLoader.source = fontSource + fontFamily = fontLoader.name } - terminalFontChanged(fontFamily, pixelSize, lineSpacing, screenScaling, fontWidth); + terminalFontChanged(fontFamily, pixelSize, lineSpacing, screenScaling, + fontWidth) } - property Storage storage: Storage{ } + property Storage storage: Storage {} function stringify(obj) { - var replacer = function(key, val) { - return val.toFixed ? Number(val.toFixed(4)) : val; + var replacer = function (key, val) { + return val.toFixed ? Number(val.toFixed(4)) : val } - return JSON.stringify(obj, replacer, 2); + return JSON.stringify(obj, replacer, 2) } - function composeSettingsString(){ + function composeSettingsString() { var settings = { - fps: fps, - x: x, - y: y, - width: width, - height: height, - windowScaling: windowScaling, - showTerminalSize: showTerminalSize, - fontScaling: fontScaling, - fontNames: fontNames, - showMenubar: showMenubar, - bloomQuality: bloomQuality, - burnInQuality: burnInQuality, - useCustomCommand: useCustomCommand, - customCommand: customCommand, - useFastBurnIn: useFastBurnIn, - blinkingCursor: blinkingCursor + "fps": fps, + "x": x, + "y": y, + "width": width, + "height": height, + "windowScaling": windowScaling, + "showTerminalSize": showTerminalSize, + "fontScaling": fontScaling, + "fontNames": fontNames, + "showMenubar": showMenubar, + "bloomQuality": bloomQuality, + "burnInQuality": burnInQuality, + "useCustomCommand": useCustomCommand, + "customCommand": customCommand, + "useFastBurnIn": useFastBurnIn } - return stringify(settings); + return stringify(settings) } - function composeProfileObject(){ + function composeProfileObject() { var settings = { - backgroundColor: _backgroundColor, - fontColor: _fontColor, - flickering: flickering, - horizontalSync: horizontalSync, - staticNoise: staticNoise, - chromaColor: chromaColor, - saturationColor: saturationColor, - screenCurvature: screenCurvature, - glowingLine: glowingLine, - burnIn: burnIn, - bloom: bloom, - rasterization: rasterization, - jitter: jitter, - rbgShift: rbgShift, - brightness: brightness, - contrast: contrast, - ambientLight: ambientLight, - windowOpacity: windowOpacity, - fontName: fontNames[rasterization], - fontWidth: fontWidth, - margin: _margin + "backgroundColor": _backgroundColor, + "fontColor": _fontColor, + "flickering": flickering, + "horizontalSync": horizontalSync, + "staticNoise": staticNoise, + "chromaColor": chromaColor, + "saturationColor": saturationColor, + "screenCurvature": screenCurvature, + "glowingLine": glowingLine, + "burnIn": burnIn, + "bloom": bloom, + "rasterization": rasterization, + "jitter": jitter, + "rbgShift": rbgShift, + "brightness": brightness, + "contrast": contrast, + "ambientLight": ambientLight, + "windowOpacity": windowOpacity, + "fontName": fontNames[rasterization], + "fontWidth": fontWidth, + "margin": _margin, + "blinkingCursor": blinkingCursor, + "frameMargin": _frameMargin, } - return settings; + return settings } function composeProfileString() { - return stringify(composeProfileObject()); + return stringify(composeProfileObject()) } - function loadSettings(){ - var settingsString = storage.getSetting("_CURRENT_SETTINGS"); - var profileString = storage.getSetting("_CURRENT_PROFILE"); + function loadSettings() { + var settingsString = storage.getSetting("_CURRENT_SETTINGS") + var profileString = storage.getSetting("_CURRENT_PROFILE") - if(!settingsString) return; - if(!profileString) return; + if (!settingsString) + return + if (!profileString) + return - loadSettingsString(settingsString); - loadProfileString(profileString); + loadSettingsString(settingsString) + loadProfileString(profileString) if (verbose) - console.log("Loading settings: " + settingsString + profileString); + console.log("Loading settings: " + settingsString + profileString) } - function storeSettings(){ - var settingsString = composeSettingsString(); - var profileString = composeProfileString(); + function storeSettings() { + var settingsString = composeSettingsString() + var profileString = composeProfileString() - storage.setSetting("_CURRENT_SETTINGS", settingsString); - storage.setSetting("_CURRENT_PROFILE", profileString); + storage.setSetting("_CURRENT_SETTINGS", settingsString) + storage.setSetting("_CURRENT_PROFILE", profileString) if (verbose) { - console.log("Storing settings: " + settingsString); - console.log("Storing profile: " + profileString); + console.log("Storing settings: " + settingsString) + console.log("Storing profile: " + profileString) } } - function loadSettingsString(settingsString){ - var settings = JSON.parse(settingsString); + function loadSettingsString(settingsString) { + var settings = JSON.parse(settingsString) - showTerminalSize = settings.showTerminalSize !== undefined ? settings.showTerminalSize : showTerminalSize + showTerminalSize = settings.showTerminalSize + !== undefined ? settings.showTerminalSize : showTerminalSize - fps = settings.fps !== undefined ? settings.fps: fps - windowScaling = settings.windowScaling !== undefined ? settings.windowScaling : windowScaling + fps = settings.fps !== undefined ? settings.fps : fps + windowScaling = settings.windowScaling + !== undefined ? settings.windowScaling : windowScaling x = settings.x !== undefined ? settings.x : x y = settings.y !== undefined ? settings.y : y @@ -290,401 +328,431 @@ QtObject{ fontNames = settings.fontNames !== undefined ? settings.fontNames : fontNames fontScaling = settings.fontScaling !== undefined ? settings.fontScaling : fontScaling - showMenubar = settings.showMenubar !== undefined ? settings.showMenubar : showMenubar; + showMenubar = settings.showMenubar !== undefined ? settings.showMenubar : showMenubar - bloomQuality = settings.bloomQuality !== undefined ? settings.bloomQuality : bloomQuality; - burnInQuality = settings.burnInQuality !== undefined ? settings.burnInQuality : burnInQuality; + bloomQuality = settings.bloomQuality !== undefined ? settings.bloomQuality : bloomQuality + burnInQuality = settings.burnInQuality + !== undefined ? settings.burnInQuality : burnInQuality - useCustomCommand = settings.useCustomCommand !== undefined ? settings.useCustomCommand : useCustomCommand - customCommand = settings.customCommand !== undefined ? settings.customCommand : customCommand + useCustomCommand = settings.useCustomCommand + !== undefined ? settings.useCustomCommand : useCustomCommand + customCommand = settings.customCommand + !== undefined ? settings.customCommand : customCommand - useFastBurnIn = settings.useFastBurnIn !== undefined ? settings.useFastBurnIn : useFastBurnIn; - - blinkingCursor = settings.blinkingCursor !== undefined ? settings.blinkingCursor : blinkingCursor + useFastBurnIn = settings.useFastBurnIn + !== undefined ? settings.useFastBurnIn : useFastBurnIn } - function loadProfileString(profileString){ - var settings = JSON.parse(profileString); + function loadProfileString(profileString) { + var settings = JSON.parse(profileString) - _backgroundColor = settings.backgroundColor !== undefined ? settings.backgroundColor : _backgroundColor; - _fontColor = settings.fontColor !== undefined ? settings.fontColor : _fontColor; + _backgroundColor = settings.backgroundColor + !== undefined ? settings.backgroundColor : _backgroundColor + _fontColor = settings.fontColor !== undefined ? settings.fontColor : _fontColor - horizontalSync = settings.horizontalSync !== undefined ? settings.horizontalSync : horizontalSync - flickering = settings.flickering !== undefined ? settings.flickering : flickering; - staticNoise = settings.staticNoise !== undefined ? settings.staticNoise : staticNoise; - chromaColor = settings.chromaColor !== undefined ? settings.chromaColor : chromaColor; - saturationColor = settings.saturationColor !== undefined ? settings.saturationColor : saturationColor; - screenCurvature = settings.screenCurvature !== undefined ? settings.screenCurvature : screenCurvature; - glowingLine = settings.glowingLine !== undefined ? settings.glowingLine : glowingLine; + horizontalSync = settings.horizontalSync + !== undefined ? settings.horizontalSync : horizontalSync + flickering = settings.flickering !== undefined ? settings.flickering : flickering + staticNoise = settings.staticNoise !== undefined ? settings.staticNoise : staticNoise + chromaColor = settings.chromaColor !== undefined ? settings.chromaColor : chromaColor + saturationColor = settings.saturationColor + !== undefined ? settings.saturationColor : saturationColor + screenCurvature = settings.screenCurvature + !== undefined ? settings.screenCurvature : screenCurvature + glowingLine = settings.glowingLine !== undefined ? settings.glowingLine : glowingLine burnIn = settings.burnIn !== undefined ? settings.burnIn : burnIn bloom = settings.bloom !== undefined ? settings.bloom : bloom - rasterization = settings.rasterization !== undefined ? settings.rasterization : rasterization; + rasterization = settings.rasterization + !== undefined ? settings.rasterization : rasterization - jitter = settings.jitter !== undefined ? settings.jitter : jitter; + jitter = settings.jitter !== undefined ? settings.jitter : jitter - rbgShift = settings.rbgShift !== undefined ? settings.rbgShift : rbgShift; + rbgShift = settings.rbgShift !== undefined ? settings.rbgShift : rbgShift - ambientLight = settings.ambientLight !== undefined ? settings.ambientLight : ambientLight; - contrast = settings.contrast !== undefined ? settings.contrast : contrast; - brightness = settings.brightness !== undefined ? settings.brightness : brightness; - windowOpacity = settings.windowOpacity !== undefined ? settings.windowOpacity : windowOpacity; + ambientLight = settings.ambientLight !== undefined ? settings.ambientLight : ambientLight + contrast = settings.contrast !== undefined ? settings.contrast : contrast + brightness = settings.brightness !== undefined ? settings.brightness : brightness + windowOpacity = settings.windowOpacity + !== undefined ? settings.windowOpacity : windowOpacity - fontNames[rasterization] = settings.fontName !== undefined ? settings.fontName : fontNames[rasterization]; - fontWidth = settings.fontWidth !== undefined ? settings.fontWidth : fontWidth; + fontNames[rasterization] = settings.fontName + !== undefined ? settings.fontName : fontNames[rasterization] + fontWidth = settings.fontWidth !== undefined ? settings.fontWidth : fontWidth - _margin = settings.margin !== undefined ? settings.margin : _margin; + _margin = settings.margin !== undefined ? settings.margin : _margin + _frameMargin = settings.frameMargin !== undefined ? settings.frameMargin : _frameMargin + blinkingCursor = settings.blinkingCursor !== undefined ? settings.blinkingCursor : blinkingCursor - handleFontChanged(); + handleFontChanged() } - function storeCustomProfiles(){ - storage.setSetting("_CUSTOM_PROFILES", composeCustomProfilesString()); + function storeCustomProfiles() { + storage.setSetting("_CUSTOM_PROFILES", composeCustomProfilesString()) } - function loadCustomProfiles(){ - var customProfileString = storage.getSetting("_CUSTOM_PROFILES"); - if(customProfileString === undefined) customProfileString = "[]"; - loadCustomProfilesString(customProfileString); + function loadCustomProfiles() { + var customProfileString = storage.getSetting("_CUSTOM_PROFILES") + if (customProfileString === undefined) + customProfileString = "[]" + loadCustomProfilesString(customProfileString) } - function loadCustomProfilesString(customProfilesString){ - var customProfiles = JSON.parse(customProfilesString); - for (var i=0; i. +*******************************************************************************/ import QtQuick 2.0 import "utils.js" as Utils @@ -70,6 +89,10 @@ Loader { } } + ShaderLibrary { + id: shaderLibrary + } + ShaderEffect { id: burnInShaderEffect @@ -99,9 +122,7 @@ Loader { uniform highp float prevLastUpdate;" + - "float rgb2grey(vec3 v){ - return dot(v, vec3(0.21, 0.72, 0.04)); - }" + + shaderLibrary.rgb2grey + "void main() { vec2 coords = qt_TexCoord0; diff --git a/app/qml/CheckableSlider.qml b/app/qml/CheckableSlider.qml index d2d55a3..d81cd41 100644 --- a/app/qml/CheckableSlider.qml +++ b/app/qml/CheckableSlider.qml @@ -1,5 +1,5 @@ /******************************************************************************* -* Copyright (c) 2013 "Filippo Scognamiglio" +* Copyright (c) 2013-2021 "Filippo Scognamiglio" * https://github.com/Swordfish90/cool-retro-term * * This file is part of cool-retro-term. @@ -17,7 +17,6 @@ * 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.0 import QtQuick.Layouts 1.1 @@ -32,41 +31,42 @@ RowLayout { property alias max_value: slider.to property alias stepSize: slider.stepSize - signal newValue(real newValue); + signal newValue(real newValue) id: setting_component Layout.fillWidth: true onValueChanged: { - check.checked = !(value == 0); - if(check.checked) - slider.value = value; + check.checked = !(value == 0) + if (check.checked) + slider.value = value } - CheckBox{ + CheckBox { id: check implicitWidth: 160 onClicked: { - if(!checked){ - checked = false; - slider.enabled = false; - newValue(0); + if (!checked) { + checked = false + slider.enabled = false + newValue(0) } else { - checked = true; - newValue(slider.value); - slider.enabled = true; + checked = true + newValue(slider.value) + slider.enabled = true } } } - Slider{ + Slider { id: slider stepSize: parent.stepSize Layout.fillWidth: true onValueChanged: { - newValue(value); + newValue(value) } } SizedLabel { - text: Math.round(((value - min_value) / (max_value - min_value)) * 100) + "%" + text: Math.round( + ((value - min_value) / (max_value - min_value)) * 100) + "%" } } diff --git a/app/qml/ColorButton.qml b/app/qml/ColorButton.qml index 1a3eeaf..f46134b 100644 --- a/app/qml/ColorButton.qml +++ b/app/qml/ColorButton.qml @@ -1,5 +1,5 @@ /******************************************************************************* -* Copyright (c) 2013 "Filippo Scognamiglio" +* Copyright (c) 2013-2021 "Filippo Scognamiglio" * https://github.com/Swordfish90/cool-retro-term * * This file is part of cool-retro-term. @@ -17,14 +17,13 @@ * 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.Dialogs 1.1 Item { id: rootItem - signal colorSelected (color color) + signal colorSelected(color color) property color color property string name @@ -35,10 +34,12 @@ Item { visible: false //This is a workaround to a Qt 5.2 bug. - onColorChanged: if (Qt.platform.os !== "osx") colorSelected(color) - onAccepted: if (Qt.platform.os === "osx") colorSelected(color) + onColorChanged: if (Qt.platform.os !== "osx") + colorSelected(color) + onAccepted: if (Qt.platform.os === "osx") + colorSelected(color) } - Rectangle{ + Rectangle { anchors.fill: parent radius: 10 color: rootItem.color @@ -50,14 +51,14 @@ Item { color: "white" opacity: 0.5 } - Text{ + Text { anchors.centerIn: parent z: parent.z + 1 text: name + ": " + rootItem.color } } - MouseArea{ + MouseArea { anchors.fill: parent - onClicked: colorDialog.visible = true; + onClicked: colorDialog.visible = true } } diff --git a/app/qml/Components/SizedLabel.qml b/app/qml/Components/SizedLabel.qml index f289adb..5e0a9b5 100644 --- a/app/qml/Components/SizedLabel.qml +++ b/app/qml/Components/SizedLabel.qml @@ -1,5 +1,7 @@ + + /******************************************************************************* -* Copyright (c) 2013 "Filippo Scognamiglio" +* Copyright (c) 2013-2021 "Filippo Scognamiglio" * https://github.com/Swordfish90/cool-retro-term * * This file is part of cool-retro-term. @@ -17,15 +19,12 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . *******************************************************************************/ - - import QtQuick 2.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. - Label { id: textfield Layout.minimumWidth: appSettings.labelWidth diff --git a/app/qml/FontPixels.qml b/app/qml/FontPixels.qml index 8b96190..0978480 100644 --- a/app/qml/FontPixels.qml +++ b/app/qml/FontPixels.qml @@ -1,5 +1,5 @@ /******************************************************************************* -* Copyright (c) 2013 "Filippo Scognamiglio" +* Copyright (c) 2013-2021 "Filippo Scognamiglio" * https://github.com/Swordfish90/cool-retro-term * * This file is part of cool-retro-term. @@ -17,10 +17,9 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . *******************************************************************************/ - import QtQuick 2.2 -QtObject{ +QtObject { property int selectedFontIndex property real scaling property var _font: fontlist.get(selectedFontIndex) @@ -31,8 +30,8 @@ QtObject{ property real defaultFontWidth: fontlist.get(selectedFontIndex).fontWidth property bool lowResolutionFont: true - property ListModel fontlist: ListModel{ - ListElement{ + property ListModel fontlist: ListModel { + ListElement { name: "COMMODORE_PET" text: "Commodore PET (1977)" source: "fonts/1977-commodore-pet/PetMe.ttf" @@ -41,7 +40,7 @@ QtObject{ baseScaling: 3.5 fontWidth: 0.8 } - ListElement{ + ListElement { name: "IBM_PC" text: "IBM PC (1981)" source: "fonts/1981-ibm-pc/PxPlus_IBM_BIOS.ttf" @@ -50,7 +49,7 @@ QtObject{ baseScaling: 3.5 fontWidth: 0.8 } - ListElement{ + ListElement { name: "PROGGY_TINY" text: "Proggy Tiny (Modern)" source: "fonts/modern-proggy-tiny/ProggyTiny.ttf" @@ -59,7 +58,7 @@ QtObject{ baseScaling: 3.3 fontWidth: 0.9 } - ListElement{ + ListElement { name: "TERMINUS_SCALED" text: "Terminus (Modern)" source: "fonts/modern-terminus/TerminusTTF-4.46.0.ttf" @@ -68,7 +67,7 @@ QtObject{ baseScaling: 3.0 fontWidth: 1.0 } - ListElement{ + ListElement { name: "PRO_FONT_SCALED" text: "Pro Font (Modern)" source: "fonts/modern-pro-font-win-tweaked/ProFontWindows.ttf" @@ -77,7 +76,7 @@ QtObject{ baseScaling: 3.0 fontWidth: 1.0 } - ListElement{ + ListElement { name: "APPLE_II" text: "Apple ][ (1977)" source: "fonts/1977-apple2/PrintChar21.ttf" @@ -86,7 +85,7 @@ QtObject{ baseScaling: 3.5 fontWidth: 0.9 } - ListElement{ + ListElement { name: "ATARI_400" text: "Atari 400-800 (1979)" source: "fonts/1979-atari-400-800/AtariClassic-Regular.ttf" @@ -95,7 +94,7 @@ QtObject{ baseScaling: 3.5 fontWidth: 0.8 } - ListElement{ + ListElement { name: "COMMODORE_64" text: "Commodore 64 (1982)" source: "fonts/1982-commodore64/C64_Pro_Mono-STYLE.ttf" diff --git a/app/qml/FontScanlines.qml b/app/qml/FontScanlines.qml index c618aed..37003ed 100644 --- a/app/qml/FontScanlines.qml +++ b/app/qml/FontScanlines.qml @@ -1,5 +1,5 @@ /******************************************************************************* -* Copyright (c) 2013 "Filippo Scognamiglio" +* Copyright (c) 2013-2021 "Filippo Scognamiglio" * https://github.com/Swordfish90/cool-retro-term * * This file is part of cool-retro-term. @@ -17,10 +17,9 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . *******************************************************************************/ - import QtQuick 2.2 -QtObject{ +QtObject { property int selectedFontIndex property real scaling property var _font: fontlist.get(selectedFontIndex) @@ -31,8 +30,8 @@ QtObject{ property real defaultFontWidth: fontlist.get(selectedFontIndex).fontWidth property bool lowResolutionFont: true - property ListModel fontlist: ListModel{ - ListElement{ + property ListModel fontlist: ListModel { + ListElement { name: "COMMODORE_PET" text: "Commodore PET (1977)" source: "fonts/1977-commodore-pet/PetMe.ttf" @@ -41,7 +40,7 @@ QtObject{ baseScaling: 3.5 fontWidth: 0.7 } - ListElement{ + ListElement { name: "IBM_PC" text: "IBM PC (1981)" source: "fonts/1981-ibm-pc/PxPlus_IBM_BIOS.ttf" @@ -50,7 +49,7 @@ QtObject{ baseScaling: 3.5 fontWidth: 0.8 } - ListElement{ + ListElement { name: "PROGGY_TINY" text: "Proggy Tiny (Modern)" source: "fonts/modern-proggy-tiny/ProggyTiny.ttf" @@ -59,7 +58,7 @@ QtObject{ baseScaling: 3.3 fontWidth: 0.9 } - ListElement{ + ListElement { name: "TERMINUS_SCALED" text: "Terminus (Modern)" source: "fonts/modern-terminus/TerminusTTF-4.46.0.ttf" @@ -68,7 +67,7 @@ QtObject{ baseScaling: 3.0 fontWidth: 1.0 } - ListElement{ + ListElement { name: "PRO_FONT_SCALED" text: "Pro Font (Modern)" source: "fonts/modern-pro-font-win-tweaked/ProFontWindows.ttf" @@ -77,7 +76,7 @@ QtObject{ baseScaling: 3.0 fontWidth: 1.0 } - ListElement{ + ListElement { name: "APPLE_II" text: "Apple ][ (1977)" source: "fonts/1977-apple2/PrintChar21.ttf" @@ -86,7 +85,7 @@ QtObject{ baseScaling: 3.5 fontWidth: 0.8 } - ListElement{ + ListElement { name: "ATARI_400" text: "Atari 400-800 (1979)" source: "fonts/1979-atari-400-800/AtariClassic-Regular.ttf" @@ -95,7 +94,7 @@ QtObject{ baseScaling: 3.5 fontWidth: 0.7 } - ListElement{ + ListElement { name: "COMMODORE_64" text: "Commodore 64 (1982)" source: "fonts/1982-commodore64/C64_Pro_Mono-STYLE.ttf" diff --git a/app/qml/Fonts.qml b/app/qml/Fonts.qml index ce78236..1dc15aa 100644 --- a/app/qml/Fonts.qml +++ b/app/qml/Fonts.qml @@ -1,5 +1,5 @@ /******************************************************************************* -* Copyright (c) 2013 "Filippo Scognamiglio" +* Copyright (c) 2013-2021 "Filippo Scognamiglio" * https://github.com/Swordfish90/cool-retro-term * * This file is part of cool-retro-term. @@ -17,27 +17,20 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . *******************************************************************************/ - import QtQuick 2.2 -QtObject{ +QtObject { property int selectedFontIndex property real scaling property var source: fontlist.get(selectedFontIndex).source property var _font: fontlist.get(selectedFontIndex) property bool lowResolutionFont: _font.lowResolutionFont - property int pixelSize: lowResolutionFont - ? _font.pixelSize - : _font.pixelSize * scaling + property int pixelSize: lowResolutionFont ? _font.pixelSize : _font.pixelSize * scaling - property int lineSpacing: lowResolutionFont - ? _font.lineSpacing - : pixelSize * _font.lineSpacing + property int lineSpacing: lowResolutionFont ? _font.lineSpacing : pixelSize * _font.lineSpacing - property real screenScaling: lowResolutionFont - ? _font.baseScaling * scaling - : 1.0 + property real screenScaling: lowResolutionFont ? _font.baseScaling * scaling : 1.0 property real defaultFontWidth: fontlist.get(selectedFontIndex).fontWidth @@ -52,9 +45,8 @@ QtObject{ // High resolution fonts are instead drawn on a texture which has the // size of the screen, and the scaling directly controls their pixels size. // Those are slower to render but are not pixelated. - property ListModel fontlist: ListModel { - ListElement{ + ListElement { name: "TERMINUS_SCALED" text: "Terminus (Modern)" source: "fonts/modern-terminus/TerminusTTF-4.46.0.ttf" @@ -66,7 +58,7 @@ QtObject{ isSystemFont: false family: "" } - ListElement{ + ListElement { name: "PRO_FONT_SCALED" text: "Pro Font (Modern)" source: "fonts/modern-pro-font-win-tweaked/ProFontWindows.ttf" @@ -78,7 +70,7 @@ QtObject{ isSystemFont: false family: "" } - ListElement{ + ListElement { name: "EXCELSIOR_SCALED" text: "Fixedsys Excelsior (Modern)" source: "fonts/modern-fixedsys-excelsior/FSEX301-L2.ttf" @@ -90,7 +82,7 @@ QtObject{ isSystemFont: false family: "" } - ListElement{ + ListElement { name: "COMMODORE_PET_SCALED" text: "Commodore PET (1977)" source: "fonts/1977-commodore-pet/PetMe.ttf" @@ -102,7 +94,7 @@ QtObject{ isSystemFont: false family: "" } - ListElement{ + ListElement { name: "PROGGY_TINY_SCALED" text: "Proggy Tiny (Modern)" source: "fonts/modern-proggy-tiny/ProggyTiny.ttf" @@ -114,7 +106,7 @@ QtObject{ isSystemFont: false family: "" } - ListElement{ + ListElement { name: "APPLE_II_SCALED" text: "Apple ][ (1977)" source: "fonts/1977-apple2/PrintChar21.ttf" @@ -126,7 +118,7 @@ QtObject{ isSystemFont: false family: "" } - ListElement{ + ListElement { name: "ATARI_400_SCALED" text: "Atari 400-800 (1979)" source: "fonts/1979-atari-400-800/AtariClassic-Regular.ttf" @@ -138,7 +130,7 @@ QtObject{ isSystemFont: false family: "" } - ListElement{ + ListElement { name: "IBM_PC_SCALED" text: "IBM PC (1981)" source: "fonts/1981-ibm-pc/PxPlus_IBM_BIOS.ttf" @@ -150,7 +142,7 @@ QtObject{ isSystemFont: false family: "" } - ListElement{ + ListElement { name: "COMMODORE_64_SCALED" text: "Commodore 64 (1982)" source: "fonts/1982-commodore64/C64_Pro_Mono-STYLE.ttf" @@ -162,7 +154,7 @@ QtObject{ isSystemFont: false family: "" } - ListElement{ + ListElement { name: "IBM_DOS" text: "IBM DOS (1985)" source: "fonts/1985-ibm-pc-vga/PxPlus_IBM_VGA8.ttf" @@ -174,7 +166,7 @@ QtObject{ isSystemFont: false family: "" } - ListElement{ + ListElement { name: "HERMIT" text: "HD: Hermit (Modern)" source: "fonts/modern-hermit/Hermit-medium.otf" @@ -185,7 +177,7 @@ QtObject{ isSystemFont: false family: "" } - ListElement{ + ListElement { name: "TERMINUS" text: "HD: Terminus (Modern)" source: "fonts/modern-terminus/TerminusTTF-4.46.0.ttf" @@ -196,7 +188,7 @@ QtObject{ isSystemFont: false family: "" } - ListElement{ + ListElement { name: "PRO_FONT" text: "HD: Pro Font (Modern)" source: "fonts/modern-pro-font-win-tweaked/ProFontWindows.ttf" @@ -207,7 +199,7 @@ QtObject{ isSystemFont: false family: "" } - ListElement{ + ListElement { name: "INCONSOLATA" text: "HD: Inconsolata (Modern)" source: "fonts/modern-inconsolata/Inconsolata.otf" @@ -218,7 +210,7 @@ QtObject{ isSystemFont: false family: "" } - ListElement{ + ListElement { name: "IBM_3278" text: "HD: IBM 3278 (1971)" source: "fonts/1971-ibm-3278/3270-Regular.ttf" @@ -234,7 +226,7 @@ QtObject{ Component.onCompleted: addSystemFonts() function addSystemFonts() { - var families = monospaceSystemFonts; + var families = monospaceSystemFonts for (var i = 0; i < families.length; i++) { if (verbose) { console.log("Adding system font: ", families[i]) @@ -245,16 +237,16 @@ QtObject{ function convertToListElement(family) { return { - name: "System: " + family, - text: qsTr("System: ") + family, - source: "", - lineSpacing: 0.1, - pixelSize: 30, - fontWidth: 1.0, - baseScaling: 1.0, - lowResolutionFont: false, - isSystemFont: true, - family: family + "name": "System: " + family, + "text": qsTr("System: ") + family, + "source": "", + "lineSpacing": 0.1, + "pixelSize": 30, + "fontWidth": 1.0, + "baseScaling": 1.0, + "lowResolutionFont": false, + "isSystemFont": true, + "family": family } } } diff --git a/app/qml/InsertNameDialog.qml b/app/qml/InsertNameDialog.qml index fc316b3..fb4d7e9 100644 --- a/app/qml/InsertNameDialog.qml +++ b/app/qml/InsertNameDialog.qml @@ -1,5 +1,5 @@ /******************************************************************************* -* Copyright (c) 2013 "Filippo Scognamiglio" +* Copyright (c) 2013-2021 "Filippo Scognamiglio" * https://github.com/Swordfish90/cool-retro-term * * This file is part of cool-retro-term. @@ -17,14 +17,13 @@ * 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.Window 2.0 import QtQuick.Controls 2.0 import QtQuick.Layouts 1.1 import QtQuick.Dialogs 1.1 -Window{ +Window { id: insertnamedialog width: 400 height: 100 @@ -39,50 +38,53 @@ Window{ title: qsTr("Error") visible: false - function showError(message){ - text = message; - open(); + function showError(message) { + text = message + open() } } - function validateName(name){ - var profile_list = appSettings.profilesList; + function validateName(name) { + var profile_list = appSettings.profilesList if (name === "") - return 1; - return 0; + return 1 + return 0 } - ColumnLayout{ + ColumnLayout { anchors.margins: 10 anchors.fill: parent - RowLayout{ - Label{text: qsTr("Name")} - TextField{ + RowLayout { + Label { + text: qsTr("Name") + } + TextField { id: namefield Layout.fillWidth: true Component.onCompleted: forceActiveFocus() onAccepted: okbutton.clickAction() } } - RowLayout{ + RowLayout { Layout.alignment: Qt.AlignBottom | Qt.AlignRight - Button{ + Button { id: okbutton text: qsTr("OK") onClicked: clickAction() - function clickAction(){ - var name = namefield.text; - switch(validateName(name)){ + function clickAction() { + var name = namefield.text + switch (validateName(name)) { case 1: - errorDialog.showError(qsTr("The name you inserted is empty. Please choose a different one.")); - break; + errorDialog.showError( + qsTr("The name you inserted is empty. Please choose a different one.")) + break default: - nameSelected(name); - close(); + nameSelected(name) + close() } } } - Button{ + Button { text: qsTr("Cancel") onClicked: close() } diff --git a/app/qml/NewTerminalFrame.qml b/app/qml/NewTerminalFrame.qml deleted file mode 100644 index f7b1669..0000000 --- a/app/qml/NewTerminalFrame.qml +++ /dev/null @@ -1,78 +0,0 @@ -import QtQuick 2.0 - -import "utils.js" as Utils - -ShaderEffect { - property color _staticFrameColor: "#ffffff" - property color _backgroundColor: appSettings.backgroundColor - property color _fontColor: appSettings.fontColor - property color _lightColor: Utils.mix(_fontColor, _backgroundColor, 0.2) - property real _ambientLight: Utils.lint(0.2, 0.8, appSettings.ambientLight) - - property color frameColor: Utils.mix(_staticFrameColor, _lightColor, _ambientLight) - property real screenCurvature: appSettings.screenCurvature * appSettings.screenCurvatureSize - property real shadowLength: 0.5 * screenCurvature * Utils.lint(0.50, 1.5, _ambientLight) - - property size aadelta: Qt.size(1.0 / width, 1.0 / height) - - fragmentShader: " - #ifdef GL_ES - precision mediump float; - #endif - - uniform lowp float screenCurvature; - uniform lowp float shadowLength; - uniform highp float qt_Opacity; - uniform lowp vec4 frameColor; - uniform mediump vec2 aadelta; - - varying highp vec2 qt_TexCoord0; - - vec2 distortCoordinates(vec2 coords){ - vec2 cc = (coords - vec2(0.5)); - float dist = dot(cc, cc) * screenCurvature; - return (coords + cc * (1.0 + dist) * dist); - } - - float max2(vec2 v) { - return max(v.x, v.y); - } - - float min2(vec2 v) { - return min(v.x, v.y); - } - - float prod2(vec2 v) { - return v.x * v.y; - } - - float sum2(vec2 v) { - return v.x + v.y; - } - - void main(){ - vec2 staticCoords = qt_TexCoord0; - vec2 coords = distortCoordinates(staticCoords); - - vec3 color = vec3(0.0); - float alpha = 0.0; - - float outShadowLength = shadowLength; - float inShadowLength = shadowLength * 0.5; - - float outShadow = max2(1.0 - smoothstep(vec2(-outShadowLength), vec2(0.0), coords) + smoothstep(vec2(1.0), vec2(1.0 + outShadowLength), coords)); - outShadow = clamp(sqrt(outShadow), 0.0, 1.0); - color += frameColor.rgb * outShadow; - alpha = sum2(1.0 - smoothstep(vec2(0.0), aadelta, coords) + smoothstep(vec2(1.0) - aadelta, vec2(1.0), coords)); - alpha = clamp(alpha, 0.0, 1.0) * mix(1.0, 0.9, outShadow); - - float inShadow = 1.0 - prod2(smoothstep(0.0, inShadowLength, coords) - smoothstep(1.0 - inShadowLength, 1.0, coords)); - inShadow = 0.5 * inShadow * inShadow; - alpha = max(alpha, inShadow); - - gl_FragColor = vec4(color * alpha, alpha); - } - " - - onStatusChanged: if (log) console.log(log) //Print warning messages -} diff --git a/app/qml/PreprocessedTerminal.qml b/app/qml/PreprocessedTerminal.qml index d9f4b5c..9edf981 100644 --- a/app/qml/PreprocessedTerminal.qml +++ b/app/qml/PreprocessedTerminal.qml @@ -1,5 +1,5 @@ /******************************************************************************* -* Copyright (c) 2013 "Filippo Scognamiglio" +* Copyright (c) 2013-2021 "Filippo Scognamiglio" * https://github.com/Swordfish90/cool-retro-term * * This file is part of cool-retro-term. @@ -73,7 +73,7 @@ Item{ id: kterminal property int textureResolutionScale: appSettings.lowResolutionFont ? devicePixelRatio : 1 - property int margin: appSettings.margin / screenScaling + property int margin: appSettings.totalMargin / screenScaling property int totalWidth: Math.floor(parent.width / (screenScaling * fontWidth)) property int totalHeight: Math.floor(parent.height / screenScaling) @@ -177,8 +177,8 @@ Item{ } property alias contextmenu: menuLoader.item - MouseArea{ - property real margin: appSettings.margin + MouseArea { + property real margin: appSettings.totalMargin acceptedButtons: Qt.LeftButton | Qt.MiddleButton | Qt.RightButton anchors.fill: parent @@ -219,8 +219,8 @@ Item{ var cc = Qt.size(0.5 - x, 0.5 - y); var distortion = (cc.height * cc.height + cc.width * cc.width) * appSettings.screenCurvature * appSettings.screenCurvatureSize; - return Qt.point((x - cc.width * (1+distortion) * distortion) * kterminal.totalWidth, - (y - cc.height * (1+distortion) * distortion) * kterminal.totalHeight) + return Qt.point((x - cc.width * (1+distortion) * distortion) * (kterminal.totalWidth), + (y - cc.height * (1+distortion) * distortion) * (kterminal.totalHeight)) } } ShaderEffectSource{ diff --git a/app/qml/SettingsAdvancedTab.qml b/app/qml/SettingsAdvancedTab.qml index 1ca7899..2a4e238 100644 --- a/app/qml/SettingsAdvancedTab.qml +++ b/app/qml/SettingsAdvancedTab.qml @@ -1,5 +1,5 @@ /******************************************************************************* -* Copyright (c) 2013 "Filippo Scognamiglio" +* Copyright (c) 2013-2021 "Filippo Scognamiglio" * https://github.com/Swordfish90/cool-retro-term * * This file is part of cool-retro-term. @@ -17,7 +17,6 @@ * 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.0 import QtQuick.Layouts 1.1 @@ -25,26 +24,26 @@ import QtQml 2.0 import "Components" -ColumnLayout{ - GroupBox{ +ColumnLayout { + GroupBox { Layout.fillWidth: true title: qsTr("Command") ColumnLayout { anchors.fill: parent - CheckBox{ + 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{ + Binding { target: useCustomCommand property: "checked" value: appSettings.useCustomCommand } - TextField{ + TextField { id: customCommand Layout.fillWidth: true text: appSettings.customCommand @@ -53,89 +52,109 @@ ColumnLayout{ // Save text even if user forgets to press enter or unfocus function saveSetting() { - appSettings.customCommand = text; + appSettings.customCommand = text } - Component.onCompleted: settings_window.closing.connect(saveSetting) + Component.onCompleted: settings_window.closing.connect( + saveSetting) } } } - GroupBox{ + GroupBox { title: qsTr("Performance") Layout.fillWidth: true - GridLayout{ + GridLayout { anchors.fill: parent columns: 4 - Label{text: qsTr("Effects FPS")} - Slider{ + Label { + text: qsTr("Effects FPS") + } + Slider { Layout.fillWidth: true Layout.columnSpan: 2 id: fpsSlider onValueChanged: { if (enabled) { - appSettings.fps = value !== 60 ? value + 1 : 0; + 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; + from = 0 + to = 60 + value = appSettings.fps !== 0 ? appSettings.fps - 1 : 60 + enabled = true } } - Label{text: appSettings.fps !== 0 ? appSettings.fps : qsTr("Max")} - Label{text: qsTr("Texture Quality")} - Slider{ + 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; + 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; + value = appSettings.windowScaling + enabled = true } } - Label{text: Math.round(txtslider.value * 100) + "%"} + Label { + text: Math.round(txtslider.value * 100) + "%" + } - Label{text: qsTr("Bloom Quality")} - Slider{ + Label { + text: qsTr("Bloom Quality") + } + Slider { Layout.fillWidth: true Layout.columnSpan: 2 id: bloomSlider - onValueChanged: if (enabled) appSettings.bloomQuality = value; + onValueChanged: if (enabled) + appSettings.bloomQuality = value stepSize: 0.05 enabled: false Component.onCompleted: { from = 0.25 - value = appSettings.bloomQuality; - enabled = true; + value = appSettings.bloomQuality + enabled = true } } - Label{text: Math.round(bloomSlider.value * 100) + "%"} + Label { + text: Math.round(bloomSlider.value * 100) + "%" + } - Label{text: qsTr("BurnIn Quality")} - Slider{ + Label { + text: qsTr("BurnIn Quality") + } + Slider { Layout.fillWidth: true id: burnInSlider Layout.columnSpan: 2 - onValueChanged: if (enabled) appSettings.burnInQuality = value; + onValueChanged: if (enabled) + appSettings.burnInQuality = value stepSize: 0.05 enabled: false Component.onCompleted: { from = 0.25 - value = appSettings.burnInQuality; - enabled = true; + value = appSettings.burnInQuality + enabled = true } } - Label{text: Math.round(burnInSlider.value * 100) + "%"} - CheckBox{ + Label { + text: Math.round(burnInSlider.value * 100) + "%" + } + CheckBox { Layout.columnSpan: 2 text: qsTr("Burnin optimization (Might display timing artifacts)") checked: appSettings.useFastBurnIn diff --git a/app/qml/SettingsEffectsTab.qml b/app/qml/SettingsEffectsTab.qml index e51299b..9c97e55 100644 --- a/app/qml/SettingsEffectsTab.qml +++ b/app/qml/SettingsEffectsTab.qml @@ -1,5 +1,5 @@ /******************************************************************************* -* Copyright (c) 2013 "Filippo Scognamiglio" +* Copyright (c) 2013-2021 "Filippo Scognamiglio" * https://github.com/Swordfish90/cool-retro-term * * This file is part of cool-retro-term. @@ -17,71 +17,70 @@ * 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.0 import QtQuick.Layouts 1.1 -ColumnLayout{ +ColumnLayout { spacing: 2 - GroupBox{ + GroupBox { title: qsTr("Effects") Layout.fillWidth: true ColumnLayout { anchors.fill: parent - CheckableSlider{ + CheckableSlider { name: qsTr("Bloom") onNewValue: appSettings.bloom = newValue value: appSettings.bloom } - CheckableSlider{ + CheckableSlider { name: qsTr("BurnIn") onNewValue: appSettings.burnIn = newValue value: appSettings.burnIn } - CheckableSlider{ + CheckableSlider { name: qsTr("Static Noise") onNewValue: appSettings.staticNoise = newValue value: appSettings.staticNoise } - CheckableSlider{ + CheckableSlider { name: qsTr("Jitter") onNewValue: appSettings.jitter = newValue value: appSettings.jitter } - CheckableSlider{ + CheckableSlider { name: qsTr("Glow Line") - onNewValue: appSettings.glowingLine = newValue; + onNewValue: appSettings.glowingLine = newValue value: appSettings.glowingLine } - CheckableSlider{ + CheckableSlider { name: qsTr("Screen Curvature") - onNewValue: appSettings.screenCurvature = newValue; - value: appSettings.screenCurvature; + onNewValue: appSettings.screenCurvature = newValue + value: appSettings.screenCurvature } - CheckableSlider{ + CheckableSlider { name: qsTr("Ambient Light") - onNewValue: appSettings.ambientLight = newValue; + onNewValue: appSettings.ambientLight = newValue value: appSettings.ambientLight enabled: appSettings.framesIndex !== 0 } - CheckableSlider{ + CheckableSlider { name: qsTr("Flickering") - onNewValue: appSettings.flickering = newValue; - value: appSettings.flickering; + onNewValue: appSettings.flickering = newValue + value: appSettings.flickering } - CheckableSlider{ + CheckableSlider { name: qsTr("Horizontal Sync") - onNewValue: appSettings.horizontalSync = newValue; - value: appSettings.horizontalSync; + onNewValue: appSettings.horizontalSync = newValue + value: appSettings.horizontalSync } - CheckableSlider{ + CheckableSlider { name: qsTr("RGB Shift") - onNewValue: appSettings.rbgShift = newValue; - value: appSettings.rbgShift; + onNewValue: appSettings.rbgShift = newValue + value: appSettings.rbgShift } } } diff --git a/app/qml/SettingsGeneralTab.qml b/app/qml/SettingsGeneralTab.qml index bd46a1f..ed3359e 100644 --- a/app/qml/SettingsGeneralTab.qml +++ b/app/qml/SettingsGeneralTab.qml @@ -1,5 +1,5 @@ /******************************************************************************* -* Copyright (c) 2013 "Filippo Scognamiglio" +* Copyright (c) 2013-2021 "Filippo Scognamiglio" * https://github.com/Swordfish90/cool-retro-term * * This file is part of cool-retro-term. @@ -17,14 +17,13 @@ * 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.4 import QtQuick.Layouts 1.1 import QtQuick.Dialogs 1.1 -ColumnLayout{ - GroupBox{ +ColumnLayout { + GroupBox { Layout.fillWidth: true title: qsTr("Profile") RowLayout { @@ -52,112 +51,127 @@ ColumnLayout{ ColumnLayout { Layout.fillHeight: true Layout.fillWidth: false - Button{ + Button { Layout.fillWidth: true text: qsTr("Save") onClicked: { - insertname.profileName = ""; + insertname.profileName = "" insertname.show() } } - Button{ + Button { Layout.fillWidth: true property alias currentIndex: profilesView.currentIndex enabled: currentIndex >= 0 text: qsTr("Load") onClicked: { - var index = currentIndex; + var index = currentIndex if (index >= 0) - appSettings.loadProfile(index); + appSettings.loadProfile(index) } } - Button{ + Button { Layout.fillWidth: true text: qsTr("Remove") property alias currentIndex: profilesView.currentIndex - enabled: currentIndex >= 0 && !appSettings.profilesList.get(currentIndex).builtin + enabled: currentIndex >= 0 && !appSettings.profilesList.get( + currentIndex).builtin onClicked: { - appSettings.profilesList.remove(currentIndex); - profilesView.selection.clear(); + 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; + profilesView.model = 0 + profilesView.model = appSettings.profilesList } } Item { // Spacing Layout.fillHeight: true } - Button{ + Button { Layout.fillWidth: true text: qsTr("Import") onClicked: { - fileDialog.selectExisting = true; - fileDialog.callBack = function (url) {loadFile(url);}; - fileDialog.open(); + fileDialog.selectExisting = true + fileDialog.callBack = function (url) { + loadFile(url) + } + fileDialog.open() } function loadFile(url) { try { if (appSettings.verbose) - console.log("Loading file: " + url); + console.log("Loading file: " + url) - var profileObject = JSON.parse(fileIO.read(url)); - var name = profileObject.name; + var profileObject = JSON.parse(fileIO.read(url)) + var name = profileObject.name if (!name) - throw "Profile doesn't have a name"; + throw "Profile doesn't have a name" - var version = profileObject.version !== undefined ? profileObject.version : 1; + var version = profileObject.version + !== undefined ? profileObject.version : 1 if (version !== appSettings.profileVersion) - throw "This profile is not supported on this version of CRT."; + throw "This profile is not supported on this version of CRT." - delete profileObject.name; + delete profileObject.name - appSettings.appendCustomProfile(name, JSON.stringify(profileObject)); + appSettings.appendCustomProfile(name, + JSON.stringify( + profileObject)) } catch (err) { messageDialog.text = qsTr(err) - messageDialog.open(); + messageDialog.open() } } } - Button{ + Button { property alias currentIndex: profilesView.currentIndex Layout.fillWidth: true text: qsTr("Export") - enabled: currentIndex >= 0 && !appSettings.profilesList.get(currentIndex).builtin + enabled: currentIndex >= 0 && !appSettings.profilesList.get( + currentIndex).builtin onClicked: { - fileDialog.selectExisting = false; - fileDialog.callBack = function (url) {storeFile(url);}; - fileDialog.open(); + fileDialog.selectExisting = false + fileDialog.callBack = function (url) { + storeFile(url) + } + fileDialog.open() } function storeFile(url) { try { - var urlString = url.toString(); + 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; + var extension = urlString.substring( + urlString.length - 5, urlString.length) + var urlTail = (extension === ".json" ? "" : ".json") + url += urlTail if (true) - console.log("Storing file: " + url); + 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 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)); + var result = fileIO.write(url, JSON.stringify( + profileSettings, + undefined, 2)) if (!result) - throw "The file could not be written."; + 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(); + console.log(err) + messageDialog.text = qsTr( + "There has been an error storing the file.") + messageDialog.open() } } } @@ -165,29 +179,44 @@ ColumnLayout{ } } - GroupBox{ + GroupBox { title: qsTr("Screen") Layout.fillWidth: true - GridLayout{ + GridLayout { anchors.fill: parent columns: 2 - Label{ text: qsTr("Brightness") } - SimpleSlider{ + Label { + text: qsTr("Brightness") + } + SimpleSlider { onValueChanged: appSettings.brightness = value value: appSettings.brightness } - Label{ text: qsTr("Contrast") } - SimpleSlider{ + Label { + text: qsTr("Contrast") + } + SimpleSlider { onValueChanged: appSettings.contrast = value value: appSettings.contrast } - Label{ text: qsTr("Margin") } - SimpleSlider{ + Label { + text: qsTr("Margin") + } + SimpleSlider { onValueChanged: appSettings._margin = value value: appSettings._margin } - Label{ text: qsTr("Opacity") } - SimpleSlider{ + Label { + text: qsTr("Frame size") + } + SimpleSlider { + onValueChanged: appSettings._frameMargin = value + value: appSettings._frameMargin + } + Label { + text: qsTr("Opacity") + } + SimpleSlider { onValueChanged: appSettings.windowOpacity = value value: appSettings.windowOpacity } @@ -195,17 +224,18 @@ ColumnLayout{ } // DIALOGS //////////////////////////////////////////////////////////////// - InsertNameDialog{ + InsertNameDialog { id: insertname onNameSelected: { - appSettings.appendCustomProfile(name, appSettings.composeProfileString()); + appSettings.appendCustomProfile(name, + appSettings.composeProfileString()) } } MessageDialog { id: messageDialog title: qsTr("File Error") onAccepted: { - messageDialog.close(); + messageDialog.close() } } Loader { @@ -213,23 +243,23 @@ ColumnLayout{ property bool selectExisting: false id: fileDialog - sourceComponent: FileDialog{ + sourceComponent: FileDialog { nameFilters: ["Json files (*.json)"] selectMultiple: false selectFolder: false selectExisting: fileDialog.selectExisting - onAccepted: callBack(fileUrl); + onAccepted: callBack(fileUrl) } onSelectExistingChanged: reload() function open() { - item.open(); + item.open() } function reload() { - active = false; - active = true; + active = false + active = true } } } diff --git a/app/qml/SettingsTerminalTab.qml b/app/qml/SettingsTerminalTab.qml index ba5a0b6..8e3a35c 100644 --- a/app/qml/SettingsTerminalTab.qml +++ b/app/qml/SettingsTerminalTab.qml @@ -1,5 +1,5 @@ /******************************************************************************* -* Copyright (c) 2013 "Filippo Scognamiglio" +* Copyright (c) 2013-2021 "Filippo Scognamiglio" * https://github.com/Swordfish90/cool-retro-term * * This file is part of cool-retro-term. @@ -17,7 +17,6 @@ * 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.1 import QtQuick.Layouts 1.1 @@ -25,135 +24,143 @@ import QtQml 2.0 import "Components" -ColumnLayout{ +ColumnLayout { - GroupBox{ + GroupBox { title: qsTr("Font") Layout.fillWidth: true - GridLayout{ + GridLayout { anchors.fill: parent columns: 2 - Label { text: qsTr("Rasterization") } + Label { + text: qsTr("Rasterization") + } ComboBox { id: rasterizationBox property string selectedElement: model[currentIndex] Layout.fillWidth: true - model: [qsTr("Default"), qsTr("Scanlines"), qsTr("Pixels")] + model: [qsTr("Default"), qsTr("Scanlines"), qsTr("Pixels"), qsTr("Sub-Pixels")] currentIndex: appSettings.rasterization onCurrentIndexChanged: { appSettings.rasterization = currentIndex } } - Label{ text: qsTr("Name") } - ComboBox{ + 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(); + 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); + function updateIndex() { + var name = appSettings.fontNames[appSettings.rasterization] + var index = appSettings.getIndexByName(name) if (index !== undefined) - currentIndex = index; + currentIndex = index } - Connections{ + Connections { target: appSettings - onTerminalFontChanged: fontChanger.updateIndex(); + onTerminalFontChanged: fontChanger.updateIndex() } - Component.onCompleted: updateIndex(); + Component.onCompleted: updateIndex() } - Label{ text: qsTr("Scaling") } - RowLayout{ + Label { + text: qsTr("Scaling") + } + RowLayout { Layout.fillWidth: true - Slider{ + Slider { Layout.fillWidth: true id: fontScalingChanger onValueChanged: appSettings.fontScaling = value value: appSettings.fontScaling stepSize: 0.05 - from: appSettings.minimumFontScaling; - to: appSettings.maximumFontScaling; + from: appSettings.minimumFontScaling + to: appSettings.maximumFontScaling } - SizedLabel{ + SizedLabel { text: Math.round(fontScalingChanger.value * 100) + "%" } } - Label{ text: qsTr("Font Width") } - RowLayout{ + Label { + text: qsTr("Font Width") + } + RowLayout { Layout.fillWidth: true - Slider{ + Slider { Layout.fillWidth: true id: widthChanger - onValueChanged: appSettings.fontWidth = value; + onValueChanged: appSettings.fontWidth = value value: appSettings.fontWidth stepSize: 0.05 from: 0.5 to: 1.5 } - SizedLabel{ + SizedLabel { text: Math.round(widthChanger.value * 100) + "%" } } } } - GroupBox{ + GroupBox { title: qsTr("Cursor") Layout.fillWidth: true ColumnLayout { anchors.fill: parent - CheckBox{ + CheckBox { id: blinkingCursor text: qsTr("Blinking Cursor") checked: appSettings.blinkingCursor onCheckedChanged: appSettings.blinkingCursor = checked } - Binding{ + Binding { target: blinkingCursor property: "checked" value: appSettings.blinkingCursor } } } - GroupBox{ + GroupBox { title: qsTr("Colors") Layout.fillWidth: true - ColumnLayout{ + ColumnLayout { anchors.fill: parent - ColumnLayout{ + ColumnLayout { Layout.fillWidth: true - CheckableSlider{ + CheckableSlider { name: qsTr("Chroma Color") onNewValue: appSettings.chromaColor = newValue value: appSettings.chromaColor } - CheckableSlider{ + CheckableSlider { name: qsTr("Saturation Color") onNewValue: appSettings.saturationColor = newValue value: appSettings.saturationColor enabled: appSettings.chromaColor !== 0 } } - RowLayout{ + RowLayout { Layout.fillWidth: true - ColorButton{ + ColorButton { name: qsTr("Font") height: 50 Layout.fillWidth: true - onColorSelected: appSettings._fontColor = color; + onColorSelected: appSettings._fontColor = color color: appSettings._fontColor } - ColorButton{ + ColorButton { name: qsTr("Background") height: 50 Layout.fillWidth: true - onColorSelected: appSettings._backgroundColor = color; + onColorSelected: appSettings._backgroundColor = color color: appSettings._backgroundColor } } diff --git a/app/qml/SettingsWindow.qml b/app/qml/SettingsWindow.qml index 3ce63dc..6b5c024 100644 --- a/app/qml/SettingsWindow.qml +++ b/app/qml/SettingsWindow.qml @@ -1,5 +1,5 @@ /******************************************************************************* -* Copyright (c) 2013 "Filippo Scognamiglio" +* Copyright (c) 2013-2021 "Filippo Scognamiglio" * https://github.com/Swordfish90/cool-retro-term * * This file is part of cool-retro-term. diff --git a/app/qml/ShaderLibrary.qml b/app/qml/ShaderLibrary.qml new file mode 100644 index 0000000..ae95f05 --- /dev/null +++ b/app/qml/ShaderLibrary.qml @@ -0,0 +1,91 @@ +import QtQuick 2.0 + +QtObject { + property string rasterizationShader: + (appSettings.rasterization === appSettings.no_rasterization ? " + lowp vec3 applyRasterization(vec2 screenCoords, lowp vec3 texel, vec2 virtualResolution, float intensity) { + return texel; + }" : "") + + + (appSettings.rasterization === appSettings.scanline_rasterization ? " + #define INTENSITY 0.30 + #define BRIGHTBOOST 0.30 + + lowp vec3 applyRasterization(vec2 screenCoords, lowp vec3 texel, vec2 virtualResolution, float intensity) { + lowp vec3 pixelHigh = ((1.0 + BRIGHTBOOST) - (0.2 * texel)) * texel; + lowp vec3 pixelLow = ((1.0 - INTENSITY) + (0.1 * texel)) * texel; + + vec2 coords = fract(screenCoords * virtualResolution) * 2.0 - vec2(1.0); + lowp float mask = 1.0 - abs(coords.y); + + lowp vec3 rasterizationColor = mix(pixelLow, pixelHigh, mask); + return mix(texel, rasterizationColor, intensity); + }" : "") + + + (appSettings.rasterization === appSettings.pixel_rasterization ? " + #define INTENSITY 0.30 + #define BRIGHTBOOST 0.30 + + lowp vec3 applyRasterization(vec2 screenCoords, lowp vec3 texel, vec2 virtualResolution, float intensity) { + lowp vec3 result = texel; + + lowp vec3 pixelHigh = ((1.0 + BRIGHTBOOST) - (0.2 * texel)) * texel; + lowp vec3 pixelLow = ((1.0 - INTENSITY) + (0.1 * texel)) * texel; + + vec2 coords = fract(screenCoords * virtualResolution) * 2.0 - vec2(1.0); + coords = coords * coords; + lowp float mask = 1.0 - coords.x - coords.y; + + lowp vec3 rasterizationColor = mix(pixelLow, pixelHigh, mask); + return mix(texel, rasterizationColor, intensity); + }" : "") + + + (appSettings.rasterization === appSettings.subpixel_rasterization ? " + #define INTENSITY 0.30 + #define BRIGHTBOOST 0.30 + #define SUBPIXELS 3.0 + const vec3 offsets = vec3(3.141592654) * vec3(1.0/2.0,1.0/2.0 - 2.0/3.0,1.0/2.0-4.0/3.0); + + lowp vec3 applyRasterization(vec2 screenCoords, lowp vec3 texel, vec2 virtualResolution, float intensity) { + vec2 omega = vec2(3.141592654) * vec2(2.0) * virtualResolution; + vec2 angle = screenCoords * omega; + vec3 xfactors = (SUBPIXELS + sin(angle.x + offsets)) / (SUBPIXELS + 1.0); + + lowp vec3 result = texel * xfactors; + lowp vec3 pixelHigh = ((1.0 + BRIGHTBOOST) - (0.2 * result)) * result; + lowp vec3 pixelLow = ((1.0 - INTENSITY) + (0.1 * result)) * result; + + vec2 coords = fract(screenCoords * virtualResolution) * 2.0 - vec2(1.0); + lowp float mask = 1.0 - abs(coords.y); + + lowp vec3 rasterizationColor = mix(pixelLow, pixelHigh, mask); + return mix(texel, rasterizationColor, intensity); + }" : "") + + + "\n\n" + + property string min2: " + float min2(vec2 v) { + return min(v.x, v.y); + }\n\n" + + property string rgb2grey: " + float rgb2grey(vec3 v) { + return dot(v, vec3(0.21, 0.72, 0.04)); + }\n\n" + + property string max2: " + float max2(vec2 v) { + return max(v.x, v.y); + }\n\n" + + property string prod2: " + float prod2(vec2 v) { + return v.x * v.y; + }\n\n" + + property string sum2: " + float sum2(vec2 v) { + return v.x + v.y; + }\n\n" +} diff --git a/app/qml/ShaderTerminal.qml b/app/qml/ShaderTerminal.qml index ed367af..4164320 100644 --- a/app/qml/ShaderTerminal.qml +++ b/app/qml/ShaderTerminal.qml @@ -1,5 +1,5 @@ /******************************************************************************* -* Copyright (c) 2013 "Filippo Scognamiglio" +* Copyright (c) 2013-2021 "Filippo Scognamiglio" * https://github.com/Swordfish90/cool-retro-term * * This file is part of cool-retro-term. @@ -38,11 +38,19 @@ Item { property real ambientLight: appSettings.ambientLight * 0.2 - property size virtual_resolution + property size virtualResolution + property size screenResolution + + property real _screenDensity: Math.min( + screenResolution.width / virtualResolution.width, + screenResolution.height / virtualResolution.height + ) ShaderEffect { id: dynamicShader + property ShaderLibrary shaderLibrary: ShaderLibrary { } + property ShaderEffectSource screenBuffer: frameBuffer property ShaderEffectSource burnInSource: burnInEffect.source property ShaderEffectSource frameSource: terminalFrameLoader.item @@ -71,10 +79,16 @@ Item { property size jitterDisplacement: Qt.size(0.007 * jitter, 0.002 * jitter) property real shadowLength: 0.25 * screenCurvature * Utils.lint(0.50, 1.5, ambientLight) property real staticNoise: appSettings.staticNoise - property size scaleNoiseSize: Qt.size((width) / (noiseTexture.width * appSettings.windowScaling * appSettings.totalFontScaling), - (height) / (noiseTexture.height * appSettings.windowScaling * appSettings.totalFontScaling)) + property size scaleNoiseSize: Qt.size((width * 0.75) / (noiseTexture.width * appSettings.windowScaling * appSettings.totalFontScaling), + (height * 0.75) / (noiseTexture.height * appSettings.windowScaling * appSettings.totalFontScaling)) - property size virtual_resolution: parent.virtual_resolution + property size virtualResolution: parent.virtualResolution + + // Rasterization might display oversamping issues if virtual resolution is close to physical display resolution. + // We progressively disable rasterization from 4x up to 2x resolution. + property real rasterizationIntensity: Utils.smoothstep(2.0, 4.0, _screenDensity) + + property real displayTerminalFrame: appSettings._frameMargin > 0 || appSettings.screenCurvature > 0 property real time: timeManager.time property ShaderEffectSource noiseSource: noiseShaderSource @@ -86,7 +100,7 @@ Item { blending: false //Smooth random texture used for flickering effect. - Image{ + Image { id: noiseTexture source: "images/allNoise512.png" width: 512 @@ -94,7 +108,7 @@ Item { fillMode: Image.Tile visible: false } - ShaderEffectSource{ + ShaderEffectSource { id: noiseShaderSource sourceItem: noiseTexture wrapMode: ShaderEffectSource.Repeat @@ -164,7 +178,8 @@ Item { uniform highp vec4 backgroundColor; uniform lowp float shadowLength; - uniform highp vec2 virtual_resolution;" + + uniform highp vec2 virtualResolution; + uniform lowp float rasterizationIntensity;\n" + (burnIn !== 0 ? " uniform sampler2D burnInSource; @@ -174,13 +189,13 @@ Item { uniform sampler2D slowBurnInSource;" : "") + (staticNoise !== 0 ? " uniform highp float staticNoise;" : "") + - (((staticNoise !== 0 || jitter !== 0) - ||(fallBack && (flickering || horizontalSync))) ? " + (((staticNoise !== 0 || jitter !== 0) ||(fallBack && (flickering || horizontalSync))) ? " uniform lowp sampler2D noiseSource; uniform highp vec2 scaleNoiseSize;" : "") + - (screenCurvature !== 0 ? " - uniform highp float screenCurvature; + (displayTerminalFrame ? " uniform lowp sampler2D frameSource;" : "") + + (screenCurvature !== 0 ? " + uniform highp float screenCurvature;" : "") + (glowingLine !== 0 ? " uniform highp float glowingLine;" : "") + (chromaColor !== 0 ? " @@ -203,17 +218,14 @@ Item { (glowingLine !== 0 ? " float randomPass(vec2 coords){ - return fract(smoothstep(-120.0, 0.0, coords.y - (virtual_resolution.y + 120.0) * fract(time * 0.00015))); + return fract(smoothstep(-120.0, 0.0, coords.y - (virtualResolution.y + 120.0) * fract(time * 0.00015))); }" : "") + - "float min2(vec2 v) { - return min(v.x, v.y); - } - - float rgb2grey(vec3 v){ - return dot(v, vec3(0.21, 0.72, 0.04)); - } + shaderLibrary.min2 + + shaderLibrary.rgb2grey + + shaderLibrary.rasterizationShader + + " float isInScreen(vec2 v) { return min2(step(0.0, v) - step(1.0, v)); } @@ -291,7 +303,7 @@ Item { color += noiseVal * noise * (1.0 - distance * 1.3);" : "") + (glowingLine !== 0 ? " - color += randomPass(coords * virtual_resolution) * glowingLine;" : "") + + color += randomPass(coords * virtualResolution) * glowingLine;" : "") + "vec3 txt_color = texture2D(screenBuffer, txt_coords).rgb;" + @@ -309,6 +321,8 @@ Item { "txt_color += fontColor.rgb * vec3(color);" + + "txt_color = applyRasterization(staticCoords, txt_color, virtualResolution, rasterizationIntensity);\n" + + "vec3 finalColor = txt_color;" + (flickering !== 0 ? " @@ -317,7 +331,7 @@ Item { (ambientLight !== 0 ? " finalColor += vec3(ambientLight) * (1.0 - distance) * (1.0 - distance);" : "") + - (screenCurvature !== 0 ? + (displayTerminalFrame ? "vec4 frameColor = texture2D(frameSource, qt_TexCoord0); finalColor = mix(finalColor, frameColor.rgb, frameColor.a);" : "") + @@ -340,7 +354,7 @@ Item { Loader { id: terminalFrameLoader - active: screenCurvature !== 0 + active: dynamicShader.displayTerminalFrame width: staticShader.width height: staticShader.height @@ -352,7 +366,7 @@ Item { visible: false format: ShaderEffectSource.RGBA - NewTerminalFrame { + TerminalFrame { id: terminalFrame blending: false anchors.fill: parent @@ -360,6 +374,10 @@ Item { } } + ShaderLibrary { + id: shaderLibrary + } + ShaderEffect { id: staticShader @@ -385,7 +403,7 @@ Item { property real ambientLight: parent.ambientLight - property size virtual_resolution: parent.virtual_resolution + property size virtualResolution: parent.virtualResolution blending: false visible: false @@ -408,7 +426,7 @@ Item { uniform highp vec4 backgroundColor; uniform lowp float screen_brightness; - uniform highp vec2 virtual_resolution;" + + uniform highp vec2 virtualResolution;" + (bloom !== 0 ? " uniform highp sampler2D bloomSource; @@ -426,36 +444,9 @@ Item { (ambientLight !== 0 ? " uniform lowp float ambientLight;" : "") + - "highp float getScanlineIntensity(vec2 coords) { - float result = 1.0;" + - - (appSettings.rasterization != appSettings.no_rasterization ? - "float val = 0.0; - vec2 rasterizationCoords = fract(coords * virtual_resolution); - val += smoothstep(0.0, 0.5, rasterizationCoords.y); - val -= smoothstep(0.5, 1.0, rasterizationCoords.y); - result *= mix(0.5, 1.0, val);" : "") + - - (appSettings.rasterization == appSettings.pixel_rasterization ? - "val = 0.0; - val += smoothstep(0.0, 0.5, rasterizationCoords.x); - val -= smoothstep(0.5, 1.0, rasterizationCoords.x); - result *= mix(0.5, 1.0, val);" : "") + " - - return result; - } - - float min2(vec2 v) { - return min(v.x, v.y); - } - - float sum2(vec2 v) { - return v.x + v.y; - } - - float rgb2grey(vec3 v){ - return dot(v, vec3(0.21, 0.72, 0.04)); - }" + + shaderLibrary.min2 + + shaderLibrary.sum2 + + shaderLibrary.rgb2grey + "vec3 convertWithChroma(vec3 inColor) { vec3 outColor = inColor;" + @@ -468,6 +459,7 @@ Item { " return outColor; }" + + shaderLibrary.rasterizationShader + "void main() {" + "vec2 cc = vec2(0.5) - qt_TexCoord0;" + @@ -490,8 +482,6 @@ Item { txt_color.b = leftColor.b * 0.30 + rightColor.b * 0.10 + txt_color.b * 0.60; " : "") + - "txt_color *= getScanlineIntensity(txt_coords);" + - "txt_color += vec3(0.0001);" + "float greyscale_color = rgb2grey(txt_color);" + diff --git a/app/qml/SimpleSlider.qml b/app/qml/SimpleSlider.qml index 003460f..e2bf0bd 100644 --- a/app/qml/SimpleSlider.qml +++ b/app/qml/SimpleSlider.qml @@ -1,5 +1,5 @@ /******************************************************************************* -* Copyright (c) 2013 "Filippo Scognamiglio" +* Copyright (c) 2013-2021 "Filippo Scognamiglio" * https://github.com/Swordfish90/cool-retro-term * * This file is part of cool-retro-term. @@ -17,7 +17,6 @@ * 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.0 import QtQuick.Layouts 1.1 @@ -33,12 +32,12 @@ RowLayout { id: setting_component spacing: 10 - Slider{ + Slider { id: slider stepSize: parent.stepSize Layout.fillWidth: true } - SizedLabel{ + SizedLabel { text: Math.round(value * maxMultiplier) + "%" } } diff --git a/app/qml/SizeOverlay.qml b/app/qml/SizeOverlay.qml index 7d67314..247534d 100644 --- a/app/qml/SizeOverlay.qml +++ b/app/qml/SizeOverlay.qml @@ -1,5 +1,5 @@ /******************************************************************************* -* Copyright (c) 2013 "Filippo Scognamiglio" +* Copyright (c) 2013-2021 "Filippo Scognamiglio" * https://github.com/Swordfish90/cool-retro-term * * This file is part of cool-retro-term. @@ -17,12 +17,12 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . *******************************************************************************/ - import QtQuick 2.2 -Rectangle{ +Rectangle { property size terminalSize property real topOpacity: 0.6 + width: textSize.width * 2 height: textSize.height * 2 radius: 5 @@ -31,17 +31,21 @@ Rectangle{ color: "black" opacity: sizetimer.running ? 0.6 : 0.0 - Behavior on opacity{NumberAnimation{duration: 200}} + Behavior on opacity { + NumberAnimation { + duration: 200 + } + } onTerminalSizeChanged: sizetimer.restart() - Text{ + Text { id: textSize anchors.centerIn: parent color: "white" text: terminalSize.width + "x" + terminalSize.height } - Timer{ + Timer { id: sizetimer interval: 1000 running: false diff --git a/app/qml/SlowBurnIn.qml b/app/qml/SlowBurnIn.qml index 44f53e9..25899ba 100644 --- a/app/qml/SlowBurnIn.qml +++ b/app/qml/SlowBurnIn.qml @@ -1,3 +1,23 @@ +/******************************************************************************* +* 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.0 import "utils.js" as Utils @@ -6,12 +26,10 @@ Loader { property ShaderEffectSource source: item ? item.source : null active: !appSettings.useFastBurnIn && appSettings.burnIn !== 0 - anchors.fill: parent sourceComponent: Item { property alias source: burnInSourceEffect - property int burnInScaling: scaleTexture * appSettings.burnInQuality ShaderEffectSource { @@ -48,7 +66,7 @@ Loader { } } - Timer{ + Timer { id: livetimer // The interval assumes 60 fps. This is the time needed burnout a white pixel. @@ -59,7 +77,7 @@ Loader { running: true onTriggered: burnInSourceEffect.updateBurnIn = false; } - Connections{ + Connections { target: kterminal onImagePainted:{ burnInSourceEffect.scheduleUpdate(); @@ -68,7 +86,7 @@ Loader { } } // Restart blurred source settings change. - Connections{ + Connections { target: appSettings onBurnInChanged: burnInSourceEffect.restartBlurSource(); onTerminalFontChanged: burnInSourceEffect.restartBlurSource(); @@ -92,28 +110,28 @@ Loader { fragmentShader: "#ifdef GL_ES - precision mediump float; - #endif\n" + + precision mediump float; + #endif\n" + - "uniform lowp float qt_Opacity;" + - "uniform lowp sampler2D txt_source;" + + "uniform lowp float qt_Opacity;" + + "uniform lowp sampler2D txt_source;" + - "varying highp vec2 qt_TexCoord0; - uniform lowp sampler2D blurredSource; - uniform highp float burnInCoefficient;" + + "varying highp vec2 qt_TexCoord0; + uniform lowp sampler2D blurredSource; + uniform highp float burnInCoefficient;" + - "float max3(vec3 v) { - return max (max (v.x, v.y), v.z); - }" + + "float max3(vec3 v) { + return max (max (v.x, v.y), v.z); + }" + - "void main() {" + - "vec2 coords = qt_TexCoord0;" + - "vec3 origColor = texture2D(txt_source, coords).rgb;" + - "vec3 blur_color = texture2D(blurredSource, coords).rgb - vec3(burnInCoefficient);" + - "vec3 color = min(origColor + blur_color, max(origColor, blur_color));" + + "void main() {" + + "vec2 coords = qt_TexCoord0;" + + "vec3 origColor = texture2D(txt_source, coords).rgb;" + + "vec3 blur_color = texture2D(blurredSource, coords).rgb - vec3(burnInCoefficient);" + + "vec3 color = min(origColor + blur_color, max(origColor, blur_color));" + - "gl_FragColor = vec4(color, max3(color - origColor));" + - "}" + "gl_FragColor = vec4(color, max3(color - origColor));" + + "}" onStatusChanged: if (log) console.log(log) //Print warning messages } diff --git a/app/qml/Storage.qml b/app/qml/Storage.qml index 6554314..cd6699d 100644 --- a/app/qml/Storage.qml +++ b/app/qml/Storage.qml @@ -1,5 +1,5 @@ /******************************************************************************* -* Copyright (c) 2013 "Filippo Scognamiglio" +* Copyright (c) 2013-2021 "Filippo Scognamiglio" * https://github.com/Swordfish90/cool-retro-term * * This file is part of cool-retro-term. @@ -27,7 +27,7 @@ QtObject { property bool initialized: false function getDatabase() { - return LocalStorage.openDatabaseSync("coolretroterm" + dbMajorVersion, dbMinorVersion, "StorageDatabase", 100000); + return LocalStorage.openDatabaseSync("coolretroterm" + dbMajorVersion, dbMinorVersion, "StorageDatabase", 100000) } function initialize() { @@ -35,43 +35,47 @@ QtObject { db.transaction( function(tx) { tx.executeSql('CREATE TABLE IF NOT EXISTS settings(setting TEXT UNIQUE, value TEXT)'); - }); + } + ) - initialized = true; + initialized = true } function setSetting(setting, value) { - if(!initialized) initialize(); + if(!initialized) initialize(); - var db = getDatabase(); - var res = ""; - db.transaction(function(tx) { - var rs = tx.executeSql('INSERT OR REPLACE INTO settings VALUES (?,?);', [setting,value]); - //console.log(rs.rowsAffected) - if (rs.rowsAffected > 0) { + var db = getDatabase(); + var res = ""; + db.transaction( + function(tx) { + var rs = tx.executeSql('INSERT OR REPLACE INTO settings VALUES (?,?);', [setting,value]); + //console.log(rs.rowsAffected) + if (rs.rowsAffected > 0) { res = "OK"; - } else { + } else { res = "Error"; - } - } - ); + } + } + ) // The function returns “OK” if it was successful, or “Error” if it wasn't - return res; + return res } function getSetting(setting) { - if(!initialized) initialize(); - var db = getDatabase(); - var res=""; - db.transaction(function(tx) { - var rs = tx.executeSql('SELECT value FROM settings WHERE setting=?;', [setting]); - if (rs.rows.length > 0) { - res = rs.rows.item(0).value; - } else { - res = undefined; - } - }) - return res + if(!initialized) initialize(); + var db = getDatabase(); + var res = ""; + db.transaction( + function(tx) { + var rs = tx.executeSql('SELECT value FROM settings WHERE setting=?;', [setting]); + if (rs.rows.length > 0) { + res = rs.rows.item(0).value; + } else { + res = undefined; + } + } + ) + return res } function dropSettings(){ @@ -79,6 +83,7 @@ QtObject { db.transaction( function(tx) { tx.executeSql('DROP TABLE settings'); - }); + } + ) } } diff --git a/app/qml/TerminalContainer.qml b/app/qml/TerminalContainer.qml index 48d6ec1..9896354 100644 --- a/app/qml/TerminalContainer.qml +++ b/app/qml/TerminalContainer.qml @@ -1,3 +1,22 @@ +/******************************************************************************* +* 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 QtGraphicalEffects 1.0 @@ -7,44 +26,49 @@ ShaderTerminal { property alias title: terminal.title property alias terminalSize: terminal.terminalSize + property real devicePixelRatio: terminalWindow.screen.devicePixelRatio + id: mainShader opacity: appSettings.windowOpacity * 0.3 + 0.7 source: terminal.mainSource burnInEffect: terminal.burnInEffect slowBurnInEffect: terminal.slowBurnInEffect - virtual_resolution: terminal.virtualResolution + virtualResolution: terminal.virtualResolution + screenResolution: Qt.size( + terminalWindow.width * devicePixelRatio * appSettings.windowScaling, + terminalWindow.height * devicePixelRatio * appSettings.windowScaling + ) - TimeManager{ + TimeManager { id: timeManager enableTimer: terminalWindow.visible } - PreprocessedTerminal{ + PreprocessedTerminal { id: terminal anchors.fill: parent } // EFFECTS //////////////////////////////////////////////////////////////// - - Loader{ + Loader { id: bloomEffectLoader active: appSettings.bloom asynchronous: true width: parent.width * appSettings.bloomQuality height: parent.height * appSettings.bloomQuality - sourceComponent: FastBlur{ - radius: Utils.lint(16, 64, appSettings.bloomQuality); + sourceComponent: FastBlur { + radius: Utils.lint(16, 64, appSettings.bloomQuality) source: terminal.mainSource transparentBorder: true } } - Loader{ + Loader { id: bloomSourceLoader active: appSettings.bloom !== 0 asynchronous: true - sourceComponent: ShaderEffectSource{ + sourceComponent: ShaderEffectSource { id: _bloomEffectSource sourceItem: bloomEffectLoader.item hideSource: true @@ -54,71 +78,4 @@ ShaderTerminal { } bloomSource: bloomSourceLoader.item - -// NewTerminalFrame { -// id: terminalFrame -// anchors.fill: parent -// blending: true -// } - - // This shader might be useful in the future. Since we used it only for a couple - // of calculations is probably best to move those in the main shader. If in the future - // we need to store another fullScreen channel this might be handy. - -// ShaderEffect { -// id: rasterizationEffect -// width: parent.width -// height: parent.height -// property real outColor: 0.0 -// property real dispX: (5 / width) * appSettings.windowScaling -// property real dispY: (5 / height) * appSettings.windowScaling -// property size virtual_resolution: terminal.virtualResolution - -// blending: false - -// fragmentShader: -// "uniform lowp float qt_Opacity;" + - -// "varying highp vec2 qt_TexCoord0; -// uniform highp vec2 virtual_resolution; -// uniform highp float dispX; -// uniform highp float dispY; -// uniform mediump float outColor; - -// highp float getScanlineIntensity(vec2 coords) { -// highp float result = 1.0;" + - -// (appSettings.rasterization != appSettings.no_rasterization ? -// "result *= abs(sin(coords.y * virtual_resolution.y * "+Math.PI+"));" : "") + -// (appSettings.rasterization == appSettings.pixel_rasterization ? -// "result *= abs(sin(coords.x * virtual_resolution.x * "+Math.PI+"));" : "") + " - -// return result; -// }" + - -// "void main() {" + -// "highp float color = getScanlineIntensity(qt_TexCoord0);" + - -// "float distance = length(vec2(0.5) - qt_TexCoord0);" + -// "color = mix(color, 0.0, 1.2 * distance * distance);" + - -// "color *= outColor + smoothstep(0.00, dispX, qt_TexCoord0.x) * (1.0 - outColor);" + -// "color *= outColor + smoothstep(0.00, dispY, qt_TexCoord0.y) * (1.0 - outColor);" + -// "color *= outColor + (1.0 - smoothstep(1.00 - dispX, 1.00, qt_TexCoord0.x)) * (1.0 - outColor);" + -// "color *= outColor + (1.0 - smoothstep(1.00 - dispY, 1.00, qt_TexCoord0.y)) * (1.0 - outColor);" + - -// "gl_FragColor.a = color;" + -// "}" - -// onStatusChanged: if (log) console.log(log) //Print warning messages -// } - -// rasterizationSource: ShaderEffectSource{ -// id: rasterizationEffectSource -// sourceItem: rasterizationEffect -// hideSource: true -// smooth: true -// wrapMode: ShaderEffectSource.ClampToEdge -// visible: false -// } } diff --git a/app/qml/TerminalFrame.qml b/app/qml/TerminalFrame.qml new file mode 100644 index 0000000..3e1baef --- /dev/null +++ b/app/qml/TerminalFrame.qml @@ -0,0 +1,104 @@ +/******************************************************************************* +* 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.0 + +import "utils.js" as Utils + +ShaderEffect { + property color _staticFrameColor: "#fff" + property color _backgroundColor: appSettings.backgroundColor + property color _fontColor: appSettings.fontColor + property color _lightColor: Utils.mix(_fontColor, _backgroundColor, 0.2) + property real _ambientLight: Utils.lint(0.2, 0.8, appSettings.ambientLight) + + property color frameColor: Utils.mix(_staticFrameColor, _lightColor, _ambientLight) + property real screenCurvature: appSettings.screenCurvature * appSettings.screenCurvatureSize + + // Coefficient of the log curve used to approximate shadowing + property real screenShadowCoeff: Utils.lint(20.0, 10.0, _ambientLight) + property real frameShadowCoeff: Utils.lint(20.0, 10.0, _ambientLight) + + property size margin: Qt.size( + appSettings.frameMargin / width * appSettings.windowScaling, + appSettings.frameMargin / height * appSettings.windowScaling + ) + + ShaderLibrary { + id: shaderLibrary + } + + fragmentShader: " + #ifdef GL_ES + precision mediump float; + #endif + + uniform lowp float screenCurvature; + uniform lowp float screenShadowCoeff; + uniform lowp float frameShadowCoeff; + uniform highp float qt_Opacity; + uniform lowp vec4 frameColor; + uniform mediump vec2 margin; + + varying highp vec2 qt_TexCoord0; + + vec2 distortCoordinates(vec2 coords){ + vec2 cc = (coords - vec2(0.5)); + float dist = dot(cc, cc) * screenCurvature; + return (coords + cc * (1.0 + dist) * dist); + } + " + + + shaderLibrary.max2 + + shaderLibrary.min2 + + shaderLibrary.prod2 + + shaderLibrary.sum2 + + + " + + vec2 positiveLog(vec2 x) { + return clamp(log(x), vec2(0.0), vec2(100.0)); + } + + void main() { + vec2 staticCoords = qt_TexCoord0; + vec2 coords = distortCoordinates(staticCoords) * (vec2(1.0) + margin * 2.0) - margin; + + vec2 vignetteCoords = staticCoords * (1.0 - staticCoords.yx); + float vignette = pow(prod2(vignetteCoords) * 15.0, 0.25); + + vec3 color = frameColor.rgb * vec3(1.0 - vignette); + float alpha = 0.0; + + float frameShadow = max2(positiveLog(-coords * frameShadowCoeff + vec2(1.0)) + positiveLog(coords * frameShadowCoeff - (vec2(frameShadowCoeff) - vec2(1.0)))); + frameShadow = max(sqrt(frameShadow), 0.0); + color *= frameShadow; + alpha = sum2(1.0 - step(vec2(0.0), coords) + step(vec2(1.0), coords)); + alpha = clamp(alpha, 0.0, 1.0); + alpha *= mix(1.0, 0.9, frameShadow); + + float screenShadow = 1.0 - prod2(positiveLog(coords * screenShadowCoeff + vec2(1.0)) * positiveLog(-coords * screenShadowCoeff + vec2(screenShadowCoeff + 1.0))); + alpha = max(0.8 * screenShadow, alpha); + + gl_FragColor = vec4(color * alpha, alpha); + } + " + + onStatusChanged: if (log) console.log(log) //Print warning messages +} diff --git a/app/qml/TimeManager.qml b/app/qml/TimeManager.qml index 52da262..6424af2 100644 --- a/app/qml/TimeManager.qml +++ b/app/qml/TimeManager.qml @@ -1,5 +1,5 @@ /******************************************************************************* -* Copyright (c) 2013 "Filippo Scognamiglio" +* Copyright (c) 2013-2021 "Filippo Scognamiglio" * https://github.com/Swordfish90/cool-retro-term * * This file is part of cool-retro-term. @@ -17,10 +17,9 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . *******************************************************************************/ - import QtQuick 2.2 -Timer{ +Timer { default property bool enableTimer: false property real time diff --git a/app/qml/main.qml b/app/qml/main.qml index a1fe125..0e8395f 100644 --- a/app/qml/main.qml +++ b/app/qml/main.qml @@ -1,5 +1,5 @@ /******************************************************************************* -* Copyright (c) 2013 "Filippo Scognamiglio" +* Copyright (c) 2013-2021 "Filippo Scognamiglio" * https://github.com/Swordfish90/cool-retro-term * * This file is part of cool-retro-term. @@ -17,14 +17,13 @@ * 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.Window 2.1 import QtQuick.Controls 2.3 import "menus" -ApplicationWindow{ +ApplicationWindow { id: terminalWindow width: 1024 @@ -37,7 +36,7 @@ ApplicationWindow{ onHeightChanged: appSettings.height = height // Load saved window geometry and show the window - Component.onCompleted: { + Component.onCompleted: { x = appSettings.x y = appSettings.y width = appSettings.width @@ -78,7 +77,7 @@ ApplicationWindow{ text: qsTr("Fullscreen") enabled: Qt.platform.os !== "osx" shortcut: "Alt+F11" - onTriggered: appSettings.fullscreen = !appSettings.fullscreen; + onTriggered: appSettings.fullscreen = !appSettings.fullscreen checkable: true checked: appSettings.fullscreen } @@ -86,68 +85,68 @@ ApplicationWindow{ id: quitAction text: qsTr("Quit") shortcut: "Ctrl+Shift+Q" - onTriggered: Qt.quit(); + onTriggered: Qt.quit() } - Action{ + Action { id: showsettingsAction text: qsTr("Settings") onTriggered: { - settingswindow.show(); - settingswindow.requestActivate(); - settingswindow.raise(); + settingswindow.show() + settingswindow.requestActivate() + settingswindow.raise() } } - Action{ + Action { id: copyAction text: qsTr("Copy") shortcut: "Ctrl+Shift+C" } - Action{ + Action { id: pasteAction text: qsTr("Paste") shortcut: "Ctrl+Shift+V" } - Action{ + Action { id: zoomIn text: qsTr("Zoom In") shortcut: "Ctrl++" - onTriggered: appSettings.incrementScaling(); + onTriggered: appSettings.incrementScaling() } - Action{ + Action { id: zoomOut text: qsTr("Zoom Out") shortcut: "Ctrl+-" - onTriggered: appSettings.decrementScaling(); + onTriggered: appSettings.decrementScaling() } - Action{ + Action { id: showAboutAction text: qsTr("About") onTriggered: { - aboutDialog.show(); - aboutDialog.requestActivate(); - aboutDialog.raise(); + aboutDialog.show() + aboutDialog.requestActivate() + aboutDialog.raise() } } - ApplicationSettings{ + ApplicationSettings { id: appSettings } - TerminalContainer{ + TerminalContainer { id: terminalContainer width: parent.width height: (parent.height + Math.abs(y)) } - SettingsWindow{ + SettingsWindow { id: settingswindow visible: false } - AboutDialog{ + AboutDialog { id: aboutDialog visible: false } - Loader{ + Loader { anchors.centerIn: parent active: appSettings.showTerminalSize - sourceComponent: SizeOverlay{ + sourceComponent: SizeOverlay { z: 3 terminalSize: terminalContainer.terminalSize } diff --git a/app/qml/menus/FullContextMenu.qml b/app/qml/menus/FullContextMenu.qml index 1b75320..d9feb58 100644 --- a/app/qml/menus/FullContextMenu.qml +++ b/app/qml/menus/FullContextMenu.qml @@ -17,17 +17,22 @@ * 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{ +Menu { id: contextmenu - MenuItem { action: copyAction } - MenuItem { action: pasteAction } - MenuItem { action: showsettingsAction } + MenuItem { + action: copyAction + } + MenuItem { + action: pasteAction + } + MenuItem { + action: showsettingsAction + } - MenuSeparator { } + MenuSeparator {} Menu { title: qsTr("File") @@ -37,36 +42,54 @@ Menu{ } Menu { title: qsTr("Edit") - MenuItem {action: copyAction} - MenuItem {action: pasteAction} - MenuSeparator { } - MenuItem {action: showsettingsAction} + MenuItem { + action: copyAction + } + MenuItem { + action: pasteAction + } + MenuSeparator {} + MenuItem { + action: showsettingsAction + } } - Menu{ + Menu { title: qsTr("View") - MenuItem {action: fullscreenAction; visible: fullscreenAction.enabled} - MenuItem {action: showMenubarAction; visible: showMenubarAction.enabled} - MenuItem {action: zoomIn} - MenuItem {action: zoomOut} + MenuItem { + action: fullscreenAction + visible: fullscreenAction.enabled + } + MenuItem { + action: showMenubarAction + visible: showMenubarAction.enabled + } + MenuItem { + action: zoomIn + } + MenuItem { + action: zoomOut + } } - Menu{ + Menu { id: profilesMenu title: qsTr("Profiles") - Instantiator{ + Instantiator { model: appSettings.profilesList delegate: MenuItem { text: model.text onTriggered: { - appSettings.loadProfileString(obj_string); - appSettings.handleFontChanged(); + appSettings.loadProfileString(obj_string) + appSettings.handleFontChanged() } } onObjectAdded: profilesMenu.insertItem(index, object) onObjectRemoved: profilesMenu.removeItem(object) } } - Menu{ + Menu { title: qsTr("Help") - MenuItem {action: showAboutAction} + MenuItem { + action: showAboutAction + } } } diff --git a/app/qml/menus/ShortContextMenu.qml b/app/qml/menus/ShortContextMenu.qml index ea711ca..9d8f63b 100644 --- a/app/qml/menus/ShortContextMenu.qml +++ b/app/qml/menus/ShortContextMenu.qml @@ -17,12 +17,15 @@ * 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{ +Menu { id: contextmenu - MenuItem { action: copyAction } - MenuItem { action: pasteAction } + MenuItem { + action: copyAction + } + MenuItem { + action: pasteAction + } } diff --git a/app/qml/menus/WindowMenu.qml b/app/qml/menus/WindowMenu.qml index 6154f1f..937153b 100644 --- a/app/qml/menus/WindowMenu.qml +++ b/app/qml/menus/WindowMenu.qml @@ -17,7 +17,6 @@ * 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 @@ -27,40 +26,60 @@ MenuBar { Menu { title: qsTr("File") - MenuItem {action: quitAction} + MenuItem { + action: quitAction + } } Menu { title: qsTr("Edit") - MenuItem {action: copyAction} - MenuItem {action: pasteAction} - MenuSeparator { } - MenuItem {action: showsettingsAction} + MenuItem { + action: copyAction + } + MenuItem { + action: pasteAction + } + MenuSeparator {} + MenuItem { + action: showsettingsAction + } } - Menu{ + Menu { title: qsTr("View") - MenuItem {action: fullscreenAction; visible: fullscreenAction.enabled} - MenuItem {action: showMenubarAction; visible: showMenubarAction.enabled} - MenuItem {action: zoomIn} - MenuItem {action: zoomOut} + MenuItem { + action: fullscreenAction + visible: fullscreenAction.enabled + } + MenuItem { + action: showMenubarAction + visible: showMenubarAction.enabled + } + MenuItem { + action: zoomIn + } + MenuItem { + action: zoomOut + } } - Menu{ + Menu { id: profilesMenu title: qsTr("Profiles") - Instantiator{ + Instantiator { model: appSettings.profilesList delegate: MenuItem { text: model.text onTriggered: { - appSettings.loadProfileString(obj_string); - appSettings.handleFontChanged(); + appSettings.loadProfileString(obj_string) + appSettings.handleFontChanged() } } onObjectAdded: profilesMenu.insertItem(index, object) onObjectRemoved: profilesMenu.removeItem(object) } } - Menu{ + Menu { title: qsTr("Help") - MenuItem {action: showAboutAction} + MenuItem { + action: showAboutAction + } } } diff --git a/app/qml/resources.qrc b/app/qml/resources.qrc index 2f15ed8..0cb4d24 100644 --- a/app/qml/resources.qrc +++ b/app/qml/resources.qrc @@ -40,10 +40,11 @@ fonts/1977-commodore-pet/PetMe.ttf BurnInEffect.qml fonts/modern-terminus/TerminusTTF-4.46.0.ttf - NewTerminalFrame.qml + TerminalFrame.qml SlowBurnIn.qml menus/WindowMenu.qml menus/FullContextMenu.qml menus/ShortContextMenu.qml + ShaderLibrary.qml diff --git a/app/qml/utils.js b/app/qml/utils.js index a8e1af0..3cb5a67 100644 --- a/app/qml/utils.js +++ b/app/qml/utils.js @@ -1,3 +1,23 @@ +/******************************************************************************* +* 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 . +*******************************************************************************/ + .pragma library function clamp(x, min, max) { if (x <= min) @@ -6,15 +26,23 @@ function clamp(x, min, max) { return max; return x; } + function lint(a, b, t) { return (1 - t) * a + (t) * b; } -function mix(c1, c2, alpha){ + +function mix(c1, c2, alpha) { return Qt.rgba(c1.r * alpha + c2.r * (1-alpha), c1.g * alpha + c2.g * (1-alpha), c1.b * alpha + c2.b * (1-alpha), c1.a * alpha + c2.a * (1-alpha)) } + +function smoothstep(min, max, value) { + let x = Math.max(0, Math.min(1, (value - min) / (max - min))); + return x * x * (3 - 2 * x); +} + function strToColor(s){ var r = parseInt(s.substring(1,3), 16) / 256; var g = parseInt(s.substring(3,5), 16) / 256;