diff --git a/app/qml/ApplicationSettings.qml b/app/qml/ApplicationSettings.qml
index 4ce607a..92bbe2d 100644
--- a/app/qml/ApplicationSettings.qml
+++ b/app/qml/ApplicationSettings.qml
@@ -813,6 +813,7 @@ QtObject {
wintitle = args[args.indexOf("-T") + 1]
}
+ settingsInitialized = true
initializedSettings()
}
Component.onDestruction: {
@@ -826,4 +827,5 @@ QtObject {
text: "100%"
}
property real labelWidth: _sampleLabel.width
+ property bool settingsInitialized: false
}
diff --git a/app/qml/PreprocessedTerminal.qml b/app/qml/PreprocessedTerminal.qml
index a44669f..a8c1d0e 100644
--- a/app/qml/PreprocessedTerminal.qml
+++ b/app/qml/PreprocessedTerminal.qml
@@ -42,6 +42,7 @@ Item{
property size terminalSize: kterminal.terminalSize
property size fontMetrics: kterminal.fontMetrics
+ property bool sessionStarted: false
// Manage copy and paste
Connections {
@@ -168,6 +169,10 @@ Item{
}
function startSession() {
+ if (terminalContainer.sessionStarted)
+ return
+
+ terminalContainer.sessionStarted = true
appSettings.initializedSettings.disconnect(startSession);
// Retrieve the variable set in main.cpp if arguments are passed.
@@ -192,6 +197,8 @@ Item{
Component.onCompleted: {
appSettings.terminalFontChanged.connect(handleFontChanged);
appSettings.initializedSettings.connect(startSession);
+ if (appSettings.settingsInitialized)
+ startSession();
appSettings.updateFont()
}
}
@@ -232,6 +239,7 @@ Item{
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 {
diff --git a/app/qml/SettingsWindow.qml b/app/qml/SettingsWindow.qml
index 99ac3c4..8f5b22e 100644
--- a/app/qml/SettingsWindow.qml
+++ b/app/qml/SettingsWindow.qml
@@ -25,6 +25,8 @@ import QtQuick.Layouts 1.3
import QtQuick.Dialogs
ApplicationWindow {
+ readonly property real tabButtonPadding: 10
+
id: settings_window
title: qsTr("Settings")
width: 640
@@ -37,15 +39,19 @@ ApplicationWindow {
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")
}
}
diff --git a/app/qml/ShaderLibrary.qml b/app/qml/ShaderLibrary.qml
deleted file mode 100644
index d555d46..0000000
--- a/app/qml/ShaderLibrary.qml
+++ /dev/null
@@ -1,92 +0,0 @@
-import QtQuick 2.0
-
-QtObject {
- property string rasterizationShader:
- ((appSettings.rasterization === appSettings.no_rasterization) ||
- (appSettings.rasterization === appSettings.modern_rasterization) ? "
- lowp vec3 applyRasterization(vec2 screenCoords, lowp vec3 texel, vec2 virtualResolution, float intensity) {
- return texel;
- }" : "") +
-
- (appSettings.rasterization === appSettings.scanline_rasterization ? "
- #define INTENSITY 0.30
- #define BRIGHTBOOST 0.30
-
- lowp vec3 applyRasterization(vec2 screenCoords, lowp vec3 texel, vec2 virtualResolution, float intensity) {
- lowp vec3 pixelHigh = ((1.0 + BRIGHTBOOST) - (0.2 * texel)) * texel;
- lowp vec3 pixelLow = ((1.0 - INTENSITY) + (0.1 * texel)) * texel;
-
- vec2 coords = fract(screenCoords * virtualResolution) * 2.0 - vec2(1.0);
- lowp float mask = 1.0 - abs(coords.y);
-
- lowp vec3 rasterizationColor = mix(pixelLow, pixelHigh, mask);
- return mix(texel, rasterizationColor, intensity);
- }" : "") +
-
- (appSettings.rasterization === appSettings.pixel_rasterization ? "
- #define INTENSITY 0.30
- #define BRIGHTBOOST 0.30
-
- lowp vec3 applyRasterization(vec2 screenCoords, lowp vec3 texel, vec2 virtualResolution, float intensity) {
- lowp vec3 result = texel;
-
- lowp vec3 pixelHigh = ((1.0 + BRIGHTBOOST) - (0.2 * texel)) * texel;
- lowp vec3 pixelLow = ((1.0 - INTENSITY) + (0.1 * texel)) * texel;
-
- vec2 coords = fract(screenCoords * virtualResolution) * 2.0 - vec2(1.0);
- coords = coords * coords;
- lowp float mask = 1.0 - coords.x - coords.y;
-
- lowp vec3 rasterizationColor = mix(pixelLow, pixelHigh, mask);
- return mix(texel, rasterizationColor, intensity);
- }" : "") +
-
- (appSettings.rasterization === appSettings.subpixel_rasterization ? "
- #define INTENSITY 0.30
- #define BRIGHTBOOST 0.30
- #define SUBPIXELS 3.0
- const vec3 offsets = vec3(3.141592654) * vec3(1.0/2.0,1.0/2.0 - 2.0/3.0,1.0/2.0-4.0/3.0);
-
- lowp vec3 applyRasterization(vec2 screenCoords, lowp vec3 texel, vec2 virtualResolution, float intensity) {
- vec2 omega = vec2(3.141592654) * vec2(2.0) * virtualResolution;
- vec2 angle = screenCoords * omega;
- vec3 xfactors = (SUBPIXELS + sin(angle.x + offsets)) / (SUBPIXELS + 1.0);
-
- lowp vec3 result = texel * xfactors;
- lowp vec3 pixelHigh = ((1.0 + BRIGHTBOOST) - (0.2 * result)) * result;
- lowp vec3 pixelLow = ((1.0 - INTENSITY) + (0.1 * result)) * result;
-
- vec2 coords = fract(screenCoords * virtualResolution) * 2.0 - vec2(1.0);
- lowp float mask = 1.0 - abs(coords.y);
-
- lowp vec3 rasterizationColor = mix(pixelLow, pixelHigh, mask);
- return mix(texel, rasterizationColor, intensity);
- }" : "") +
-
- "\n\n"
-
- property string min2: "
- float min2(vec2 v) {
- return min(v.x, v.y);
- }\n\n"
-
- property string rgb2grey: "
- float rgb2grey(vec3 v) {
- return dot(v, vec3(0.21, 0.72, 0.04));
- }\n\n"
-
- property string max2: "
- float max2(vec2 v) {
- return max(v.x, v.y);
- }\n\n"
-
- property string prod2: "
- float prod2(vec2 v) {
- return v.x * v.y;
- }\n\n"
-
- property string sum2: "
- float sum2(vec2 v) {
- return v.x + v.y;
- }\n\n"
-}
diff --git a/app/qml/ShaderTerminal.qml b/app/qml/ShaderTerminal.qml
index f3d4246..6f6afb9 100644
--- a/app/qml/ShaderTerminal.qml
+++ b/app/qml/ShaderTerminal.qml
@@ -50,6 +50,7 @@ Item {
property ShaderEffectSource source
property BurnInEffect burnInEffect
property ShaderEffectSource bloomSource
+ property QtObject timeManager
property color fontColor: appSettings.fontColor
property color backgroundColor: appSettings.backgroundColor
@@ -105,7 +106,7 @@ Item {
property real displayTerminalFrame: appSettings._frameSize > 0 || appSettings.screenCurvature > 0
- property real time: timeManager.time
+ property real time: timeManager ? timeManager.time : 0
property ShaderEffectSource noiseSource: noiseShaderSource
property real frameSize: appSettings.frameSize
@@ -160,10 +161,6 @@ Item {
}
}
- ShaderLibrary {
- id: shaderLibrary
- }
-
ShaderEffect {
id: staticShader
diff --git a/app/qml/TerminalContainer.qml b/app/qml/TerminalContainer.qml
index 2e9e361..c5411b3 100644
--- a/app/qml/TerminalContainer.qml
+++ b/app/qml/TerminalContainer.qml
@@ -32,6 +32,7 @@ ShaderTerminal {
id: mainShader
opacity: appSettings.windowOpacity * 0.3 + 0.7
+ timeManager: terminalWindow.timeManager
source: terminal.mainSource
burnInEffect: terminal.burnInEffect
virtualResolution: terminal.virtualResolution
@@ -41,16 +42,15 @@ ShaderTerminal {
)
bloomSource: bloomSourceLoader.item
- TimeManager {
- id: timeManager
- enableTimer: terminalWindow.visible
- }
-
PreprocessedTerminal {
id: terminal
anchors.fill: parent
}
+ function activate() {
+ terminal.mainTerminal.forceActiveFocus()
+ }
+
// EFFECTS ////////////////////////////////////////////////////////////////
Loader {
id: bloomEffectLoader
diff --git a/app/qml/TerminalTabs.qml b/app/qml/TerminalTabs.qml
new file mode 100644
index 0000000..6fe61cb
--- /dev/null
+++ b/app/qml/TerminalTabs.qml
@@ -0,0 +1,128 @@
+/*******************************************************************************
+* Copyright (c) 2013-2021 "Filippo Scognamiglio"
+* https://github.com/Swordfish90/cool-retro-term
+*
+* This file is part of cool-retro-term.
+*
+* cool-retro-term is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see .
+*******************************************************************************/
+import QtQuick
+import QtQuick.Controls
+import QtQuick.Layouts
+
+Item {
+ id: tabsRoot
+
+ readonly property string title: stack.currentItem ? stack.currentItem.title : ""
+ readonly property size terminalSize: stack.currentItem ? stack.currentItem.terminalSize : Qt.size(0, 0)
+ property alias currentIndex: tabBar.currentIndex
+ readonly property int count: tabsModel.count
+
+ function addTab() {
+ tabsModel.append({ title: qsTr("Tab %1").arg(tabsModel.count + 1) })
+ tabBar.currentIndex = tabsModel.count - 1
+ }
+
+ function closeTab(index) {
+ if (tabsModel.count <= 1)
+ return
+
+ tabsModel.remove(index)
+ if (tabBar.currentIndex >= tabsModel.count) {
+ tabBar.currentIndex = tabsModel.count - 1
+ }
+ }
+
+ function closeCurrentTab() {
+ closeTab(tabBar.currentIndex)
+ }
+
+ ListModel {
+ id: tabsModel
+ }
+
+ Component.onCompleted: addTab()
+
+ ColumnLayout {
+ anchors.fill: parent
+ spacing: 0
+
+ TabBar {
+ id: tabBar
+ Layout.fillWidth: true
+ focusPolicy: Qt.NoFocus
+ visible: tabsModel.count > 1
+
+ background: Rectangle {
+ color: palette.window
+ }
+
+ Repeater {
+ model: tabsModel
+ TabButton {
+ id: tabButton
+ contentItem: RowLayout {
+ anchors.fill: parent
+ anchors { leftMargin: 6; rightMargin: 6 }
+ spacing: 6
+
+ Label {
+ text: model.title
+ elide: Text.ElideRight
+ Layout.fillWidth: true
+ Layout.alignment: Qt.AlignVCenter
+ }
+
+ ToolButton {
+ text: "\u00d7"
+ focusPolicy: Qt.NoFocus
+ visible: tabsModel.count > 1
+ enabled: visible
+ Layout.alignment: Qt.AlignVCenter
+ onClicked: tabsRoot.closeTab(index)
+ }
+ }
+ }
+ }
+ }
+
+ StackLayout {
+ id: stack
+ Layout.fillWidth: true
+ Layout.fillHeight: true
+ currentIndex: tabBar.currentIndex
+
+ Repeater {
+ model: tabsModel
+ onItemAdded: function(index, item) {
+ if (index === tabBar.currentIndex)
+ item.activate()
+ }
+ TerminalContainer {
+ Layout.fillWidth: true
+ Layout.fillHeight: true
+ onTitleChanged: tabsModel.setProperty(index, "title", title)
+ }
+ }
+ }
+ }
+
+ Connections {
+ target: tabBar
+ onCurrentIndexChanged: {
+ if (stack.currentItem)
+ stack.currentItem.activate()
+ }
+ }
+}
diff --git a/app/qml/main.qml b/app/qml/main.qml
index 8ae0774..e6321c4 100644
--- a/app/qml/main.qml
+++ b/app/qml/main.qml
@@ -71,7 +71,7 @@ ApplicationWindow {
color: "#00000000"
- title: terminalContainer.title || qsTr(appSettings.wintitle)
+ title: terminalTabs.title || qsTr(appSettings.wintitle)
Action {
id: showMenubarAction
@@ -137,11 +137,27 @@ ApplicationWindow {
aboutDialog.raise()
}
}
+ Action {
+ id: newTabAction
+ text: qsTr("New Tab")
+ onTriggered: terminalTabs.addTab()
+ }
+ Action {
+ id: closeTabAction
+ text: qsTr("Close Tab")
+ enabled: terminalTabs.count > 1
+ onTriggered: terminalTabs.closeCurrentTab()
+ }
ApplicationSettings {
id: appSettings
}
- TerminalContainer {
- id: terminalContainer
+ TimeManager {
+ id: sharedTimeManager
+ enableTimer: terminalWindow.visible
+ }
+ property alias timeManager: sharedTimeManager
+ TerminalTabs {
+ id: terminalTabs
width: parent.width
height: (parent.height + Math.abs(y))
}
@@ -158,7 +174,7 @@ ApplicationWindow {
active: appSettings.showTerminalSize
sourceComponent: SizeOverlay {
z: 3
- terminalSize: terminalContainer.terminalSize
+ terminalSize: terminalTabs.terminalSize
}
}
onClosing: {
diff --git a/app/qml/menus/FullContextMenu.qml b/app/qml/menus/FullContextMenu.qml
index 2be1639..c22d1f8 100644
--- a/app/qml/menus/FullContextMenu.qml
+++ b/app/qml/menus/FullContextMenu.qml
@@ -33,6 +33,15 @@ Menu {
}
MenuSeparator {}
+ Menu {
+ title: qsTr("Tabs")
+ MenuItem {
+ action: newTabAction
+ }
+ MenuItem {
+ action: closeTabAction
+ }
+ }
Menu {
title: qsTr("File")
diff --git a/app/qml/menus/ShortContextMenu.qml b/app/qml/menus/ShortContextMenu.qml
index 9d8f63b..95cef0e 100644
--- a/app/qml/menus/ShortContextMenu.qml
+++ b/app/qml/menus/ShortContextMenu.qml
@@ -28,4 +28,14 @@ Menu {
MenuItem {
action: pasteAction
}
+ MenuSeparator {}
+ Menu {
+ title: qsTr("Tabs")
+ MenuItem {
+ action: newTabAction
+ }
+ MenuItem {
+ action: closeTabAction
+ }
+ }
}
diff --git a/app/qml/resources.qrc b/app/qml/resources.qrc
index f2d0960..4e4fc9c 100644
--- a/app/qml/resources.qrc
+++ b/app/qml/resources.qrc
@@ -21,6 +21,7 @@
Storage.qml
SettingsAdvancedTab.qml
TerminalContainer.qml
+ TerminalTabs.qml
images/crt256.png
utils.js
images/allNoise512.png
@@ -42,7 +43,6 @@
menus/WindowMenu.qml
menus/FullContextMenu.qml
menus/ShortContextMenu.qml
- ShaderLibrary.qml
menus/OSXMenu.qml
../shaders/terminal_dynamic.vert.qsb
../shaders/terminal_static.vert.qsb
diff --git a/app/shaders/terminal_static_rgb0_bloom0_curve0_shine0.frag.qsb b/app/shaders/terminal_static_rgb0_bloom0_curve0_shine0.frag.qsb
new file mode 100644
index 0000000..afaa6c3
Binary files /dev/null and b/app/shaders/terminal_static_rgb0_bloom0_curve0_shine0.frag.qsb differ
diff --git a/app/shaders/terminal_static_rgb0_bloom0_curve0_shine1.frag.qsb b/app/shaders/terminal_static_rgb0_bloom0_curve0_shine1.frag.qsb
new file mode 100644
index 0000000..6bba6e7
Binary files /dev/null and b/app/shaders/terminal_static_rgb0_bloom0_curve0_shine1.frag.qsb differ
diff --git a/app/shaders/terminal_static_rgb0_bloom0_curve1_shine0.frag.qsb b/app/shaders/terminal_static_rgb0_bloom0_curve1_shine0.frag.qsb
new file mode 100644
index 0000000..eade077
Binary files /dev/null and b/app/shaders/terminal_static_rgb0_bloom0_curve1_shine0.frag.qsb differ
diff --git a/app/shaders/terminal_static_rgb0_bloom0_curve1_shine1.frag.qsb b/app/shaders/terminal_static_rgb0_bloom0_curve1_shine1.frag.qsb
new file mode 100644
index 0000000..9f97211
Binary files /dev/null and b/app/shaders/terminal_static_rgb0_bloom0_curve1_shine1.frag.qsb differ
diff --git a/app/shaders/terminal_static_rgb0_bloom1_curve0_shine0.frag.qsb b/app/shaders/terminal_static_rgb0_bloom1_curve0_shine0.frag.qsb
new file mode 100644
index 0000000..93be2df
Binary files /dev/null and b/app/shaders/terminal_static_rgb0_bloom1_curve0_shine0.frag.qsb differ
diff --git a/app/shaders/terminal_static_rgb0_bloom1_curve0_shine1.frag.qsb b/app/shaders/terminal_static_rgb0_bloom1_curve0_shine1.frag.qsb
new file mode 100644
index 0000000..d5658a9
Binary files /dev/null and b/app/shaders/terminal_static_rgb0_bloom1_curve0_shine1.frag.qsb differ
diff --git a/app/shaders/terminal_static_rgb0_bloom1_curve1_shine0.frag.qsb b/app/shaders/terminal_static_rgb0_bloom1_curve1_shine0.frag.qsb
new file mode 100644
index 0000000..b4a2ec8
Binary files /dev/null and b/app/shaders/terminal_static_rgb0_bloom1_curve1_shine0.frag.qsb differ
diff --git a/app/shaders/terminal_static_rgb0_bloom1_curve1_shine1.frag.qsb b/app/shaders/terminal_static_rgb0_bloom1_curve1_shine1.frag.qsb
new file mode 100644
index 0000000..6b275b1
Binary files /dev/null and b/app/shaders/terminal_static_rgb0_bloom1_curve1_shine1.frag.qsb differ
diff --git a/app/shaders/terminal_static_rgb1_bloom0_curve0_shine0.frag.qsb b/app/shaders/terminal_static_rgb1_bloom0_curve0_shine0.frag.qsb
new file mode 100644
index 0000000..d22b6f7
Binary files /dev/null and b/app/shaders/terminal_static_rgb1_bloom0_curve0_shine0.frag.qsb differ
diff --git a/app/shaders/terminal_static_rgb1_bloom0_curve0_shine1.frag.qsb b/app/shaders/terminal_static_rgb1_bloom0_curve0_shine1.frag.qsb
new file mode 100644
index 0000000..11ac6ac
Binary files /dev/null and b/app/shaders/terminal_static_rgb1_bloom0_curve0_shine1.frag.qsb differ
diff --git a/app/shaders/terminal_static_rgb1_bloom0_curve1_shine0.frag.qsb b/app/shaders/terminal_static_rgb1_bloom0_curve1_shine0.frag.qsb
new file mode 100644
index 0000000..5911d99
Binary files /dev/null and b/app/shaders/terminal_static_rgb1_bloom0_curve1_shine0.frag.qsb differ
diff --git a/app/shaders/terminal_static_rgb1_bloom0_curve1_shine1.frag.qsb b/app/shaders/terminal_static_rgb1_bloom0_curve1_shine1.frag.qsb
new file mode 100644
index 0000000..8153274
Binary files /dev/null and b/app/shaders/terminal_static_rgb1_bloom0_curve1_shine1.frag.qsb differ
diff --git a/app/shaders/terminal_static_rgb1_bloom1_curve0_shine0.frag.qsb b/app/shaders/terminal_static_rgb1_bloom1_curve0_shine0.frag.qsb
new file mode 100644
index 0000000..e28fd4a
Binary files /dev/null and b/app/shaders/terminal_static_rgb1_bloom1_curve0_shine0.frag.qsb differ
diff --git a/app/shaders/terminal_static_rgb1_bloom1_curve0_shine1.frag.qsb b/app/shaders/terminal_static_rgb1_bloom1_curve0_shine1.frag.qsb
new file mode 100644
index 0000000..4ae50ea
Binary files /dev/null and b/app/shaders/terminal_static_rgb1_bloom1_curve0_shine1.frag.qsb differ
diff --git a/app/shaders/terminal_static_rgb1_bloom1_curve1_shine0.frag.qsb b/app/shaders/terminal_static_rgb1_bloom1_curve1_shine0.frag.qsb
new file mode 100644
index 0000000..705559c
Binary files /dev/null and b/app/shaders/terminal_static_rgb1_bloom1_curve1_shine0.frag.qsb differ
diff --git a/app/shaders/terminal_static_rgb1_bloom1_curve1_shine1.frag.qsb b/app/shaders/terminal_static_rgb1_bloom1_curve1_shine1.frag.qsb
new file mode 100644
index 0000000..085ed5b
Binary files /dev/null and b/app/shaders/terminal_static_rgb1_bloom1_curve1_shine1.frag.qsb differ