1
0
mirror of https://github.com/Swordfish90/cool-retro-term.git synced 2026-02-08 00:32:27 +00:00

16 Commits
rolling ... osx

Author SHA1 Message Date
Filippo Scognamiglio
462831ca66 Merge pull request #134 from sschueller/patch-1
Update README.md
2014-10-02 22:14:00 +02:00
Stefan Schüller
273ac3d126 Update README.md 2014-10-02 13:35:20 +02:00
Filippo Scognamiglio
4a7e23f024 Merge pull request #65 from e1senh0rn/osx
Various OSX fixes.
2014-08-04 18:00:08 +02:00
Dmitry Shaposhnik
84e0feb626 Add OS X build instructions to README 2014-08-04 08:39:42 -05:00
Dmitry Shaposhnik
906e981449 Add 'imports' to gitignore 2014-08-04 08:39:36 -05:00
Dmitry Shaposhnik
d887842bdc Do not list 'app' in project subdirs 2014-08-04 08:31:48 -05:00
Dmitry Shaposhnik
ed701b0ac6 Remove auto-generated makefile 2014-08-04 08:28:51 -05:00
Filippo Scognamiglio
e9e3732b26 Merge pull request #58 from guitorri/osx-headers
fix compilation errors, OSX 10.6-10.9
2014-08-03 15:22:26 +02:00
Guilherme Brondani Torri
2f11060364 fix compilation errors, OSX 10.6-10.9
* add missing headers
* https://github.com/Swordifish90/cool-old-term/issues/12
2014-08-02 18:16:50 +02:00
Filippo Scognamiglio
d3d1407ca7 Remove dummy signal. Shame on me. 2014-08-01 18:09:36 +02:00
Filippo Scognamiglio
5586c36efe Fix missing sources in konsole-qml-plugin.pro. 2014-08-01 14:09:48 +02:00
Filippo Scognamiglio
4064a38998 Merge branch 'master' of https://github.com/aacalfa/cool-old-term into osx 2014-08-01 14:03:46 +02:00
aacalfa
5978a0de70 Reorganizing last commit. Changes to kpty.cpp were moved to file utmpmac.cpp. Thus I modified .pro
file to add this new file utmpmac to be compiled. I have put both .cpp and .h files inside a macro
so that they are only considered when building from a mac. Same with include from kpty.cpp.
2014-07-31 22:28:12 -03:00
aacalfa
9d7efad798 Reverting PreprocessedTerminal.qml to be used in pull request. 2014-07-31 14:25:23 -03:00
aacalfa
d063e888a3 Another workaround to solve blur problem. 2014-07-31 12:16:43 -03:00
aacalfa
c612a1d586 Workaround to work for MacOS X. 2014-07-31 11:55:52 -03:00
381 changed files with 27700 additions and 7871 deletions

4
.github/FUNDING.yml vendored
View File

@@ -1,4 +0,0 @@
# 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']

View File

