Merge upstream cool-retro-terminal updates

This commit is contained in:
Reed Johns 2025-02-24 11:30:46 -07:00
commit abef7e54a7
45 changed files with 2205 additions and 1709 deletions

4
.github/FUNDING.yml vendored Normal file
View File

@ -0,0 +1,4 @@
# These are supported funding model platforms
patreon: swordfish90
custom: ['https://www.paypal.com/cgi-bin/webscr?cmd=_donations&business=flscogna%40gmail.com&item_name=Support+CRT&currency_code=EUR&source=url']

98
.github/workflows/appimage.yml vendored Normal file
View File

@ -0,0 +1,98 @@
name: "ci"
on:
push:
tags: "**"
workflow_dispatch:
defaults:
run:
shell: bash
jobs:
appimage:
runs-on: ubuntu-18.04
steps:
- name: Checkout repository
uses: actions/checkout@v2
with:
submodules: true
- name: Install dependencies
run: |
sudo add-apt-repository -y ppa:beineri/opt-qt-5.15.2-bionic
sudo apt-get update -qq
sudo apt-get install -y \
build-essential make wget libgl1-mesa-dev \
qt515declarative qt515graphicaleffects \
qt515quickcontrols qt515quickcontrols2
- name: Download QT appimage builder
run: |
wget -c -O linuxdeployqt.AppImage \
https://github.com/probonopd/linuxdeployqt/releases/download/continuous/linuxdeployqt-continuous-x86_64.AppImage
chmod a+x linuxdeployqt.AppImage
- name: Build project
run: |
source /opt/qt*/bin/qt*-env.sh && \
qmake -v && \
qmake CONFIG+=release PREFIX=/usr && \
make -j$(nproc)
- name: Install to appdir
run: |
source /opt/qt*/bin/qt*-env.sh && \
make INSTALL_ROOT=appdir -j$(nproc) install
- name: Extract version number
run: |
# Extract version for linuxdeployqt to name the file. Use the tag as
# release name but remove prefix.
echo "VERSION=$(echo '${{ github.ref }}' | sed 's;.*/;;')" >> $GITHUB_ENV
- name: Build appimage directory
run: |
mkdir -p \
appdir/usr/bin \
appdir/usr/lib \
appdir/usr/share/applications \
appdir/usr/share/metainfo \
appdir/usr/share/icons/hicolor/128x128/apps
cp cool-retro-term appdir/usr/bin/
cp cool-retro-term.desktop appdir/usr/share/applications/
cp packaging/appdata/cool-retro-term.appdata.xml appdir/usr/share/metainfo/
cp app/icons/128x128/cool-retro-term.png appdir/usr/share/icons/hicolor/128x128/apps/
cp -r ./app/qml appdir/usr/
# Workaround for https://github.com/probonopd/linuxdeployqt/issues/78
cp -r ./qmltermwidget/QMLTermWidget appdir/usr/qml/
find appdir | sort
- name: Build appimage
run: |
source /opt/qt*/bin/qt*-env.sh && \
./linuxdeployqt.AppImage appdir/usr/share/applications/cool-retro-term.desktop \
-verbose=1 -appimage \
-qmldir=./app/qml/ \
-qmldir=./qmltermwidget/
env:
# Unset environment variables
QTDIR:
QT_PLUGIN_PATH:
LD_LIBRARY_PATH:
- name: Upload release
uses: softprops/action-gh-release@v1
with:
body: appimage release
files: ./**/Cool_Retro_Term-*-x86_64.AppImage
- name: Clean up
if: always()
run: |
find appdir -executable -type f -exec ldd {} \; | grep " => /usr" | cut -d " " -f 2-3 | sort | uniq
make clean
rm -rf appdir

1
.gitignore vendored
View File

@ -18,6 +18,7 @@
*.pro.user.*
*.moc
moc_*.cpp
moc_*.h
qrc_*.cpp
ui_*.h
Makefile*

View File

