mirror of
https://github.com/Swordfish90/cool-retro-term.git
synced 2026-02-08 00:32:27 +00:00
First implementation of tabs.
This commit is contained in:
@@ -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
|
||||
}
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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"
|
||||
}
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
128
app/qml/TerminalTabs.qml
Normal file
128
app/qml/TerminalTabs.qml
Normal file
@@ -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 <http://www.gnu.org/licenses/>.
|
||||
*******************************************************************************/
|
||||
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()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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: {
|
||||
|
||||
@@ -33,6 +33,15 @@ Menu {
|
||||
}
|
||||
|
||||
MenuSeparator {}
|
||||
Menu {
|
||||
title: qsTr("Tabs")
|
||||
MenuItem {
|
||||
action: newTabAction
|
||||
}
|
||||
MenuItem {
|
||||
action: closeTabAction
|
||||
}
|
||||
}
|
||||
|
||||
Menu {
|
||||
title: qsTr("File")
|
||||
|
||||
@@ -28,4 +28,14 @@ Menu {
|
||||
MenuItem {
|
||||
action: pasteAction
|
||||
}
|
||||
MenuSeparator {}
|
||||
Menu {
|
||||
title: qsTr("Tabs")
|
||||
MenuItem {
|
||||
action: newTabAction
|
||||
}
|
||||
MenuItem {
|
||||
action: closeTabAction
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
<file>Storage.qml</file>
|
||||
<file>SettingsAdvancedTab.qml</file>
|
||||
<file>TerminalContainer.qml</file>
|
||||
<file>TerminalTabs.qml</file>
|
||||
<file>images/crt256.png</file>
|
||||
<file>utils.js</file>
|
||||
<file>images/allNoise512.png</file>
|
||||
@@ -42,7 +43,6 @@
|
||||
<file>menus/WindowMenu.qml</file>
|
||||
<file>menus/FullContextMenu.qml</file>
|
||||
<file>menus/ShortContextMenu.qml</file>
|
||||
<file>ShaderLibrary.qml</file>
|
||||
<file>menus/OSXMenu.qml</file>
|
||||
<file>../shaders/terminal_dynamic.vert.qsb</file>
|
||||
<file>../shaders/terminal_static.vert.qsb</file>
|
||||
|
||||
BIN
app/shaders/terminal_static_rgb0_bloom0_curve0_shine0.frag.qsb
Normal file
BIN
app/shaders/terminal_static_rgb0_bloom0_curve0_shine0.frag.qsb
Normal file
Binary file not shown.
BIN
app/shaders/terminal_static_rgb0_bloom0_curve0_shine1.frag.qsb
Normal file
BIN
app/shaders/terminal_static_rgb0_bloom0_curve0_shine1.frag.qsb
Normal file
Binary file not shown.
BIN
app/shaders/terminal_static_rgb0_bloom0_curve1_shine0.frag.qsb
Normal file
BIN
app/shaders/terminal_static_rgb0_bloom0_curve1_shine0.frag.qsb
Normal file
Binary file not shown.
BIN
app/shaders/terminal_static_rgb0_bloom0_curve1_shine1.frag.qsb
Normal file
BIN
app/shaders/terminal_static_rgb0_bloom0_curve1_shine1.frag.qsb
Normal file
Binary file not shown.
BIN
app/shaders/terminal_static_rgb0_bloom1_curve0_shine0.frag.qsb
Normal file
BIN
app/shaders/terminal_static_rgb0_bloom1_curve0_shine0.frag.qsb
Normal file
Binary file not shown.
BIN
app/shaders/terminal_static_rgb0_bloom1_curve0_shine1.frag.qsb
Normal file
BIN
app/shaders/terminal_static_rgb0_bloom1_curve0_shine1.frag.qsb
Normal file
Binary file not shown.
BIN
app/shaders/terminal_static_rgb0_bloom1_curve1_shine0.frag.qsb
Normal file
BIN
app/shaders/terminal_static_rgb0_bloom1_curve1_shine0.frag.qsb
Normal file
Binary file not shown.
BIN
app/shaders/terminal_static_rgb0_bloom1_curve1_shine1.frag.qsb
Normal file
BIN
app/shaders/terminal_static_rgb0_bloom1_curve1_shine1.frag.qsb
Normal file
Binary file not shown.
BIN
app/shaders/terminal_static_rgb1_bloom0_curve0_shine0.frag.qsb
Normal file
BIN
app/shaders/terminal_static_rgb1_bloom0_curve0_shine0.frag.qsb
Normal file
Binary file not shown.
BIN
app/shaders/terminal_static_rgb1_bloom0_curve0_shine1.frag.qsb
Normal file
BIN
app/shaders/terminal_static_rgb1_bloom0_curve0_shine1.frag.qsb
Normal file
Binary file not shown.
BIN
app/shaders/terminal_static_rgb1_bloom0_curve1_shine0.frag.qsb
Normal file
BIN
app/shaders/terminal_static_rgb1_bloom0_curve1_shine0.frag.qsb
Normal file
Binary file not shown.
BIN
app/shaders/terminal_static_rgb1_bloom0_curve1_shine1.frag.qsb
Normal file
BIN
app/shaders/terminal_static_rgb1_bloom0_curve1_shine1.frag.qsb
Normal file
Binary file not shown.
BIN
app/shaders/terminal_static_rgb1_bloom1_curve0_shine0.frag.qsb
Normal file
BIN
app/shaders/terminal_static_rgb1_bloom1_curve0_shine0.frag.qsb
Normal file
Binary file not shown.
BIN
app/shaders/terminal_static_rgb1_bloom1_curve0_shine1.frag.qsb
Normal file
BIN
app/shaders/terminal_static_rgb1_bloom1_curve0_shine1.frag.qsb
Normal file
Binary file not shown.
BIN
app/shaders/terminal_static_rgb1_bloom1_curve1_shine0.frag.qsb
Normal file
BIN
app/shaders/terminal_static_rgb1_bloom1_curve1_shine0.frag.qsb
Normal file
Binary file not shown.
BIN
app/shaders/terminal_static_rgb1_bloom1_curve1_shine1.frag.qsb
Normal file
BIN
app/shaders/terminal_static_rgb1_bloom1_curve1_shine1.frag.qsb
Normal file
Binary file not shown.
Reference in New Issue
Block a user