@@ -1,129 +0,0 @@
name: Release
on:
workflow_dispatch:
push:
branches:
- main
- master
tags:
- '*'
permissions:
contents: write
jobs:
build-appimage:
name: Build (Linux, AppImage)
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v4
with:
submodules: recursive
- name: Install build deps
run: |
sudo apt update
sudo apt install -y build-essential rsync wget
- name: Install Qt
uses: jurplel/install-qt-action@v4
with:
version: 6.10.0
dir: ..
modules: qt5compat qtshadertools
setup-python: false
cache: true
- name: Build AppImage
run: |
./scripts/build-appimage.sh
- name: Collect artifact
run: |
mkdir -p release
mv ./*.AppImage release/
- name: Upload artifact
uses: actions/upload-artifact@v4
with:
name: cool-retro-term-appimage
path: ./release/*
build-dmg:
name: Build (macOS, DMG)
runs-on: macos-14
steps:
- uses: actions/checkout@v4
with:
submodules: recursive
- name: Install Qt
uses: jurplel/install-qt-action@v4
with:
version: 6.10.*
modules: qt5compat qtshadertools
setup-python: true
python-version: '3.11'
cache: true
- name: Build DMG
run: |
JOBS="$(sysctl -n hw.ncpu)"
./scripts/build-dmg.sh
- name: Collect artifact
run: |
mkdir -p release
mv ./*.dmg release/
- name: Upload artifact
uses: actions/upload-artifact@v4
with:
name: cool-retro-term-dmg
path: ./release/*
release:
name: Create Release
runs-on: ubuntu-22.04
needs:
- build-appimage
- build-dmg
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Download AppImage
uses: actions/download-artifact@v4
with:
name: cool-retro-term-appimage
path: ./release
- name: Download DMG
uses: actions/download-artifact@v4
with:
name: cool-retro-term-dmg
path: ./release
- name: Update rolling tag
if: startsWith(github.ref, 'refs/heads/')
run: |
git tag -f rolling
git push -f origin rolling
- name: Publish rolling release
if: startsWith(github.ref, 'refs/heads/')
uses: softprops/action-gh-release@v2
with:
tag_name: rolling
name: Rolling Release
prerelease: true
files: ./release/*
- name: Publish tagged release
if: startsWith(github.ref, 'refs/tags/')
uses: softprops/action-gh-release@v2
with:
tag_name: ${{ github.ref_name }}
files: ./release/*

21
.gitignore vendored
View File

@@ -18,7 +18,6 @@
*.pro.user.*
*.moc
moc_*.cpp
moc_*.h
qrc_*.cpp
ui_*.h
Makefile*
@@ -36,22 +35,4 @@ Makefile*
*.xcf
# Ubuntu SDk
*.excludes
*.json
# Excludes compiled files
imports
cool-retro-term
build
# Linux
*.AppImage
# Mac OSX
.DS_Store
*.app
*.dmg
/imports/

7
.gitmodules vendored
View File

@@ -1,7 +0,0 @@
[submodule "qmltermwidget"]
path = qmltermwidget
url = https://github.com/Swordfish90/qmltermwidget
branch = unstable
[submodule "KDSingleApplication"]
path = KDSingleApplication
url = https://github.com/KDAB/KDSingleApplication.git

109
README.md
View File

@@ -1,30 +1,101 @@
# cool-retro-term
#cool-old-term
|> Default Amber|C:\ IBM DOS|$ Default Green|
|---|---|---|
|![Default Amber Cool Retro Term](https://user-images.githubusercontent.com/121322/32070717-16708784-ba42-11e7-8572-a8fcc10d7f7d.gif)|![IBM DOS](https://user-images.githubusercontent.com/121322/32070716-16567e5c-ba42-11e7-9e64-ba96dfe9b64d.gif)|![Default Green Cool Retro Term](https://user-images.githubusercontent.com/121322/32070715-163a1c94-ba42-11e7-80bb-41fbf10fc634.gif)|
## Description
cool-retro-term is a terminal emulator which mimics the look and feel of the old cathode tube screens.
##Description
cool-old-term is a terminal emulator which tries to mimic the look and feel of the old cathode tube screens.
It has been designed to be eye-candy, customizable, and reasonably lightweight.
It uses the QML port of qtermwidget (Konsole): https://github.com/Swordfish90/qmltermwidget.
It now uses the konsole engine which is powerful and mature.
This terminal emulator works under Linux and macOS and requires Qt6.
This terminal emulator requires Qt 5.2 or higher to run.
Settings such as colors, fonts, and effects can be accessed via context menu.
##Screenshots
![Image](<http://i.imgur.com/NUfvnlu.png>)
![Image](<http://i.imgur.com/4LpfLF8.png>)
![Image](<http://i.imgur.com/MMmM6Ht.png>)
## Screenshots
![Image](<https://i.imgur.com/TNumkDn.png>)
![Image](<https://i.imgur.com/hfjWOM4.png>)
![Image](<https://i.imgur.com/GYRDPzJ.jpg>)
##Build instructions
## Install
##Dependencies
Make sure to install these first.
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).
---
Alternatively, most distributions such as Ubuntu, Fedora or Arch already package cool-retro-term in their official repositories.
**Ubuntu 14.04**
## Building
sudo apt-get install build-essential qmlscene qt5-qmake qt5-default qtdeclarative5-dev qtdeclarative5-controls-plugin qtdeclarative5-qtquick2-plugin libqt5qml-graphicaleffects qtdeclarative5-dialogs-plugin qtdeclarative5-localstorage-plugin qtdeclarative5-window-plugin
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)).
---
**Debian Jessie**
sudo apt-get install build-essential qmlscene qt5-qmake qt5-default qtdeclarative5-dev qml-module-qtquick-controls qml-module-qtgraphicaleffects qml-module-qtquick-dialogs qml-module-qtquick-localstorage qml-module-qtquick-window2
---
**Fedora**
This command should install the known fedora dependencies:
```
sudo yum -y install qt5-qtbase qt5-qtbase-devel qt5-qtdeclarative qt5-qtdeclarative-devel qt5-qtgraphicaleffects qt5-qtquickcontrols
```
or:
```
sudo dnf -y install qt5-qtbase qt5-qtbase-devel qt5-qtdeclarative qt5-qtdeclarative-devel qt5-qtgraphicaleffects qt5-qtquickcontrols
```
Compile using the following:
```
git clone https://github.com/Swordifish90/cool-old-term.git
cd cool-old-term/konsole-qml-plugin
qmake-qt5 && make && make install
cd ..
./cool-old-term
```
---
**Arch Linux**
sudo pacman -S qt5-base qt5-declarative qt5-quickcontrols qt5-graphicaleffects
You can also install this [package](https://aur.archlinux.org/packages/cool-old-term-git/) directly via the [AUR](https://aur.archlinux.org):
yaourt -S aur/cool-old-term-git
---
**OS X**
brew install qt5
export CPPFLAGS="-I/usr/local/opt/qt5/include"
export LDFLAGS="-L/usr/local/opt/qt5/lib"
export PATH=/usr/local/opt/qt5/bin:$PATH
git clone https://github.com/Swordifish90/cool-old-term.git
git checkout osx
qmake && make && make install
# Have fun!
./cool-old-term
---
**Anyone else**
Install Qt directly from here http://qt-project.org/downloads . Once done export them in you path (replace "_/opt/Qt5.3.1/5.3/gcc_64/bin_" with your correct folder):
export PATH=/opt/Qt5.3.1/5.3/gcc_64/bin/:$PATH
###Compile
Once you installed all dependencies (Qt is installed and in your path) you need to compile and run the application:
```bash
# Get it from GitHub
git clone https://github.com/Swordifish90/cool-old-term.git
# Build it
cd cool-old-term
cd konsole-qml-plugin
qmake && make && make install
cd ..
# Have fun!
./cool-old-term
```

103
app/AboutDialog.qml Normal file
View File

@@ -0,0 +1,103 @@
import QtQuick 2.2
import QtQuick.Controls 1.1
import QtQuick.Layouts 1.1
import QtQuick.Window 2.0
Window{
id: dialogwindow
title: qsTr("About")
width: 450
height: 300
ColumnLayout{
anchors.fill: parent
anchors.margins: 15
spacing: 15
Text {
anchors.horizontalCenter: parent.horizontalCenter
text: "cool-old-term"
font {bold: true; pointSize: 18}
}
Loader{
id: mainContent
Layout.fillHeight: true
Layout.fillWidth: true
states: [
State {
name: "Default"
PropertyChanges {
target: mainContent
sourceComponent: defaultComponent
}
},
State {
name: "License"
PropertyChanges {
target: mainContent
sourceComponent: licenseComponent
}
}
]
Component.onCompleted: mainContent.state = "Default";
}
Item{
Layout.fillWidth: true
height: childrenRect.height
Button{
anchors.left: parent.left
text: qsTr("License")
onClicked: {
mainContent.state == "Default" ? mainContent.state = "License" : mainContent.state = "Default"
}
}
Button{
anchors.right: parent.right
text: qsTr("Close")
onClicked: dialogwindow.close();
}
}
}
// MAIN COMPONENTS ////////////////////////////////////////////////////////
Component{
id: defaultComponent
ColumnLayout{
anchors.fill: parent
anchors.margins: 10
spacing: 10
Item{
Layout.fillHeight: true
}
Text{
anchors.horizontalCenter: parent.horizontalCenter
horizontalAlignment: Text.AlignHCenter
text: shadersettings.version + "\n" +
qsTr("Author: ") + "Filippo Scognamiglio\n" +
qsTr("Email: ") + "flscogna@gmail.com\n" +
qsTr("Source: ") + "https://github.com/Swordifish90/cool-old-term\n"
}
}
}
Component{
id: licenseComponent
TextArea{
anchors.fill: parent
readOnly: true
text: "Copyright (c) 2013 Filippo Scognamiglio <flscogna@gmail.com>\n\n" +
"https://github.com/Swordifish90/cool-old-term\n\n" +
"cool-old-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/>."
}
}
}

359
app/ApplicationSettings.qml Normal file
View File

@@ -0,0 +1,359 @@
/*******************************************************************************
* Copyright (c) 2013 "Filippo Scognamiglio"
* https://github.com/Swordifish90/cool-old-term
*
* This file is part of cool-old-term.
*
* cool-old-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
Item{
property string version: "0.9"
// GENERAL SETTINGS ///////////////////////////////////////////////////
property bool fullscreen: false
property bool showMenubar: true
property real windowOpacity: 1.0
property real ambient_light: 0.2
property real contrast: 0.85
property real brightness: 0.5
property bool show_terminal_size: true
property real window_scaling: 1.0
onWindow_scalingChanged: handleFontChanged();
property real fps: 0
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 strToColor(s){
var r = parseInt(s.substring(1,3), 16) / 256;
var g = parseInt(s.substring(3,5), 16) / 256;
var b = parseInt(s.substring(5,7), 16) / 256;
return Qt.rgba(r, g, b, 1.0);
}
// PROFILE SETTINGS ///////////////////////////////////////////////////////
property string _background_color: "#000000"
property string _font_color: "#ff8100"
property color font_color: mix(strToColor(_font_color), strToColor(_background_color), 0.7 + (contrast * 0.3))
property color background_color: mix(strToColor(_background_color), strToColor(_font_color), 0.7 + (contrast * 0.3))
property real noise_strength: 0.1
property real screen_distortion: 0.1
property real glowing_line_strength: 0.2
property real motion_blur: 0.40
property real bloom_strength: 0.65
property real jitter: 0.18
property real horizontal_sincronization: 0.08
property real brightness_flickering: 0.1
readonly property int no_rasterization: 0
readonly property int scanline_rasterization: 1
readonly property int pixel_rasterization: 2
property int rasterization: no_rasterization
ListModel{
id: framelist
ListElement{text: "No frame"; source: "./frames/NoFrame.qml"; reflections: false}
ListElement{text: "Simple white frame"; source: "./frames/WhiteSimpleFrame.qml"; reflections: true}
ListElement{text: "Rough black frame"; source: "./frames/BlackRoughFrame.qml"; reflections: true}
}
property string frame_source: frames_list.get(frames_index).source
property int frames_index: 1
property var frames_list: framelist
// FONTS //////////////////////////////////////////////////////////////////
signal terminalFontChanged(string fontSource, int pixelSize, int lineSpacing, size virtualCharSize)
Loader{
id: fontManager
states: [
State { when: rasterization == no_rasterization
PropertyChanges {target: fontManager; source: "Fonts.qml" } },
State { when: rasterization == scanline_rasterization
PropertyChanges {target: fontManager; source: "FontScanlines.qml" } },
State { when: rasterization == pixel_rasterization;
PropertyChanges {target: fontManager; source: "FontPixels.qml" } }
]
onLoaded: handleFontChanged()
}
signal fontScalingChanged
property var fontScalingList: fontManager.item.fontScalingList
property var fontScalingIndexes: [5,1,1]
function setScalingIndex(newScaling){
fontScalingIndexes[rasterization] = newScaling;
fontScalingChanged();
handleFontChanged();
}
function getScalingIndex(){
return fontScalingIndexes[rasterization];
}
property var fontIndexes: [0,0,0]
property var fontlist: fontManager.item.fontlist
function handleFontChanged(){
if(!fontManager.item) return;
fontManager.item.selectedFontIndex = fontIndexes[rasterization];
fontManager.item.selectedScalingIndex = fontScalingIndexes[rasterization];
var fontSource = fontManager.item.source;
var pixelSize = fontManager.item.pixelSize;
var lineSpacing = fontManager.item.lineSpacing;
var virtualCharSize = fontManager.item.virtualCharSize;
terminalFontChanged(fontSource, pixelSize, lineSpacing, virtualCharSize);
}
// FRAMES /////////////////////////////////////////////////////////////////
property bool _frameReflections: true
property bool reflectionsAllowed: framelist.get(frames_index).reflections
property bool frameReflections: _frameReflections && reflectionsAllowed
property alias profiles_list: profileslist
property int profiles_index: 0
// DB STORAGE /////////////////////////////////////////////////////////////
Storage{id: storage}
function composeSettingsString(){
var settings = {
fps: fps,
window_scaling: window_scaling,
show_terminal_size: show_terminal_size,
fontScalingIndexes: fontScalingIndexes,
fontIndexes: fontIndexes,
frameReflections: _frameReflections,
showMenubar: showMenubar
}
return JSON.stringify(settings);
}
function composeProfileString(){
var settings = {
background_color: _background_color,
font_color: _font_color,
brightness_flickering: brightness_flickering,
horizontal_sincronization: horizontal_sincronization,
noise_strength: noise_strength,
screen_distortion: screen_distortion,
glowing_line_strength: glowing_line_strength,
frames_index: frames_index,
motion_blur: motion_blur,
bloom_strength: bloom_strength,
rasterization: rasterization,
jitter: jitter,
brightness: brightness,
contrast: contrast,
ambient_light: ambient_light,
windowOpacity: windowOpacity,
fontIndex: fontIndexes[rasterization]
}
return JSON.stringify(settings);
}
function loadSettings(){
var settingsString = storage.getSetting("_CURRENT_SETTINGS");
var profileString = storage.getSetting("_CURRENT_PROFILE");
if(!settingsString) return;
if(!profileString) return;
loadSettingsString(settingsString);
loadProfileString(profileString);
console.log("Loading settings: " + settingsString + profileString);
}
function storeSettings(){
var settingsString = composeSettingsString();
var profileString = composeProfileString();
storage.setSetting("_CURRENT_SETTINGS", settingsString);
storage.setSetting("_CURRENT_PROFILE", profileString);
console.log("Storing settings: " + settingsString);
console.log("Storing profile: " + profileString);
}
function loadSettingsString(settingsString){
var settings = JSON.parse(settingsString);
show_terminal_size = settings.show_terminal_size !== undefined ? settings.show_terminal_size : show_terminal_size
fps = settings.fps !== undefined ? settings.fps: fps
window_scaling = settings.window_scaling !== undefined ? settings.window_scaling : window_scaling
fontIndexes = settings.fontIndexes !== undefined ? settings.fontIndexes : fontIndexes
fontScalingIndexes = settings.fontScalingIndexes !== undefined ? settings.fontScalingIndexes : fontScalingIndexes
_frameReflections = settings.frameReflections !== undefined ? settings.frameReflections : _frameReflections;
showMenubar = settings.showMenubar !== undefined ? settings.showMenubar : showMenubar;
}
function loadProfileString(profileString){
var settings = JSON.parse(profileString);
_background_color = settings.background_color !== undefined ? settings.background_color : _background_color;
_font_color = settings.font_color !== undefined ? settings.font_color : _font_color;
horizontal_sincronization = settings.horizontal_sincronization !== undefined ? settings.horizontal_sincronization : horizontal_sincronization
brightness_flickering = settings.brightness_flickering !== undefined ? settings.brightness_flickering : brightness_flickering;
noise_strength = settings.noise_strength !== undefined ? settings.noise_strength : noise_strength;
screen_distortion = settings.screen_distortion !== undefined ? settings.screen_distortion : screen_distortion;
glowing_line_strength = settings.glowing_line_strength !== undefined ? settings.glowing_line_strength : glowing_line_strength;
motion_blur = settings.motion_blur !== undefined ? settings.motion_blur : motion_blur
bloom_strength = settings.bloom_strength !== undefined ? settings.bloom_strength : bloom_strength
frames_index = settings.frames_index !== undefined ? settings.frames_index : frames_index;
rasterization = settings.rasterization !== undefined ? settings.rasterization : rasterization;
jitter = settings.jitter !== undefined ? settings.jitter : jitter;
ambient_light = settings.ambient_light !== undefined ? settings.ambient_light : ambient_light;
contrast = settings.contrast !== undefined ? settings.contrast : contrast;
brightness = settings.brightness !== undefined ? settings.brightness : brightness;
windowOpacity = settings.windowOpacity !== undefined ? settings.windowOpacity : windowOpacity;
fontIndexes[rasterization] = settings.fontIndex !== undefined ? settings.fontIndex : fontIndexes[rasterization];
}
function storeCustomProfiles(){
storage.setSetting("_CUSTOM_PROFILES", composeCustomProfilesString());
}
function loadCustomProfiles(){
var customProfileString = storage.getSetting("_CUSTOM_PROFILES");
if(customProfileString === undefined) customProfileString = "[]";
loadCustomProfilesString(customProfileString);
}
function loadCustomProfilesString(customProfilesString){
var customProfiles = JSON.parse(customProfilesString);
for (var i=0; i<customProfiles.length; i++) {
var profile = customProfiles[i];
console.log("Loading custom profile: " + JSON.stringify(profile));
profiles_list.append(profile);
}
}
function composeCustomProfilesString(){
var customProfiles = []
for(var i=0; i<profileslist.count; i++){
var profile = profileslist.get(i);
if(profile.builtin) continue;
customProfiles.push({text: profile.text, obj_string: profile.obj_string, builtin: false})
}
return JSON.stringify(customProfiles);
}
function loadCurrentProfile(){
loadProfile(profiles_index);
}
function loadProfile(index){
var profile = profileslist.get(index);
loadProfileString(profile.obj_string);
}
function addNewCustomProfile(name){
var profileString = composeProfileString();
profileslist.append({text: name, obj_string: profileString, builtin: false});
}
// PROFILES ///////////////////////////////////////////////////////////////
ListModel{
id: profileslist
ListElement{
text: "Default Amber"
obj_string: '{"ambient_light":0.2,"background_color":"#000000","bloom_strength":0.65,"brightness":0.5,"brightness_flickering":0.1,"contrast":0.85,"fontIndex":0,"font_color":"#ff8100","frames_index":1,"glowing_line_strength":0.2,"horizontal_sincronization":0.08,"jitter":0.18,"motion_blur":0.4,"noise_strength":0.1,"rasterization":0,"screen_distortion":0.1,"windowOpacity":1}'
builtin: true
}
ListElement{
text: "Default Green"
obj_string: '{"ambient_light":0.2,"background_color":"#000000","bloom_strength":0.4,"brightness":0.5,"brightness_flickering":0.1,"contrast":0.85,"fontIndex":0,"font_color":"#0ccc68","frames_index":1,"glowing_line_strength":0.2,"horizontal_sincronization":0.08,"jitter":0.18,"motion_blur":0.45,"noise_strength":0.1,"rasterization":0,"screen_distortion":0.1,"windowOpacity":1}'
builtin: true
}
ListElement{
text: "Default Scanlines"
obj_string: '{"ambient_light":0.2,"background_color":"#000000","bloom_strength":0.4,"brightness":0.5,"brightness_flickering":0.1,"contrast":0.85,"fontIndex":0,"font_color":"#00ff5b","frames_index":1,"glowing_line_strength":0.2,"horizontal_sincronization":0.07,"jitter":0.11,"motion_blur":0.4,"noise_strength":0.05,"rasterization":1,"screen_distortion":0.1,"windowOpacity":1}'
builtin: true
}
ListElement{
text: "Default Pixelated"
obj_string: '{"ambient_light":0.2,"background_color":"#000000","bloom_strength":0.4,"brightness":0.5,"brightness_flickering":0.1,"contrast":0.85,"fontIndex":0,"font_color":"#ff8100","frames_index":1,"glowing_line_strength":0.2,"horizontal_sincronization":0.1,"jitter":0,"motion_blur":0.45,"noise_strength":0.14,"rasterization":2,"screen_distortion":0.05,"windowOpacity":1}'
builtin: true
}
ListElement{
text: "Apple ]["
obj_string: '{"ambient_light":0.2,"background_color":"#000000","bloom_strength":0.5,"brightness":0.5,"brightness_flickering":0.2,"contrast":0.85,"fontIndex":2,"font_color":"#2fff91","frames_index":1,"glowing_line_strength":0.22,"horizontal_sincronization":0.08,"jitter":0.1,"motion_blur":0.65,"noise_strength":0.08,"rasterization":1,"screen_distortion":0.18,"windowOpacity":1}'
builtin: true
}
ListElement{
text: "Vintage"
obj_string: '{"ambient_light":0.2,"background_color":"#000000","bloom_strength":0.4,"brightness":0.5,"brightness_flickering":0.54,"contrast":0.85,"fontIndex":0,"font_color":"#00ff3e","frames_index":2,"glowing_line_strength":0.3,"horizontal_sincronization":0.2,"jitter":0.4,"motion_blur":0.75,"noise_strength":0.2,"rasterization":1,"screen_distortion":0.1,"windowOpacity":1}'
builtin: true
}
ListElement{
text: "IBM Dos"
obj_string: '{"ambient_light":0.2,"background_color":"#000000","bloom_strength":0.4,"brightness":0.5,"brightness_flickering":0.07,"contrast":0.85,"fontIndex":7,"font_color":"#ffffff","frames_index":1,"glowing_line_strength":0.13,"horizontal_sincronization":0,"jitter":0.08,"motion_blur":0.3,"noise_strength":0.03,"rasterization":0,"screen_distortion":0.1,"windowOpacity":1}'
builtin: true
}
ListElement{
text: "Transparent Green"
obj_string: '{"ambient_light":0.2,"background_color":"#000000","bloom_strength":0.4549689440993788,"brightness":0.5,"brightness_flickering":0.20341614906832298,"contrast":0.85,"fontIndex":0,"font_color":"#0ccc68","frames_index":0,"glowing_line_strength":0.15993788819875776,"horizontal_sincronization":0.05045871559633028,"jitter":0.20341614906832298,"motion_blur":0.24999999999999997,"noise_strength":0.20031055900621117,"rasterization":0,"screen_distortion":0.05045871559633028,"windowOpacity":0.5956221198156681}'
builtin: true
}
}
Component.onCompleted: {
loadSettings();
loadCustomProfiles();
}
Component.onDestruction: {
storeSettings();
storeCustomProfiles();
//storage.dropSettings(); //DROPS THE SETTINGS!.. REMEMBER TO DISABLE ONCE ENABLED!!
}
}

63
app/CheckableSlider.qml Normal file
View File

@@ -0,0 +1,63 @@
/*******************************************************************************
* Copyright (c) 2013 "Filippo Scognamiglio"
* https://github.com/Swordifish90/cool-old-term
*
* This file is part of cool-old-term.
*
* cool-old-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.Layouts 1.1
RowLayout {
property bool enabled: true
property alias name: check.text
property double value: (check.checked) ? _value : 0.0
property alias _value: slider.value
property alias min_value: slider.minimumValue
property alias max_value: slider.maximumValue
property alias stepSize: slider.stepSize
id: setting_component
anchors.left: parent.left
anchors.right: parent.right
spacing: 25
CheckBox{
id: check
implicitWidth: 150
Component.onCompleted: checked = (_value !== 0);
enabled: parent.enabled
}
Slider{
id: slider
stepSize: parent.stepSize
Layout.fillWidth: true
enabled: check.checked && parent.enabled
}
Text{
id: textfield
property string unformattedText: Math.round(((value - min_value) / (max_value - min_value)) * 100)
text: formatNumber(unformattedText)
}
function formatNumber(num) {
var n = "" + num;
while (n.length < 3) {
n = " " + n;
}
return n + "%";
}
}

View File

@@ -1,10 +1,10 @@
/*******************************************************************************
* Copyright (c) 2013-2021 "Filippo Scognamiglio"
* https://github.com/Swordfish90/cool-retro-term
* Copyright (c) 2013 "Filippo Scognamiglio"
* https://github.com/Swordifish90/cool-old-term
*
* This file is part of cool-retro-term.
* This file is part of cool-old-term.
*
* cool-retro-term is free software: you can redistribute it and/or modify
* cool-old-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.
@@ -17,33 +17,31 @@
* 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
import QtQuick.Dialogs 1.1
Item {
id: rootItem
signal colorSelected(color color)
property color color
signal colorSelected (color color)
property color button_color
property string name
ColorDialog {
id: colorDialog
title: qsTr("Choose a color")
modality: Qt.ApplicationModal
selectedColor: rootItem.color
visible: false
onSelectedColorChanged: {
if (!appSettings.isMacOS && visible)
colorSelected(selectedColor)
}
onAccepted: colorSelected(selectedColor)
//This is a workaround to a Qt 5.2 bug.
onCurrentColorChanged: colorDialog.color = colorDialog.currentColor;
onAccepted: colorSelected(color)
}
Rectangle {
Rectangle{
anchors.fill: parent
radius: 10
color: rootItem.color
color: button_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
text: name + ": " + button_color
}
}
MouseArea {
MouseArea{
anchors.fill: parent
onClicked: colorDialog.open()
onClicked: colorDialog.visible = true;
}
}

71
app/FontPixels.qml Normal file
View File

@@ -0,0 +1,71 @@
/*******************************************************************************
* Copyright (c) 2013 "Filippo Scognamiglio"
* https://github.com/Swordifish90/cool-old-term
*
* This file is part of cool-old-term.
*
* cool-old-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
Item{
property int selectedFontIndex
property int selectedScalingIndex
property alias fontlist: fontlist
property var _font: fontlist.get(selectedFontIndex)
property var _scaling: fontScalingList[selectedScalingIndex]
property var source: _font.source
property var fontScalingList: [0.75, 1.0, 1.25, 1.50, 1.75, 2.0, 2.25, 2.5]
property int pixelSize: _font.pixelSize * _scaling
property int lineSpacing: (_font.pixelSize / _font.virtualCharHeight) * _font.lineSpacing
property size virtualCharSize: Qt.size(_font.virtualCharWidth,
_font.virtualCharHeight)
ListModel{
id: fontlist
ListElement{
text: "Commodore PET (1977)"
source: "fonts/1977-commodore-pet/COMMODORE_PET.ttf"
lineSpacing: 2
virtualCharWidth: 8
virtualCharHeight: 8
pixelSize: 32
}
ListElement{
text: "Apple ][ (1977)"
source: "fonts/1977-apple2/PrintChar21.ttf"
lineSpacing: 2
virtualCharWidth: 7
virtualCharHeight: 8
pixelSize: 32
}
ListElement{
text: "Atari 400-800 (1979)"
source: "fonts/1979-atari-400-800/ATARI400800_original.TTF"
lineSpacing: 3
virtualCharWidth: 8
virtualCharHeight: 8
pixelSize: 32
}
ListElement{
text: "Commodore 64 (1982)"
source: "fonts/1982-commodore64/C64_User_Mono_v1.0-STYLE.ttf"
lineSpacing: 3
virtualCharWidth: 8
virtualCharHeight: 8
pixelSize: 32
}
}
}

79
app/FontScanlines.qml Normal file
View File

@@ -0,0 +1,79 @@
/*******************************************************************************
* Copyright (c) 2013 "Filippo Scognamiglio"
* https://github.com/Swordifish90/cool-old-term
*
* This file is part of cool-old-term.
*
* cool-old-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
Item{
property int selectedFontIndex
property int selectedScalingIndex
property alias fontlist: fontlist
property var _font: fontlist.get(selectedFontIndex)
property var _scaling: fontScalingList[selectedScalingIndex]
property var source: _font.source
property var fontScalingList: [0.75, 1.0, 1.25, 1.50, 1.75, 2.0, 2.25, 2.50]
property int pixelSize: _font.pixelSize * _scaling
property int lineSpacing: (_font.pixelSize / _font.virtualCharHeight) * _font.lineSpacing
property size virtualCharSize: Qt.size(_font.virtualCharWidth,
_font.virtualCharHeight)
ListModel{
id: fontlist
ListElement{
text: "Commodore PET 2Y (1977)"
source: "fonts/1977-commodore-pet/COMMODORE_PET_2y.ttf"
lineSpacing: 2
virtualCharWidth: 4
virtualCharHeight: 8
pixelSize: 32
}
ListElement{
text: "Commodore PET (1977)"
source: "fonts/1977-commodore-pet/COMMODORE_PET.ttf"
lineSpacing: 2
virtualCharWidth: 8
virtualCharHeight: 8
pixelSize: 32
}
ListElement{
text: "Apple ][ (1977)"
source: "fonts/1977-apple2/PrintChar21.ttf"
lineSpacing: 2
virtualCharWidth: 8
virtualCharHeight: 8
pixelSize: 32
}
ListElement{
text: "Atari 400-800 (1979)"
source: "fonts/1979-atari-400-800/ATARI400800_original.TTF"
lineSpacing: 3
virtualCharWidth: 8
virtualCharHeight: 8
pixelSize: 32
}
ListElement{
text: "Commodore 64 (1982)"
source: "fonts/1982-commodore64/C64_User_Mono_v1.0-STYLE.ttf"
lineSpacing: 3
virtualCharWidth: 8
virtualCharHeight: 8
pixelSize: 32
}
}
}

87
app/Fonts.qml Normal file
View File

@@ -0,0 +1,87 @@
/*******************************************************************************
* Copyright (c) 2013 "Filippo Scognamiglio"
* https://github.com/Swordifish90/cool-old-term
*
* This file is part of cool-old-term.
*
* cool-old-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
Item{
property int selectedFontIndex
property int selectedScalingIndex
property alias fontlist: fontlist
property var source: fontlist.get(selectedFontIndex).source
property var _font: fontlist.get(selectedFontIndex)
property var _scaling: fontScalingList[selectedScalingIndex]
property var fontScalingList: [0.5, 0.6, 0.7, 0.8, 0.9, 1.0, 1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 1.7, 1.8, 1.9, 2.0, 2.1, 2.2, 2.3, 2.4, 2.5]
property int pixelSize: _font.pixelSize * _scaling
property int lineSpacing: pixelSize * _font.lineSpacing
//In this configuration lineSpacing is proportional to pixelSize.
ListModel{
id: fontlist
ListElement{
text: "Terminus (Modern)"
source: "fonts/modern-terminus/TerminusTTF-Bold-4.38.2.ttf"
lineSpacing: 0.2
pixelSize: 35
}
ListElement{
text: "Commodore PET (1977)"
source: "fonts/1977-commodore-pet/COMMODORE_PET.ttf"
lineSpacing: 0.2
pixelSize: 24
}
ListElement{
text: "Commodore PET 2Y (1977)"
source: "fonts/1977-commodore-pet/COMMODORE_PET_2y.ttf"
lineSpacing: 0.2
pixelSize: 32
}
ListElement{
text: "Apple ][ (1977)"
source: "fonts/1977-apple2/PrintChar21.ttf"
lineSpacing: 0.2
pixelSize: 24
}
ListElement{
text: "Atari 400-800 (1979)"
source: "fonts/1979-atari-400-800/ATARI400800_original.TTF"
lineSpacing: 0.3
pixelSize: 24
}
ListElement{
text: "Commodore 64 (1982)"
source: "fonts/1982-commodore64/C64_User_Mono_v1.0-STYLE.ttf"
lineSpacing: 0.3
pixelSize: 24
}
ListElement{
text: "Atari ST (1985)"
source: "fonts/1985-atari-st/AtariST8x16SystemFont.ttf"
lineSpacing: 0.2
pixelSize: 32
}
ListElement{
text: "IBM DOS (1985)"
source: "fonts/1985-ibm-pc-vga/Perfect DOS VGA 437.ttf"
lineSpacing: 0.2
pixelSize: 32
}
}
}

21
app/Glossy.qml Normal file
View File

@@ -0,0 +1,21 @@
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" }
}
}

62
app/InsertNameDialog.qml Normal file
View File

@@ -0,0 +1,62 @@
/*******************************************************************************
* Copyright (c) 2013 "Filippo Scognamiglio"
* https://github.com/Swordifish90/cool-old-term
*
* This file is part of cool-old-term.
*
* cool-old-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.Window 2.0
import QtQuick.Controls 1.1
import QtQuick.Layouts 1.1
Window{
id: insertnamedialog
width: 400
height: 100
modality: Qt.ApplicationModal
title: qsTr("Save current profile")
signal nameSelected(string name)
ColumnLayout{
anchors.margins: 10
anchors.fill: parent
RowLayout{
Label{text: qsTr("Name")}
TextField{
id: namefield
Layout.fillWidth: true
Component.onCompleted: forceActiveFocus()
}
}
RowLayout{
anchors.right: parent.right
anchors.bottom: parent.bottom
Button{
text: qsTr("OK")
onClicked: {
nameSelected(namefield.text);
close();
}
}
Button{
text: qsTr("Cancel")
onClicked: close()
}
}
}
}

View File

@@ -0,0 +1,426 @@
/*******************************************************************************
* Copyright (c) 2013 "Filippo Scognamiglio"
* https://github.com/Swordifish90/cool-old-term
*
* This file is part of cool-old-term.
*
* cool-old-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
import QtQuick.Controls 1.1
import org.kde.konsole 0.1
Item{
id: terminalContainer
property variant theSource: finalSource
property variant bloomSource: bloomSourceLoader.item
property variant rasterizationSource: rasterizationEffectSource
property variant staticNoiseSource: staticNoiseSource
property alias kterminal: kterminal
signal sizeChanged
onWidthChanged: sizeChanged()
onHeightChanged: sizeChanged()
//The blur effect has to take into account the framerate
property int fps: shadersettings.fps !== 0 ? shadersettings.fps : 60
property real fpsAttenuation: Math.sqrt(60 / fps)
property real mBlur: shadersettings.motion_blur
property real motionBlurCoefficient: (_maxBlurCoefficient * mBlur + _minBlurCoefficient * (1 - mBlur))
property real _minBlurCoefficient: 0.70
property real _maxBlurCoefficient: 0.90
property size virtualPxSize: Qt.size(1,1)
property size virtual_resolution: Qt.size(width / virtualPxSize.width, height / virtualPxSize.height)
property real deltay: 0.5 / virtual_resolution.height
property real deltax: 0.5 / virtual_resolution.width
property real mBloom: shadersettings.bloom_strength
property int mScanlines: shadersettings.rasterization
onMScanlinesChanged: restartBlurredSource()
property size terminalSize: kterminal.terminalSize
property size paintedTextSize
onMBlurChanged: restartBlurredSource()
function restartBlurredSource(){
if(!blurredSource) return;
blurredSource.live = true;
livetimer.restart()
}
function pasteClipboard(){
kterminal.pasteClipboard();
}
function copyClipboard(){
kterminal.copyClipboard();
}
KTerminal {
id: kterminal
anchors.fill: parent
colorScheme: "cool-old-term"
session: KSession {
id: ksession
kbScheme: "linux"
onFinished: {
Qt.quit()
}
}
FontLoader{ id: fontLoader }
Text{id: fontMetrics; text: "B"; visible: false}
function getPaintedSize(pixelSize){
fontMetrics.font.family = fontLoader.name;
fontMetrics.font.pixelSize = pixelSize;
return Qt.size(fontMetrics.paintedWidth, fontMetrics.paintedHeight);
}
function isValid(size){
return size.width >= 0 && size.height >= 0;
}
function handleFontChange(fontSource, pixelSize, lineSpacing, virtualCharSize){
fontLoader.source = fontSource;
font.pixelSize = pixelSize * shadersettings.window_scaling;
font.family = fontLoader.name;
var paintedSize = getPaintedSize(pixelSize);
var charSize = isValid(virtualCharSize)
? virtualCharSize
: Qt.size(paintedSize.width / 2, paintedSize.height / 2);
var virtualPxSize = Qt.size((paintedSize.width / charSize.width) * shadersettings.window_scaling,
(paintedSize.height / charSize.height) * shadersettings.window_scaling)
terminalContainer.virtualPxSize = virtualPxSize;
setLineSpacing(lineSpacing * shadersettings.window_scaling);
restartBlurredSource();
}
Component.onCompleted: {
shadersettings.terminalFontChanged.connect(handleFontChange);
forceActiveFocus();
}
}
Menu{
id: contextmenu
MenuItem{action: copyAction}
MenuItem{action: pasteAction}
MenuSeparator{}
MenuItem{action: fullscreenAction}
MenuItem{action: showMenubarAction}
}
MouseArea{
acceptedButtons: Qt.LeftButton | Qt.MiddleButton | Qt.RightButton
anchors.fill: parent
onWheel:{
var coord = correctDistortion(wheel.x, wheel.y);
var lines = wheel.angleDelta.y > 0 ? -2 : 2;
kterminal.scrollWheel(coord.width, coord.height, lines);
}
onClicked: {
if (mouse.button == Qt.RightButton){
contextmenu.popup();
} else if (mouse.button == Qt.MiddleButton){
kterminal.pasteSelection();
}
}
onDoubleClicked: {
if (mouse.button == Qt.LeftButton){
var coord = correctDistortion(mouse.x, mouse.y);
kterminal.mouseDoubleClick(coord.width, coord.height);
}
}
onPositionChanged: {
if (pressedButtons & Qt.LeftButton){
var coord = correctDistortion(mouse.x, mouse.y);
kterminal.mouseMove(coord.width, coord.height);
}
}
onPressed: {
if (mouse.button == Qt.LeftButton){
var coord = correctDistortion(mouse.x, mouse.y);
kterminal.mousePress(coord.width, coord.height);
}
}
onReleased: {
if (mouse.button == Qt.LeftButton){
var coord = correctDistortion(mouse.x, mouse.y);
kterminal.mouseRelease(coord.width, coord.height);
}
}
//Frame displacement properties
property real dtop: frame.item.displacementTop
property real dleft:frame.item.displacementLeft
property real dright: frame.item.displacementRight
property real dbottom: frame.item.displacementBottom
function correctDistortion(x, y){
x = x / width;
y = y / height;
x = (-dleft + x * (width + dleft + dright)) / width
y = (-dtop + y * (height + dtop + dbottom)) / height
var cc = Qt.size(0.5 - x, 0.5 - y);
var distortion = (cc.height * cc.height + cc.width * cc.width) * shadersettings.screen_distortion;
return Qt.size((x - cc.width * (1+distortion) * distortion) * width,
(y - cc.height * (1+distortion) * distortion) * height)
}
}
ShaderEffectSource{
id: source
sourceItem: kterminal
hideSource: true
smooth: false
}
ShaderEffectSource{
id: blurredSource
sourceItem: blurredterminal
recursive: true
live: false
hideSource: true
smooth: false
antialiasing: false
Timer{
id: livetimer
running: true
onRunningChanged: running ?
timeManager.onTimeChanged.connect(blurredSource.scheduleUpdate) :
timeManager.onTimeChanged.disconnect(blurredSource.scheduleUpdate)
Component.onCompleted: kterminal.updatedImage.connect(restart);
}
}
ShaderEffectSource{
id: finalSource
sourceItem: blurredterminal
sourceRect: frame.sourceRect
//format: ShaderEffectSource.Alpha
hideSource: true
}
ShaderEffect {
id: blurredterminal
anchors.fill: parent
property variant source: source
property variant blurredSource: (mBlur !== 0) ? blurredSource : undefined
property size virtual_resolution: parent.virtual_resolution
property size delta: Qt.size((mScanlines == shadersettings.pixel_rasterization ? deltax : 0),
mScanlines != shadersettings.no_rasterization ? deltay : 0)
blending: false
fragmentShader:
"uniform lowp float qt_Opacity;" +
"uniform lowp sampler2D source;" +
"uniform highp vec2 delta;" +
"varying highp vec2 qt_TexCoord0;
uniform highp vec2 virtual_resolution;" +
(mBlur !== 0 ?
"uniform lowp sampler2D blurredSource;"
: "") +
"void main() {" +
"vec2 coords = qt_TexCoord0;" +
(mScanlines != shadersettings.no_rasterization ? "
coords.y = floor(virtual_resolution.y * coords.y) / virtual_resolution.y;" +
(mScanlines == shadersettings.pixel_rasterization ? "
coords.x = floor(virtual_resolution.x * coords.x) / virtual_resolution.x;" : "")
: "") +
"coords = coords + delta;" +
"vec4 vcolor = texture2D(source, coords) * 256.0;
float color = vcolor.r * 0.21 + vcolor.g * 0.72 + vcolor.b + 0.04;" +
(mBlur !== 0 ?
"float blurredSourceColor = texture2D(blurredSource, coords).a * 256.0;" +
"blurredSourceColor = blurredSourceColor - blurredSourceColor * " + (1.0 - motionBlurCoefficient) * fpsAttenuation+ ";" +
"color = step(1.0, color) * color + step(color, 1.0) * blurredSourceColor;"
: "") +
"gl_FragColor.a = floor(color) / 256.0;" +
"}"
onStatusChanged: if (log) console.log(log) //Print warning messages
}
///////////////////////////////////////////////////////////////////////////
// EFFECTS //////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////
// BLOOM ////////////////////////////////////////////////////////////////
Loader{
id: bloomEffectLoader
active: mBloom != 0
anchors.fill: parent
sourceComponent: FastBlur{
radius: 48
source: kterminal
transparentBorder: true
smooth: false
}
}
Loader{
id: bloomSourceLoader
active: mBloom != 0
sourceComponent: ShaderEffectSource{
sourceItem: bloomEffectLoader.item
hideSource: true
sourceRect: frame.sourceRect
smooth: false
}
}
// NOISE ////////////////////////////////////////////////////////////////
ShaderEffect {
id: staticNoiseEffect
anchors.fill: parent
property size virtual_resolution: terminalContainer.virtual_resolution
blending: false
fragmentShader:
"uniform lowp float qt_Opacity;
varying highp vec2 qt_TexCoord0;
uniform highp vec2 virtual_resolution;" +
"highp float noise(vec2 co)
{
highp float a = 12.9898;
highp float b = 78.233;
highp float c = 43758.5453;
highp float dt= dot(co.xy ,vec2(a,b));
highp float sn= mod(dt,3.14);
return fract(sin(sn) * c);
}
vec2 sw(vec2 p) {return vec2( floor(p.x) , floor(p.y) );}
vec2 se(vec2 p) {return vec2( ceil(p.x) , floor(p.y) );}
vec2 nw(vec2 p) {return vec2( floor(p.x) , ceil(p.y) );}
vec2 ne(vec2 p) {return vec2( ceil(p.x) , ceil(p.y) );}
float smoothNoise(vec2 p) {
vec2 inter = smoothstep(0., 1., fract(p));
float s = mix(noise(sw(p)), noise(se(p)), inter.x);
float n = mix(noise(nw(p)), noise(ne(p)), inter.x);
return mix(s, n, inter.y);
}" +
"void main() {" +
"gl_FragColor.a = smoothNoise(qt_TexCoord0 * virtual_resolution);" +
"}"
onStatusChanged: if (log) console.log(log) //Print warning messages
}
ShaderEffectSource{
id: staticNoiseSource
sourceItem: staticNoiseEffect
textureSize: Qt.size(parent.width, parent.height)
wrapMode: ShaderEffectSource.Repeat
smooth: true
hideSource: true
//format: ShaderEffectSource.Alpha
}
// RASTERIZATION //////////////////////////////////////////////////////////
ShaderEffect{
id: rasterizationContainer
width: frame.sourceRect.width
height: frame.sourceRect.height
property size offset: Qt.size(width - rasterizationEffect.width, height - rasterizationEffect.height)
property size txtRes: Qt.size(width, height)
blending: false
fragmentShader:
"uniform lowp float qt_Opacity;
uniform highp vec2 offset;
uniform highp vec2 txtRes;" +
"varying highp vec2 qt_TexCoord0;" +
"void main() {" +
"float color = 1.0;
color *= smoothstep(0.0, offset.x / txtRes.x, qt_TexCoord0.x);
color *= smoothstep(0.0, offset.y / txtRes.y, qt_TexCoord0.y);
color *= smoothstep(0.0, offset.x / txtRes.x, 1.0 - qt_TexCoord0.x);
color *= smoothstep(0.0, offset.y / txtRes.y, 1.0 - qt_TexCoord0.y);" +
"float distance = length(vec2(0.5) - qt_TexCoord0);" +
"color = mix(color, 0.0, 1.2 * distance * distance);" +
"gl_FragColor.a = color;" +
"}"
ShaderEffect {
id: rasterizationEffect
width: terminalContainer.width
height: terminalContainer.height
anchors.centerIn: parent
property size virtual_resolution: terminalContainer.virtual_resolution
blending: false
fragmentShader:
"uniform lowp float qt_Opacity;" +
"varying highp vec2 qt_TexCoord0;
uniform highp vec2 virtual_resolution;
float getScanlineIntensity(vec2 coords) {
float result = 1.0;" +
(mScanlines != shadersettings.no_rasterization ?
"result *= abs(sin(coords.y * virtual_resolution.y * "+Math.PI+"));" : "") +
(mScanlines == shadersettings.pixel_rasterization ?
"result *= abs(sin(coords.x * virtual_resolution.x * "+Math.PI+"));" : "") + "
return result;
}" +
"void main() {" +
"float color = getScanlineIntensity(qt_TexCoord0);" +
"float distance = length(vec2(0.5) - qt_TexCoord0);" +
"color = mix(color, 0.0, 1.2 * distance * distance);" +
"gl_FragColor.a = color;" +
"}"
onStatusChanged: if (log) console.log(log) //Print warning messages
}
onStatusChanged: if (log) console.log(log) //Print warning messages
}
ShaderEffectSource{
id: rasterizationEffectSource
sourceItem: rasterizationContainer
hideSource: true
smooth: true
//format: ShaderEffectSource.Alpha
}
}

View File

@@ -0,0 +1,79 @@
/*******************************************************************************
* Copyright (c) 2013 "Filippo Scognamiglio"
* https://github.com/Swordifish90/cool-old-term
*
* This file is part of cool-old-term.
*
* cool-old-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.Layouts 1.1
Tab{
GroupBox{
title: qsTr("Effects")
anchors.fill: parent
ColumnLayout{
anchors.fill: parent
CheckableSlider{
name: qsTr("Bloom")
onValueChanged: shadersettings.bloom_strength = value
_value: shadersettings.bloom_strength
}
CheckableSlider{
name: qsTr("Motion Blur")
onValueChanged: shadersettings.motion_blur = value
_value: shadersettings.motion_blur
}
CheckableSlider{
name: qsTr("Noise")
onValueChanged: shadersettings.noise_strength = value
_value: shadersettings.noise_strength
}
CheckableSlider{
name: qsTr("Jitter")
onValueChanged: shadersettings.jitter = value
_value: shadersettings.jitter
}
CheckableSlider{
name: qsTr("Glow")
onValueChanged: shadersettings.glowing_line_strength = value;
_value: shadersettings.glowing_line_strength
}
CheckableSlider{
name: qsTr("Screen distortion")
onValueChanged: shadersettings.screen_distortion = value;
_value: shadersettings.screen_distortion;
}
CheckableSlider{
name: qsTr("Ambient light")
onValueChanged: shadersettings.ambient_light = value;
_value: shadersettings.ambient_light
enabled: shadersettings.frames_index !== 0
}
CheckableSlider{
name: qsTr("Brightness flickering")
onValueChanged: shadersettings.brightness_flickering= value;
_value: shadersettings.brightness_flickering;
}
CheckableSlider{
name: qsTr("Horizontal flickering")
onValueChanged: shadersettings.horizontal_sincronization = value;
_value: shadersettings.horizontal_sincronization;
}
}
}
}

141
app/SettingsGeneralTab.qml Normal file
View File

@@ -0,0 +1,141 @@
/*******************************************************************************
* Copyright (c) 2013 "Filippo Scognamiglio"
* https://github.com/Swordifish90/cool-old-term
*
* This file is part of cool-old-term.
*
* cool-old-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.Layouts 1.1
Tab{
ColumnLayout{
anchors.fill: parent
GroupBox{
Layout.fillWidth: true
title: qsTr("Profile")
ColumnLayout{
anchors.fill: parent
ComboBox{
id: profilesbox
Layout.fillWidth: true
model: shadersettings.profiles_list
currentIndex: shadersettings.profiles_index
}
RowLayout{
Layout.fillWidth: true
Button{
Layout.fillWidth: true
text: qsTr("Load")
onClicked: {
shadersettings.profiles_index = profilesbox.currentIndex
shadersettings.loadCurrentProfile();
shadersettings.handleFontChanged();
}
}
Button{
Layout.fillWidth: true
text: qsTr("Store current")
onClicked: insertname.show()
}
Button{
Layout.fillWidth: true
text: qsTr("Remove Selected")
enabled: !shadersettings.profiles_list.get(profilesbox.currentIndex).builtin
onClicked: {
shadersettings.profiles_list.remove(profilesbox.currentIndex)
profilesbox.currentIndex = profilesbox.currentIndex - 1
}
}
}
InsertNameDialog{
id: insertname
onNameSelected: shadersettings.addNewCustomProfile(name)
}
}
}
GroupBox{
title: qsTr("Lights")
Layout.fillWidth: true
GridLayout{
anchors.fill: parent
columns: 2
Text{ text: qsTr("Brightness") }
SimpleSlider{
onValueChanged: shadersettings.brightness = value
value: shadersettings.brightness
}
Text{ text: qsTr("Contrast") }
SimpleSlider{
onValueChanged: shadersettings.contrast = value
value: shadersettings.contrast
}
Text{ text: qsTr("Opacity") }
SimpleSlider{
onValueChanged: shadersettings.windowOpacity = value
value: shadersettings.windowOpacity
}
}
}
GroupBox{
title: qsTr("Performace")
Layout.fillWidth: true
Layout.columnSpan: 2
anchors.left: parent.left
anchors.right: parent.right
GridLayout{
anchors.fill: parent
rows: 3
columns: 3
CheckBox{
Layout.columnSpan: 3
checked: !shadersettings._frameReflections
text: qsTr("Disable reflections")
onCheckedChanged: shadersettings._frameReflections = !checked
enabled: shadersettings.reflectionsAllowed
}
CheckBox{
property int fps: checked ? slider.value : 0
onFpsChanged: shadersettings.fps = fps
checked: shadersettings.fps !== 0
text: qsTr("Limit FPS")
}
Slider{
id: slider
Layout.fillWidth: true
stepSize: 1
maximumValue: 60
minimumValue: 1
enabled: shadersettings.fps !== 0
value: shadersettings.fps !== 0 ? shadersettings.fps : 60
}
Text{text: slider.value}
Text{text: qsTr("Texture quality")}
Slider{
Layout.fillWidth: true
id: txtslider
onValueChanged: shadersettings.window_scaling = value;
value: shadersettings.window_scaling
tickmarksEnabled: true
stepSize: 0.25
Component.onCompleted: minimumValue = 0.5 //Without this value gets set to 0.5
}
Text{text: Math.round(txtslider.value * 100) + "%"}
}
}
}
}

128
app/SettingsTerminalTab.qml Normal file
View File

@@ -0,0 +1,128 @@
/*******************************************************************************
* Copyright (c) 2013 "Filippo Scognamiglio"
* https://github.com/Swordifish90/cool-old-term
*
* This file is part of cool-old-term.
*
* cool-old-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.Layouts 1.1
Tab{
ColumnLayout{
anchors.fill: parent
GroupBox{
title: qsTr("Rasterization Mode")
Layout.fillWidth: true
ComboBox {
id: rasterizationBox
property string selectedElement: model[currentIndex]
anchors.fill: parent
model: [qsTr("Default"), qsTr("Scanlines"), qsTr("Pixels")]
currentIndex: shadersettings.rasterization
onCurrentIndexChanged: {
scalingChanger.enabled = false;
shadersettings.rasterization = currentIndex
fontChanger.updateIndex();
scalingChanger.updateIndex();
scalingChanger.enabled = true;
}
}
}
GroupBox{
title: qsTr("Font") + " (" + rasterizationBox.selectedElement + ")"
Layout.fillWidth: true
GridLayout{
anchors.fill: parent
columns: 2
Text{ text: qsTr("Name") }
ComboBox{
id: fontChanger
Layout.fillWidth: true
model: shadersettings.fontlist
currentIndex: updateIndex()
onActivated: {
shadersettings.fontIndexes[shadersettings.rasterization] = index;
shadersettings.handleFontChanged();
}
function updateIndex(){
currentIndex = shadersettings.fontIndexes[shadersettings.rasterization];
}
}
Text{ text: qsTr("Scaling") }
RowLayout{
Layout.fillWidth: true
Slider{
id: scalingChanger
Layout.fillWidth: true
minimumValue: 0
maximumValue: shadersettings.fontScalingList.length - 1
stepSize: 1
tickmarksEnabled: true
value: updateIndex()
onValueChanged: {
if(!enabled) return; //Ugly and hacky solution. Look for a better solution.
shadersettings.setScalingIndex(value);
}
function updateIndex(){
value = shadersettings.getScalingIndex();
}
Component.onCompleted: shadersettings.fontScalingChanged.connect(updateIndex);
}
Text{
text: shadersettings.fontScalingList[scalingChanger.value].toFixed(2)
}
}
}
}
GroupBox{
title: qsTr("Colors")
Layout.fillWidth: true
RowLayout{
anchors.fill: parent
ColorButton{
name: qsTr("Font")
height: 50
Layout.fillWidth: true
onColorSelected: shadersettings._font_color = color;
button_color: shadersettings._font_color
}
ColorButton{
name: qsTr("Background")
height: 50
Layout.fillWidth: true
onColorSelected: shadersettings._background_color = color;
button_color: shadersettings._background_color
}
}
}
GroupBox{
title: qsTr("Frame")
Layout.fillWidth: true
RowLayout{
anchors.fill: parent
ComboBox{
id: framescombobox
Layout.fillWidth: true
model: shadersettings.frames_list
currentIndex: shadersettings.frames_index
onCurrentIndexChanged: shadersettings.frames_index = currentIndex
}
}
}
}
}

54
app/SettingsWindow.qml Normal file
View File

@@ -0,0 +1,54 @@
/*******************************************************************************
* Copyright (c) 2013 "Filippo Scognamiglio"
* https://github.com/Swordifish90/cool-old-term
*
* This file is part of cool-old-term.
*
* cool-old-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.Window 2.1
import QtQuick.Layouts 1.1
import QtQuick.Dialogs 1.1
Window {
id: settings_window
title: qsTr("Settings")
width: 640
height: 450
property int tabmargins: 15
TabView{
anchors.fill: parent
anchors.margins: 10
SettingsGeneralTab{
title: qsTr("General")
anchors.fill: parent
anchors.margins: tabmargins
}
SettingsTerminalTab{
title: qsTr("Terminal")
anchors.fill: parent
anchors.margins: tabmargins
}
SettingsEffectsTab{
title: qsTr("Effects")
anchors.fill: parent
anchors.margins: tabmargins
}
}
}

200
app/ShaderTerminal.qml Normal file
View File

@@ -0,0 +1,200 @@
/*******************************************************************************
* Copyright (c) 2013 "Filippo Scognamiglio"
* https://github.com/Swordifish90/cool-old-term
*
* This file is part of cool-old-term.
*
* cool-old-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
ShaderEffect {
property color font_color: shadersettings.font_color
property color background_color: shadersettings.background_color
property variant source: terminal.theSource
property variant bloomSource: terminal.bloomSource
property variant rasterizationSource: terminal.rasterizationSource
property variant noiseSource: terminal.staticNoiseSource
property size txt_Size: Qt.size(frame.sourceRect.width, frame.sourceRect.height)
property real bloom: shadersettings.bloom_strength * 2.5
property int rasterization: shadersettings.rasterization
property real jitter: shadersettings.jitter * 0.007
property real noise_strength: shadersettings.noise_strength
property real screen_distorsion: shadersettings.screen_distortion
property real glowing_line_strength: shadersettings.glowing_line_strength
property real brightness_flickering: shadersettings.brightness_flickering
property real horizontal_sincronization: shadersettings.horizontal_sincronization
property bool frameReflections: shadersettings.frameReflections
property real disp_top: frame.item.displacementTop * shadersettings.window_scaling
property real disp_bottom: frame.item.displacementBottom * shadersettings.window_scaling
property real disp_left: frame.item.displacementLeft * shadersettings.window_scaling
property real disp_right: frame.item.displacementRight * shadersettings.window_scaling
property real brightness: shadersettings.brightness * 1.5 + 0.5
property real time: timeManager.time
property variant randomFunctionSource: randfuncsource
blending: false
//Smooth random texture used for flickering effect.
Image{
id: randtexture
source: "frames/images/randfunction.png"
width: 512
height: 512
sourceSize.width: 512
sourceSize.height: 256
fillMode: Image.TileVertically
}
ShaderEffectSource{
id: randfuncsource
sourceItem: randtexture
live: false
hideSource: true
wrapMode: ShaderEffectSource.Repeat
}
//Print the number with a reasonable precision for the shader.
function str(num){
return num.toFixed(8);
}
vertexShader: "
uniform highp mat4 qt_Matrix;
uniform highp float time;
uniform sampler2D randomFunctionSource;
uniform highp vec2 txt_Size;
attribute highp vec4 qt_Vertex;
attribute highp vec2 qt_MultiTexCoord0;
varying highp vec2 qt_TexCoord0;" +
(brightness_flickering !== 0.0 ?"
varying lowp float brightness;" : "") +
(horizontal_sincronization !== 0.0 ?"
varying lowp float horizontal_distortion;" : "") +
"
void main() {
qt_TexCoord0.x = -"+str(disp_left)+"/txt_Size.x + qt_MultiTexCoord0.x / ((txt_Size.x -("+str(disp_left+disp_right)+")) / txt_Size.x);" + "
qt_TexCoord0.y = -"+str(disp_top)+"/txt_Size.y + qt_MultiTexCoord0.y / ((txt_Size.y -("+str(disp_top+disp_bottom)+")) / txt_Size.y);" + "
vec2 coords = vec2(fract(time/(1024.0*2.0)), fract(time/(1024.0*1024.0)));" +
(brightness_flickering !== 0.0 ? "
brightness = 1.0 + (texture2D(randomFunctionSource, coords).g - 0.5) * "+str(brightness_flickering)+";"
: "") +
(horizontal_sincronization !== 0.0 ? "
float randval = 1.5 * texture2D(randomFunctionSource,(vec2(1.0) -coords) * 0.5).g;
float negsinc = 1.0 - "+str(0.6*horizontal_sincronization)+";
horizontal_distortion = step(negsinc, randval) * (randval - negsinc) * "+str(0.3*horizontal_sincronization)+";"
: "") +
"gl_Position = qt_Matrix * qt_Vertex;
}"
fragmentShader: "
uniform sampler2D source;
uniform highp float qt_Opacity;
uniform highp float time;
uniform highp vec2 txt_Size;
varying highp vec2 qt_TexCoord0;
uniform highp vec4 font_color;
uniform highp vec4 background_color;
uniform highp sampler2D rasterizationSource;" +
(bloom !== 0 ? "
uniform highp sampler2D bloomSource;" : "") +
(noise_strength !== 0 ? "
uniform highp float noise_strength;" : "") +
(noise_strength !== 0 || jitter !== 0 ? "
uniform lowp sampler2D noiseSource;" : "") +
(screen_distorsion !== 0 ? "
uniform highp float screen_distorsion;" : "")+
(glowing_line_strength !== 0 ? "
uniform highp float glowing_line_strength;" : "")+
(brightness_flickering !== 0 ? "
varying lowp float brightness;" : "") +
(horizontal_sincronization !== 0 ? "
varying lowp float horizontal_distortion;" : "") +
(glowing_line_strength !== 0 ? "
float randomPass(vec2 coords){
return fract(smoothstep(-0.2, 0.0, coords.y - 3.0 * fract(time * 0.0001))) * glowing_line_strength;
}" : "") +
"void main() {" +
"vec2 cc = vec2(0.5) - qt_TexCoord0;" +
"float distance = length(cc);" +
(noise_strength ? "
float noise = noise_strength;" : "") +
(screen_distorsion !== 0 ? "
float distortion = dot(cc, cc) * screen_distorsion;
vec2 coords = (qt_TexCoord0 - cc * (1.0 + distortion) * distortion);"
:"
vec2 coords = qt_TexCoord0;") +
(frameReflections ? "
vec2 inside = step(0.0, coords) - step(1.0, coords);
coords = abs(mod(floor(coords), 2.0) - fract(coords)) * clamp(inside.x + inside.y, 0.0, 1.0);" : "") +
(horizontal_sincronization !== 0 ? "
float h_distortion = 0.5 * sin(time*0.001 + coords.y*10.0*fract(time/10.0));
h_distortion += 0.5 * cos(time*0.04 + 0.03 + coords.y*50.0*fract(time/10.0 + 0.4));
coords.x = coords.x + h_distortion * horizontal_distortion;" +
(noise_strength ? "
noise += horizontal_distortion;" : "")
: "") +
(jitter !== 0 ? "
vec2 offset = vec2(texture2D(noiseSource, coords + fract(time / 57.0)).a,
texture2D(noiseSource, coords + fract(time / 251.0)).a) - 0.5;
vec2 txt_coords = coords + offset * "+str(jitter)+";"
: "vec2 txt_coords = coords;") +
"float color = texture2D(source, txt_coords).a;" +
(noise_strength !== 0 ? "
float noiseVal = texture2D(noiseSource, qt_TexCoord0 + vec2(fract(time / 51.0), fract(time / 237.0))).a;
color += noiseVal * noise * (1.0 - distance * 1.3);" : "") +
(glowing_line_strength !== 0 ? "
color += randomPass(coords) * glowing_line_strength;" : "") +
"vec3 finalColor = mix(background_color, font_color, color).rgb;" +
"finalColor *= texture2D(rasterizationSource, coords).a;" +
(bloom !== 0 ? "
finalColor += font_color.rgb * texture2D(bloomSource, coords).r *" + str(bloom) + ";" : "") +
(brightness_flickering !== 0 ? "
finalColor *= brightness;" : "") +
"gl_FragColor = vec4(finalColor *"+str(brightness)+", qt_Opacity);
}"
onStatusChanged: if (log) console.log(log) //Print warning messages
}

View File

@@ -1,10 +1,10 @@
/*******************************************************************************
* Copyright (c) 2013-2021 "Filippo Scognamiglio"
* https://github.com/Swordfish90/cool-retro-term
* Copyright (c) 2013 "Filippo Scognamiglio"
* https://github.com/Swordifish90/cool-old-term
*
* This file is part of cool-retro-term.
* This file is part of cool-old-term.
*
* cool-retro-term is free software: you can redistribute it and/or modify
* cool-old-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.
@@ -17,27 +17,34 @@
* 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.0
import QtQuick.Layouts 1.1
import "Components"
import QtQuick 2.2
import QtQuick.Controls 1.1
import QtQuick.Layouts 1.1
RowLayout {
property alias value: slider.value
property alias stepSize: slider.stepSize
property alias minimumValue: slider.from
property alias maximumValue: slider.to
property alias minimumValue: slider.minimumValue
property alias maximumValue: slider.maximumValue
property real maxMultiplier: 100
id: setting_component
spacing: 10
Slider {
Slider{
id: slider
stepSize: parent.stepSize
Layout.fillWidth: true
}
SizedLabel {
text: Math.round(value * maxMultiplier) + "%"
Text{
id: textfield
text: formatNumber(Math.round(value * maxMultiplier))
}
function formatNumber(num) {
var n = "" + num;
while (n.length < 3) {
n = " " + n;
}
return n + "%";
}
}

View File

@@ -1,10 +1,10 @@
/*******************************************************************************
* Copyright (c) 2013-2021 "Filippo Scognamiglio"
* https://github.com/Swordfish90/cool-retro-term
* Copyright (c) 2013 "Filippo Scognamiglio"
* https://github.com/Swordifish90/cool-old-term
*
* This file is part of cool-retro-term.
* This file is part of cool-old-term.
*
* cool-retro-term is free software: you can redistribute it and/or modify
* cool-old-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.
@@ -17,33 +17,31 @@
* 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.5
property real topOpacity: 0.6
width: textSize.width * 2
height: textSize.height * 2
radius: 5
border.width: 2
border.color: "white"
color: "black"
opacity: sizetimer.running ? 0.5 : 0.0
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,10 +1,10 @@
/*******************************************************************************
* Copyright (c) 2013-2021 "Filippo Scognamiglio"
* https://github.com/Swordfish90/cool-retro-term
* Copyright (c) 2013 "Filippo Scognamiglio"
* https://github.com/Swordifish90/cool-old-term
*
* This file is part of cool-retro-term.
* This file is part of cool-old-term.
*
* cool-retro-term is free software: you can redistribute it and/or modify
* cool-old-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.
@@ -21,13 +21,11 @@
import QtQuick 2.2
import QtQuick.LocalStorage 2.0
QtObject {
readonly property string dbMajorVersion: "2"
readonly property string dbMinorVersion: "1.0"
Item {
property bool initialized: false
function getDatabase() {
return LocalStorage.openDatabaseSync("coolretroterm" + dbMajorVersion, dbMinorVersion, "StorageDatabase", 100000)
return LocalStorage.openDatabaseSync("coololdterm", "1.0", "StorageDatabase", 100000);
}
function initialize() {
@@ -35,47 +33,43 @@ 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(){
@@ -83,7 +77,6 @@ QtObject {
db.transaction(
function(tx) {
tx.executeSql('DROP TABLE settings');
}
)
});
}
}

View File

@@ -1,10 +1,10 @@
/*******************************************************************************
* Copyright (c) 2013-2021 "Filippo Scognamiglio"
* https://github.com/Swordfish90/cool-retro-term
* Copyright (c) 2013 "Filippo Scognamiglio"
* https://github.com/Swordifish90/cool-old-term
*
* This file is part of cool-retro-term.
* This file is part of cool-old-term.
*
* cool-retro-term is free software: you can redistribute it and/or modify
* cool-old-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.
@@ -17,15 +17,23 @@
* 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
import QtQuick 2.2
Timer{
default property bool enableTimer: false
property real time
NumberAnimation on time {
from: 0
to: 100000
running: shadersettings.fps === 0 && enableTimer
duration: 100000
loops: Animation.Infinite
}
onTriggered: time += interval
running: shadersettings.fps !== 0 && enableTimer
interval: Math.round(1000 / shadersettings.fps)
repeat: true
}

View File

@@ -1,117 +0,0 @@
QT += qml quick widgets sql quickcontrols2
TARGET = cool-retro-term
APP_VERSION = $$system(git -C $$PWD/.. describe --tags --always --dirty=-dirty)
isEmpty(APP_VERSION): APP_VERSION = "unknown"
DEFINES += APP_VERSION=\\\"$$APP_VERSION\\\"
# TODO: When migrating to CMake, use KDSingleApplication's CMakeLists.txt instead of these manual sources.
INCLUDEPATH += $$PWD/../KDSingleApplication/src
HEADERS += \
$$PWD/../KDSingleApplication/src/kdsingleapplication.h \
$$PWD/../KDSingleApplication/src/kdsingleapplication_lib.h \
$$PWD/../KDSingleApplication/src/kdsingleapplication_localsocket_p.h
SOURCES += \
$$PWD/../KDSingleApplication/src/kdsingleapplication.cpp \
$$PWD/../KDSingleApplication/src/kdsingleapplication_localsocket.cpp
DEFINES += KDSINGLEAPPLICATION_STATIC_BUILD
DESTDIR = $$OUT_PWD/../
HEADERS += \
fileio.h \
fontmanager.h \
fontlistmodel.h
SOURCES += main.cpp \
fileio.cpp \
fontmanager.cpp \
fontlistmodel.cpp
macx:ICON = icons/crt.icns
RESOURCES += qml/resources.qrc
# Shader compilation (Qt Shader Baker)
QSB_BIN = $$[QT_HOST_BINS]/qsb
isEmpty(QSB_BIN): QSB_BIN = $$[QT_INSTALL_BINS]/qsb
SHADERS_DIR = $${_PRO_FILE_PWD_}/shaders
SHADERS += $$files($$SHADERS_DIR/*.frag) $$files($$SHADERS_DIR/*.vert)
SHADERS -= $$SHADERS_DIR/terminal_dynamic.frag
SHADERS -= $$SHADERS_DIR/terminal_static.frag
SHADERS -= $$SHADERS_DIR/passthrough.vert
qsb.input = SHADERS
qsb.output = ../../app/shaders/${QMAKE_FILE_NAME}.qsb
qsb.commands = $$QSB_BIN --glsl \"100 es,120,150\" --hlsl 50 --msl 12 --qt6 -o ${QMAKE_FILE_OUT} ${QMAKE_FILE_IN}
qsb.clean = $$qsb.output
qsb.name = qsb ${QMAKE_FILE_IN}
qsb.variable_out = QSB_FILES
QMAKE_EXTRA_COMPILERS += qsb
PRE_TARGETDEPS += $$QSB_FILES
OTHER_FILES += $$SHADERS $$QSB_FILES
DYNAMIC_SHADER = $$SHADERS_DIR/terminal_dynamic.frag
STATIC_SHADER = $$SHADERS_DIR/terminal_static.frag
RASTER_MODES = 0 1 2 3 4
BINARY_FLAGS = 0 1
VARIANT_SHADER_DIR = $$relative_path($$PWD/shaders, $$OUT_PWD)
VARIANT_OUTPUTS =
for(raster_mode, RASTER_MODES) {
for(burn_in, BINARY_FLAGS) {
for(display_frame, BINARY_FLAGS) {
for(chroma_on, BINARY_FLAGS) {
dynamic_variant = terminal_dynamic_raster$${raster_mode}_burn$${burn_in}_frame$${display_frame}_chroma$${chroma_on}
dynamic_output = $${VARIANT_SHADER_DIR}/$${dynamic_variant}.frag.qsb
dynamic_target = shader_variant_$${dynamic_variant}
$${dynamic_target}.target = $${dynamic_output}
$${dynamic_target}.depends = $$DYNAMIC_SHADER
$${dynamic_target}.commands = $$QSB_BIN --glsl \"100 es,120,150\" --hlsl 50 --msl 12 --qt6 -DCRT_RASTER_MODE=$${raster_mode} -DCRT_BURN_IN=$${burn_in} -DCRT_DISPLAY_FRAME=$${display_frame} -DCRT_CHROMA=$${chroma_on} -o $${dynamic_output} $$DYNAMIC_SHADER
QMAKE_EXTRA_TARGETS += $${dynamic_target}
VARIANT_OUTPUTS += $${dynamic_output}
}
}
}
}
for(rgb_shift, BINARY_FLAGS) {
for(bloom_on, BINARY_FLAGS) {
for(curve_on, BINARY_FLAGS) {
for(shine_on, BINARY_FLAGS) {
static_variant = terminal_static_rgb$${rgb_shift}_bloom$${bloom_on}_curve$${curve_on}_shine$${shine_on}
static_output = $${VARIANT_SHADER_DIR}/$${static_variant}.frag.qsb
static_target = shader_variant_$${static_variant}
$${static_target}.target = $${static_output}
$${static_target}.depends = $$STATIC_SHADER
$${static_target}.commands = $$QSB_BIN --glsl \"100 es,120,150\" --hlsl 50 --msl 12 --qt6 -DCRT_RGB_SHIFT=$${rgb_shift} -DCRT_BLOOM=$${bloom_on} -DCRT_CURVATURE=$${curve_on} -DCRT_FRAME_SHININESS=$${shine_on} -o $${static_output} $$STATIC_SHADER
QMAKE_EXTRA_TARGETS += $${static_target}
VARIANT_OUTPUTS += $${static_output}
}
}
}
}
PRE_TARGETDEPS += $${VARIANT_OUTPUTS}
#########################################
## INTALLS
#########################################
target.path += /usr/bin/
INSTALLS += target
# Install icons
unix {
icon32.files = icons/32x32/cool-retro-term.png
icon32.path = /usr/share/icons/hicolor/32x32/apps
icon64.files = icons/64x64/cool-retro-term.png
icon64.path = /usr/share/icons/hicolor/64x64/apps
icon128.files = icons/128x128/cool-retro-term.png
icon128.path = /usr/share/icons/hicolor/128x128/apps
icon256.files = icons/256x256/cool-retro-term.png
icon256.path = /usr/share/icons/hicolor/256x256/apps
INSTALLS += icon32 icon64 icon128 icon256
}

View File

@@ -1,37 +0,0 @@
#include "fileio.h"
FileIO::FileIO()
{
}
bool FileIO::write(const QString& sourceUrl, const QString& data) {
if (sourceUrl.isEmpty())
return false;
QUrl url(sourceUrl);
QFile file(url.toLocalFile());
if (!file.open(QFile::WriteOnly | QFile::Truncate))
return false;
QTextStream out(&file);
out << data;
file.close();
return true;
}
QString FileIO::read(const QString& sourceUrl) {
if (sourceUrl.isEmpty())
return "";
QUrl url(sourceUrl);
QFile file(url.toLocalFile());
if (!file.open(QFile::ReadOnly))
return "";
QTextStream in(&file);
QString result = in.readAll();
file.close();
return result;
}

View File

@@ -1,21 +0,0 @@
#ifndef FILEIO_H
#define FILEIO_H
#include <QObject>
#include <QFile>
#include <QTextStream>
#include <QUrl>
class FileIO : public QObject
{
Q_OBJECT
public:
FileIO();
public slots:
bool write(const QString& sourceUrl, const QString& data);
QString read(const QString& sourceUrl);
};
#endif // FILEIO_H

View File

@@ -1,94 +0,0 @@
#include "fontlistmodel.h"
FontListModel::FontListModel(QObject *parent)
: QAbstractListModel(parent)
{
}
int FontListModel::rowCount(const QModelIndex &parent) const
{
if (parent.isValid()) {
return 0;
}
return m_fonts.size();
}
QVariant FontListModel::data(const QModelIndex &index, int role) const
{
if (!index.isValid() || index.row() < 0 || index.row() >= m_fonts.size()) {
return QVariant();
}
const FontEntry &font = m_fonts.at(index.row());
switch (role) {
case NameRole:
return font.name;
case TextRole:
return font.text;
case SourceRole:
return font.source;
case BaseWidthRole:
return font.baseWidth;
case PixelSizeRole:
return font.pixelSize;
case LowResolutionRole:
return font.lowResolutionFont;
case IsSystemRole:
return font.isSystemFont;
case FamilyRole:
return font.family;
case FallbackNameRole:
return font.fallbackName;
default:
return QVariant();
}
}
QHash<int, QByteArray> FontListModel::roleNames() const
{
QHash<int, QByteArray> roles;
roles[NameRole] = "name";
roles[TextRole] = "text";
roles[SourceRole] = "source";
roles[BaseWidthRole] = "baseWidth";
roles[PixelSizeRole] = "pixelSize";
roles[LowResolutionRole] = "lowResolutionFont";
roles[IsSystemRole] = "isSystemFont";
roles[FamilyRole] = "family";
roles[FallbackNameRole] = "fallbackName";
return roles;
}
void FontListModel::setFonts(const QVector<FontEntry> &fonts)
{
beginResetModel();
m_fonts = fonts;
endResetModel();
emit countChanged();
}
const QVector<FontEntry> &FontListModel::fonts() const
{
return m_fonts;
}
QVariantMap FontListModel::get(int index) const
{
QVariantMap map;
if (index < 0 || index >= m_fonts.size()) {
return map;
}
const FontEntry &font = m_fonts.at(index);
map.insert("name", font.name);
map.insert("text", font.text);
map.insert("source", font.source);
map.insert("baseWidth", font.baseWidth);
map.insert("pixelSize", font.pixelSize);
map.insert("lowResolutionFont", font.lowResolutionFont);
map.insert("isSystemFont", font.isSystemFont);
map.insert("family", font.family);
map.insert("fallbackName", font.fallbackName);
return map;
}

View File

@@ -1,59 +0,0 @@
#ifndef FONTLISTMODEL_H
#define FONTLISTMODEL_H
#include <QAbstractListModel>
#include <QVector>
#include <QVariant>
#include <QVariantMap>
#include <QString>
struct FontEntry
{
QString name;
QString text;
QString source;
qreal baseWidth = 1.0;
int pixelSize = 0;
bool lowResolutionFont = false;
bool isSystemFont = false;
QString family;
QString fallbackName;
};
class FontListModel : public QAbstractListModel
{
Q_OBJECT
Q_PROPERTY(int count READ rowCount NOTIFY countChanged)
public:
explicit FontListModel(QObject *parent = nullptr);
enum Roles {
NameRole = Qt::UserRole + 1,
TextRole,
SourceRole,
BaseWidthRole,
PixelSizeRole,
LowResolutionRole,
IsSystemRole,
FamilyRole,
FallbackNameRole
};
int rowCount(const QModelIndex &parent = QModelIndex()) const override;
QVariant data(const QModelIndex &index, int role) const override;
QHash<int, QByteArray> roleNames() const override;
void setFonts(const QVector<FontEntry> &fonts);
const QVector<FontEntry> &fonts() const;
Q_INVOKABLE QVariantMap get(int index) const;
signals:
void countChanged();
private:
QVector<FontEntry> m_fonts;
};
#endif // FONTLISTMODEL_H

View File

@@ -1,584 +0,0 @@
#include "fontmanager.h"
#include <QFont>
#include <QFontDatabase>
#include <QFontMetricsF>
#include <QtGlobal>
#include <QtMath>
namespace {
constexpr int kModernRasterization = 4;
constexpr int kBaseFontPixelHeight = 32;
constexpr int kSystemFontPixelSize = 32;
}
FontManager::FontManager(QObject *parent)
: QObject(parent)
, m_fontListModel(this)
, m_filteredFontListModel(this)
{
populateBundledFonts();
populateSystemFonts();
m_fontListModel.setFonts(m_allFonts);
updateFilteredFonts();
updateComputedFont();
}
QStringList FontManager::retrieveMonospaceFonts()
{
QStringList result;
QFontDatabase fontDatabase;
const QStringList fontFamilies = fontDatabase.families();
for (const QString &fontFamily : fontFamilies) {
QFont font(fontFamily);
if (fontDatabase.isFixedPitch(font.family())) {
result.append(fontFamily);
}
}
return result;
}
void FontManager::refresh()
{
updateFilteredFonts();
updateComputedFont();
}
FontListModel *FontManager::fontList()
{
return &m_fontListModel;
}
FontListModel *FontManager::filteredFontList()
{
return &m_filteredFontListModel;
}
int FontManager::fontSource() const
{
return m_fontSource;
}
void FontManager::setFontSource(int fontSource)
{
if (m_fontSource == fontSource) {
return;
}
m_fontSource = fontSource;
emit fontSourceChanged();
updateFilteredFonts();
updateComputedFont();
}
int FontManager::rasterization() const
{
return m_rasterization;
}
void FontManager::setRasterization(int rasterization)
{
if (m_rasterization == rasterization) {
return;
}
m_rasterization = rasterization;
emit rasterizationChanged();
updateFilteredFonts();
updateComputedFont();
}
QString FontManager::fontName() const
{
return m_fontName;
}
void FontManager::setFontName(const QString &fontName)
{
if (m_fontName == fontName) {
return;
}
m_fontName = fontName;
emit fontNameChanged();
updateFilteredFonts();
updateComputedFont();
}
qreal FontManager::fontScaling() const
{
return m_fontScaling;
}
void FontManager::setFontScaling(qreal fontScaling)
{
if (qFuzzyCompare(m_fontScaling, fontScaling)) {
return;
}
m_fontScaling = fontScaling;
emit fontScalingChanged();
updateComputedFont();
}
qreal FontManager::fontWidth() const
{
return m_fontWidth;
}
void FontManager::setFontWidth(qreal fontWidth)
{
if (qFuzzyCompare(m_fontWidth, fontWidth)) {
return;
}
m_fontWidth = fontWidth;
emit fontWidthChanged();
updateComputedFont();
}
qreal FontManager::lineSpacing() const
{
return m_lineSpacing;
}
void FontManager::setLineSpacing(qreal lineSpacing)
{
if (qFuzzyCompare(m_lineSpacing, lineSpacing)) {
return;
}
m_lineSpacing = lineSpacing;
emit lineSpacingChanged();
updateComputedFont();
}
qreal FontManager::baseFontScaling() const
{
return m_baseFontScaling;
}
void FontManager::setBaseFontScaling(qreal baseFontScaling)
{
if (qFuzzyCompare(m_baseFontScaling, baseFontScaling)) {
return;
}
m_baseFontScaling = baseFontScaling;
emit baseFontScalingChanged();
updateComputedFont();
}
bool FontManager::lowResolutionFont() const
{
return m_lowResolutionFont;
}
void FontManager::setFontSubstitutions(const QString &family, const QStringList &substitutes)
{
if (family.isEmpty()) {
return;
}
QFont::removeSubstitutions(family);
if (substitutes.isEmpty()) {
return;
}
QFont::insertSubstitutions(family, substitutes);
}
void FontManager::removeFontSubstitution(const QString &family)
{
if (family.isEmpty()) {
return;
}
QFont::removeSubstitutions(family);
}
void FontManager::populateBundledFonts()
{
m_allFonts.clear();
addBundledFont(
"TERMINESS_SCALED",
"Terminess",
":/fonts/terminus/TerminessNerdFontMono-Regular.ttf",
1.0,
12,
true);
addBundledFont(
"BIGBLUE_TERMINAL_SCALED",
"BigBlue Terminal",
":/fonts/bigblue-terminal/BigBlueTerm437NerdFontMono-Regular.ttf",
1.0,
12,
true);
addBundledFont(
"EXCELSIOR_SCALED",
"Fixedsys Excelsior",
":/fonts/fixedsys-excelsior/FSEX301-L2.ttf",
1.0,
16,
true,
"UNSCII_16_SCALED");
addBundledFont(
"GREYBEARD_SCALED",
"Greybeard",
":/fonts/greybeard/Greybeard-16px.ttf",
1.0,
16,
true,
"UNSCII_16_SCALED");
addBundledFont(
"COMMODORE_PET_SCALED",
"Commodore PET",
":/fonts/pet-me/PetMe.ttf",
0.5,
8,
true,
"UNSCII_8_SCALED");
addBundledFont(
"GOHU_11_SCALED",
"Gohu 11",
":/fonts/gohu/GohuFont11NerdFontMono-Regular.ttf",
1.0,
11,
true);
addBundledFont(
"COZETTE_SCALED",
"Cozette",
":/fonts/cozette/CozetteVector.ttf",
1.0,
13,
true);
addBundledFont(
"UNSCII_8_SCALED",
"Unscii 8",
":/fonts/unscii/unscii-8.ttf",
0.5,
8,
true,
"UNSCII_8_SCALED");
addBundledFont(
"UNSCII_8_THIN_SCALED",
"Unscii 8 Thin",
":/fonts/unscii/unscii-8-thin.ttf",
0.5,
8,
true,
"UNSCII_8_SCALED");
addBundledFont(
"UNSCII_16_SCALED",
"Unscii 16",
":/fonts/unscii/unscii-16-full.ttf",
1.0,
16,
true,
"UNSCII_16_SCALED");
addBundledFont(
"APPLE_II_SCALED",
"Apple ][",
":/fonts/apple2/PrintChar21.ttf",
0.5,
8,
true,
"UNSCII_8_SCALED");
addBundledFont(
"ATARI_400_SCALED",
"Atari 400-800",
":/fonts/atari-400-800/AtariClassic-Regular.ttf",
0.5,
8,
true,
"UNSCII_8_SCALED");
addBundledFont(
"COMMODORE_64_SCALED",
"Commodore 64",
":/fonts/pet-me/PetMe64.ttf",
0.5,
8,
true,
"UNSCII_8_SCALED");
addBundledFont(
"IBM_EGA_8x8",
"IBM EGA 8x8",
":/fonts/oldschool-pc-fonts/PxPlus_IBM_EGA_8x8.ttf",
0.5,
8,
true,
"UNSCII_8_SCALED");
addBundledFont(
"IBM_VGA_8x16",
"IBM VGA 8x16",
":/fonts/oldschool-pc-fonts/PxPlus_IBM_VGA_8x16.ttf",
1.0,
16,
true,
"UNSCII_16_SCALED");
addBundledFont(
"TERMINESS",
"Terminess",
":/fonts/terminus/TerminessNerdFontMono-Regular.ttf",
1.0,
32,
false);
addBundledFont(
"HACK",
"Hack",
":/fonts/hack/HackNerdFontMono-Regular.ttf",
1.0,
32,
false);
addBundledFont(
"FIRA_CODE",
"Fira Code",
":/fonts/fira-code/FiraCodeNerdFontMono-Regular.ttf",
1.0,
32,
false);
addBundledFont(
"IOSEVKA",
"Iosevka",
":/fonts/iosevka/IosevkaTermNerdFontMono-Regular.ttf",
1.0,
32,
false);
addBundledFont(
"JETBRAINS_MONO",
"JetBrains Mono",
":/fonts/jetbrains-mono/JetBrainsMonoNerdFontMono-Regular.ttf",
1.0,
32,
false);
addBundledFont(
"IBM_3278",
"IBM 3278",
":/fonts/ibm-3278/3270NerdFontMono-Regular.ttf",
1.0,
32,
false);
addBundledFont(
"SOURCE_CODE_PRO",
"Source Code Pro",
":/fonts/source-code-pro/SauceCodeProNerdFontMono-Regular.ttf",
1.0,
32,
false);
addBundledFont(
"DEPARTURE_MONO_SCALED",
"Departure Mono",
":/fonts/departure-mono/DepartureMonoNerdFontMono-Regular.otf",
1.0,
11,
true);
addBundledFont(
"OPENDYSLEXIC",
"OpenDyslexic",
":/fonts/opendyslexic/OpenDyslexicMNerdFontMono-Regular.otf",
1.0,
32,
false);
}
void FontManager::addBundledFont(const QString &name,
const QString &text,
const QString &source,
qreal baseWidth,
int pixelSize,
bool lowResolutionFont,
const QString &fallbackName)
{
FontEntry entry;
entry.name = name;
entry.text = text;
entry.source = source;
entry.pixelSize = pixelSize;
entry.lowResolutionFont = lowResolutionFont;
entry.isSystemFont = false;
entry.fallbackName = fallbackName;
entry.family = resolveFontFamily(source);
entry.baseWidth = lowResolutionFont
? computeBaseWidth(entry.family, pixelSize, baseWidth)
: baseWidth;
m_allFonts.append(entry);
}
void FontManager::populateSystemFonts()
{
const QStringList families = retrieveMonospaceFonts();
for (const QString &family : families) {
if (m_bundledFamilies.contains(family)) {
continue;
}
FontEntry entry;
entry.name = family;
entry.text = family;
entry.source = QString();
entry.baseWidth = 1.0;
entry.pixelSize = kSystemFontPixelSize;
entry.lowResolutionFont = false;
entry.isSystemFont = true;
entry.family = family;
m_allFonts.append(entry);
}
}
void FontManager::updateFilteredFonts()
{
QVector<FontEntry> filtered;
bool fontNameFound = false;
const bool modernMode = (m_rasterization == kModernRasterization);
for (const FontEntry &font : m_allFonts) {
const bool isBundled = !font.isSystemFont;
const bool matchesSource = (m_fontSource == 0 && isBundled)
|| (m_fontSource == 1 && font.isSystemFont);
if (!matchesSource) {
continue;
}
const bool matchesRasterization = font.isSystemFont
|| (modernMode == !font.lowResolutionFont);
if (!matchesRasterization) {
continue;
}
filtered.append(font);
if (font.name == m_fontName) {
fontNameFound = true;
}
}
if (!fontNameFound && !filtered.isEmpty()) {
if (m_fontName != filtered.first().name) {
m_fontName = filtered.first().name;
emit fontNameChanged();
}
}
m_filteredFontListModel.setFonts(filtered);
emit filteredFontListChanged();
}
void FontManager::updateComputedFont()
{
const FontEntry *font = findFontByName(m_fontName);
if (!font) {
const QVector<FontEntry> &filteredFonts = m_filteredFontListModel.fonts();
if (!filteredFonts.isEmpty()) {
font = &filteredFonts.first();
}
}
if (!font) {
return;
}
const qreal totalFontScaling = m_baseFontScaling * m_fontScaling;
const qreal targetPixelHeight = kBaseFontPixelHeight * totalFontScaling;
const qreal lineSpacingFactor = m_lineSpacing;
const int lineSpacing = qRound(targetPixelHeight * lineSpacingFactor);
const int pixelSize = font->lowResolutionFont
? font->pixelSize
: static_cast<int>(targetPixelHeight);
const qreal nativeLineHeight = font->pixelSize + qRound(font->pixelSize * lineSpacingFactor);
const qreal targetLineHeight = targetPixelHeight + lineSpacing;
const qreal screenScaling = font->lowResolutionFont
? (nativeLineHeight > 0 ? targetLineHeight / nativeLineHeight : 1.0)
: 1.0;
const qreal fontWidth = font->baseWidth * m_fontWidth;
QString fontFamily = font->family.isEmpty() ? font->name : font->family;
QString fallbackFontFamily;
if (!font->fallbackName.isEmpty() && font->fallbackName != font->name) {
const FontEntry *fallback = findFontByName(font->fallbackName);
if (fallback) {
fallbackFontFamily = fallback->family.isEmpty() ? fallback->name : fallback->family;
}
}
QStringList fallbackChain;
if (!fallbackFontFamily.isEmpty()) {
fallbackChain.append(fallbackFontFamily);
}
#if defined(Q_OS_MAC)
fallbackChain.append(QStringLiteral("Menlo"));
#else
fallbackChain.append(QStringLiteral("Monospace"));
#endif
setFontSubstitutions(fontFamily, fallbackChain);
if (m_lowResolutionFont != font->lowResolutionFont) {
m_lowResolutionFont = font->lowResolutionFont;
emit lowResolutionFontChanged();
}
emit terminalFontChanged(fontFamily,
pixelSize,
lineSpacing,
screenScaling,
fontWidth,
fallbackFontFamily,
font->lowResolutionFont);
}
const FontEntry *FontManager::findFontByName(const QString &name) const
{
for (const FontEntry &font : m_allFonts) {
if (font.name == name) {
return &font;
}
}
return nullptr;
}
QString FontManager::resolveFontFamily(const QString &sourcePath)
{
const auto cached = m_loadedFamilies.constFind(sourcePath);
if (cached != m_loadedFamilies.constEnd()) {
return cached.value();
}
const int fontId = QFontDatabase::addApplicationFont(sourcePath);
QString family;
if (fontId != -1) {
const QStringList families = QFontDatabase::applicationFontFamilies(fontId);
if (!families.isEmpty()) {
family = families.first();
}
}
if (!family.isEmpty()) {
m_bundledFamilies.insert(family);
}
m_loadedFamilies.insert(sourcePath, family);
return family;
}
qreal FontManager::computeBaseWidth(const QString &family, int pixelSize, qreal fallbackWidth) const
{
if (family.isEmpty()) {
return fallbackWidth;
}
QFont font(family);
font.setPixelSize(pixelSize);
QFontMetricsF metrics(font);
const qreal glyphWidth = metrics.horizontalAdvance(QLatin1String("M"));
const qreal glyphHeight = metrics.height();
if (glyphWidth <= 0.0 || glyphHeight <= 0.0) {
return fallbackWidth;
}
const qreal targetRatio = 0.5;
qreal computedWidth = (targetRatio * glyphHeight) / glyphWidth;
return qBound(0.25, computedWidth, 2.0);
}

View File

@@ -1,111 +0,0 @@
#ifndef FONTMANAGER_H
#define FONTMANAGER_H
#include <QObject>
#include <QStringList>
#include <QHash>
#include <QSet>
#include "fontlistmodel.h"
class FontManager : public QObject
{
Q_OBJECT
Q_PROPERTY(FontListModel *fontList READ fontList CONSTANT)
Q_PROPERTY(FontListModel *filteredFontList READ filteredFontList NOTIFY filteredFontListChanged)
Q_PROPERTY(int fontSource READ fontSource WRITE setFontSource NOTIFY fontSourceChanged)
Q_PROPERTY(int rasterization READ rasterization WRITE setRasterization NOTIFY rasterizationChanged)
Q_PROPERTY(QString fontName READ fontName WRITE setFontName NOTIFY fontNameChanged)
Q_PROPERTY(qreal fontScaling READ fontScaling WRITE setFontScaling NOTIFY fontScalingChanged)
Q_PROPERTY(qreal fontWidth READ fontWidth WRITE setFontWidth NOTIFY fontWidthChanged)
Q_PROPERTY(qreal lineSpacing READ lineSpacing WRITE setLineSpacing NOTIFY lineSpacingChanged)
Q_PROPERTY(qreal baseFontScaling READ baseFontScaling WRITE setBaseFontScaling NOTIFY baseFontScalingChanged)
Q_PROPERTY(bool lowResolutionFont READ lowResolutionFont NOTIFY lowResolutionFontChanged)
public:
explicit FontManager(QObject *parent = nullptr);
Q_INVOKABLE void refresh();
FontListModel *fontList();
FontListModel *filteredFontList();
int fontSource() const;
void setFontSource(int fontSource);
int rasterization() const;
void setRasterization(int rasterization);
QString fontName() const;
void setFontName(const QString &fontName);
qreal fontScaling() const;
void setFontScaling(qreal fontScaling);
qreal fontWidth() const;
void setFontWidth(qreal fontWidth);
qreal lineSpacing() const;
void setLineSpacing(qreal lineSpacing);
qreal baseFontScaling() const;
void setBaseFontScaling(qreal baseFontScaling);
bool lowResolutionFont() const;
signals:
void fontSourceChanged();
void rasterizationChanged();
void fontNameChanged();
void fontScalingChanged();
void fontWidthChanged();
void lineSpacingChanged();
void baseFontScalingChanged();
void lowResolutionFontChanged();
void filteredFontListChanged();
void terminalFontChanged(QString fontFamily,
int pixelSize,
int lineSpacing,
qreal screenScaling,
qreal fontWidth,
QString fallbackFontFamily,
bool lowResolutionFont);
private:
QStringList retrieveMonospaceFonts();
void populateBundledFonts();
void populateSystemFonts();
void addBundledFont(const QString &name,
const QString &text,
const QString &source,
qreal baseWidth,
int pixelSize,
bool lowResolutionFont,
const QString &fallbackName = QString());
void setFontSubstitutions(const QString &family, const QStringList &substitutes);
void removeFontSubstitution(const QString &family);
void updateFilteredFonts();
void updateComputedFont();
const FontEntry *findFontByName(const QString &name) const;
QString resolveFontFamily(const QString &sourcePath);
qreal computeBaseWidth(const QString &family, int pixelSize, qreal fallbackWidth) const;
FontListModel m_fontListModel;
FontListModel m_filteredFontListModel;
QVector<FontEntry> m_allFonts;
int m_fontSource = 0;
int m_rasterization = 0;
QString m_fontName = QStringLiteral("TERMINESS_SCALED");
qreal m_fontScaling = 1.0;
qreal m_fontWidth = 1.0;
qreal m_lineSpacing = 0.1;
qreal m_baseFontScaling = 0.75;
bool m_lowResolutionFont = false;
QHash<QString, QString> m_loadedFamilies;
QSet<QString> m_bundledFamilies;
};
#endif // FONTMANAGER_H

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -0,0 +1,317 @@
{\rtf1\ansi\deff0\deftab720{\fonttbl{\f0\fswiss MS Sans Serif;}{\f1\froman\fcharset2 Symbol;}{\f2\fmodern\fprq1 Atari Classic Chunky;}{\f3\froman Times New Roman;}{\f4\fswiss\fprq2 Arial;}}
{\colortbl\red0\green0\blue0;\red0\green0\blue255;}
\deflang1033\pard\plain\f2\fs24\cf1 Atari Classic TrueType Fonts \plain\f2\fs24\cf0
\par \plain\f4\fs16\cf0 (Windows Version 1.1)
\par Created by Mark Simonson (v.1.0-1998, v.1.1-2001)
\par marksim@bitstream.net
\par Website: Mac/Atari Fusion--Atari Home Computer Resources for Mac Users
\par http://www2.bitstream.net/~marksim/atarimac/
\par Macintosh version also available.
\par
\par With these fonts installed, you can view and print Atari text files in any text editor that allows you to change fonts (WordPad, for example). Tip: In order to get the correct line breaks, you will need to change the ATASCII return character (155) to the DOS LF character. (In the Character Map accessory, the ATASCII return is the blank character that comes just before the inverse up-arrow.)
\par
\par There are three different fonts. \plain\f4\fs16\cf0\b Atari Classic Chunky \plain\f4\fs16\cf0 is a pixel-for-pixel copy of the original ATASCII character set. \plain\f4\fs16\cf0\b Atari Classic Smooth \plain\f4\fs16\cf0 interprets the pixel aliasing (stair steps) as diagonal lines. \plain\f4\fs16\cf0\b Atari Classic Extrasmooth \plain\f4\fs16\cf0 refines this idea further with the addition of curves. \plain\f4\fs16\cf0\b Smooth\plain\f4\fs16\cf0 and \plain\f4\fs16\cf0\b Extrasmooth\plain\f4\fs16\cf0 were designed for better appearance and legibility at larger sizes and on print-outs. Use the one that looks best to you.
\par
\par These fonts will tend to look uneven at font sizes that do not correspond to the 8-by-8 pixel grid that the characters are based on. Because Windows assumes 96ppi screen resolution, they will look best in a font size that is a multiple of 6 (i.e., 6pt, 12pt, 18pt, etc.). (In Windows, 6 points = 8 pixels.)
\par
\par The Atari Classic TrueType fonts duplicate the ATASCII character set on a low-level basis. Unlike a normal Windows font, ATASCII utilizes all character codes from $00 to $FF (0 to 255). The lower half are normal characters; the upper half are inverse versions of the lower half. The basic ASCII characters ($00 to $7F) correspond fairly closely except for the first 32, which don't normally contain characters in a Windows font.
\par
\par Due to differences between the way Windows and the Atari use character codes, not all characters will display properly in Windows. In fact, some characters will not display at all (though they do exist in the font). Unfortunately, this is due to certain character codes being reserved in Windows and there doesn't appear to be any way to work around it. The character codes affected are: $00-$1F (0-31), $7F-$81 (127-129), $8D-$90 (141-144), $9D (157), and $9F (158).
\par
\par Not all characters can be typed from the keyboard. You can however copy characters as needed from this document (see tables below). The Character Map desk accessory can help also.
\par
\par \plain\f4\fs16\cf0\b ATASCII CHARACTER SET TABLES
\par \plain\f4\fs16\cf0
\par In order to see the ATASCII character set with these tables, the Atari Classic TrueType fonts must be installed. Characters that are not displayed properly are due to character code usage differences between ATASCII and Windows (see above).
\par
\par
\par \plain\f4\fs16\cf0\b TABLE 1: ATASCII Character Dump Block
\par \plain\f4\fs16\cf0
\par All characters (ATASCII $00 thru $FF) 16 characters per
\par line.
\par
\par
\par \plain\f2\fs12\cf0 \'01\'02\'03\'04\'05\'06\'07\'08\tab
\par \'0b\'0c
\par \'0e\'0f
\par \'10\'11\'12\'13\'14\'15\'16\'17\'18\'19\'1a\'1b\'1c\'1d\'1e\'1f
\par !"#$%&'()*+,-./
\par 0123456789:;<=>?
\par @ABCDEFGHIJKLMNO
\par PQRSTUVWXYZ[\\]^_
\par `abcdefghijklmno
\par pqrstuvwxyz\{|\}~
\par \'80\'81\'82\'83\'84\'85\'86\'87\'88\'89\'8a\'8b\'8c\'8d\'8e\'8f
\par \'90''""\bullet \endash \emdash \'98\'99\'9a \'9c\'9d\'9e\'9f
\par \~\'a1\'a2\'a3\'a4\'a5\'a6\'a7\'a8\'a9\'aa\'ab\'ac\'ad\'ae\'af
\par \'b0\'b1\'b2\'b3\'b4\'b5\'b6\'b7\'b8\'b9\'ba\'bb\'bc\'bd\'be\'bf
\par \'c0\'c1\'c2\'c3\'c4\'c5\'c6\'c7\'c8\'c9\'ca\'cb\'cc\'cd\'ce\'cf
\par \'d0\'d1\'d2\'d3\'d4\'d5\'d6\'d7\'d8\'d9\'da\'db\'dc\'dd\'de\'df
\par \'e0\'e1\'e2\'e3\'e4\'e5\'e6\'e7\'e8\'e9\'ea\'eb\'ec\'ed\'ee\'ef
\par \'f0\'f1\'f2\'f3\'f4\'f5\'f6\'f7\'f8\'f9\'fa\'fb\'fc\'fd\'fe\'ff
\par \plain\f4\fs16\cf0
\par
\par \plain\f4\fs16\cf0\b TABLE 2: ATASCII Character Dump List
\par \plain\f4\fs16\cf0
\par All characters (ATASCII $00 thru $FF) one character per
\par line with hexadecimal value indicated on the left.
\par
\par \plain\f2\fs12\cf0 00=
\par 01=\'01
\par 02=\'02
\par 03=\'03
\par 04=\'04
\par 05=\'05
\par 06=\'06
\par 07=\'07
\par 08=\'08
\par 09=\tab
\par 0A=
\par
\par 0B=\'0b
\par 0C=\'0c
\par 0D=
\par 0E=\'0e
\par 0F=\'0f
\par 10=\'10
\par 11=\'11
\par 12=\'12
\par 13=\'13
\par 14=\'14
\par 15=\'15
\par 16=\'16
\par 17=\'17
\par 18=\'18
\par 19=\'19
\par 1A=\'1a
\par 1B=\'1b
\par 1C=\'1c
\par 1D=\'1d
\par 1E=\'1e
\par 1F=\'1f
\par 20=
\par 21=!
\par 22="
\par 23=#
\par 24=$
\par 25=%
\par 26=&
\par 27='
\par 28=(
\par 29=)
\par 2A=*
\par 2B=+
\par 2C=,
\par 2D=-
\par 2E=.
\par 2F=/
\par 30=0
\par 31=1
\par 32=2
\par 33=3
\par 34=4
\par 35=5
\par 36=6
\par 37=7
\par 38=8
\par 39=9
\par 3A=:
\par 3B=;
\par 3C=<
\par 3D==
\par 3E=>
\par 3F=?
\par 40=@
\par 41=A
\par 42=B
\par 43=C
\par 44=D
\par 45=E
\par 46=F
\par 47=G
\par 48=H
\par 49=I
\par 4A=J
\par 4B=K
\par 4C=L
\par 4D=M
\par 4E=N
\par 4F=O
\par 50=P
\par 51=Q
\par 52=R
\par 53=S
\par 54=T
\par 55=U
\par 56=V
\par 57=W
\par 58=X
\par 59=Y
\par 5A=Z
\par 5B=[
\par 5C=\\
\par 5D=]
\par 5E=^
\par 5F=_
\par 60=`
\par 61=a
\par 62=b
\par 63=c
\par 64=d
\par 65=e
\par 66=f
\par 67=g
\par 68=h
\par 69=i
\par 6A=j
\par 6B=k
\par 6C=l
\par 6D=m
\par 6E=n
\par 6F=o
\par 70=p
\par 71=q
\par 72=r
\par 73=s
\par 74=t
\par 75=u
\par 76=v
\par 77=w
\par 78=x
\par 79=y
\par 7A=z
\par 7B=\{
\par 7C=|
\par 7D=\}
\par 7E=~
\par 7F=
\par 80=\'80
\par 81=\'81
\par 82=\'82
\par 83=\'83
\par 84=\'84
\par 85=\'85
\par 86=\'86
\par 87=\'87
\par 88=\'88
\par 89=\'89
\par 8A=\'8a
\par 8B=\'8b
\par 8C=\'8c
\par 8D=\'8d
\par 8E=\'8e
\par 8F=\'8f
\par 90=\'90
\par 91='
\par 92='
\par 93="
\par 94="
\par 95=\bullet
\par 96=\endash
\par 97=\emdash
\par 98=\'98
\par 99=\'99
\par 9A=\'9a
\par 9B=
\par 9C=\'9c
\par 9D=\'9d
\par 9E=\'9e
\par 9F=\'9f
\par A0=\~
\par A1=\'a1
\par A2=\'a2
\par A3=\'a3
\par A4=\'a4
\par A5=\'a5
\par A6=\'a6
\par A7=\'a7
\par A8=\'a8
\par A9=\'a9
\par AA=\'aa
\par AB=\'ab
\par AC=\'ac
\par AD=\'ad
\par AE=\'ae
\par AF=\'af
\par B0=\'b0
\par B1=\'b1
\par B2=\'b2
\par B3=\'b3
\par B4=\'b4
\par B5=\'b5
\par B6=\'b6
\par B7=\'b7
\par B8=\'b8
\par B9=\'b9
\par BA=\'ba
\par BB=\'bb
\par BC=\'bc
\par BD=\'bd
\par BE=\'be
\par BF=\'bf
\par C0=\'c0
\par C1=\'c1
\par C2=\'c2
\par C3=\'c3
\par C4=\'c4
\par C5=\'c5
\par C6=\'c6
\par C7=\'c7
\par C8=\'c8
\par C9=\'c9
\par CA=\'ca
\par CB=\'cb
\par CC=\'cc
\par CD=\'cd
\par CE=\'ce
\par CF=\'cf
\par D0=\'d0
\par D1=\'d1
\par D2=\'d2
\par D3=\'d3
\par D4=\'d4
\par D5=\'d5
\par D6=\'d6
\par D7=\'d7
\par D8=\'d8
\par D9=\'d9
\par DA=\'da
\par DB=\'db
\par DC=\'dc
\par DD=\'dd
\par DE=\'de
\par DF=\'df
\par E0=\'e0
\par E1=\'e1
\par E2=\'e2
\par E3=\'e3
\par E4=\'e4
\par E5=\'e5
\par E6=\'e6
\par E7=\'e7
\par E8=\'e8
\par E9=\'e9
\par EA=\'ea
\par EB=\'eb
\par EC=\'ec
\par ED=\'ed
\par EE=\'ee
\par EF=\'ef
\par F0=\'f0
\par F1=\'f1
\par F2=\'f2
\par F3=\'f3
\par F4=\'f4
\par F5=\'f5
\par F6=\'f6
\par F7=\'f7
\par F8=\'f8
\par F9=\'f9
\par FA=\'fa
\par FB=\'fb
\par FC=\'fc
\par FD=\'fd
\par FE=\'fe
\par FF=\'ff
\par }

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -0,0 +1,6 @@
Fonts in this package are (c) 2010 Style.
You MAY NOT: sell this font; include/redistribute this font in any font collection regardless of pricing; provide the font for direct download from any web site. You MAY: link to "http://style64.org/c64-truetype" in order for others to download and install the font; embed this font or its .eot and .woff variants without any modification and using the same filename it was provided with for display on any web site using @font-face rules; use this font in static images and vector art; include this font without any modification and using the same filename it was provided with as part of a software package but ONLY if said software package is freely provided to end users. You may also contact us to negotiate a (possibly commercial) license for your use outside of these guidelines at "http://style64.org/contact-style".
At all times the most recent version of this license can be found at "http://style64.org/c64-truetype/license".

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -0,0 +1,72 @@
/
/(_____________ ____
\ /______)\ | |
:\ | / \:| |:::::::::: : .. . : .. . . :. .
\_____| / | \| |______
___ / ________ \... . . .
\______________ \ | | /.. . . . . .
\ |__| /
--x--x-----x----\______ |-/_____/-x--x-xx--x-- - -x -- - - -- - - -
. . . . . . . . . . . .\____|. . . . . .
-------------------------------------------------------------------------------
>> perfect dos vga 437 - general information >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
-------------------------------------------------------------------------------
"Perfect DOS VGA 437" and "Perfect DOS VGA 437 Win" are truetype fonts
designed to emulate the MS-DOS/Text mode standard font, used on VGA monitors,
with the 437 Codepage (standard US/International). This is a "bitmap" font,
meaning it emulates a bitmap font and can only be used at a given size (8 or
multiples of it like 16, 24, 32, etc). It's optimized for Flash too, so it
won't produce antialias if used at round positions.
There are two fonts available. "Perfect DOS VGA 437" uses the original DOS
codepage 437. It should be used, for example, if you're opening DOS ASCII
files on notepad or another windows-based editor. Since it's faithful to the
original DOS codes, it won't accent correctly in windows ("é" would produce
something different, not an "e" with an acute).
There's also "Perfect DOS VGA 437 Win" which is the exactly same font adapted
to a windows codepage. This should use accented characters correctly but won't
work if you're opening a DOS-based text file.
UPDATE: this is a new version, updated in august/2008. It has fixed leading
metrics for Mac systems.
-------------------------------------------------------------------------------
>> perfect dos vga 437 - creation process >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
-------------------------------------------------------------------------------
This font was created to be used on a Flash-based ANSi viewer I'm working. To
create it, I created a small Quick Basic program to write all characters on
screen,
CLS
FOR l = 0 TO 255
charWrite 1 + (l MOD 20), 1 + (l \ 20) * 6 + (l MOD 2), LTRIM$(RTRIM$(STR$(l))) + CHR$(l)
NEXT
SUB charWrite (lin, col, char$)
DEF SEG = &HB800
FOR i = 1 TO LEN(char$)
POKE ((lin - 1) * 160) + ((col - 2 + i) * 2), ASC(MID$(char$, i, 1))
IF (i = LEN(char$)) THEN POKE ((lin - 1) * 160) + ((col - 2 + i) * 2) + 1, 113
NEXT
END SUB
Then captured the text screen using SCREEN THIEF (a very, very old screen
capture TSR program which converts text screens to images accurately). I then
recreated the font polygon by polygon on Fontlab, while looking at the image
on Photoshop. No conversion took place.
-------------------------------------------------------------------------------
>> author >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
-------------------------------------------------------------------------------
zeh fernando remembers the old days. SMASH DAH FUCKING ENTAH.
http://www.fatorcaos.com.br
rorshack ^ maiden brazil
-------------------------------------------------------------------------------
^zehPULLSdahTRICK^kudosOUTtoWHOkeepsITreal^smashDAHfuckingENTAH!!!^lowres4ever^
-------------------------------------------------------------------------------

Binary file not shown.

Binary file not shown.

View File

@@ -0,0 +1,28 @@
import QtQuick 2.2
import "utils"
TerminalFrame{
id: frame
z: 2.1
anchors.fill: parent
addedWidth: 200
addedHeight: 370
borderLeft: 148
borderRight: 148
borderTop: 232
borderBottom: 232
imageSource: "../images/black-frame.png"
normalsSource: "../images/black-frame-normals.png"
rectX: 20
rectY: 20
distortionCoefficient: 1.9
displacementLeft: 70.0
displacementTop: 55.0
displacementRight: 50.0
displacementBottom: 38.0
shaderString: "FrameShader.qml"
}

22
app/frames/NoFrame.qml Normal file
View File

@@ -0,0 +1,22 @@
import QtQuick 2.2
import "utils"
TerminalFrame{
id: frame
z: 2.1
anchors.fill: parent
addedWidth: 0
addedHeight: 0
borderLeft: 0
borderRight: 0
borderTop: 0
borderBottom: 0
rectX: 15
rectY: 15
displacementLeft: 0
displacementTop: 0
displacementRight: 0
displacementBottom: 0
}

View File

@@ -0,0 +1,28 @@
import QtQuick 2.2
import "utils"
TerminalFrame{
id: frame
z: 2.1
anchors.fill: parent
addedWidth: 140
addedHeight: 140
borderLeft: 116
borderRight: 116
borderTop: 116
borderBottom: 116
imageSource: "../images/screen-frame.png"
normalsSource: "../images/screen-frame-normals.png"
rectX: 15
rectY: 15
distortionCoefficient: 1.5
displacementLeft: 45
displacementTop: 40
displacementRight: 38.0
displacementBottom: 28.0
shaderString: "FrameShader.qml"
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 132 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 507 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 571 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 811 KiB

View File

@@ -0,0 +1,91 @@
import QtQuick 2.2
import QtGraphicalEffects 1.0
ShaderEffect{
property variant source: framesource
property variant normals: framesourcenormals
property real screen_distorsion: shadersettings.screen_distortion * framecontainer.distortionCoefficient
property real ambient_light: shadersettings.ambient_light
property color font_color: shadersettings.font_color
property color background_color: shadersettings.background_color
property real brightness: shadersettings.brightness * 1.5 + 0.5
property bool frameReflections: shadersettings.frameReflections
property variant lightSource: reflectionEffectSourceLoader.item
Loader{
id: reflectionEffectLoader
width: parent.width * 0.33
height: parent.height * 0.33
active: frameReflections
sourceComponent: FastBlur{
id: frameReflectionEffect
radius: 128
source: terminal.kterminal
smooth: false
}
}
Loader{
id: reflectionEffectSourceLoader
active: frameReflections
sourceComponent: ShaderEffectSource{
id: frameReflectionSource
sourceItem: reflectionEffectLoader.item
hideSource: true
smooth: true
}
}
blending: true
fragmentShader: "
uniform sampler2D source;
uniform sampler2D normals;
uniform highp float screen_distorsion;
uniform highp float ambient_light;
uniform highp float qt_Opacity;" +
(frameReflections ?
"uniform sampler2D lightSource;" : "") + "
uniform vec4 font_color;
uniform vec4 background_color;
varying lowp float brightness;
varying highp vec2 qt_TexCoord0;
vec2 distortCoordinates(vec2 coords){
vec2 cc = coords - vec2(0.5);
float dist = dot(cc, cc) * screen_distorsion;
return (coords + cc * (1.0 + dist) * dist);
}
void main(){
vec2 coords = distortCoordinates(qt_TexCoord0);
vec4 txt_color = texture2D(source, coords);
vec4 txt_normal = texture2D(normals, coords);
vec3 normal = normalize(txt_normal.rgb * 2.0 - 1.0);
vec3 light_direction = normalize(vec3(0.5, 0.5, 0.0) - vec3(qt_TexCoord0, 0.0));
float dotProd = dot(normal, light_direction);" +
(frameReflections ? "
float screenLight = texture2D(lightSource, coords).r;
float clampedDotProd = clamp(dotProd, 0.05, 1.0);
float diffuseReflection = clamp(screenLight * 1.5 * clampedDotProd, 0.0, 0.35);
float reflectionAlpha = mix(1.0, 0.90, dotProd);"
: "
float diffuseReflection = 0.0;
float reflectionAlpha = 1.0;") + "
vec3 back_color = background_color.rgb * (0.2 + 0.5 * dotProd);
vec3 front_color = font_color.rgb * (0.05 + diffuseReflection);
vec4 dark_color = vec4((back_color + front_color) * txt_normal.a, txt_normal.a * reflectionAlpha);
gl_FragColor = mix(dark_color, txt_color, ambient_light);
}"
onStatusChanged: if (log) console.log(log) //Print warning messages
}

View File

@@ -0,0 +1,23 @@
import QtQuick 2.2
ShaderEffect{
property variant source: framesource
property real screen_distorsion: shadersettings.screen_distortion
fragmentShader: "
uniform sampler2D source;
uniform highp float screen_distorsion;
varying highp vec2 qt_TexCoord0;
vec2 distortCoordinates(vec2 coords){
vec2 cc = coords - vec2(0.5);
float dist = dot(cc, cc) * screen_distorsion;
return (coords + cc * (1.0 + dist) * dist);
}
void main(){
vec2 coords = distortCoordinates(qt_TexCoord0);
float inside = texture2D(source, coords).a;
gl_FragColor = vec4(vec3(0.0), inside);
}"
}

View File

@@ -0,0 +1,81 @@
import QtQuick 2.2
Item{
id: framecontainer
property int textureWidth: terminalWindow.width
property int textureHeight: terminalWindow.height
property int addedWidth
property int addedHeight
property int borderLeft
property int borderRight
property int borderTop
property int borderBottom
property string imageSource
property string normalsSource
property string shaderString
//Value used to create the rect used to add the border to the texture
property real rectX
property real rectY
//Values used to displace the texture in the screen. Used to make reflections correct.
property real displacementLeft
property real displacementTop
property real displacementRight
property real displacementBottom
property real distortionCoefficient
property rect sourceRect: Qt.rect(-rectX * shadersettings.window_scaling,
-rectY * shadersettings.window_scaling,
terminal.width + 2*rectX * shadersettings.window_scaling,
terminal.height + 2*rectY * shadersettings.window_scaling)
BorderImage{
id: frameimage
anchors.centerIn: parent
width: textureWidth + addedWidth
height: textureHeight + addedHeight
border.bottom: borderBottom
border.top: borderTop
border.left: borderLeft
border.right: borderRight
source: imageSource
horizontalTileMode: BorderImage.Stretch
verticalTileMode: BorderImage.Stretch
}
BorderImage{
id: framenormals
anchors.fill: frameimage
border.bottom: borderBottom
border.top: borderTop
border.left: borderLeft
border.right: borderRight
source: normalsSource
horizontalTileMode: BorderImage.Stretch
verticalTileMode: BorderImage.Stretch
}
ShaderEffectSource{
id: framesource
sourceItem: frameimage
hideSource: true
textureSize: Qt.size(parent.width, parent.height)
}
ShaderEffectSource{
id: framesourcenormals
sourceItem: framenormals
hideSource: true
textureSize: Qt.size(parent.width, parent.height)
}
Loader{
anchors.centerIn: parent
width: parent.width + (addedWidth / textureWidth) * parent.width
height: parent.height + (addedHeight / textureHeight) * parent.height
source: shaderString
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 62 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

View File

@@ -1,169 +0,0 @@
#include <QtQml/QQmlApplicationEngine>
#include <QtGui/QGuiApplication>
#include <QQmlContext>
#include <QStringList>
#include <QtWidgets/QApplication>
#include <QIcon>
#include <QQuickStyle>
#include <QtQml/qqml.h>
#include <kdsingleapplication.h>
#include <QDebug>
#include <stdlib.h>
#include <QLoggingCategory>
#include <fileio.h>
#include <fontlistmodel.h>
#include <fontmanager.h>
#if defined(Q_OS_MAC)
#include <CoreFoundation/CoreFoundation.h>
#include <QStyleFactory>
#include <QMenu>
#endif
QString getNamedArgument(QStringList args, QString name, QString defaultName)
{
int index = args.indexOf(name);
return (index != -1) ? args[index + 1] : QString(defaultName);
}
QString getNamedArgument(QStringList args, QString name)
{
return getNamedArgument(args, name, "");
}
int main(int argc, char *argv[])
{
// Some environmental variable are necessary on certain platforms.
// Disable Connections slot warnings
QLoggingCategory::setFilterRules("qt.qml.connections.warning=false");
QGuiApplication::setHighDpiScaleFactorRoundingPolicy(Qt::HighDpiScaleFactorRoundingPolicy::Round);
// #if defined (Q_OS_LINUX)
// setenv("QSG_RENDER_LOOP", "threaded", 0);
// #endif
#if defined(Q_OS_MAC)
// This allows UTF-8 characters usage in OSX.
setenv("LC_CTYPE", "UTF-8", 1);
// Ensure key repeat works for letter keys (disable macOS press-and-hold for this app).
CFPreferencesSetAppValue(CFSTR("ApplePressAndHoldEnabled"), kCFBooleanFalse, kCFPreferencesCurrentApplication);
CFPreferencesAppSynchronize(kCFPreferencesCurrentApplication);
// Qt6 macOS default look is still lacking, so let's force Fusion for now
QQuickStyle::setStyle(QStringLiteral("Fusion"));
#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]" << Qt::endl;
cout << " --default-settings Run cool-retro-term with the default settings" << Qt::endl;
cout << " --workdir <dir> Change working directory to 'dir'" << Qt::endl;
cout << " -e <cmd> Command to execute. This option will catch all following arguments, so use it as the last option." << Qt::endl;
cout << " --fullscreen Run cool-retro-term in fullscreen." << Qt::endl;
cout << " -p|--profile <prof> Run cool-retro-term with the given profile." << Qt::endl;
cout << " -h|--help Print this help." << Qt::endl;
cout << " --verbose Print additional information such as profiles and settings." << Qt::endl;
return 0;
}
QString appVersion(QStringLiteral(APP_VERSION));
if (argc>1 && (!strcmp(argv[1],"-v") || !strcmp(argv[1],"--version"))) {
QTextStream cout(stdout, QIODevice::WriteOnly);
cout << "cool-retro-term " << appVersion << Qt::endl;
return 0;
}
QApplication app(argc, argv);
app.setAttribute(Qt::AA_MacDontSwapCtrlAndMeta, true);
app.setApplicationName(QStringLiteral("cool-retro-term"));
app.setOrganizationName(QStringLiteral("cool-retro-term"));
app.setOrganizationDomain(QStringLiteral("cool-retro-term"));
app.setApplicationVersion(appVersion);
KDSingleApplication singleApp(QStringLiteral("cool-retro-term"));
if (!singleApp.isPrimaryInstance()) {
if (singleApp.sendMessage("new-window"))
return 0;
qWarning() << "KDSingleApplication: primary not reachable, continuing as independent instance.";
}
QQmlApplicationEngine engine;
FileIO fileIO;
qmlRegisterType<FontManager>("CoolRetroTerm", 1, 0, "FontManager");
qmlRegisterUncreatableType<FontListModel>("CoolRetroTerm", 1, 0, "FontListModel", "FontListModel is created by FontManager");
#if !defined(Q_OS_MAC)
app.setWindowIcon(QIcon::fromTheme("cool-retro-term", QIcon(":../icons/32x32/cool-retro-term.png")));
#if defined(Q_OS_LINUX)
QGuiApplication::setDesktopFileName(QStringLiteral("cool-retro-term"));
#endif
#else
app.setWindowIcon(QIcon(":../icons/32x32/cool-retro-term.png"));
#endif
// Manage command line arguments from the cpp side
QStringList args = app.arguments();
// Manage default command
QStringList cmdList;
if (args.contains("-e")) {
cmdList << args.mid(args.indexOf("-e") + 1);
}
QVariant command(cmdList.empty() ? QVariant() : cmdList[0]);
QVariant commandArgs(cmdList.size() <= 1 ? QVariant() : QVariant(cmdList.mid(1)));
engine.rootContext()->setContextProperty("appVersion", appVersion);
engine.rootContext()->setContextProperty("defaultCmd", command);
engine.rootContext()->setContextProperty("defaultCmdArgs", commandArgs);
engine.rootContext()->setContextProperty("workdir", getNamedArgument(args, "--workdir", "$HOME"));
engine.rootContext()->setContextProperty("fileIO", &fileIO);
// Manage import paths for Linux and OSX.
QStringList importPathList = engine.importPathList();
importPathList.append(QCoreApplication::applicationDirPath() + "/qmltermwidget");
importPathList.append(QCoreApplication::applicationDirPath() + "/../PlugIns");
importPathList.append(QCoreApplication::applicationDirPath() + "/../../../qmltermwidget");
engine.setImportPathList(importPathList);
engine.load(QUrl(QStringLiteral ("qrc:/main.qml")));
if (engine.rootObjects().isEmpty()) {
qDebug() << "Cannot load QML interface";
return EXIT_FAILURE;
}
// Quit the application when the engine closes.
QObject::connect((QObject*) &engine, SIGNAL(quit()), (QObject*) &app, SLOT(quit()));
auto requestNewWindow = [&engine]() {
if (engine.rootObjects().isEmpty())
return;
QObject *rootObject = engine.rootObjects().constFirst();
QMetaObject::invokeMethod(rootObject, "createWindow", Qt::QueuedConnection);
};
QObject::connect(&singleApp, &KDSingleApplication::messageReceived, &app,
[&requestNewWindow](const QByteArray &message) {
if (message.isEmpty() || message == QByteArray("new-window"))
requestNewWindow();
});
#if defined(Q_OS_MAC)
QMenu *dockMenu = new QMenu(nullptr);
dockMenu->addAction(QObject::tr("New Window"), [&requestNewWindow]() { requestNewWindow(); });
dockMenu->setAsDockMenu();
#endif
return app.exec();
}

193
app/main.qml Normal file
View File

@@ -0,0 +1,193 @@
/*******************************************************************************
* Copyright (c) 2013 "Filippo Scognamiglio"
* https://github.com/Swordifish90/cool-old-term
*
* This file is part of cool-old-term.
*
* cool-old-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.Window 2.1
import QtQuick.Controls 1.1
import QtGraphicalEffects 1.0
import org.kde.konsole 0.1
ApplicationWindow{
id: terminalWindow
width: 1024
height: 768
minimumWidth: 320
minimumHeight: 240
property bool fullscreen: shadersettings.fullscreen
onFullscreenChanged: visibility = (fullscreen ? Window.FullScreen : Window.Windowed)
flags: Qt.WA_TranslucentBackground
color: "#00000000"
title: qsTr("cool-old-term")
Action {
id: showMenubarAction
text: qsTr("Show Menubar")
checkable: true
checked: shadersettings.showMenubar
onTriggered: shadersettings.showMenubar = !shadersettings.showMenubar
}
Action {
id: fullscreenAction
text: qsTr("&Fullscreen")
shortcut: "Alt+F11"
onTriggered: shadersettings.fullscreen = !shadersettings.fullscreen;
checkable: true
checked: shadersettings.fullscreen
}
Action {
id: quitAction
text: qsTr("&Quit")
shortcut: "Ctrl+Q"
onTriggered: terminalWindow.close();
}
Action{
id: showsettingsAction
text: qsTr("&Settings")
onTriggered: settingswindow.show();
}
Action{
id: copyAction
text: qsTr("&Copy")
shortcut: "Ctrl+Shift+C"
onTriggered: terminal.copyClipboard()
}
Action{
id: pasteAction
text: qsTr("&Paste")
shortcut: "Ctrl+Shift+V"
onTriggered: terminal.pasteClipboard()
}
Action{
id: zoomIn
text: qsTr("&Zoom In")
shortcut: "Ctrl++"
onTriggered: {
var oldScaling = shadersettings.fontScalingIndexes[shadersettings.rasterization];
var maxScalingIndex = shadersettings.fontScalingList.length - 1;
shadersettings.setScalingIndex(Math.min(oldScaling + 1, maxScalingIndex));
}
}
Action{
id: zoomOut
text: qsTr("&Zoom Out")
shortcut: "Ctrl+-"
onTriggered: {
var oldScaling = shadersettings.fontScalingIndexes[shadersettings.rasterization];
shadersettings.setScalingIndex(Math.max(oldScaling - 1, 0));
}
}
Action{
id: showAboutAction
text: qsTr("About")
onTriggered: {
aboutDialog.show();
}
}
menuBar: MenuBar {
id: menubar
Menu {
title: qsTr("File")
visible: shadersettings.showMenubar
MenuItem {action: quitAction}
}
Menu {
title: qsTr("Edit")
visible: shadersettings.showMenubar
MenuItem {action: copyAction}
MenuItem {action: pasteAction}
MenuSeparator{}
MenuItem {action: showsettingsAction}
}
Menu{
title: qsTr("View")
visible: shadersettings.showMenubar
MenuItem {action: fullscreenAction}
MenuItem {action: showMenubarAction}
MenuSeparator{}
MenuItem {action: zoomIn}
MenuItem {action: zoomOut}
}
Menu{
title: qsTr("Help")
visible: shadersettings.showMenubar
MenuItem {action: showAboutAction}
}
}
ApplicationSettings{
id: shadersettings
}
TimeManager{
id: timeManager
enableTimer: terminalWindow.visible
}
Item{
id: maincontainer
anchors.centerIn: parent
width: parent.width * shadersettings.window_scaling
height: parent.height * shadersettings.window_scaling
scale: 1.0 / shadersettings.window_scaling
smooth: false
antialiasing: false
opacity: shadersettings.windowOpacity * 0.3 + 0.7
Loader{
id: frame
anchors.fill: parent
property rect sourceRect: item.sourceRect
z: 2.1
source: shadersettings.frame_source
}
PreprocessedTerminal{
id: terminal
anchors.fill: parent
anchors.margins: 30
}
ShaderTerminal{
id: shadercontainer
anchors.fill: parent
z: 1.9
}
}
SettingsWindow{
id: settingswindow
visible: false
}
AboutDialog{
id: aboutDialog
visible: false
}
Loader{
id: sizeoverlayloader
z: 3
anchors.centerIn: parent
active: shadersettings.show_terminal_size
sourceComponent: SizeOverlay{
terminalSize: terminal.terminalSize
}
}
Component.onCompleted: shadersettings.handleFontChanged();
}

View File

@@ -1,134 +0,0 @@
/*******************************************************************************
* 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.2
import QtQuick.Layouts 1.1
import QtQuick.Window 2.0
ApplicationWindow {
id: dialogwindow
title: qsTr("About")
width: 600
height: 400
ColumnLayout {
anchors.fill: parent
anchors.margins: 15
spacing: 15
Text {
Layout.alignment: Qt.AlignHCenter
text: "cool-retro-term"
color: palette.text
font {
bold: true
pointSize: 18
}
}
Loader {
id: mainContent
Layout.fillHeight: true
Layout.fillWidth: true
states: [
State {
name: "Default"
PropertyChanges {
target: mainContent
sourceComponent: defaultComponent
}
},
State {
name: "License"
PropertyChanges {
target: mainContent
sourceComponent: licenseComponent
}
}
]
Component.onCompleted: mainContent.state = "Default"
}
Item {
Layout.fillWidth: true
height: childrenRect.height
Button {
anchors.left: parent.left
text: qsTr("License")
onClicked: {
mainContent.state == "Default" ? mainContent.state
= "License" : mainContent.state = "Default"
}
}
Button {
anchors.right: parent.right
text: qsTr("Close")
onClicked: dialogwindow.close()
}
}
}
// MAIN COMPONENTS ////////////////////////////////////////////////////////
Component {
id: defaultComponent
ColumnLayout {
anchors.fill: parent
spacing: 10
Image {
Layout.fillWidth: true
Layout.fillHeight: true
Layout.alignment: Qt.AlignHCenter
fillMode: Image.PreserveAspectFit
source: "images/crt256.png"
smooth: true
}
Text {
Layout.alignment: Qt.AlignCenter
horizontalAlignment: Text.AlignHCenter
color: palette.text
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 {
id: licenseComponent
ScrollView {
anchors.fill: parent
clip: true
TextArea {
readOnly: true
wrapMode: TextEdit.Wrap
color: palette.text
text: "Copyright (c) 2013-2025 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/>."
}
}
}
}

View File

@@ -1,882 +0,0 @@
/*******************************************************************************
* 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.0
import CoolRetroTerm 1.0
import "utils.js" as Utils
QtObject {
readonly property string version: appVersion
readonly property int profileVersion: 2
// STATIC CONSTANTS ////////////////////////////////////////////////////////
readonly property real screenCurvatureSize: 0.6
readonly property real minimumFontScaling: 0.25
readonly property real maximumFontScaling: 2.50
readonly property int defaultMargin: 16
readonly property real minBurnInFadeTime: 0.16
readonly property real maxBurnInFadeTime: 1.6
property bool isMacOS: Qt.platform.os === "osx"
// GENERAL SETTINGS ///////////////////////////////////////////////////////
property bool showMenubar: false
property bool showTerminalSize: true
property real windowScaling: 1.0
property int effectsFrameSkip: 3
property bool verbose: false
property real bloomQuality: 0.5
property real burnInQuality: 0.5
property bool blinkingCursor: false
// PROFILE SETTINGS ///////////////////////////////////////////////////////
property real windowOpacity: 1.0
property real ambientLight: 0.2
property real contrast: 0.80
property real brightness: 0.5
property bool useCustomCommand: false
property string customCommand: ""
property string _backgroundColor: "#000000"
property string _fontColor: "#ff8100"
property string _frameColor: "#ffffff"
property string saturatedColor: Utils.mix(Utils.strToColor(_fontColor), Utils.strToColor("#FFFFFF"), (saturationColor * 0.5))
property color fontColor: Utils.mix(Utils.strToColor(_backgroundColor), Utils.strToColor(saturatedColor), (0.7 + (contrast * 0.3)))
property color backgroundColor: Utils.mix(Utils.strToColor(saturatedColor), Utils.strToColor(_backgroundColor), (0.7 + (contrast * 0.3)))
property color frameColor: Utils.strToColor(_frameColor)
property real staticNoise: 0.12
property real screenCurvature: 0.3
property real glowingLine: 0.2
property real burnIn: 0.25
property real bloom: 0.55
property real chromaColor: 0.25
property real saturationColor: 0.25
property real jitter: 0.2
property real horizontalSync: 0.08
property real flickering: 0.1
property real rgbShift: 0.0
property real _frameShininess: 0.2
property real frameShininess: _frameShininess * 0.5
property real _frameSize: 0.2
property real frameSize: _frameSize * 0.05
property real _screenRadius: 0.2
property real screenRadius: Utils.lint(4.0, 120.0, _screenRadius)
property real _margin: 0.5
property real margin: Utils.lint(1.0, 40.0, _margin) + (1.0 - Math.SQRT1_2) * screenRadius
readonly property bool frameEnabled: ambientLight > 0 || _frameSize > 0 || screenCurvature > 0
readonly property int no_rasterization: 0
readonly property int scanline_rasterization: 1
readonly property int pixel_rasterization: 2
readonly property int subpixel_rasterization: 3
readonly property int modern_rasterization: 4
property alias rasterization: fontManager.rasterization
readonly property int bundled_fonts: 0
readonly property int system_fonts: 1
property alias fontSource: fontManager.fontSource
// FONTS //////////////////////////////////////////////////////////////////
readonly property real baseFontScaling: 0.75
property alias fontScaling: fontManager.fontScaling
property real totalFontScaling: baseFontScaling * fontScaling
property alias fontWidth: fontManager.fontWidth
property alias lineSpacing: fontManager.lineSpacing
property alias lowResolutionFont: fontManager.lowResolutionFont
property alias fontName: fontManager.fontName
property alias filteredFontList: fontManager.filteredFontList
property FontManager fontManager: FontManager {
id: fontManager
baseFontScaling: baseFontScaling
}
signal initializedSettings
function incrementScaling() {
fontScaling = Math.min(fontScaling + 0.05, maximumFontScaling)
}
function decrementScaling() {
fontScaling = Math.max(fontScaling - 0.05, minimumFontScaling)
}
function close() {
storeSettings()
storeCustomProfiles()
Qt.quit()
}
property Storage storage: Storage {}
function stringify(obj) {
var replacer = function (key, val) {
return val.toFixed ? Number(val.toFixed(4)) : val
}
return JSON.stringify(obj, replacer, 2)
}
function composeSettingsString() {
var settings = {
"effectsFrameSkip": effectsFrameSkip,
"windowScaling": windowScaling,
"showTerminalSize": showTerminalSize,
"fontScaling": fontScaling,
"showMenubar": showMenubar,
"bloomQuality": bloomQuality,
"burnInQuality": burnInQuality,
"useCustomCommand": useCustomCommand,
"customCommand": customCommand
}
return stringify(settings)
}
function composeProfileObject() {
var profile = {
"backgroundColor": _backgroundColor,
"fontColor": _fontColor,
"flickering": flickering,
"horizontalSync": horizontalSync,
"staticNoise": staticNoise,
"chromaColor": chromaColor,
"saturationColor": saturationColor,
"screenCurvature": screenCurvature,
"glowingLine": glowingLine,
"burnIn": burnIn,
"bloom": bloom,
"rasterization": rasterization,
"jitter": jitter,
"rgbShift": rgbShift,
"brightness": brightness,
"contrast": contrast,
"ambientLight": ambientLight,
"windowOpacity": windowOpacity,
"fontName": fontName,
"fontSource": fontSource,
"fontWidth": fontWidth,
"margin": _margin,
"blinkingCursor": blinkingCursor,
"frameSize": _frameSize,
"screenRadius": _screenRadius,
"frameColor": _frameColor,
"frameShininess": _frameShininess
}
return profile
}
function composeProfileString() {
return stringify(composeProfileObject())
}
function loadSettings() {
var settingsString = storage.getSetting("_CURRENT_SETTINGS")
var profileString = storage.getSetting("_CURRENT_PROFILE")
if (!settingsString)
return
if (!profileString)
return
loadSettingsString(settingsString)
loadProfileString(profileString)
if (verbose)
console.log("Loading settings: " + settingsString + profileString)
}
function storeSettings() {
var settingsString = composeSettingsString()
var profileString = composeProfileString()
storage.setSetting("_CURRENT_SETTINGS", settingsString)
storage.setSetting("_CURRENT_PROFILE", profileString)
if (verbose) {
console.log("Storing settings: " + settingsString)
console.log("Storing profile: " + profileString)
}
}
function loadSettingsString(settingsString) {
var settings = JSON.parse(settingsString)
showTerminalSize = settings.showTerminalSize
!== undefined ? settings.showTerminalSize : showTerminalSize
effectsFrameSkip = settings.effectsFrameSkip !== undefined ? settings.effectsFrameSkip : effectsFrameSkip
windowScaling = settings.windowScaling
!== undefined ? settings.windowScaling : windowScaling
fontScaling = settings.fontScaling !== undefined ? settings.fontScaling : fontScaling
showMenubar = settings.showMenubar !== undefined ? settings.showMenubar : showMenubar
bloomQuality = settings.bloomQuality !== undefined ? settings.bloomQuality : bloomQuality
burnInQuality = settings.burnInQuality
!== undefined ? settings.burnInQuality : burnInQuality
useCustomCommand = settings.useCustomCommand
!== undefined ? settings.useCustomCommand : useCustomCommand
customCommand = settings.customCommand
!== undefined ? settings.customCommand : customCommand
}
function loadProfileString(profileString) {
var settings = JSON.parse(profileString)
_backgroundColor = settings.backgroundColor
!== undefined ? settings.backgroundColor : _backgroundColor
_fontColor = settings.fontColor !== undefined ? settings.fontColor : _fontColor
horizontalSync = settings.horizontalSync
!== undefined ? settings.horizontalSync : horizontalSync
flickering = settings.flickering !== undefined ? settings.flickering : flickering
staticNoise = settings.staticNoise !== undefined ? settings.staticNoise : staticNoise
chromaColor = settings.chromaColor !== undefined ? settings.chromaColor : chromaColor
saturationColor = settings.saturationColor
!== undefined ? settings.saturationColor : saturationColor
screenCurvature = settings.screenCurvature
!== undefined ? settings.screenCurvature : screenCurvature
glowingLine = settings.glowingLine !== undefined ? settings.glowingLine : glowingLine
burnIn = settings.burnIn !== undefined ? settings.burnIn : burnIn
bloom = settings.bloom !== undefined ? settings.bloom : bloom
rasterization = settings.rasterization
!== undefined ? settings.rasterization : rasterization
jitter = settings.jitter !== undefined ? settings.jitter : jitter
rgbShift = settings.rgbShift !== undefined ? settings.rgbShift : rgbShift
ambientLight = settings.ambientLight !== undefined ? settings.ambientLight : ambientLight
contrast = settings.contrast !== undefined ? settings.contrast : contrast
brightness = settings.brightness !== undefined ? settings.brightness : brightness
windowOpacity = settings.windowOpacity
!== undefined ? settings.windowOpacity : windowOpacity
fontName = settings.fontName !== undefined ? settings.fontName : fontName
fontSource = settings.fontSource !== undefined ? settings.fontSource : fontSource
fontWidth = settings.fontWidth !== undefined ? settings.fontWidth : fontWidth
lineSpacing = settings.lineSpacing !== undefined ? settings.lineSpacing : lineSpacing
_margin = settings.margin !== undefined ? settings.margin : _margin
_frameSize = settings.frameSize !== undefined ? settings.frameSize : _frameSize
_screenRadius = settings.screenRadius !== undefined ? settings.screenRadius : _screenRadius
_frameColor = settings.frameColor !== undefined ? settings.frameColor : _frameColor
_frameShininess = settings.frameShininess !== undefined ? settings.frameShininess : _frameShininess
blinkingCursor = settings.blinkingCursor !== undefined ? settings.blinkingCursor : blinkingCursor
}
function storeCustomProfiles() {
storage.setSetting("_CUSTOM_PROFILES", composeCustomProfilesString())
}
function loadCustomProfiles() {
var customProfileString = storage.getSetting("_CUSTOM_PROFILES")
if (customProfileString === undefined)
customProfileString = "[]"
loadCustomProfilesString(customProfileString)
}
function loadCustomProfilesString(customProfilesString) {
var customProfiles = JSON.parse(customProfilesString)
for (var i = 0; i < customProfiles.length; i++) {
var profile = customProfiles[i]
if (verbose)
console.log("Loading custom profile: " + stringify(profile))
profilesList.append(profile)
}
}
function composeCustomProfilesString() {
var customProfiles = []
for (var i = 0; i < profilesList.count; i++) {
var profile = profilesList.get(i)
if (profile.builtin)
continue
customProfiles.push({
"text": profile.text,
"obj_string": profile.obj_string,
"builtin": false
})
}
return stringify(customProfiles)
}
function loadProfile(index) {
var profile = profilesList.get(index)
loadProfileString(profile.obj_string)
}
function appendCustomProfile(name, profileString) {
profilesList.append({
"text": name,
"obj_string": profileString,
"builtin": false
})
}
// PROFILES ///////////////////////////////////////////////////////////////
property ListModel profilesList: ListModel {
ListElement {
text: "Default Amber"
obj_string: '{
"ambientLight": 0.3,
"backgroundColor": "#000000",
"bloom": 0.6,
"brightness": 0.5,
"burnIn": 0.3,
"chromaColor": 0.2,
"contrast": 0.8,
"flickering": 0.1,
"fontColor": "#ff8100",
"fontName": "TERMINESS_SCALED",
"fontSource": 0,
"fontWidth": 1,
"lineSpacing": 0.1,
"glowingLine": 0.2,
"horizontalSync": 0.1,
"jitter": 0.2,
"rasterization": 0,
"rgbShift": 0,
"saturationColor": 0.2,
"screenCurvature": 0.2,
"screenRadius": 0.1,
"staticNoise": 0.1,
"windowOpacity": 1,
"margin": 0.3,
"blinkingCursor": false,
"frameSize": 0.1,
"frameColor": "#cfcfcf",
"frameShininess": 0.3
}'
builtin: true
}
ListElement {
text: "Monochrome Green"
obj_string: '{
"ambientLight": 0.3,
"backgroundColor": "#000000",
"bloom": 0.5,
"brightness": 0.5,
"burnIn": 0.3,
"chromaColor": 0.0,
"contrast": 0.8,
"flickering": 0.1,
"fontColor": "#0ccc68",
"fontName": "DEPARTURE_MONO_SCALED",
"fontSource": 0,
"fontWidth": 1,
"lineSpacing": 0.1,
"glowingLine": 0.2,
"horizontalSync": 0.1,
"jitter": 0.2,
"rasterization": 0,
"rgbShift": 0,
"saturationColor": 0.0,
"screenCurvature": 0.3,
"screenRadius": 0.2,
"staticNoise": 0.1,
"windowOpacity": 1,
"margin": 0.3,
"blinkingCursor": false,
"frameSize": 0.1,
"frameColor": "#d4d4d4",
"frameShininess": 0.1
}'
builtin: true
}
ListElement {
text: "Deep Blue"
obj_string: '{
"ambientLight": 0.0,
"backgroundColor": "#000000",
"bloom": 0.6,
"brightness": 0.5,
"burnIn": 0.3,
"chromaColor": 1.0,
"contrast": 0.8,
"flickering": 0.1,
"fontColor": "#7fb4ff",
"fontName": "BIGBLUE_TERMINAL_SCALED",
"fontSource": 0,
"fontWidth": 1,
"lineSpacing": 0.1,
"glowingLine": 0.2,
"horizontalSync": 0.1,
"jitter": 0.2,
"rasterization": 0,
"rgbShift": 0,
"saturationColor": 0.2,
"screenCurvature": 0.4,
"screenRadius": 0.1,
"staticNoise": 0.1,
"windowOpacity": 1,
"margin": 0.3,
"blinkingCursor": false,
"frameSize": 0.1,
"frameColor": "#ffffff",
"frameShininess": 0.9
}'
builtin: true
}
ListElement {
text: "Commodore 64"
obj_string: '{
"ambientLight": 0.4,
"backgroundColor": "#3b3b8f",
"bloom": 0.4,
"brightness": 0.6,
"burnIn": 0.1,
"chromaColor": 0.0,
"contrast": 0.7,
"flickering": 0.1,
"fontColor": "#a9a7ff",
"fontName": "COMMODORE_64_SCALED",
"fontSource": 0,
"fontWidth": 1,
"lineSpacing": 0.1,
"glowingLine": 0.1,
"horizontalSync": 0.0,
"jitter": 0.0,
"rasterization": 1,
"rgbShift": 0,
"saturationColor": 0,
"screenCurvature": 0.5,
"screenRadius": 0.1,
"staticNoise": 0.1,
"windowOpacity": 1,
"margin": 0.3,
"blinkingCursor": false,
"frameSize": 0.5,
"frameColor": "#999999",
"frameShininess": 0.0
}'
builtin: true
}
ListElement {
text: "Commodore PET"
obj_string: '{
"ambientLight": 0.0,
"backgroundColor": "#000000",
"bloom": 0.4,
"brightness": 0.5,
"burnIn": 0.4,
"chromaColor": 0,
"contrast": 0.8,
"flickering": 0.2,
"fontColor": "#ffffff",
"fontName": "COMMODORE_PET_SCALED",
"fontSource": 0,
"fontWidth": 1.25,
"lineSpacing": 0.1,
"glowingLine": 0.3,
"horizontalSync": 0.2,
"jitter": 0.15,
"rasterization": 1,
"rgbShift": 0.0,
"saturationColor": 0,
"screenCurvature": 0.7,
"screenRadius": 0.3,
"staticNoise": 0.2,
"windowOpacity": 1,
"margin": 0.2,
"blinkingCursor": false,
"frameSize": 0.5,
"frameColor": "#000000",
"frameShininess": 0.6
}'
builtin: true
}
ListElement {
text: "Apple ]["
obj_string: '{
"ambientLight": 1.0,
"backgroundColor": "#001100",
"bloom": 0.3,
"brightness": 0.5,
"burnIn": 0.3,
"chromaColor": 0,
"contrast": 0.8,
"flickering": 0.2,
"fontColor": "#4dff6b",
"fontName": "APPLE_II_SCALED",
"fontSource": 0,
"fontWidth": 1.25,
"lineSpacing": 0.1,
"glowingLine": 0.3,
"horizontalSync": 0.2,
"jitter": 0.2,
"rasterization": 1,
"rgbShift": 0.0,
"saturationColor": 0,
"screenCurvature": 0.5,
"screenRadius": 0.3,
"staticNoise": 0.2,
"windowOpacity": 1,
"margin": 0.0,
"blinkingCursor": false,
"frameSize": 0.2,
"frameColor": "#ffffff",
"frameShininess": 0.8
}'
builtin: true
}
ListElement {
text: "Atari 400"
obj_string: '{
"ambientLight": 0.1,
"backgroundColor": "#0f1f5a",
"bloom": 0.1,
"brightness": 0.6,
"burnIn": 0.2,
"chromaColor": 0,
"contrast": 0.9,
"flickering": 0.1,
"fontColor": "#8ed6ff",
"fontName": "ATARI_400_SCALED",
"fontSource": 0,
"fontWidth": 1,
"lineSpacing": 0.1,
"glowingLine": 0.1,
"horizontalSync": 0.0,
"jitter": 0.0,
"rasterization": 1,
"rgbShift": 0.0,
"saturationColor": 0,
"screenCurvature": 0.4,
"screenRadius": 0.2,
"staticNoise": 0.1,
"windowOpacity": 1,
"margin": 0.2,
"blinkingCursor": false,
"frameSize": 0.4,
"frameColor": "#cccccc",
"frameShininess": 0.3
}'
builtin: true
}
ListElement {
text: "IBM VGA 8x16"
obj_string: '{
"ambientLight": 0.2,
"backgroundColor": "#000000",
"bloom": 0.2,
"brightness": 0.6,
"burnIn": 0.1,
"chromaColor": 0.5,
"contrast": 1.0,
"flickering": 0.1,
"fontColor": "#c0c0c0",
"fontName": "IBM_VGA_8x16",
"fontSource": 0,
"fontWidth": 1,
"lineSpacing": 0.1,
"glowingLine": 0.1,
"horizontalSync": 0.0,
"jitter": 0.0,
"rasterization": 1,
"rgbShift": 0.1,
"saturationColor": 0,
"screenCurvature": 0.3,
"screenRadius": 0.1,
"staticNoise": 0.0,
"windowOpacity": 1,
"margin": 0.2,
"blinkingCursor": false,
"frameSize": 0.1,
"frameColor": "#ffffff",
"frameShininess": 0.3
}'
builtin: true
}
ListElement {
text: "IBM 3278 Reborn"
obj_string: '{
"ambientLight": 0.2,
"backgroundColor": "#000000",
"bloom": 0.2,
"brightness": 0.5,
"burnIn": 0.5,
"chromaColor": 0,
"contrast": 0.8,
"flickering": 0,
"fontColor": "#3cff7a",
"fontName": "IBM_3278",
"fontSource": 0,
"fontWidth": 1,
"lineSpacing": 0.1,
"glowingLine": 0.0,
"horizontalSync": 0,
"jitter": 0,
"rasterization": 4,
"rgbShift": 0,
"saturationColor": 0,
"screenCurvature": 0,
"screenRadius": 0.0,
"staticNoise": 0.0,
"windowOpacity": 1,
"margin": 0.1,
"blinkingCursor": false,
"frameSize": 0,
"frameColor": "#ffffff",
"frameShininess": 0.2
}'
builtin: true
}
ListElement {
text: "Neon Cyan"
obj_string: '{
"ambientLight": 0.1,
"backgroundColor": "#001018",
"bloom": 0.6,
"brightness": 0.6,
"burnIn": 0.1,
"chromaColor": 1,
"contrast": 0.9,
"flickering": 0.1,
"fontColor": "#52f7ff",
"fontName": "IOSEVKA",
"fontSource": 0,
"fontWidth": 1,
"lineSpacing": 0.1,
"glowingLine": 0.2,
"horizontalSync": 0.0,
"jitter": 0.1,
"rasterization": 4,
"rgbShift": 0.0,
"saturationColor": 0.6,
"screenCurvature": 0,
"screenRadius": 0.0,
"staticNoise": 0.1,
"windowOpacity": 0.8,
"margin": 0.1,
"blinkingCursor": false,
"frameSize": 0,
"frameColor": "#c3c3c3",
"frameShininess": 0.2
}'
builtin: true
}
ListElement {
text: "Ghost Terminal"
obj_string: '{
"ambientLight": 0.3,
"backgroundColor": "#0b1014",
"bloom": 0.3,
"brightness": 0.6,
"burnIn": 0.2,
"chromaColor": 0,
"contrast": 0.5,
"flickering": 0.0,
"fontColor": "#a6b3c0",
"fontName": "JETBRAINS_MONO",
"fontSource": 0,
"fontWidth": 1,
"lineSpacing": 0.1,
"glowingLine": 0.1,
"horizontalSync": 0.0,
"jitter": 0.0,
"rasterization": 4,
"rgbShift": 0.0,
"saturationColor": 0.0,
"screenCurvature": 0,
"screenRadius": 0.0,
"staticNoise": 0.1,
"windowOpacity": 0.7,
"margin": 0.1,
"blinkingCursor": false,
"frameSize": 0,
"frameColor": "#a7a7a7",
"frameShininess": 0.2
}'
builtin: true
}
ListElement {
text: "Plasma"
obj_string: '{
"ambientLight": 0.1,
"backgroundColor": "#070014",
"bloom": 0.7,
"brightness": 0.6,
"burnIn": 0.1,
"chromaColor": 1,
"contrast": 0.8,
"flickering": 0.1,
"fontColor": "#ff9bd6",
"fontName": "FIRA_CODE",
"fontSource": 0,
"fontWidth": 1,
"lineSpacing": 0.1,
"glowingLine": 0.2,
"horizontalSync": 0.0,
"jitter": 0.1,
"rasterization": 4,
"rgbShift": 0.1,
"saturationColor": 0.8,
"screenCurvature": 0,
"screenRadius": 0.0,
"staticNoise": 0.1,
"windowOpacity": 1.0,
"margin": 0.1,
"blinkingCursor": false,
"frameSize": 0,
"frameColor": "#d0d0d0",
"frameShininess": 0.2
}'
builtin: true
}
ListElement {
text: "Boring"
obj_string: '{
"ambientLight": 0.1,
"backgroundColor": "#000000",
"bloom": 0.5,
"brightness": 0.5,
"burnIn": 0.05,
"chromaColor": 1,
"contrast": 0.8,
"flickering": 0.0,
"fontColor": "#ffffff",
"fontName": "JETBRAINS_MONO",
"fontSource": 0,
"fontWidth": 1,
"lineSpacing": 0.1,
"glowingLine": 0.1,
"horizontalSync": 0,
"jitter": 0.0,
"rasterization": 4,
"rgbShift": 0,
"saturationColor": 0.0,
"screenCurvature": 0,
"screenRadius": 0.0,
"staticNoise": 0.0,
"windowOpacity": 1.0,
"margin": 0.0,
"blinkingCursor": false,
"frameSize": 0,
"frameColor": "#c0c0c0",
"frameShininess": 0.2
}'
builtin: true
}
ListElement {
text: "E-Ink"
obj_string: '{
"ambientLight": 0.6,
"backgroundColor": "#f2f2ec",
"bloom": 0.0,
"brightness": 1.0,
"burnIn": 0.6,
"chromaColor": 0,
"contrast": 0.5,
"flickering": 0.0,
"fontColor": "#101010",
"fontName": "HACK",
"fontSource": 0,
"fontWidth": 1,
"lineSpacing": 0.1,
"glowingLine": 0.0,
"horizontalSync": 0.0,
"jitter": 0.0,
"rasterization": 4,
"rgbShift": 0,
"saturationColor": 0,
"screenCurvature": 0,
"screenRadius": 0.0,
"staticNoise": 0.0,
"windowOpacity": 1,
"margin": 0.1,
"blinkingCursor": false,
"frameSize": 0,
"frameColor": "#cdcdcd",
"frameShininess": 0.2
}'
builtin: true
}
}
function getProfileIndexByName(name) {
for (var i = 0; i < profilesList.count; i++) {
if (profilesList.get(i).text === name)
return i
}
return -1
}
Component.onCompleted: {
// Manage the arguments from the QML side.
var args = Qt.application.arguments
if (args.indexOf("--verbose") !== -1) {
verbose = true
}
if (args.indexOf("--default-settings") === -1) {
loadSettings()
}
loadCustomProfiles()
var profileArgPosition = args.indexOf("--profile")
if (profileArgPosition !== -1) {
var profileIndex = getProfileIndexByName(args[profileArgPosition + 1])
if (profileIndex !== -1) {
loadProfile(profileIndex)
} else {
console.log("Warning: selected profile is not valid; ignoring it")
}
}
initializedSettings()
}
// VARS ///////////////////////////////////////////////////////////////////
property Label _sampleLabel: Label {
text: "100%"
}
property real labelWidth: _sampleLabel.width
}

View File

@@ -1,129 +0,0 @@
/*******************************************************************************
* 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
Loader {
id: burnInEffect
property ShaderEffectSource effectSource: item ? item.source : null
property real lastUpdate: 0
property real prevLastUpdate: 0
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.burnIn !== 0
anchors.fill: parent
function completelyUpdate() {
let newTime = timeManager.time
if (newTime > lastUpdate) {
prevLastUpdate = lastUpdate
lastUpdate = newTime
}
item.source.scheduleUpdate()
}
function restartBlurSource() {
prevLastUpdate = timeManager.time
lastUpdate = prevLastUpdate
completelyUpdate()
}
sourceComponent: Item {
property alias source: burnInEffectSource
ShaderEffectSource {
id: burnInEffectSource
anchors.fill: parent
sourceItem: burnInShaderEffect
live: false
recursive: true
hideSource: true
wrapMode: ShaderEffectSource.ClampToEdge
format: ShaderEffectSource.RGBA
smooth: true
visible: false
Connections {
target: kterminal
onImagePainted: {
completelyUpdate()
}
}
// Restart blurred source settings change.
Connections {
target: appSettings.fontManager
onTerminalFontChanged: {
burnInEffect.restartBlurSource()
}
}
Connections {
target: appSettings
onBurnInChanged: {
burnInEffect.restartBlurSource()
}
onRasterizationChanged: {
burnInEffect.restartBlurSource()
}
onBurnInQualityChanged: {
burnInEffect.restartBlurSource()
}
}
}
ShaderEffect {
id: burnInShaderEffect
property real time: timeManager.time
property variant txt_source: kterminalSource
property variant burnInSource: burnInEffectSource
property real burnInTime: burnInFadeTime
property real burnInLastUpdate: burnInEffect.lastUpdate
property real prevLastUpdate: burnInEffect.prevLastUpdate
anchors.fill: parent
blending: false
fragmentShader: "qrc:/shaders/burn_in.frag.qsb"
vertexShader: "qrc:/shaders/burn_in.vert.qsb"
onStatusChanged: if (log) console.log(log) //Print warning messages
}
}
}

View File

@@ -1,72 +0,0 @@
/*******************************************************************************
* 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.0
import QtQuick.Layouts 1.1
import "Components"
RowLayout {
property alias name: check.text
property double value
property alias min_value: slider.from
property alias max_value: slider.to
property alias stepSize: slider.stepSize
signal newValue(real newValue)
id: setting_component
Layout.fillWidth: true
onValueChanged: {
check.checked = !(value == 0)
if (check.checked)
slider.value = value
}
CheckBox {
id: check
implicitWidth: 160
onClicked: {
if (!checked) {
checked = false
slider.enabled = false
newValue(0)
} else {
checked = true
newValue(slider.value)
slider.enabled = true
}
}
}
Slider {
id: slider
stepSize: parent.stepSize
Layout.fillWidth: true
onValueChanged: {
newValue(value)
}
}
SizedLabel {
text: Math.round(
((value - min_value) / (max_value - min_value)) * 100) + "%"
}
}

View File

@@ -1,32 +0,0 @@
/*******************************************************************************
* 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 QtQuick.Controls 2.0
import QtQuick.Layouts 1.0
// This component is simply a label with a predefined size.
// Used to improve alignment.
Label {
id: textfield
Layout.minimumWidth: appSettings.labelWidth
width: appSettings.labelWidth
}

View File

@@ -1,93 +0,0 @@
/*******************************************************************************
* 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.Window 2.0
import QtQuick.Controls 2.0
import QtQuick.Layouts 1.1
import QtQuick.Dialogs
Window {
id: insertnamedialog
width: 400
height: 100
modality: Qt.ApplicationModal
title: qsTr("Save new profile")
property alias profileName: namefield.text
signal nameSelected(string name)
MessageDialog {
id: errorDialog
title: qsTr("Error")
visible: false
function showError(message) {
text = message
open()
}
}
function validateName(name) {
var profile_list = appSettings.profilesList
if (name === "")
return 1
return 0
}
ColumnLayout {
anchors.margins: 10
anchors.fill: parent
RowLayout {
Label {
text: qsTr("Name")
}
TextField {
id: namefield
Layout.fillWidth: true
Component.onCompleted: forceActiveFocus()
onAccepted: okbutton.clickAction()
}
}
RowLayout {
Layout.alignment: Qt.AlignBottom | Qt.AlignRight
Button {
id: okbutton
text: qsTr("OK")
onClicked: clickAction()
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
default:
nameSelected(name)
close()
}
}
}
Button {
text: qsTr("Cancel")
onClicked: close()
}
}
}
}

View File

@@ -1,291 +0,0 @@
/*******************************************************************************
* 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.0
import QMLTermWidget 2.0
import "menus"
import "utils.js" as Utils
Item{
id: terminalContainer
signal sessionFinished()
property size virtualResolution: Qt.size(kterminal.totalWidth, kterminal.totalHeight)
property alias mainTerminal: kterminal
property ShaderEffectSource mainSource: kterminalSource
property BurnInEffect burnInEffect: burnInEffect
property real fontWidth: 1.0
property real screenScaling: 1.0
property real scaleTexture: 1.0
property alias title: ksession.title
property alias kterminal: kterminal
property size terminalSize: kterminal.terminalSize
property size fontMetrics: kterminal.fontMetrics
// Manage copy and paste
Connections {
target: copyAction
onTriggered: {
kterminal.copyClipboard()
}
}
Connections {
target: pasteAction
onTriggered: {
kterminal.pasteClipboard()
}
}
//When settings are updated sources need to be redrawn.
Connections {
target: appSettings
onFontScalingChanged: {
terminalContainer.updateSources()
}
onFontWidthChanged: {
terminalContainer.updateSources()
}
}
Connections {
target: terminalContainer
onWidthChanged: {
terminalContainer.updateSources()
}
onHeightChanged: {
terminalContainer.updateSources()
}
}
function updateSources() {
kterminal.update()
}
QMLTermWidget {
id: kterminal
property int textureResolutionScale: appSettings.lowResolutionFont ? Screen.devicePixelRatio : 1
property int margin: appSettings.margin / screenScaling
property int totalWidth: Math.floor(parent.width / (screenScaling * fontWidth))
property int totalHeight: Math.floor(parent.height / screenScaling)
property int rawWidth: totalWidth - 2 * margin
property int rawHeight: totalHeight - 2 * margin
textureSize: Qt.size(width / textureResolutionScale, height / textureResolutionScale)
width: ensureMultiple(rawWidth, Screen.devicePixelRatio)
height: ensureMultiple(rawHeight, Screen.devicePixelRatio)
/** Ensure size is a multiple of factor. This is needed for pixel perfect scaling on highdpi screens. */
function ensureMultiple(size, factor) {
return Math.round(size / factor) * factor;
}
fullCursorHeight: true
blinkingCursor: appSettings.blinkingCursor
colorScheme: "cool-retro-term"
session: QMLTermSession {
id: ksession
onFinished: {
terminalContainer.sessionFinished()
}
}
QMLTermScrollbar {
id: kterminalScrollbar
terminal: kterminal
anchors.margins: width * 0.5
width: terminal.fontMetrics.width * 0.75
Rectangle {
anchors.fill: parent
anchors.topMargin: 1
anchors.bottomMargin: 1
color: "white"
opacity: 0.7
}
}
function handleFontChanged(fontFamily, pixelSize, lineSpacing, screenScaling, fontWidth, fallbackFontFamily, lowResolutionFont) {
kterminal.lineSpacing = lineSpacing;
kterminal.antialiasText = !lowResolutionFont;
kterminal.smooth = !lowResolutionFont;
kterminal.enableBold = !lowResolutionFont;
kterminal.enableItalic = !lowResolutionFont;
kterminal.font = Qt.font({
family: fontFamily,
pixelSize: pixelSize
});
terminalContainer.fontWidth = fontWidth;
terminalContainer.screenScaling = screenScaling;
scaleTexture = Math.max(1.0, Math.floor(screenScaling * appSettings.windowScaling));
}
Connections {
target: appSettings
onWindowScalingChanged: {
scaleTexture = Math.max(1.0, Math.floor(terminalContainer.screenScaling * appSettings.windowScaling));
}
}
function startSession() {
// Retrieve the variable set in main.cpp if arguments are passed.
if (defaultCmd) {
ksession.setShellProgram(defaultCmd);
ksession.setArgs(defaultCmdArgs);
} else if (appSettings.useCustomCommand) {
var args = Utils.tokenizeCommandLine(appSettings.customCommand);
ksession.setShellProgram(args[0]);
ksession.setArgs(args.slice(1));
} else if (!defaultCmd && appSettings.isMacOS) {
// OSX Requires the following default parameters for auto login.
ksession.setArgs(["-i", "-l"]);
}
if (workdir)
ksession.initialWorkingDirectory = workdir;
ksession.startShellProgram();
forceActiveFocus();
}
Component.onCompleted: {
appSettings.fontManager.terminalFontChanged.connect(handleFontChanged);
appSettings.fontManager.refresh()
startSession();
}
Component.onDestruction: {
appSettings.fontManager.terminalFontChanged.disconnect(handleFontChanged);
}
}
Component {
id: shortContextMenu
ShortContextMenu { }
}
Component {
id: fullContextMenu
FullContextMenu { }
}
Loader {
id: menuLoader
sourceComponent: (appSettings.isMacOS || (appSettings.showMenubar && !terminalWindow.fullscreen) ? shortContextMenu : fullContextMenu)
}
property alias contextmenu: menuLoader.item
MouseArea {
property real margin: appSettings.margin
property real frameSize: appSettings.frameSize * terminalWindow.normalizedWindowScale
acceptedButtons: Qt.LeftButton | Qt.MiddleButton | Qt.RightButton
anchors.fill: parent
cursorShape: kterminal.terminalUsesMouse ? Qt.ArrowCursor : Qt.IBeamCursor
onWheel: function(wheel) {
if (wheel.modifiers & Qt.ControlModifier) {
wheel.angleDelta.y > 0 ? zoomIn.trigger() : zoomOut.trigger();
} else {
var coord = correctDistortion(wheel.x, wheel.y);
kterminal.simulateWheel(coord.x, coord.y, wheel.buttons, wheel.modifiers, wheel.angleDelta);
}
}
onDoubleClicked: function(mouse) {
var coord = correctDistortion(mouse.x, mouse.y);
kterminal.simulateMouseDoubleClick(coord.x, coord.y, mouse.button, mouse.buttons, mouse.modifiers);
}
onPressed: function(mouse) {
kterminal.forceActiveFocus()
if ((!kterminal.terminalUsesMouse || mouse.modifiers & Qt.ShiftModifier) && mouse.button == Qt.RightButton) {
contextmenu.popup();
} else {
var coord = correctDistortion(mouse.x, mouse.y);
kterminal.simulateMousePress(coord.x, coord.y, mouse.button, mouse.buttons, mouse.modifiers)
}
}
onReleased: function(mouse) {
var coord = correctDistortion(mouse.x, mouse.y);
kterminal.simulateMouseRelease(coord.x, coord.y, mouse.button, mouse.buttons, mouse.modifiers);
}
onPositionChanged: function(mouse) {
var coord = correctDistortion(mouse.x, mouse.y);
kterminal.simulateMouseMove(coord.x, coord.y, mouse.button, mouse.buttons, mouse.modifiers);
}
function correctDistortion(x, y) {
x = (x - margin) / width;
y = (y - margin) / height;
x = x * (1 + frameSize * 2) - frameSize;
y = y * (1 + frameSize * 2) - frameSize;
var cc = Qt.size(0.5 - x, 0.5 - y);
var distortion = (cc.height * cc.height + cc.width * cc.width)
* appSettings.screenCurvature * appSettings.screenCurvatureSize
* terminalWindow.normalizedWindowScale;
return Qt.point((x - cc.width * (1+distortion) * distortion) * (kterminal.totalWidth),
(y - cc.height * (1+distortion) * distortion) * (kterminal.totalHeight))
}
}
ShaderEffectSource{
id: kterminalSource
sourceItem: kterminal
hideSource: true
wrapMode: ShaderEffectSource.Repeat
visible: false
textureSize: Qt.size(kterminal.totalWidth * scaleTexture, kterminal.totalHeight * scaleTexture)
sourceRect: Qt.rect(-kterminal.margin, -kterminal.margin, kterminal.totalWidth, kterminal.totalHeight)
}
Item {
id: burnInContainer
property int burnInScaling: scaleTexture * appSettings.burnInQuality
width: Math.round(appSettings.lowResolutionFont
? kterminal.totalWidth * Math.max(1, burnInScaling)
: kterminal.totalWidth * scaleTexture * appSettings.burnInQuality)
height: Math.round(appSettings.lowResolutionFont
? kterminal.totalHeight * Math.max(1, burnInScaling)
: kterminal.totalHeight * scaleTexture * appSettings.burnInQuality)
BurnInEffect {
id: burnInEffect
}
}
}