@ -1,39 +1,25 @@
# cool-cyber-term
## Description
this is a modified version of cool-retro-term, which enables you to add background images to crt.
You will have to specify a folder with all your background images you want to use, aswell as a opacity factor if you want to still see your desktop, and a scaling factor, in case you want the pictures to be pixellated. all this has to be done in the file background_selection.py.
cool-retro-term is a terminal emulator which mimics the look and feel of the old cathode tube screens.
It has been designed to be eye-candy, customizable, and reasonably lightweight.
The used image will then be chosen randomly, each time you start a new terminal.
It uses the QML port of qtermwidget (Konsole): https://github.com/Swordfish90/qmltermwidget.
You may want to add a shortcut, which can be done as followed:
1. go to settings -> devices -> keyboard
2. change the "launch terminal" shortcut to anything but ctrl-alt-t
3. add a new shortcut and use as shortcut ctrl-alt-t and use as command '/opt/cool-cyber-term/start.sh'
This terminal emulator works under Linux and macOS and requires Qt5. It's suggested that you stick to the latest LTS version.
## Screenshot
![Imgur](https://i.imgur.com/q47kwHt.jpg)
Settings such as colors, fonts, and effects can be accessed via context menu.
## Screenshots
![Image](<https://i.imgur.com/TNumkDn.png>)
![Image](<https://i.imgur.com/hfjWOM4.png>)
![Image](<https://i.imgur.com/GYRDPzJ.jpg>)
## Install
This was tested on ubuntu 18.04.
### Install Dependencies
If you want to get a hold of the latest version, just go to the Releases page and grab the latest AppImage (Linux) or dmg (macOS).
sudo apt-get install build-essential qml-module-qtgraphicaleffects qml-module-qt-labs-folderlistmodel qml-module-qt-labs-settings qml-module-qtquick-controls qml-module-qtquick-dialogs qmlscene qt5-default qt5-qmake qtdeclarative5-dev qtdeclarative5-localstorage-plugin qtdeclarative5-qtquick2-plugin qtdeclarative5-window-plugin imagemagick python3
### Compile
Alternatively, most distributions such as Ubuntu, Fedora or Arch already package cool-retro-term in their official repositories.
```bash
# Get it!
git clone --recursive https://github.com/neurudan/cool-cyber-term.git
## Building
# Move it!
sudo mv cool-cyber-term /opt/
sudo chmod -R a=rwx /opt/cool-cyber-term
cd /opt/cool-cyber-term
sudo cp cool-cyber-term.desktop /usr/share/applications
# Build it!
qmake && make
# Use it!
```
Check out the wiki and follow the instructions on how to build it on [Linux](https://github.com/Swordfish90/cool-retro-term/wiki/Build-Instructions-(Linux)) and [macOS](https://github.com/Swordfish90/cool-retro-term/wiki/Build-Instructions-(macOS)).

View File

@ -1,4 +1,4 @@
QT += qml quick widgets sql
QT += qml quick widgets sql quickcontrols2
TARGET = cool-retro-term
DESTDIR = $$OUT_PWD/../

View File

@ -6,11 +6,13 @@
#include <QtWidgets/QApplication>
#include <QIcon>
#include <QQuickStyle>
#include <QDebug>
#include <stdlib.h>
#include <QFontDatabase>
#include <QLoggingCategory>
#include <fileio.h>
#include <monospacefontmanager.h>
@ -33,6 +35,9 @@ int main(int argc, char *argv[])
// This disables QT appmenu under Ubuntu, which is not working with QML apps.
setenv("QT_QPA_PLATFORMTHEME", "", 1);
// Disable Connections slot warnings
QLoggingCategory::setFilterRules("qt.qml.connections.warning=false");
#if defined (Q_OS_LINUX)
setenv("QSG_RENDER_LOOP", "threaded", 0);
#endif
@ -42,10 +47,30 @@ int main(int argc, char *argv[])
setenv("LC_CTYPE", "UTF-8", 1);
#endif
if (argc>1 && (!strcmp(argv[1],"-h") || !strcmp(argv[1],"--help"))) {
QTextStream cout(stdout, QIODevice::WriteOnly);
cout << "Usage: " << argv[0] << " [--default-settings] [--workdir <dir>] [--program <prog>] [-p|--profile <prof>] [--fullscreen] [-h|--help]" << endl;
cout << " --default-settings Run cool-retro-term with the default settings" << endl;
cout << " --workdir <dir> Change working directory to 'dir'" << endl;
cout << " -e <cmd> Command to execute. This option will catch all following arguments, so use it as the last option." << endl;
cout << " -T <title> Set window title to 'title'." << endl;
cout << " --fullscreen Run cool-retro-term in fullscreen." << endl;
cout << " -p|--profile <prof> Run cool-retro-term with the given profile." << endl;
cout << " -h|--help Print this help." << endl;
cout << " --verbose Print additional information such as profiles and settings." << endl;
return 0;
}
QString appVersion("1.2.0");
if (argc>1 && (!strcmp(argv[1],"-v") || !strcmp(argv[1],"--version"))) {
QTextStream cout(stdout, QIODevice::WriteOnly);
cout << "cool-retro-term " << appVersion << endl;
return 0;
}
QApplication app(argc, argv);
// set application attributes
// Has no effects, see https://bugreports.qt.io/browse/QTBUG-51293
// app.setAttribute(Qt::AA_MacDontSwapCtrlAndMeta, true);
app.setAttribute(Qt::AA_MacDontSwapCtrlAndMeta, true);
QQmlApplicationEngine engine;
FileIO fileIO;
@ -57,29 +82,11 @@ int main(int argc, char *argv[])
app.setWindowIcon(QIcon(":../icons/32x32/cool-retro-term.png"));
#endif
app.setOrganizationName("cool-retro-term");
app.setOrganizationDomain("cool-retro-term");
// Manage command line arguments from the cpp side
QStringList args = app.arguments();
if (args.contains("-h") || args.contains("--help")) {
// BUG: This usage help text goes to stderr, should go to stdout.
// BUG: First line of output is surrounded by double quotes.
qDebug() << "Usage: " + args.at(0) + " [--default-settings] [--workdir <dir>] [--program <prog>] [-p|--profile <prof>] [--fullscreen] [-h|--help]";
qDebug() << " --default-settings Run cool-retro-term with the default settings";
qDebug() << " --workdir <dir> Change working directory to 'dir'";
qDebug() << " -e <cmd> Command to execute. This option will catch all following arguments, so use it as the last option.";
qDebug() << " -T <title> Set window title to 'title'.";
qDebug() << " --fullscreen Run cool-retro-term in fullscreen.";
qDebug() << " -p|--profile <prof> Run cool-retro-term with the given profile.";
qDebug() << " -h|--help Print this help.";
qDebug() << " --verbose Print additional information such as profiles and settings.";
return 0;
}
QString appVersion("1.1.1");
if (args.contains("-v") || args.contains("--version")) {
qDebug() << ("cool-retro-term " + appVersion).toStdString().c_str();
return 0;
}
// Manage default command
QStringList cmdList;

View File

@ -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 <http://www.gnu.org/licenses/>.
*******************************************************************************/
import QtQuick 2.2
import QtQuick.Controls 1.1
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,36 +97,37 @@ 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
TextArea{
ScrollView {
anchors.fill: parent
readOnly: true
text: "Copyright (c) 2013 Filippo Scognamiglio <flscogna@gmail.com>\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 <http://www.gnu.org/licenses/>."
clip: true
TextArea {
readOnly: true
wrapMode: TextEdit.Wrap
text: "Copyright (c) 2013-2021 Filippo Scognamiglio <flscogna@gmail.com>\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 <http://www.gnu.org/licenses/>."
}
}
}
}

File diff suppressed because it is too large Load Diff

View File

@ -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 <http://www.gnu.org/licenses/>.
*******************************************************************************/
import QtQuick 2.0
import "utils.js" as Utils
@ -10,26 +29,29 @@ Loader {
property real lastUpdate: 0
property real prevLastUpdate: 0
property real delay: (1.0 / appSettings.fps) * 1000
property real burnIn: appSettings.burnIn
property real burnInFadeTime: 1 / Utils.lint(_minBurnInFadeTime, _maxBurnInFadeTime, burnIn)
property real _minBurnInFadeTime: appSettings.minBurnInFadeTime
property real _maxBurnInFadeTime: appSettings.maxBurnInFadeTime
active: appSettings.useFastBurnIn && appSettings.burnIn !== 0
active: appSettings.burnIn !== 0
anchors.fill: parent
function completelyUpdate() {
prevLastUpdate = lastUpdate;
lastUpdate = timeManager.time;
item.source.scheduleUpdate();
let newTime = timeManager.time
if (newTime > lastUpdate) {
prevLastUpdate = lastUpdate
lastUpdate = newTime
}
item.source.scheduleUpdate()
}
function restartBlurSource(){
prevLastUpdate = timeManager.time;
lastUpdate = prevLastUpdate;
completelyUpdate();
function restartBlurSource() {
prevLastUpdate = timeManager.time
lastUpdate = prevLastUpdate
completelyUpdate()
}
sourceComponent: Item {
@ -53,23 +75,37 @@ Loader {
Connections {
target: kterminal
onImagePainted: completelyUpdate()
onImagePainted: {
completelyUpdate()
}
}
// Restart blurred source settings change.
Connections{
target: appSettings
onBurnInChanged: burnInEffect.restartBlurSource();
onTerminalFontChanged: burnInEffect.restartBlurSource();
onRasterizationChanged: burnInEffect.restartBlurSource();
onBurnInQualityChanged: burnInEffect.restartBlurSource();
}
Connections {
target: kterminalScrollbar
onOpacityChanged: completelyUpdate()
target: appSettings
onBurnInChanged: {
burnInEffect.restartBlurSource()
}
onTerminalFontChanged: {
burnInEffect.restartBlurSource()
}
onRasterizationChanged: {
burnInEffect.restartBlurSource()
}
onBurnInQualityChanged: {
burnInEffect.restartBlurSource()
}
}
}
ShaderLibrary {
id: shaderLibrary
}
ShaderEffect {
id: burnInShaderEffect
@ -99,9 +135,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;

View File

@ -1,51 +0,0 @@
import QtQuick 2.2
import QtQuick.Controls 1.1
MenuBar {
id: defaultMenuBar
property bool visible: true
Menu {
title: qsTr("File")
visible: defaultMenuBar.visible
MenuItem {action: quitAction}
}
Menu {
title: qsTr("Edit")
visible: defaultMenuBar.visible && appSettings.showMenubar
MenuItem {action: copyAction}
MenuItem {action: pasteAction}
MenuSeparator{visible: Qt.platform.os !== "osx"}
MenuItem {action: showsettingsAction}
}
Menu{
title: qsTr("View")
visible: defaultMenuBar.visible
MenuItem {action: fullscreenAction; visible: fullscreenAction.enabled}
MenuItem {action: showMenubarAction; visible: showMenubarAction.enabled}
MenuSeparator{visible: showMenubarAction.enabled}
MenuItem {action: zoomIn}
MenuItem {action: zoomOut}
}
Menu{
id: profilesMenu
title: qsTr("Profiles")
visible: defaultMenuBar.visible
Instantiator{
model: appSettings.profilesList
delegate: MenuItem {
text: model.text
onTriggered: {
appSettings.loadProfileString(obj_string);
appSettings.handleFontChanged();
}
}
onObjectAdded: profilesMenu.insertItem(index, object)
onObjectRemoved: profilesMenu.removeItem(object)
}
}
Menu{
title: qsTr("Help")
visible: defaultMenuBar.visible
MenuItem {action: showAboutAction}
}
}

View File

@ -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,9 +17,8 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*******************************************************************************/
import QtQuick 2.2
import QtQuick.Controls 1.1
import QtQuick.Controls 2.0
import QtQuick.Layouts 1.1
import "Components"
@ -28,46 +27,46 @@ RowLayout {
property alias name: check.text
property double value
property alias min_value: slider.minimumValue
property alias max_value: slider.maximumValue
property alias min_value: slider.from
property alias max_value: slider.to
property alias stepSize: slider.stepSize
signal newValue(real newValue);
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 {
Layout.fillHeight: true
text: Math.round(((value - min_value) / (max_value - min_value)) * 100) + "%"
text: Math.round(
((value - min_value) / (max_value - min_value)) * 100) + "%"
}
}

View File

@ -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 <http://www.gnu.org/licenses/>.
*******************************************************************************/
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,15 +34,14 @@ 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 (!appSettings.isMacOS) colorSelected(color)
onAccepted: if (appSettings.isMacOS) colorSelected(color)
}
Rectangle{
Rectangle {
anchors.fill: parent
radius: 10
color: rootItem.color
border.color: "black"
Glossy {}
Rectangle {
anchors.fill: parent
anchors.margins: parent.height * 0.25
@ -51,14 +49,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
}
}

View File

@ -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,19 +19,14 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*******************************************************************************/
import QtQuick 2.0
import QtQuick.Controls 1.0
import QtQuick.Controls 2.0
import QtQuick.Layouts 1.0
// This component is simply a label with a predefined size.
// Used to improve alignment.
Item {
property alias text: textfield.text
Label {
id: textfield
Layout.minimumWidth: appSettings.labelWidth
width: appSettings.labelWidth
Label{
id: textfield
anchors { right: parent.right; verticalCenter: parent.verticalCenter }
}
}

View File

@ -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 <http://www.gnu.org/licenses/>.
*******************************************************************************/
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"

View File

@ -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 <http://www.gnu.org/licenses/>.
*******************************************************************************/
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"

View File

@ -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 <http://www.gnu.org/licenses/>.
*******************************************************************************/
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,10 +210,10 @@ QtObject{
isSystemFont: false
family: ""
}
ListElement{
ListElement {
name: "IBM_3278"
text: "HD: IBM 3278 (1971)"
source: "fonts/1971-ibm-3278/3270Medium.ttf"
source: "fonts/1971-ibm-3278/3270-Regular.ttf"
lineSpacing: 0.2
pixelSize: 32
fontWidth: 1.0
@ -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
}
}
}

View File

@ -1,21 +0,0 @@
import QtQuick 2.2
Rectangle {
anchors.centerIn: parent
width: parent.width - parent.border.width
height: parent.height - parent.border.width
radius:parent.radius - parent.border.width/2
smooth: true
border.width: parent.border.width/2
border.color: "#22FFFFFF"
gradient: Gradient {
GradientStop { position: 0; color: "#88FFFFFF" }
GradientStop { position: .1; color: "#55FFFFFF" }
GradientStop { position: .5; color: "#33FFFFFF" }
GradientStop { position: .501; color: "#11000000" }
GradientStop { position: .8; color: "#11FFFFFF" }
GradientStop { position: 1; color: "#55FFFFFF" }
}
}

View File

@ -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 <http://www.gnu.org/licenses/>.
*******************************************************************************/
import QtQuick 2.2
import QtQuick.Window 2.0
import QtQuick.Controls 1.1
import QtQuick.Controls 2.0
import QtQuick.Layouts 1.1
import QtQuick.Dialogs 1.1
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()
}

View File

@ -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
}

View File

@ -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.
@ -19,10 +19,11 @@
*******************************************************************************/
import QtQuick 2.2
import QtQuick.Controls 1.1
import QtQuick.Controls 2.0
import QMLTermWidget 1.0
import "menus"
import "utils.js" as Utils
Item{
@ -33,7 +34,6 @@ Item{
property ShaderEffectSource mainSource: kterminalSource
property BurnInEffect burnInEffect: burnInEffect
property SlowBurnIn slowBurnInEffect: slowBurnInEffect
property real fontWidth: 1.0
property real screenScaling: 1.0
property real scaleTexture: 1.0
@ -44,35 +44,61 @@ Item{
property size fontMetrics: kterminal.fontMetrics
// Manage copy and paste
Connections{
Connections {
target: copyAction
onTriggered: kterminal.copyClipboard();
onTriggered: {
kterminal.copyClipboard()
}
}
Connections{
Connections {
target: pasteAction
onTriggered: kterminal.pasteClipboard()
onTriggered: {
kterminal.pasteClipboard()
}
}
//When settings are updated sources need to be redrawn.
Connections{
Connections {
target: appSettings
onFontScalingChanged: terminalContainer.updateSources();
onFontWidthChanged: terminalContainer.updateSources();
onFontScalingChanged: {
terminalContainer.updateSources()
}
onFontWidthChanged: {
terminalContainer.updateSources()
}
}
Connections{
Connections {
target: terminalContainer
onWidthChanged: terminalContainer.updateSources();
onHeightChanged: terminalContainer.updateSources();
onWidthChanged: {
terminalContainer.updateSources()
}
onHeightChanged: {
terminalContainer.updateSources()
}
}
Connections {
target: terminalWindow
onActiveChanged: {
kterminal.forceActiveFocus()
}
}
function updateSources() {
kterminal.update();
kterminal.update()
}
QMLTermWidget {
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)
@ -94,6 +120,7 @@ Item{
smooth: !appSettings.lowResolutionFont
enableBold: false
fullCursorHeight: true
blinkingCursor: appSettings.blinkingCursor
session: QMLTermSession {
id: ksession
@ -141,7 +168,7 @@ Item{
var args = Utils.tokenizeCommandLine(appSettings.customCommand);
ksession.setShellProgram(args[0]);
ksession.setArgs(args.slice(1));
} else if (!defaultCmd && Qt.platform.os === "osx") {
} else if (!defaultCmd && appSettings.isMacOS) {
// OSX Requires the following default parameters for auto login.
ksession.setArgs(["-i", "-l"]);
}
@ -155,36 +182,28 @@ Item{
Component.onCompleted: {
appSettings.terminalFontChanged.connect(handleFontChanged);
appSettings.initializedSettings.connect(startSession);
appSettings.handleFontChanged()
}
}
Component {
id: linuxContextMenu
Menu{
id: contextmenu
MenuItem { action: copyAction }
MenuItem { action: pasteAction }
MenuSeparator { visible: !appSettings.showMenubar }
MenuItem { action: showsettingsAction ; visible: !appSettings.showMenubar}
MenuSeparator { visible: !appSettings.showMenubar }
CRTMainMenuBar { visible: !appSettings.showMenubar }
}
id: shortContextMenu
ShortContextMenu { }
}
Component {
id: osxContextMenu
Menu{
id: contextmenu
MenuItem{action: copyAction}
MenuItem{action: pasteAction}
}
id: fullContextMenu
FullContextMenu { }
}
Loader {
id: menuLoader
sourceComponent: (Qt.platform.os === "osx" ? osxContextMenu : linuxContextMenu)
sourceComponent: (appSettings.isMacOS || appSettings.showMenubar ? shortContextMenu : fullContextMenu)
}
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
@ -225,8 +244,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{
@ -256,9 +275,5 @@ Item{
BurnInEffect {
id: burnInEffect
}
SlowBurnIn {
id: slowBurnInEffect
}
}
}

View File

@ -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,129 +17,143 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*******************************************************************************/
import QtQuick 2.2
import QtQuick.Controls 1.1
import QtQuick.Controls 2.0
import QtQuick.Layouts 1.1
import QtQml 2.0
import "Components"
Tab{
ColumnLayout{
anchors.fill: parent
ColumnLayout {
GroupBox {
Layout.fillWidth: true
title: qsTr("Command")
GroupBox{
Layout.fillWidth: true
title: qsTr("Command")
ColumnLayout {
anchors.fill: parent
CheckBox{
id: useCustomCommand
text: qsTr("Use custom command instead of shell at startup")
checked: appSettings.useCustomCommand
onCheckedChanged: appSettings.useCustomCommand = checked
}
// Workaround for QTBUG-31627 for pre 5.3.0
Binding{
target: useCustomCommand
property: "checked"
value: appSettings.useCustomCommand
}
TextField{
id: customCommand
Layout.fillWidth: true
text: appSettings.customCommand
enabled: useCustomCommand.checked
onEditingFinished: appSettings.customCommand = text
ColumnLayout {
anchors.fill: parent
CheckBox {
id: useCustomCommand
text: qsTr("Use custom command instead of shell at startup")
checked: appSettings.useCustomCommand
onCheckedChanged: appSettings.useCustomCommand = checked
}
// Workaround for QTBUG-31627 for pre 5.3.0
Binding {
target: useCustomCommand
property: "checked"
value: appSettings.useCustomCommand
}
TextField {
id: customCommand
Layout.fillWidth: true
text: appSettings.customCommand
enabled: useCustomCommand.checked
onEditingFinished: appSettings.customCommand = text
// Save text even if user forgets to press enter or unfocus
function saveSetting() {
appSettings.customCommand = text;
}
Component.onCompleted: settings_window.closing.connect(saveSetting)
// Save text even if user forgets to press enter or unfocus
function saveSetting() {
appSettings.customCommand = text
}
Component.onCompleted: settings_window.closing.connect(
saveSetting)
}
}
}
GroupBox{
title: qsTr("Performance")
Layout.fillWidth: true
GridLayout{
anchors.fill: parent
rows: 2
columns: 3
GroupBox {
title: qsTr("Performance")
Layout.fillWidth: true
GridLayout {
anchors.fill: parent
columns: 4
Label{text: qsTr("Effects FPS")}
Slider{
Layout.fillWidth: true
id: fpsSlider
onValueChanged: {
if (enabled) {
appSettings.fps = value !== 60 ? value + 1 : 0;
}
}
stepSize: 1
enabled: false
Component.onCompleted: {
minimumValue = 0;
maximumValue = 60;
value = appSettings.fps !== 0 ? appSettings.fps - 1 : 60;
enabled = true;
Label {
text: qsTr("Effects FPS")
}
Slider {
Layout.fillWidth: true
Layout.columnSpan: 2
id: fpsSlider
onValueChanged: {
if (enabled) {
appSettings.fps = value !== 60 ? value + 1 : 0
}
}
stepSize: 1
enabled: false
Component.onCompleted: {
from = 0
to = 60
value = appSettings.fps !== 0 ? appSettings.fps - 1 : 60
enabled = true
}
}
SizedLabel{text: appSettings.fps !== 0 ? appSettings.fps : qsTr("Max")}
Label{text: qsTr("Texture Quality")}
Slider{
Layout.fillWidth: true
id: txtslider
onValueChanged: if (enabled) appSettings.windowScaling = value;
stepSize: 0.05
enabled: false
Component.onCompleted: {
minimumValue = 0.25 //Without this value gets set to 0.5
value = appSettings.windowScaling;
enabled = true;
}
SizedLabel {
text: appSettings.fps !== 0 ? appSettings.fps : qsTr("Max")
}
Label {
text: qsTr("Texture Quality")
}
Slider {
id: txtslider
Layout.fillWidth: true
Layout.columnSpan: 2
onValueChanged: if (enabled)
appSettings.windowScaling = value
stepSize: 0.05
enabled: false
Component.onCompleted: {
from = 0.25 //Without this value gets set to 0.5
value = appSettings.windowScaling
enabled = true
}
SizedLabel{text: Math.round(txtslider.value * 100) + "%"}
}
SizedLabel {
text: Math.round(txtslider.value * 100) + "%"
}
Label{text: qsTr("Bloom Quality")}
Slider{
Layout.fillWidth: true
id: bloomSlider
onValueChanged: if (enabled) appSettings.bloomQuality = value;
stepSize: 0.05
enabled: false
Component.onCompleted: {
minimumValue = 0.25
value = appSettings.bloomQuality;
enabled = true;
}
Label {
text: qsTr("Bloom Quality")
}
Slider {
Layout.fillWidth: true
Layout.columnSpan: 2
id: bloomSlider
onValueChanged: if (enabled)
appSettings.bloomQuality = value
stepSize: 0.05
enabled: false
Component.onCompleted: {
from = 0.25
value = appSettings.bloomQuality
enabled = true
}
SizedLabel{text: Math.round(bloomSlider.value * 100) + "%"}
}
SizedLabel {
text: Math.round(bloomSlider.value * 100) + "%"
}
Label{text: qsTr("BurnIn Quality")}
Slider{
Layout.fillWidth: true
id: burnInSlider
onValueChanged: if (enabled) appSettings.burnInQuality = value;
stepSize: 0.05
enabled: false
Component.onCompleted: {
minimumValue = 0.25
value = appSettings.burnInQuality;
enabled = true;
}
}
SizedLabel{text: Math.round(burnInSlider.value * 100) + "%"}
CheckBox{
Layout.columnSpan: 2
text: qsTr("Burnin optimization (Might display timing artifacts)")
checked: appSettings.useFastBurnIn
onCheckedChanged: appSettings.useFastBurnIn = checked
Label {
text: qsTr("BurnIn Quality")
}
Slider {
Layout.fillWidth: true
id: burnInSlider
Layout.columnSpan: 2
onValueChanged: if (enabled)
appSettings.burnInQuality = value
stepSize: 0.05
enabled: false
Component.onCompleted: {
from = 0.25
value = appSettings.burnInQuality
enabled = true
}
}
SizedLabel {
text: Math.round(burnInSlider.value * 100) + "%"
}
}
}
}

View File

@ -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,74 +17,70 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*******************************************************************************/
import QtQuick 2.2
import QtQuick.Controls 1.1
import QtQuick.Controls 2.0
import QtQuick.Layouts 1.1
Tab{
ColumnLayout{
anchors.fill: parent
spacing: 2
ColumnLayout {
spacing: 2
GroupBox{
title: qsTr("Effects")
Layout.fillWidth: true
GroupBox {
title: qsTr("Effects")
Layout.fillWidth: true
ColumnLayout {
anchors.fill: parent
ColumnLayout {
anchors.fill: parent
CheckableSlider{
name: qsTr("Bloom")
onNewValue: appSettings.bloom = newValue
value: appSettings.bloom
}
CheckableSlider{
name: qsTr("BurnIn")
onNewValue: appSettings.burnIn = newValue
value: appSettings.burnIn
}
CheckableSlider{
name: qsTr("Static Noise")
onNewValue: appSettings.staticNoise = newValue
value: appSettings.staticNoise
}
CheckableSlider{
name: qsTr("Jitter")
onNewValue: appSettings.jitter = newValue
value: appSettings.jitter
}
CheckableSlider{
name: qsTr("Glow Line")
onNewValue: appSettings.glowingLine = newValue;
value: appSettings.glowingLine
}
CheckableSlider{
name: qsTr("Screen Curvature")
onNewValue: appSettings.screenCurvature = newValue;
value: appSettings.screenCurvature;
}
CheckableSlider{
name: qsTr("Ambient Light")
onNewValue: appSettings.ambientLight = newValue;
value: appSettings.ambientLight
enabled: appSettings.framesIndex !== 0
}
CheckableSlider{
name: qsTr("Flickering")
onNewValue: appSettings.flickering = newValue;
value: appSettings.flickering;
}
CheckableSlider{
name: qsTr("Horizontal Sync")
onNewValue: appSettings.horizontalSync = newValue;
value: appSettings.horizontalSync;
}
CheckableSlider{
name: qsTr("RGB Shift")
onNewValue: appSettings.rbgShift = newValue;
value: appSettings.rbgShift;
}
CheckableSlider {
name: qsTr("Bloom")
onNewValue: appSettings.bloom = newValue
value: appSettings.bloom
}
CheckableSlider {
name: qsTr("BurnIn")
onNewValue: appSettings.burnIn = newValue
value: appSettings.burnIn
}
CheckableSlider {
name: qsTr("Static Noise")
onNewValue: appSettings.staticNoise = newValue
value: appSettings.staticNoise
}
CheckableSlider {
name: qsTr("Jitter")
onNewValue: appSettings.jitter = newValue
value: appSettings.jitter
}
CheckableSlider {
name: qsTr("Glow Line")
onNewValue: appSettings.glowingLine = newValue
value: appSettings.glowingLine
}
CheckableSlider {
name: qsTr("Screen Curvature")
onNewValue: appSettings.screenCurvature = newValue
value: appSettings.screenCurvature
}
CheckableSlider {
name: qsTr("Ambient Light")
onNewValue: appSettings.ambientLight = newValue
value: appSettings.ambientLight
enabled: appSettings.framesIndex !== 0
}
CheckableSlider {
name: qsTr("Flickering")
onNewValue: appSettings.flickering = newValue
value: appSettings.flickering
}
CheckableSlider {
name: qsTr("Horizontal Sync")
onNewValue: appSettings.horizontalSync = newValue
value: appSettings.horizontalSync
}
CheckableSlider {
name: qsTr("RGB Shift")
onNewValue: appSettings.rbgShift = newValue
value: appSettings.rbgShift
}
}
}

View File

@ -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,218 +17,252 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*******************************************************************************/
import QtQuick 2.2
import QtQuick.Controls 1.1
import QtQuick.Controls 2.4
import QtQuick.Layouts 1.1
import QtQuick.Dialogs 1.1
Tab{
ColumnLayout{
anchors.fill: parent
GroupBox{
Layout.fillWidth: true
Layout.fillHeight: true
title: qsTr("Profile")
RowLayout {
anchors.fill: parent
TableView {
id: profilesView
ColumnLayout {
GroupBox {
Layout.fillWidth: true
title: qsTr("Profile")
RowLayout {
anchors.fill: parent
ListView {
id: profilesView
Layout.fillWidth: true
Layout.fillHeight: true
model: appSettings.profilesList
clip: true
delegate: Rectangle {
width: label.width
height: label.height
color: (index == profilesView.currentIndex) ? palette.highlight : palette.base
Label {
id: label
text: appSettings.profilesList.get(index).text
MouseArea {
anchors.fill: parent
onClicked: profilesView.currentIndex = index
onDoubleClicked: appSettings.loadProfile(index)
}
}
}
}
ColumnLayout {
Layout.fillHeight: true
Layout.fillWidth: false
Button {
Layout.fillWidth: true
text: qsTr("Save")
onClicked: {
insertname.profileName = ""
insertname.show()
}
}
Button {
Layout.fillWidth: true
property alias currentIndex: profilesView.currentIndex
enabled: currentIndex >= 0
text: qsTr("Load")
onClicked: {
var index = currentIndex
if (index >= 0)
appSettings.loadProfile(index)
}
}
Button {
Layout.fillWidth: true
text: qsTr("Remove")
property alias currentIndex: profilesView.currentIndex
enabled: currentIndex >= 0 && !appSettings.profilesList.get(
currentIndex).builtin
onClicked: {
appSettings.profilesList.remove(currentIndex)
profilesView.selection.clear()
// TODO This is a very ugly workaround. The view didn't update on Qt 5.3.2.
profilesView.model = 0
profilesView.model = appSettings.profilesList
}
}
Item {
// Spacing
Layout.fillHeight: true
model: appSettings.profilesList
headerVisible: false
TableViewColumn {
title: qsTr("Profile")
role: "text"
width: parent.width * 0.5
}
onActivated: {
appSettings.loadProfile(row);
}
}
ColumnLayout {
Layout.fillHeight: true
Layout.fillWidth: false
Button{
Layout.fillWidth: true
text: qsTr("Save")
onClicked: {
insertname.profileName = "";
insertname.show()
Button {
Layout.fillWidth: true
text: qsTr("Import")
onClicked: {
fileDialog.selectExisting = true
fileDialog.callBack = function (url) {
loadFile(url)
}
fileDialog.open()
}
Button{
Layout.fillWidth: true
property alias currentIndex: profilesView.currentRow
enabled: currentIndex >= 0
text: qsTr("Load")
onClicked: {
var index = profilesView.currentRow;
if (index >= 0)
appSettings.loadProfile(index);
}
}
Button{
Layout.fillWidth: true
text: qsTr("Remove")
property alias currentIndex: profilesView.currentRow
function loadFile(url) {
try {
if (appSettings.verbose)
console.log("Loading file: " + url)
enabled: currentIndex >= 0 && !appSettings.profilesList.get(currentIndex).builtin
onClicked: {
appSettings.profilesList.remove(currentIndex);
profilesView.selection.clear();
var profileObject = JSON.parse(fileIO.read(url))
var name = profileObject.name
// TODO This is a very ugly workaround. The view didn't update on Qt 5.3.2.
profilesView.model = 0;
profilesView.model = appSettings.profilesList;
}
}
Item {
// Spacing
Layout.fillHeight: true
}
Button{
Layout.fillWidth: true
text: qsTr("Import")
onClicked: {
fileDialog.selectExisting = true;
fileDialog.callBack = function (url) {loadFile(url);};
fileDialog.open();
}
function loadFile(url) {
try {
if (appSettings.verbose)
console.log("Loading file: " + url);
if (!name)
throw "Profile doesn't have a name"
var profileObject = JSON.parse(fileIO.read(url));
var name = profileObject.name;
var version = profileObject.version
!== undefined ? profileObject.version : 1
if (version !== appSettings.profileVersion)
throw "This profile is not supported on this version of CRT."
if (!name)
throw "Profile doesn't have a name";
delete profileObject.name
var version = profileObject.version !== undefined ? profileObject.version : 1;
if (version !== appSettings.profileVersion)
throw "This profile is not supported on this version of CRT.";
delete profileObject.name;
appSettings.appendCustomProfile(name, JSON.stringify(profileObject));
} catch (err) {
messageDialog.text = qsTr(err)
messageDialog.open();
}
}
}
Button{
property alias currentIndex: profilesView.currentRow
Layout.fillWidth: true
text: qsTr("Export")
enabled: currentIndex >= 0 && !appSettings.profilesList.get(currentIndex).builtin
onClicked: {
fileDialog.selectExisting = false;
fileDialog.callBack = function (url) {storeFile(url);};
fileDialog.open();
}
function storeFile(url) {
try {
var urlString = url.toString();
// Fix the extension if it's missing.
var extension = urlString.substring(urlString.length - 5, urlString.length);
var urlTail = (extension === ".json" ? "" : ".json");
url += urlTail;
if (true)
console.log("Storing file: " + url);
var profileObject = appSettings.profilesList.get(currentIndex);
var profileSettings = JSON.parse(profileObject.obj_string);
profileSettings["name"] = profileObject.text;
profileSettings["version"] = appSettings.profileVersion;
var result = fileIO.write(url, JSON.stringify(profileSettings, undefined, 2));
if (!result)
throw "The file could not be written.";
} catch (err) {
console.log(err);
messageDialog.text = qsTr("There has been an error storing the file.")
messageDialog.open();
}
appSettings.appendCustomProfile(name,
JSON.stringify(
profileObject))
} catch (err) {
messageDialog.text = qsTr(err)
messageDialog.open()
}
}
}
}
}
Button {
property alias currentIndex: profilesView.currentIndex
GroupBox{
title: qsTr("Screen")
Layout.fillWidth: true
GridLayout{
anchors.fill: parent
columns: 2
Label{ text: qsTr("Brightness") }
SimpleSlider{
onValueChanged: appSettings.brightness = value
value: appSettings.brightness
Layout.fillWidth: true
text: qsTr("Export")
enabled: currentIndex >= 0 && !appSettings.profilesList.get(
currentIndex).builtin
onClicked: {
fileDialog.selectExisting = false
fileDialog.callBack = function (url) {
storeFile(url)
}
fileDialog.open()
}
function storeFile(url) {
try {
var urlString = url.toString()
// Fix the extension if it's missing.
var extension = urlString.substring(
urlString.length - 5, urlString.length)
var urlTail = (extension === ".json" ? "" : ".json")
url += urlTail
if (true)
console.log("Storing file: " + url)
var profileObject = appSettings.profilesList.get(
currentIndex)
var profileSettings = JSON.parse(
profileObject.obj_string)
profileSettings["name"] = profileObject.text
profileSettings["version"] = appSettings.profileVersion
var result = fileIO.write(url, JSON.stringify(
profileSettings,
undefined, 2))
if (!result)
throw "The file could not be written."
} catch (err) {
console.log(err)
messageDialog.text = qsTr(
"There has been an error storing the file.")
messageDialog.open()
}
}
}
Label{ text: qsTr("Contrast") }
SimpleSlider{
onValueChanged: appSettings.contrast = value
value: appSettings.contrast
}
Label{ text: qsTr("Margin") }
SimpleSlider{
onValueChanged: appSettings._margin = value
value: appSettings._margin
}
Label{ text: qsTr("Opacity") }
SimpleSlider{
onValueChanged: appSettings.windowOpacity = value
value: appSettings.windowOpacity
}
}
}
// DIALOGS ////////////////////////////////////////////////////////////////
InsertNameDialog{
id: insertname
onNameSelected: {
appSettings.appendCustomProfile(name, appSettings.composeProfileString());
}
}
MessageDialog {
id: messageDialog
title: qsTr("File Error")
onAccepted: {
messageDialog.close();
}
}
Loader {
property var callBack
property bool selectExisting: false
id: fileDialog
sourceComponent: FileDialog{
nameFilters: ["Json files (*.json)"]
selectMultiple: false
selectFolder: false
selectExisting: fileDialog.selectExisting
onAccepted: callBack(fileUrl);
}
onSelectExistingChanged: reload()
function open() {
item.open();
}
function reload() {
active = false;
active = true;
}
}
}
GroupBox {
title: qsTr("Screen")
Layout.fillWidth: true
GridLayout {
anchors.fill: parent
columns: 2
Label {
text: qsTr("Brightness")
}
SimpleSlider {
onValueChanged: appSettings.brightness = value
value: appSettings.brightness
}
Label {
text: qsTr("Contrast")
}
SimpleSlider {
onValueChanged: appSettings.contrast = value
value: appSettings.contrast
}
Label {
text: qsTr("Margin")
}
SimpleSlider {
onValueChanged: appSettings._margin = value
value: appSettings._margin
}
Label {
text: qsTr("Frame size")
}
SimpleSlider {
onValueChanged: appSettings._frameMargin = value
value: appSettings._frameMargin
}
Label {
text: qsTr("Opacity")
visible: !appSettings.isMacOS
}
SimpleSlider {
onValueChanged: appSettings.windowOpacity = value
value: appSettings.windowOpacity
visible: !appSettings.isMacOS
}
}
}
// DIALOGS ////////////////////////////////////////////////////////////////
InsertNameDialog {
id: insertname
onNameSelected: {
appSettings.appendCustomProfile(name,
appSettings.composeProfileString())
}
}
MessageDialog {
id: messageDialog
title: qsTr("File Error")
onAccepted: {
messageDialog.close()
}
}
Loader {
property var callBack
property bool selectExisting: false
id: fileDialog
sourceComponent: FileDialog {
nameFilters: ["Json files (*.json)"]
selectMultiple: false
selectFolder: false
selectExisting: fileDialog.selectExisting
onAccepted: callBack(fileUrl)
}
onSelectExistingChanged: reload()
function open() {
item.open()
}
function reload() {
active = false
active = true
}
}
}

View File

@ -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,138 +17,154 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*******************************************************************************/
import QtQuick 2.2
import QtQuick.Controls 1.1
import QtQuick.Controls 2.1
import QtQuick.Layouts 1.1
import QtQml 2.0
import "Components"
Tab{
ColumnLayout{
anchors.fill: parent
ColumnLayout {
GroupBox{
title: qsTr("Font")
Layout.fillWidth: true
GridLayout{
anchors.fill: parent
columns: 2
Label { text: qsTr("Rasterization") }
ComboBox {
id: rasterizationBox
GroupBox {
title: qsTr("Font")
Layout.fillWidth: true
GridLayout {
anchors.fill: parent
columns: 2
Label {
text: qsTr("Rasterization")
}
ComboBox {
id: rasterizationBox
property string selectedElement: model[currentIndex]
property string selectedElement: model[currentIndex]
Layout.fillWidth: true
model: [qsTr("Default"), qsTr("Scanlines"), qsTr("Pixels")]
currentIndex: appSettings.rasterization
onCurrentIndexChanged: {
appSettings.rasterization = currentIndex
Layout.fillWidth: true
model: [qsTr("Default"), qsTr("Scanlines"), qsTr("Pixels"), qsTr("Sub-Pixels")]
currentIndex: appSettings.rasterization
onCurrentIndexChanged: {
appSettings.rasterization = currentIndex
}
}
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()
}
function updateIndex() {
var name = appSettings.fontNames[appSettings.rasterization]
var index = appSettings.getIndexByName(name)
if (index !== undefined)
currentIndex = index
}
Connections {
target: appSettings
onTerminalFontChanged: {
fontChanger.updateIndex()
}
}
Label{ text: qsTr("Name") }
ComboBox{
id: fontChanger
Component.onCompleted: updateIndex()
}
Label {
text: qsTr("Scaling")
}
RowLayout {
Layout.fillWidth: true
Slider {
Layout.fillWidth: true
model: appSettings.fontlist
onActivated: {
var name = appSettings.fontlist.get(index).name;
appSettings.fontNames[appSettings.rasterization] = name;
appSettings.handleFontChanged();
}
function updateIndex(){
var name = appSettings.fontNames[appSettings.rasterization];
var index = appSettings.getIndexByName(name);
if (index !== undefined)
currentIndex = index;
}
Connections{
target: appSettings
onTerminalFontChanged: fontChanger.updateIndex();
}
Component.onCompleted: updateIndex();
id: fontScalingChanger
onValueChanged: appSettings.fontScaling = value
value: appSettings.fontScaling
stepSize: 0.05
from: appSettings.minimumFontScaling
to: appSettings.maximumFontScaling
}
Label{ text: qsTr("Scaling") }
RowLayout{
Layout.fillWidth: true
Slider{
Layout.fillWidth: true
id: fontScalingChanger
onValueChanged: if(enabled) appSettings.fontScaling = value
stepSize: 0.05
enabled: false // Another trick to fix initial bad behavior.
Component.onCompleted: {
minimumValue = appSettings.minimumFontScaling;
maximumValue = appSettings.maximumFontScaling;
value = appSettings.fontScaling;
enabled = true;
}
Connections{
target: appSettings
onFontScalingChanged: fontScalingChanger.value = appSettings.fontScaling;
}
}
SizedLabel{
text: Math.round(fontScalingChanger.value * 100) + "%"
}
SizedLabel {
text: Math.round(fontScalingChanger.value * 100) + "%"
}
Label{ text: qsTr("Font Width") }
RowLayout{
}
Label {
text: qsTr("Font Width")
}
RowLayout {
Layout.fillWidth: true
Slider {
Layout.fillWidth: true
Slider{
Layout.fillWidth: true
id: widthChanger
onValueChanged: appSettings.fontWidth = value;
value: appSettings.fontWidth
stepSize: 0.05
Component.onCompleted: {
// This is needed to avoid unnecessary chnaged events.
minimumValue = 0.5;
maximumValue = 1.5;
}
}
SizedLabel{
text: Math.round(widthChanger.value * 100) + "%"
}
id: widthChanger
onValueChanged: appSettings.fontWidth = value
value: appSettings.fontWidth
stepSize: 0.05
from: 0.5
to: 1.5
}
SizedLabel {
text: Math.round(widthChanger.value * 100) + "%"
}
}
}
GroupBox{
title: qsTr("Colors")
Layout.fillWidth: true
ColumnLayout{
anchors.fill: parent
ColumnLayout{
Layout.fillWidth: true
CheckableSlider{
name: qsTr("Chroma Color")
onNewValue: appSettings.chromaColor = newValue
value: appSettings.chromaColor
}
CheckableSlider{
name: qsTr("Saturation Color")
onNewValue: appSettings.saturationColor = newValue
value: appSettings.saturationColor
enabled: appSettings.chromaColor !== 0
}
}
GroupBox {
title: qsTr("Cursor")
Layout.fillWidth: true
ColumnLayout {
anchors.fill: parent
CheckBox {
id: blinkingCursor
text: qsTr("Blinking Cursor")
checked: appSettings.blinkingCursor
onCheckedChanged: appSettings.blinkingCursor = checked
}
Binding {
target: blinkingCursor
property: "checked"
value: appSettings.blinkingCursor
}
}
}
GroupBox {
title: qsTr("Colors")
Layout.fillWidth: true
ColumnLayout {
anchors.fill: parent
ColumnLayout {
Layout.fillWidth: true
CheckableSlider {
name: qsTr("Chroma Color")
onNewValue: appSettings.chromaColor = newValue
value: appSettings.chromaColor
}
RowLayout{
CheckableSlider {
name: qsTr("Saturation Color")
onNewValue: appSettings.saturationColor = newValue
value: appSettings.saturationColor
enabled: appSettings.chromaColor !== 0
}
}
RowLayout {
Layout.fillWidth: true
ColorButton {
name: qsTr("Font")
height: 50
Layout.fillWidth: true
ColorButton{
name: qsTr("Font")
height: 50
Layout.fillWidth: true
onColorSelected: appSettings._fontColor = color;
color: appSettings._fontColor
}
ColorButton{
name: qsTr("Background")
height: 50
Layout.fillWidth: true
onColorSelected: appSettings._backgroundColor = color;
color: appSettings._backgroundColor
}
onColorSelected: appSettings._fontColor = color
color: appSettings._fontColor
}
ColorButton {
name: qsTr("Background")
height: 50
Layout.fillWidth: true
onColorSelected: appSettings._backgroundColor = color
color: appSettings._backgroundColor
}
}
}

View File

@ -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.
@ -19,46 +19,57 @@
*******************************************************************************/
import QtQuick 2.2
import QtQuick.Controls 1.1
import QtQuick.Controls 2.1
import QtQuick.Window 2.1
import QtQuick.Layouts 1.1
import QtQuick.Layouts 1.3
import QtQuick.Dialogs 1.1
Window {
id: settings_window
title: qsTr("Settings")
width: 580
height: 400
width: 640
height: 640
property int tabmargins: 15
TabView{
id: tabView
anchors.fill: parent
anchors.margins: 10
SettingsGeneralTab {
id: generalTab
title: qsTr("General")
anchors.fill: parent
anchors.margins: tabmargins
Item {
anchors { fill: parent; margins: tabmargins }
TabBar {
id: bar
anchors { left: parent.left; right: parent.right; top: parent.top; }
TabButton {
text: qsTr("General")
}
TabButton {
text: qsTr("Terminal")
}
TabButton {
text: qsTr("Effects")
}
TabButton {
text: qsTr("Advanced")
}
}
SettingsTerminalTab {
id: terminalTab
title: qsTr("Terminal")
anchors.fill: parent
anchors.margins: tabmargins
}
SettingsEffectsTab {
id: effectsTab
title: qsTr("Effects")
anchors.fill: parent
anchors.margins: tabmargins
}
SettingsAdvancedTab {
id: performanceTab
title: qsTr("Advanced")
anchors.fill: parent
anchors.margins: tabmargins
Frame {
anchors {
top: bar.bottom
left: parent.left
right: parent.right
bottom: parent.bottom
}
StackLayout {
anchors.fill: parent
currentIndex: bar.currentIndex
SettingsGeneralTab { }
SettingsTerminalTab { }
SettingsEffectsTab { }
SettingsAdvancedTab { }
}
}
}
}

91
app/qml/ShaderLibrary.qml Normal file
View File

@ -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"
}

View File

@ -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.
@ -24,7 +24,6 @@ import QtGraphicalEffects 1.0
import "utils.js" as Utils
Item {
property SlowBurnIn slowBurnInEffect
property ShaderEffectSource source
property BurnInEffect burnInEffect
property ShaderEffectSource bloomSource
@ -38,11 +37,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
@ -59,22 +66,24 @@ Item {
property real glowingLine: appSettings.glowingLine * 0.2
// Fast burnin properties
property real burnIn: appSettings.useFastBurnIn ? appSettings.burnIn : 0
property real burnIn: appSettings.burnIn
property real burnInLastUpdate: burnInEffect.lastUpdate
property real burnInTime: burnInEffect.burnInFadeTime
// Slow burnin properties
property real slowBurnIn: appSettings.useFastBurnIn ? 0 : appSettings.burnIn
property ShaderEffectSource slowBurnInSource: slowBurnInEffect.source
property real jitter: appSettings.jitter
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 +95,7 @@ Item {
blending: false
//Smooth random texture used for flickering effect.
Image{
Image {
id: noiseTexture
source: "images/allNoise512.png"
width: 512
@ -94,7 +103,7 @@ Item {
fillMode: Image.Tile
visible: false
}
ShaderEffectSource{
ShaderEffectSource {
id: noiseShaderSource
sourceItem: noiseTexture
wrapMode: ShaderEffectSource.Repeat
@ -164,23 +173,22 @@ 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;
uniform highp float burnInLastUpdate;
uniform highp float burnInTime;" : "") +
(slowBurnIn !== 0 ? "
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 +211,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 +296,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;" +
@ -302,13 +307,10 @@ Item {
txt_color = max(txt_color, convertWithChroma(burnInColor));"
: "") +
(slowBurnIn !== 0 ? "
vec4 txt_blur = texture2D(slowBurnInSource, staticCoords);
txt_color = max(txt_color, convertWithChroma(txt_blur.rgb * txt_blur.a));
" : "") +
"txt_color += fontColor.rgb * vec3(color);" +
"txt_color = applyRasterization(staticCoords, txt_color, virtualResolution, rasterizationIntensity);\n" +
"vec3 finalColor = txt_color;" +
(flickering !== 0 ? "
@ -317,7 +319,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 +342,7 @@ Item {
Loader {
id: terminalFrameLoader
active: screenCurvature !== 0
active: dynamicShader.displayTerminalFrame
width: staticShader.width
height: staticShader.height
@ -352,7 +354,7 @@ Item {
visible: false
format: ShaderEffectSource.RGBA
NewTerminalFrame {
TerminalFrame {
id: terminalFrame
blending: false
anchors.fill: parent
@ -360,6 +362,10 @@ Item {
}
}
ShaderLibrary {
id: shaderLibrary
}
ShaderEffect {
id: staticShader
@ -385,7 +391,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 +414,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 +432,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 +447,7 @@ Item {
" return outColor;
}" +
shaderLibrary.rasterizationShader +
"void main() {" +
"vec2 cc = vec2(0.5) - qt_TexCoord0;" +
@ -490,8 +470,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);" +

View File

@ -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,9 +17,8 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*******************************************************************************/
import QtQuick 2.2
import QtQuick.Controls 1.1
import QtQuick.Controls 2.0
import QtQuick.Layouts 1.1
import "Components"
@ -27,18 +26,18 @@ import "Components"
RowLayout {
property alias value: slider.value
property alias stepSize: slider.stepSize
property alias minimumValue: slider.minimumValue
property alias maximumValue: slider.maximumValue
property alias minimumValue: slider.from
property alias maximumValue: slider.to
property real maxMultiplier: 100
id: setting_component
spacing: 10
Slider{
Slider {
id: slider
stepSize: parent.stepSize
Layout.fillWidth: true
}
SizedLabel{
SizedLabel {
text: Math.round(value * maxMultiplier) + "%"
}
}

View File

@ -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 <http://www.gnu.org/licenses/>.
*******************************************************************************/
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

View File

@ -1,122 +0,0 @@
import QtQuick 2.0
import "utils.js" as Utils
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 {
property bool updateBurnIn: false
property real burnIn: appSettings.burnIn
property real fps: appSettings.fps !== 0 ? appSettings.fps : 60
property real burnInFadeTime: Utils.lint(minBurnInFadeTime, maxBurnInFadeTime, burnIn)
property real burnInCoefficient: 1000 / (fps * burnInFadeTime)
property real minBurnInFadeTime: appSettings.minBurnInFadeTime
property real maxBurnInFadeTime: appSettings.maxBurnInFadeTime
id: burnInSourceEffect
anchors.fill: parent
sourceItem: burnInEffect
recursive: true
live: false
hideSource: true
wrapMode: kterminalSource.wrapMode
visible: false
function restartBlurSource(){
livetimer.restart();
}
// This updates the burnin synched with the timer.
Connections {
target: burnInSourceEffect.updateBurnIn ? timeManager : null
ignoreUnknownSignals: false
onTimeChanged: {
burnInSourceEffect.scheduleUpdate();
}
}
Timer{
id: livetimer
// The interval assumes 60 fps. This is the time needed burnout a white pixel.
// We multiply 1.1 to have a little bit of margin over the theoretical value.
// This solution is not extremely clean, but it's probably the best to avoid measuring fps.
interval: burnInSourceEffect.burnInFadeTime * 1.1
running: true
onTriggered: burnInSourceEffect.updateBurnIn = false;
}
Connections{
target: kterminal
onImagePainted:{
burnInSourceEffect.scheduleUpdate();
burnInSourceEffect.updateBurnIn = true;
livetimer.restart();
}
}
// Restart blurred source settings change.
Connections{
target: appSettings
onBurnInChanged: burnInSourceEffect.restartBlurSource();
onTerminalFontChanged: burnInSourceEffect.restartBlurSource();
onRasterizationChanged: burnInSourceEffect.restartBlurSource();
onBurnInQualityChanged: burnInSourceEffect.restartBlurSource();
}
Connections {
target: kterminalScrollbar
onOpacityChanged: burnInSourceEffect.restartBlurSource();
}
ShaderEffect {
id: burnInEffect
property variant txt_source: kterminalSource
property variant blurredSource: burnInSourceEffect
property real burnInCoefficient: burnInSourceEffect.burnInCoefficient
anchors.fill: parent
blending: false
fragmentShader:
"#ifdef GL_ES
precision mediump float;
#endif\n" +
"uniform lowp float qt_Opacity;" +
"uniform lowp sampler2D txt_source;" +
"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);
}" +
"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));" +
"}"
onStatusChanged: if (log) console.log(log) //Print warning messages
}
}
}
}

View File

@ -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');
});
}
)
}
}

View File

@ -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 <http://www.gnu.org/licenses/>.
*******************************************************************************/
import QtQuick 2.2
import QtGraphicalEffects 1.0
@ -7,44 +26,48 @@ 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 +77,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
// }
}

104
app/qml/TerminalFrame.qml Normal file
View File

@ -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 <http://www.gnu.org/licenses/>.
*******************************************************************************/
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
}

View File

@ -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 <http://www.gnu.org/licenses/>.
*******************************************************************************/
import QtQuick 2.2
Timer{
Timer {
default property bool enableTimer: false
property real time

Binary file not shown.

View File

@ -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 <http://www.gnu.org/licenses/>.
*******************************************************************************/
import QtQuick 2.2
import QtQuick.Window 2.1
import QtQuick.Controls 1.1
import QtQuick.Controls 2.3
import QtQuick.Controls.Styles 1.4
import QtGraphicalEffects 1.0
@ -45,8 +44,6 @@ ApplicationWindow{
// Load saved window geometry and show the window
Component.onCompleted: {
appSettings.handleFontChanged();
x = appSettings.x
y = appSettings.y
width = appSettings.width
@ -63,22 +60,30 @@ ApplicationWindow{
property bool fullscreen: appSettings.fullscreen
onFullscreenChanged: visibility = (fullscreen ? Window.FullScreen : Window.Windowed)
//Workaround: Without __contentItem a ugly thin border is visible.
menuBar: CRTMainMenuBar{
id: mainMenu
visible: (Qt.platform.os === "osx" || appSettings.showMenubar)
__contentItem.visible: mainMenu.visible
menuBar: qtquickMenuLoader.item
Loader {
id: qtquickMenuLoader
active: !appSettings.isMacOS && appSettings.showMenubar
sourceComponent: WindowMenu { }
}
Loader {
id: globalMenuLoader
active: appSettings.isMacOS
sourceComponent: OSXMenu { }
}
property string wintitle: appSettings.wintitle
color: "#00000000"
title: terminalContainer.title || qsTr(appSettings.wintitle)
Action {
id: showMenubarAction
text: qsTr("Show Menubar")
enabled: Qt.platform.os !== "osx"
enabled: !appSettings.isMacOS
shortcut: "Ctrl+Shift+M"
checkable: true
checked: appSettings.showMenubar
@ -87,9 +92,9 @@ ApplicationWindow{
Action {
id: fullscreenAction
text: qsTr("Fullscreen")
enabled: Qt.platform.os !== "osx"
enabled: !appSettings.isMacOS
shortcut: "Alt+F11"
onTriggered: appSettings.fullscreen = !appSettings.fullscreen;
onTriggered: appSettings.fullscreen = !appSettings.fullscreen
checkable: true
checked: appSettings.fullscreen
}
@ -97,69 +102,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
y: appSettings.showMenubar ? 0 : -2 // Workaroud to hide the margin in the menubar.
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
}
@ -167,7 +171,7 @@ ApplicationWindow{
onClosing: {
// OSX Since we are currently supporting only one window
// quit the application when it is closed.
if (Qt.platform.os === "osx")
if (appSettings.isMacOS)
Qt.quit()
}
}

View File

@ -0,0 +1,95 @@
/*******************************************************************************
* 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 <http://www.gnu.org/licenses/>.
*******************************************************************************/
import QtQuick 2.2
import QtQuick.Controls 2.3
Menu {
id: contextmenu
MenuItem {
action: copyAction
}
MenuItem {
action: pasteAction
}
MenuItem {
action: showsettingsAction
}
MenuSeparator {}
Menu {
title: qsTr("File")
MenuItem {
action: quitAction
}
}
Menu {
title: qsTr("Edit")
MenuItem {
action: copyAction
}
MenuItem {
action: pasteAction
}
MenuSeparator {}
MenuItem {
action: showsettingsAction
}
}
Menu {
title: qsTr("View")
MenuItem {
action: fullscreenAction
visible: fullscreenAction.enabled
}
MenuItem {
action: showMenubarAction
visible: showMenubarAction.enabled
}
MenuItem {
action: zoomIn
}
MenuItem {
action: zoomOut
}
}
Menu {
id: profilesMenu
title: qsTr("Profiles")
Instantiator {
model: appSettings.profilesList
delegate: MenuItem {
text: model.text
onTriggered: {
appSettings.loadProfileString(obj_string)
appSettings.handleFontChanged()
}
}
onObjectAdded: profilesMenu.insertItem(index, object)
onObjectRemoved: profilesMenu.removeItem(object)
}
}
Menu {
title: qsTr("Help")
MenuItem {
action: showAboutAction
}
}
}

89
app/qml/menus/OSXMenu.qml Normal file
View File

@ -0,0 +1,89 @@
/*******************************************************************************
* 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 <http://www.gnu.org/licenses/>.
*******************************************************************************/
import QtQuick 2.3
import Qt.labs.platform 1.1
MenuBar {
id: defaultMenuBar
Menu {
title: qsTr("File")
MenuItem {
text: quitAction.text
onTriggered: quitAction.trigger()
}
}
Menu {
title: qsTr("Edit")
MenuItem {
text: copyAction.text
shortcut: "Meta+C"
onTriggered: copyAction.trigger()
}
MenuItem {
text: pasteAction.text
shortcut: "Meta+V"
onTriggered: pasteAction.trigger()
}
MenuSeparator {}
MenuItem {
text: showsettingsAction.text
shortcut: showsettingsAction.shortcut
onTriggered: showsettingsAction.trigger()
}
}
Menu {
title: qsTr("View")
MenuItem {
text: zoomIn.text
shortcut: "Meta++"
onTriggered: zoomIn.trigger()
}
MenuItem {
text: zoomOut.text
shortcut: "Meta+-"
onTriggered: zoomOut.trigger()
}
}
Menu {
id: profilesMenu
title: qsTr("Profiles")
Instantiator {
model: appSettings.profilesList
delegate: MenuItem {
text: model.text
onTriggered: {
appSettings.loadProfileString(obj_string)
appSettings.handleFontChanged()
}
}
onObjectAdded: profilesMenu.insertItem(index, object)
onObjectRemoved: profilesMenu.removeItem(object)
}
}
Menu {
title: qsTr("Help")
MenuItem {
text: showAboutAction.text
onTriggered: showAboutAction.trigger()
}
}
}

View File

@ -0,0 +1,31 @@
/*******************************************************************************
* 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 <http://www.gnu.org/licenses/>.
*******************************************************************************/
import QtQuick 2.2
import QtQuick.Controls 2.3
Menu {
id: contextmenu
MenuItem {
action: copyAction
}
MenuItem {
action: pasteAction
}
}

View File

@ -0,0 +1,85 @@
/*******************************************************************************
* 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 <http://www.gnu.org/licenses/>.
*******************************************************************************/
import QtQuick 2.2
import QtQuick.Controls 2.3
MenuBar {
id: defaultMenuBar
visible: appSettings.showMenubar
Menu {
title: qsTr("File")
MenuItem {
action: quitAction
}
}
Menu {
title: qsTr("Edit")
MenuItem {
action: copyAction
}
MenuItem {
action: pasteAction
}
MenuSeparator {}
MenuItem {
action: showsettingsAction
}
}
Menu {
title: qsTr("View")
MenuItem {
action: fullscreenAction
visible: fullscreenAction.enabled
}
MenuItem {
action: showMenubarAction
visible: showMenubarAction.enabled
}
MenuItem {
action: zoomIn
}
MenuItem {
action: zoomOut
}
}
Menu {
id: profilesMenu
title: qsTr("Profiles")
Instantiator {
model: appSettings.profilesList
delegate: MenuItem {
text: model.text
onTriggered: {
appSettings.loadProfileString(obj_string)
appSettings.handleFontChanged()
}
}
onObjectAdded: profilesMenu.insertItem(index, object)
onObjectRemoved: profilesMenu.removeItem(object)
}
}
Menu {
title: qsTr("Help")
MenuItem {
action: showAboutAction
}
}
}

View File

@ -12,7 +12,6 @@
<file>TimeManager.qml</file>
<file>SimpleSlider.qml</file>
<file>ColorButton.qml</file>
<file>Glossy.qml</file>
<file>AboutDialog.qml</file>
<file>InsertNameDialog.qml</file>
<file>SettingsEffectsTab.qml</file>
@ -20,9 +19,8 @@
<file>SettingsTerminalTab.qml</file>
<file>FontScanlines.qml</file>
<file>fonts/1977-apple2/PrintChar21.ttf</file>
<file>fonts/1971-ibm-3278/3270Medium.ttf</file>
<file>fonts/1971-ibm-3278/3270-Regular.ttf</file>
<file>Storage.qml</file>
<file>CRTMainMenuBar.qml</file>
<file>SettingsAdvancedTab.qml</file>
<file>TerminalContainer.qml</file>
<file>images/crt256.png</file>
@ -42,7 +40,11 @@
<file>fonts/1977-commodore-pet/PetMe.ttf</file>
<file>BurnInEffect.qml</file>
<file>fonts/modern-terminus/TerminusTTF-4.46.0.ttf</file>
<file>NewTerminalFrame.qml</file>
<file>SlowBurnIn.qml</file>
<file>TerminalFrame.qml</file>
<file>menus/WindowMenu.qml</file>
<file>menus/FullContextMenu.qml</file>
<file>menus/ShortContextMenu.qml</file>
<file>ShaderLibrary.qml</file>
<file>menus/OSXMenu.qml</file>
</qresource>
</RCC>

View File

@ -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 <http://www.gnu.org/licenses/>.
*******************************************************************************/
.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;

@ -1 +1 @@
Subproject commit 48274c75660e28d44af7c195e79accdf1bd44963
Subproject commit 63228027e1f97c24abb907550b22ee91836929c5

View File

@ -66,4 +66,6 @@ parts:
- libgl1-mesa-dev
- qtdeclarative5-dev-tools
- qml-module-qtquick-extras
- qml-module-qt-labs-settings
- qml-module-qt-labs-folderlistmodel