View File

@@ -1,151 +0,0 @@
/*******************************************************************************
* 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.0
import QtQuick.Layouts 1.1
import QtQml 2.0
import "Components"
ColumnLayout {
GroupBox {
Layout.fillWidth: true
Layout.fillHeight: true
title: qsTr("Miscellaneous")
padding: appSettings.defaultMargin
ColumnLayout {
anchors.fill: parent
CheckBox {
id: useCustomCommand
text: qsTr("Use custom command instead of shell at startup")
checked: appSettings.useCustomCommand
onCheckedChanged: appSettings.useCustomCommand = checked
}
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)
}
CheckBox {
id: blinkingCursor
text: qsTr("Blinking Cursor")
checked: appSettings.blinkingCursor
onCheckedChanged: appSettings.blinkingCursor = checked
}
CheckBox {
id: showMenubar
text: qsTr("Show Menubar")
enabled: !appSettings.isMacOS
checked: appSettings.showMenubar
onCheckedChanged: appSettings.showMenubar = checked
}
}
}
GroupBox {
title: qsTr("Performance")
Layout.fillWidth: true
Layout.fillHeight: true
padding: appSettings.defaultMargin
GridLayout {
anchors.fill: parent
columns: 4
Label {
text: qsTr("Effects FPS")
}
Slider {
Layout.fillWidth: true
Layout.columnSpan: 2
id: effectsFpsSlider
onValueChanged: appSettings.effectsFrameSkip = Math.round(value)
stepSize: 1
enabled: true
from: 5
to: 1
value: appSettings.effectsFrameSkip
}
SizedLabel {
text: Math.round(100 / Math.max(1, Math.round(effectsFpsSlider.value))) + "%"
}
Label {
text: qsTr("Texture Quality")
}
Slider {
id: txtslider
Layout.fillWidth: true
Layout.columnSpan: 2
onValueChanged: appSettings.windowScaling = value
stepSize: 0.05
enabled: true
from: 0.25
value: appSettings.windowScaling
}
SizedLabel {
text: Math.round(txtslider.value * 100) + "%"
}
Label {
text: qsTr("Bloom Quality")
}
Slider {
Layout.fillWidth: true
Layout.columnSpan: 2
id: bloomSlider
onValueChanged: appSettings.bloomQuality = value
stepSize: 0.05
enabled: true
from: 0.25
value: appSettings.bloomQuality
}
SizedLabel {
text: Math.round(bloomSlider.value * 100) + "%"
}
Label {
text: qsTr("BurnIn Quality")
}
Slider {
Layout.fillWidth: true
id: burnInSlider
Layout.columnSpan: 2
onValueChanged: appSettings.burnInQuality = value
stepSize: 0.05
enabled: true
from: 0.25
value: appSettings.burnInQuality
}
SizedLabel {
text: Math.round(burnInSlider.value * 100) + "%"
}
}
}
}

View File

@@ -1,96 +0,0 @@
/*******************************************************************************
* 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.0
import QtQuick.Layouts 1.1
ColumnLayout {
Layout.fillWidth: true
Layout.fillHeight: true
spacing: 2
GroupBox {
title: qsTr("Effects")
Layout.fillWidth: true
Layout.fillHeight: true
padding: appSettings.defaultMargin
ColumnLayout {
anchors.fill: parent
CheckableSlider {
name: qsTr("Bloom")
onNewValue: function(newValue) { appSettings.bloom = newValue }
value: appSettings.bloom
}
CheckableSlider {
name: qsTr("BurnIn")
onNewValue: function(newValue) { appSettings.burnIn = newValue }
value: appSettings.burnIn
}
CheckableSlider {
name: qsTr("Static Noise")
onNewValue: function(newValue) { appSettings.staticNoise = newValue }
value: appSettings.staticNoise
}
CheckableSlider {
name: qsTr("Jitter")
onNewValue: function(newValue) { appSettings.jitter = newValue }
value: appSettings.jitter
}
CheckableSlider {
name: qsTr("Glow Line")
onNewValue: function(newValue) { appSettings.glowingLine = newValue }
value: appSettings.glowingLine
}
CheckableSlider {
name: qsTr("Screen Curvature")
onNewValue: function(newValue) { appSettings.screenCurvature = newValue }
value: appSettings.screenCurvature
}
CheckableSlider {
name: qsTr("Ambient Light")
onNewValue: function(newValue) { appSettings.ambientLight = newValue }
value: appSettings.ambientLight
enabled: appSettings.framesIndex !== 0
}
CheckableSlider {
name: qsTr("Flickering")
onNewValue: function(newValue) { appSettings.flickering = newValue }
value: appSettings.flickering
}
CheckableSlider {
name: qsTr("Horizontal Sync")
onNewValue: function(newValue) { appSettings.horizontalSync = newValue }
value: appSettings.horizontalSync
}
CheckableSlider {
name: qsTr("RGB Shift")
onNewValue: function(newValue) { appSettings.rgbShift = newValue }
value: appSettings.rgbShift
}
CheckableSlider {
name: qsTr("Frame Shininess")
onNewValue: function(newValue) { appSettings._frameShininess = newValue }
value: appSettings._frameShininess
}
}
}
}

View File

@@ -1,278 +0,0 @@
/*******************************************************************************
* 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.4
import QtQuick.Layouts 1.1
import QtQuick.Dialogs
ColumnLayout {
GroupBox {
Layout.fillWidth: true
Layout.fillHeight: true
title: qsTr("Profile")
padding: appSettings.defaultMargin
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
}
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)
var profileObject = JSON.parse(fileIO.read(url))
var name = profileObject.name
if (!name)
throw "Profile doesn't have a 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.currentIndex
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()
}
}
}
}
}
}
GroupBox {
title: qsTr("Screen")
Layout.fillWidth: true
Layout.fillHeight: true
padding: appSettings.defaultMargin
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("Radius")
}
SimpleSlider {
onValueChanged: appSettings._screenRadius = value
value: appSettings._screenRadius
}
Label {
text: qsTr("Frame size")
}
SimpleSlider {
onValueChanged: appSettings._frameSize = value
value: appSettings._frameSize
}
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")
buttons: MessageDialog.Ok
onAccepted: {
messageDialog.close()
}
}
Loader {
property var callBack
property bool selectExisting: false
id: fileDialog
sourceComponent: FileDialog {
nameFilters: ["Json files (*.json)"]
fileMode: fileDialog.selectExisting ? FileDialog.OpenFile : FileDialog.SaveFile
onAccepted: callBack(selectedFile)
}
onSelectExistingChanged: reload()
function open() {
item.open()
}
function reload() {
active = false
active = true
}
}
}

View File

@@ -1,222 +0,0 @@
/*******************************************************************************
* 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.1
import QtQuick.Layouts 1.1
import QtQml 2.0
import "Components"
ColumnLayout {
GroupBox {
title: qsTr("Font")
Layout.fillWidth: true
Layout.fillHeight: true
padding: appSettings.defaultMargin
GridLayout {
anchors.fill: parent
columns: 2
Label {
text: qsTr("Source")
}
RowLayout {
Layout.fillWidth: true
RadioButton {
text: qsTr("Bundled")
checked: appSettings.fontSource === appSettings.bundled_fonts
onClicked: {
appSettings.fontSource = appSettings.bundled_fonts
}
}
RadioButton {
text: qsTr("System")
checked: appSettings.fontSource === appSettings.system_fonts
onClicked: {
appSettings.fontSource = appSettings.system_fonts
}
}
}
Label {
text: qsTr("Rendering")
enabled: appSettings.fontSource === appSettings.bundled_fonts
}
ComboBox {
id: renderingBox
property string selectedElement: model[currentIndex]
Layout.fillWidth: true
model: [qsTr("Default"), qsTr("Scanlines"), qsTr("Pixels"), qsTr("Sub-Pixels"), qsTr("Modern")]
currentIndex: appSettings.rasterization
onCurrentIndexChanged: {
appSettings.rasterization = currentIndex
}
enabled: appSettings.fontSource === appSettings.bundled_fonts
}
Label {
text: qsTr("Name")
}
ComboBox {
id: fontChanger
Layout.fillWidth: true
model: appSettings.filteredFontList
textRole: "text"
onActivated: {
var font = appSettings.filteredFontList.get(currentIndex)
// If selecting a high-res font while not in Modern mode,
// switch to Modern to render at full resolution.
if (!font.lowResolutionFont && appSettings.rasterization !== appSettings.modern_rasterization) {
appSettings.rasterization = appSettings.modern_rasterization
}
// If selecting a low-res font while in Modern mode, switch back to default.
if (font.lowResolutionFont && appSettings.rasterization === appSettings.modern_rasterization) {
appSettings.rasterization = appSettings.no_rasterization
}
appSettings.fontName = font.name
}
function updateIndex() {
for (var i = 0; i < appSettings.filteredFontList.count; i++) {
var font = appSettings.filteredFontList.get(i)
if (font.name === appSettings.fontName) {
currentIndex = i
return
}
}
currentIndex = 0
}
Connections {
target: appSettings.fontManager
onTerminalFontChanged: {
fontChanger.updateIndex()
}
onFilteredFontListChanged: {
fontChanger.updateIndex()
}
}
Component.onCompleted: updateIndex()
}
Label {
text: qsTr("Scaling")
}
RowLayout {
Layout.fillWidth: true
Slider {
Layout.fillWidth: true
id: fontScalingChanger
onValueChanged: appSettings.fontScaling = value
value: appSettings.fontScaling
stepSize: 0.05
from: appSettings.minimumFontScaling
to: appSettings.maximumFontScaling
}
SizedLabel {
text: Math.round(fontScalingChanger.value * 100) + "%"
}
}
Label {
text: qsTr("Font Width")
}
RowLayout {
Layout.fillWidth: true
Slider {
Layout.fillWidth: true
id: widthChanger
onValueChanged: appSettings.fontWidth = value
value: appSettings.fontWidth
stepSize: 0.05
from: 0.5
to: 1.5
}
SizedLabel {
text: Math.round(widthChanger.value * 100) + "%"
}
}
Label {
text: qsTr("Line Spacing")
}
RowLayout {
Layout.fillWidth: true
Slider {
Layout.fillWidth: true
id: lineSpacingChanger
onValueChanged: appSettings.lineSpacing = value
value: appSettings.lineSpacing
stepSize: 0.01
from: 0.0
to: 1.0
}
SizedLabel {
text: Math.round(lineSpacingChanger.value * 100) + "%"
}
}
}
}
GroupBox {
title: qsTr("Colors")
Layout.fillWidth: true
Layout.fillHeight: true
padding: appSettings.defaultMargin
ColumnLayout {
anchors.fill: parent
ColumnLayout {
Layout.fillWidth: true
CheckableSlider {
name: qsTr("Chroma Color")
onNewValue: function(newValue) { appSettings.chromaColor = newValue }
value: appSettings.chromaColor
}
CheckableSlider {
name: qsTr("Saturation Color")
onNewValue: function(newValue) { appSettings.saturationColor = newValue }
value: appSettings.saturationColor
enabled: appSettings.chromaColor !== 0
}
}
RowLayout {
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
}
ColorButton {
name: qsTr("Frame")
height: 50
Layout.fillWidth: true
onColorSelected: appSettings._frameColor = color
color: appSettings._frameColor
}
}
}
}
}

View File

@@ -1,76 +0,0 @@
/*******************************************************************************
* 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.1
import QtQuick.Window 2.1
import QtQuick.Layouts 1.3
import QtQuick.Dialogs
ApplicationWindow {
readonly property real tabButtonPadding: 10
id: settings_window
title: qsTr("Settings")
width: 640
height: 520
Item {
anchors { fill: parent; }
TabBar {
id: bar
anchors { left: parent.left; right: parent.right; top: parent.top; }
TabButton {
padding: tabButtonPadding
text: qsTr("General")
}
TabButton {
padding: tabButtonPadding
text: qsTr("Terminal")
}
TabButton {
padding: tabButtonPadding
text: qsTr("Effects")
}
TabButton {
padding: tabButtonPadding
text: qsTr("Advanced")
}
}
StackLayout {
anchors {
top: bar.bottom
left: parent.left
right: parent.right
bottom: parent.bottom
margins: 16
}
currentIndex: bar.currentIndex
SettingsGeneralTab { }
SettingsTerminalTab { }
SettingsEffectsTab { }
SettingsAdvancedTab { }
}
}
}

View File

@@ -1,200 +0,0 @@
/*******************************************************************************
* 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 "utils.js" as Utils
Item {
function dynamicFragmentPath() {
var rasterMode = appSettings.rasterization;
var burnInOn = appSettings.burnIn > 0 ? 1 : 0;
var frameOn = appSettings.frameEnabled ? 1 : 0;
var chromaOn = appSettings.chromaColor > 0 ? 1 : 0;
return "qrc:/shaders/terminal_dynamic_raster" + rasterMode +
"_burn" + burnInOn +
"_frame" + frameOn +
"_chroma" + chromaOn +
".frag.qsb";
}
function staticFragmentPath() {
var rgbShiftOn = appSettings.rgbShift > 0 ? 1 : 0;
var bloomOn = appSettings.bloom > 0 ? 1 : 0;
var curvatureOn = (appSettings.screenCurvature > 0 || appSettings.frameSize > 0) ? 1 : 0;
var shineOn = appSettings.frameShininess > 0 ? 1 : 0;
return "qrc:/shaders/terminal_static_rgb" + rgbShiftOn +
"_bloom" + bloomOn +
"_curve" + curvatureOn +
"_shine" + shineOn +
".frag.qsb";
}
property ShaderEffectSource source
property BurnInEffect burnInEffect
property ShaderEffectSource bloomSource
property color fontColor: appSettings.fontColor
property color backgroundColor: appSettings.backgroundColor
property real screenCurvature: appSettings.screenCurvature * appSettings.screenCurvatureSize * terminalWindow.normalizedWindowScale
property real frameSize: appSettings.frameSize * terminalWindow.normalizedWindowScale
property real chromaColor: appSettings.chromaColor
property real ambientLight: appSettings.ambientLight * 0.2
property size virtualResolution
property size screenResolution
property real _screenDensity: Math.min(
screenResolution.width / virtualResolution.width,
screenResolution.height / virtualResolution.height
)
ShaderEffect {
id: dynamicShader
property ShaderEffectSource screenBuffer: frameBuffer
property ShaderEffectSource burnInSource: burnInEffect.effectSource
property ShaderEffectSource frameSource: terminalFrameLoader.item
property color fontColor: parent.fontColor
property color backgroundColor: parent.backgroundColor
property real screenCurvature: parent.screenCurvature
property real chromaColor: parent.chromaColor
property real ambientLight: parent.ambientLight
property real flickering: appSettings.flickering
property real horizontalSync: appSettings.horizontalSync
property real horizontalSyncStrength: Utils.lint(0.05, 0.35, horizontalSync)
property real glowingLine: appSettings.glowingLine * 0.2
// Fast burnin properties
property real burnIn: appSettings.burnIn
property real burnInLastUpdate: burnInEffect.lastUpdate
property real burnInTime: burnInEffect.burnInFadeTime
property real jitter: appSettings.jitter
property size jitterDisplacement: Qt.size(0.007 * jitter, 0.002 * jitter)
property real staticNoise: appSettings.staticNoise
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 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 time: timeManager ? timeManager.time : 0
property ShaderEffectSource noiseSource: noiseShaderSource
property real frameSize: parent.frameSize
property real frameShininess: appSettings.frameShininess
property real bloom: parent.bloomSource ? appSettings.bloom * 2.5 : 0
anchors.fill: parent
blending: false
Image {
id: noiseTexture
source: "images/allNoise512.png"
width: 512
height: 512
fillMode: Image.Tile
visible: false
}
ShaderEffectSource {
id: noiseShaderSource
sourceItem: noiseTexture
wrapMode: ShaderEffectSource.Repeat
visible: false
smooth: true
}
vertexShader: "qrc:/shaders/terminal_dynamic.vert.qsb"
fragmentShader: dynamicFragmentPath()
onStatusChanged: if (log) console.log(log)
}
Loader {
id: terminalFrameLoader
active: appSettings.frameEnabled
width: staticShader.width
height: staticShader.height
sourceComponent: ShaderEffectSource {
sourceItem: terminalFrame
hideSource: true
visible: false
format: ShaderEffectSource.RGBA
TerminalFrame {
id: terminalFrame
blending: false
anchors.fill: parent
}
}
}
ShaderEffect {
id: staticShader
width: parent.width * appSettings.windowScaling
height: parent.height * appSettings.windowScaling
property ShaderEffectSource source: parent.source
property ShaderEffectSource bloomSource: parent.bloomSource
property color fontColor: parent.fontColor
property color backgroundColor: parent.backgroundColor
property real bloom: bloomSource ? appSettings.bloom * 2.5 : 0
property real screenCurvature: parent.screenCurvature
property real chromaColor: appSettings.chromaColor;
property real rgbShift: appSettings.rgbShift * (4.0 / width) * appSettings.totalFontScaling
property real screen_brightness: Utils.lint(0.5, 1.5, appSettings.brightness)
property real frameShininess: appSettings.frameShininess
property real frameSize: parent.frameSize
blending: false
visible: false
vertexShader: "qrc:/shaders/terminal_static.vert.qsb"
fragmentShader: staticFragmentPath()
onStatusChanged: if (log) console.log(log)
}
ShaderEffectSource {
id: frameBuffer
visible: false
sourceItem: staticShader
hideSource: true
}
}

View File

@@ -1,81 +0,0 @@
/*******************************************************************************
* 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 Qt5Compat.GraphicalEffects
import "utils.js" as Utils
ShaderTerminal {
property alias title: terminal.title
property alias terminalSize: terminal.terminalSize
signal sessionFinished()
property bool loadBloomEffect: appSettings.bloom > 0 || appSettings._frameShininess > 0
id: mainShader
opacity: appSettings.windowOpacity * 0.3 + 0.7
source: terminal.mainSource
burnInEffect: terminal.burnInEffect
virtualResolution: terminal.virtualResolution
screenResolution: Qt.size(
terminalWindow.width * Screen.devicePixelRatio * appSettings.windowScaling,
terminalWindow.height * Screen.devicePixelRatio * appSettings.windowScaling
)
bloomSource: bloomSourceLoader.item
PreprocessedTerminal {
id: terminal
anchors.fill: parent
onSessionFinished: mainShader.sessionFinished()
}
function activate() {
terminal.mainTerminal.forceActiveFocus()
}
// EFFECTS ////////////////////////////////////////////////////////////////
Loader {
id: bloomEffectLoader
active: loadBloomEffect
asynchronous: true
width: parent.width * appSettings.bloomQuality
height: parent.height * appSettings.bloomQuality
sourceComponent: FastBlur {
radius: Utils.lint(16, 64, appSettings.bloomQuality)
source: terminal.mainSource
transparentBorder: true
}
}
Loader {
id: bloomSourceLoader
active: loadBloomEffect
asynchronous: true
sourceComponent: ShaderEffectSource {
id: _bloomEffectSource
sourceItem: bloomEffectLoader.item
wrapMode: ShaderEffectSource.Repeat
hideSource: true
smooth: true
visible: false
}
}
}

View File

@@ -1,52 +0,0 @@
/*******************************************************************************
* 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: Utils.sum(appSettings.frameColor, Qt.rgba(0.1, 0.1, 0.1, 1.0))
property color _backgroundColor: appSettings.backgroundColor
property color _fontColor: appSettings.fontColor
property color _lightColor: Utils.mix(_fontColor, _backgroundColor, 0.2)
property color frameColor: Utils.mix(
Utils.scaleColor(_lightColor, 0.2),
_staticFrameColor,
0.125 + 0.750 * ambientLight
)
property real screenCurvature: appSettings.screenCurvature * appSettings.screenCurvatureSize * terminalWindow.normalizedWindowScale
property real frameShininess: appSettings.frameShininess
property real frameSize: appSettings.frameSize * terminalWindow.normalizedWindowScale
property real screenRadius: appSettings.screenRadius
property size viewportSize: Qt.size(width / appSettings.windowScaling, height / appSettings.windowScaling)
property real ambientLight: appSettings.ambientLight
vertexShader: "qrc:/shaders/terminal_frame.vert.qsb"
fragmentShader: "qrc:/shaders/terminal_frame.frag.qsb"
onStatusChanged: if (log) console.log(log) //Print warning messages
}

View File

@@ -1,155 +0,0 @@
/*******************************************************************************
* 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
import QtQuick.Controls
import QtQuick.Layouts
import QtQml.Models
Item {
id: tabsRoot
readonly property int innerPadding: 6
readonly property string currentTitle: tabsModel.get(currentIndex).title ?? "cool-retro-term"
property alias currentIndex: tabBar.currentIndex
readonly property int count: tabsModel.count
property size terminalSize: Qt.size(0, 0)
function normalizeTitle(rawTitle) {
if (rawTitle === undefined || rawTitle === null) {
return ""
}
return String(rawTitle).trim()
}
function addTab() {
tabsModel.append({ title: "" })
tabBar.currentIndex = tabsModel.count - 1
}
function closeTab(index) {
if (tabsModel.count <= 1) {
terminalWindow.close()
return
}
tabsModel.remove(index)
tabBar.currentIndex = Math.min(tabBar.currentIndex, tabsModel.count - 1)
}
ListModel {
id: tabsModel
}
Component.onCompleted: addTab()
ColumnLayout {
anchors.fill: parent
spacing: 0
Rectangle {
id: tabRow
Layout.fillWidth: true
height: rowLayout.implicitHeight
color: palette.window
visible: tabsModel.count > 1
RowLayout {
id: rowLayout
anchors.fill: parent
spacing: 0
TabBar {
id: tabBar
Layout.fillWidth: true
Layout.fillHeight: true
focusPolicy: Qt.NoFocus
Repeater {
model: tabsModel
TabButton {
id: tabButton
contentItem: RowLayout {
anchors.fill: parent
anchors { leftMargin: innerPadding; rightMargin: innerPadding }
spacing: innerPadding
Label {
text: model.title
elide: Text.ElideRight
Layout.fillWidth: true
Layout.alignment: Qt.AlignVCenter
}
ToolButton {
text: "\u00d7"
focusPolicy: Qt.NoFocus
padding: innerPadding
Layout.alignment: Qt.AlignVCenter
onClicked: tabsRoot.closeTab(index)
}
}
}
}
}
ToolButton {
id: addTabButton
text: "+"
focusPolicy: Qt.NoFocus
Layout.fillHeight: true
padding: innerPadding
Layout.alignment: Qt.AlignVCenter
onClicked: tabsRoot.addTab()
}
}
}
StackLayout {
id: stack
Layout.fillWidth: true
Layout.fillHeight: true
currentIndex: tabBar.currentIndex
Repeater {
model: tabsModel
TerminalContainer {
property bool shouldHaveFocus: terminalWindow.active && StackLayout.isCurrentItem
onShouldHaveFocusChanged: {
if (shouldHaveFocus) {
activate()
}
}
onTitleChanged: tabsModel.setProperty(index, "title", normalizeTitle(title))
Layout.fillWidth: true
Layout.fillHeight: true
onSessionFinished: tabsRoot.closeTab(index)
onTerminalSizeChanged: updateTerminalSize()
function updateTerminalSize() {
// Every tab will have the same size so we can simply take the first one.
if (index == 0) {
tabsRoot.terminalSize = terminalSize
}
}
}
}
}
}
}

View File

@@ -1,136 +0,0 @@
/*******************************************************************************
* 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.Window 2.1
import QtQuick.Controls 2.3
import "menus"
ApplicationWindow {
id: terminalWindow
width: 1024
height: 768
// Show the window once it is ready.
Component.onCompleted: {
visible = true
}
minimumWidth: 320
minimumHeight: 240
visible: false
property bool fullscreen: false
onFullscreenChanged: visibility = (fullscreen ? Window.FullScreen : Window.Windowed)
menuBar: WindowMenu { }
property real normalizedWindowScale: 1024 / ((0.5 * width + 0.5 * height))
color: "#00000000"
title: terminalTabs.currentTitle
Action {
id: fullscreenAction
text: qsTr("Fullscreen")
enabled: !appSettings.isMacOS
shortcut: StandardKey.FullScreen
onTriggered: fullscreen = !fullscreen
checkable: true
checked: fullscreen
}
Action {
id: newWindowAction
text: qsTr("New Window")
shortcut: appSettings.isMacOS ? "Meta+N" : "Ctrl+Shift+N"
onTriggered: appRoot.createWindow()
}
Action {
id: quitAction
text: qsTr("Quit")
shortcut: appSettings.isMacOS ? StandardKey.Close : "Ctrl+Shift+Q"
onTriggered: terminalWindow.close()
}
Action {
id: showsettingsAction
text: qsTr("Settings")
onTriggered: {
settingsWindow.show()
settingsWindow.requestActivate()
settingsWindow.raise()
}
}
Action {
id: copyAction
text: qsTr("Copy")
shortcut: appSettings.isMacOS ? StandardKey.Copy : "Ctrl+Shift+C"
}
Action {
id: pasteAction
text: qsTr("Paste")
shortcut: appSettings.isMacOS ? StandardKey.Paste : "Ctrl+Shift+V"
}
Action {
id: zoomIn
text: qsTr("Zoom In")
shortcut: StandardKey.ZoomIn
onTriggered: appSettings.incrementScaling()
}
Action {
id: zoomOut
text: qsTr("Zoom Out")
shortcut: StandardKey.ZoomOut
onTriggered: appSettings.decrementScaling()
}
Action {
id: showAboutAction
text: qsTr("About")
onTriggered: {
aboutDialog.show()
aboutDialog.requestActivate()
aboutDialog.raise()
}
}
Action {
id: newTabAction
text: qsTr("New Tab")
shortcut: appSettings.isMacOS ? StandardKey.AddTab : "Ctrl+Shift+T"
onTriggered: terminalTabs.addTab()
}
TerminalTabs {
id: terminalTabs
width: parent.width
height: (parent.height + Math.abs(y))
}
Loader {
anchors.centerIn: parent
active: appSettings.showTerminalSize
sourceComponent: SizeOverlay {
z: 3
terminalSize: terminalTabs.terminalSize
}
}
onClosing: {
appRoot.closeWindow(terminalWindow)
}
}

View File

@@ -1,45 +0,0 @@
/*******************************************************************************
* 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
QtObject {
id: timeManager
property bool enableTimer: false
property real time: 0
property int framesPerUpdate: Math.max(1, appSettings.effectsFrameSkip)
property int _frameCounter: 0
property var frameDriver: FrameAnimation {
running: enableTimer
onTriggered: {
timeManager._frameCounter += 1
if (timeManager._frameCounter >= timeManager.framesPerUpdate) {
time = elapsedTime
timeManager._frameCounter = 0
}
}
}
onEnableTimerChanged: if (!enableTimer) _frameCounter = 0
onFramesPerUpdateChanged: _frameCounter = 0
}

Some files were not shown because too many files have changed in this diff Show More