aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAdrian Kummerlaender2015-06-29 22:31:24 +0200
committerAdrian Kummerlaender2015-06-29 22:31:24 +0200
commitf01eadd3530e61063b43aa615123dcd82ce3d239 (patch)
treedc75476440857aa3ca4d914feff7bf923e2e2931
parent97e3cfada0d599fe6121d92d52e4782fc02aed08 (diff)
downloadMetaTerm-f01eadd3530e61063b43aa615123dcd82ce3d239.tar
MetaTerm-f01eadd3530e61063b43aa615123dcd82ce3d239.tar.gz
MetaTerm-f01eadd3530e61063b43aa615123dcd82ce3d239.tar.bz2
MetaTerm-f01eadd3530e61063b43aa615123dcd82ce3d239.tar.lz
MetaTerm-f01eadd3530e61063b43aa615123dcd82ce3d239.tar.xz
MetaTerm-f01eadd3530e61063b43aa615123dcd82ce3d239.tar.zst
MetaTerm-f01eadd3530e61063b43aa615123dcd82ce3d239.zip
Added vim-like UI normal and insert modes
Normal mode allows for selecting the a terminal or newline text input. Insert mode sets the keyboard focus to the currently selected item. This transforms _MetaTerm_ into a fully keyboard driven application.
-rw-r--r--EmbeddedTerminal.qml20
-rw-r--r--MetaTerm.qml83
-rw-r--r--TerminalItem.qml128
3 files changed, 178 insertions, 53 deletions
diff --git a/EmbeddedTerminal.qml b/EmbeddedTerminal.qml
index e02ba61..f4f104e 100644
--- a/EmbeddedTerminal.qml
+++ b/EmbeddedTerminal.qml
@@ -12,7 +12,8 @@ Item {
width: container.width
height: container.height
- function focus() { terminal.forceActiveFocus() }
+ function select() { highlighter.select() }
+ function deselect() { highlighter.deselect() }
Row {
id: container
@@ -23,7 +24,7 @@ Item {
width: 10
height: terminal.height
- color: "#aadb0f"
+ color: "#909636"
Behavior on opacity {
NumberAnimation {
@@ -32,8 +33,10 @@ Item {
}
}
- function focus() { opacity = 1 }
- function unfocus() { opacity = 0 }
+ function select() { opacity = 1 }
+ function deselect() { opacity = 0 }
+ function focus() { color = "#352F6A" }
+ function unfocus() { color = "#909636" }
}
Rectangle {
@@ -66,16 +69,15 @@ Item {
}
}
+ onTermGetFocus: highlighter.focus()
+ onTermLostFocus: highlighter.unfocus()
+
MouseArea {
anchors.fill: parent
- acceptedButtons: Qt.LeftButton
- onClicked: parent.forceActiveFocus();
+ acceptedButtons: Qt.NoButton
onWheel: { }
}
- onTermGetFocus: highlighter.focus()
- onTermLostFocus: highlighter.unfocus()
-
Component.onCompleted: {
terminal.forceActiveFocus();
session.startShellProgram();
diff --git a/MetaTerm.qml b/MetaTerm.qml
index f95baa7..913f514 100644
--- a/MetaTerm.qml
+++ b/MetaTerm.qml
@@ -2,11 +2,15 @@ import QtQuick 2.0
import QMLTermWidget 1.0
import QtQuick.Controls 1.2
+
Rectangle {
+ id: root
anchors.fill: parent
color: "#161616"
+ property string uiMode : "insert"
+
Flickable {
id: terminalListFlickable
boundsBehavior: Flickable.StopAtBounds
@@ -37,16 +41,26 @@ Rectangle {
function nextItem() {
if ( activeItem < (children.length - 1) ) {
- children[++activeItem].focus();
+ children[ activeItem].deselect();
+ children[++activeItem].select();
}
}
function prevItem() {
if ( activeItem > 0 ) {
- children[--activeItem].focus();
+ children[ activeItem].deselect();
+ children[--activeItem].select();
}
}
+ function focusItem() {
+ children[activeItem].forceActiveFocus();
+ }
+
+ function unfocusItem() {
+ children[activeItem].unfocus();
+ }
+
TerminalItem {
width: terminalListFlickable.width
onExecuted: terminalList.createItem()
@@ -58,19 +72,80 @@ Rectangle {
}
Action {
+ id: insertTerminalAction
+ shortcut: "i"
+ onTriggered: {
+ switch ( uiMode ) {
+ case "normal": {
+ uiMode = "insert";
+ terminalList.focusItem();
+ break;
+ }
+ default: {
+ break;
+ }
+ }
+
+ console.log(uiMode);
+ }
+ }
+
+ Action {
+ id: escapeTerminalAction
+ shortcut: "Shift+ESC"
+ onTriggered: {
+ switch ( uiMode ) {
+ case "insert": {
+ uiMode = "normal";
+ root.forceActiveFocus();
+ terminalList.unfocusItem();
+ break;
+ }
+ default: {
+ break;
+ }
+ }
+
+ console.log(uiMode);
+ }
+ }
+
+ Action {
id: nextTerminalAction
shortcut: "j"
- onTriggered: terminalList.nextItem()
+ onTriggered: {
+ switch ( uiMode ) {
+ case "normal": {
+ terminalList.nextItem();
+ break;
+ }
+ default: {
+ break;
+ }
+ }
+ }
}
Action {
id: prevTerminalAction
shortcut: "k"
- onTriggered: terminalList.prevItem()
+ onTriggered: {
+ switch ( uiMode ) {
+ case "normal": {
+ terminalList.prevItem();
+ break;
+ }
+ default: {
+ break;
+ }
+ }
+ }
}
ScrollBar {
flickable: terminalListFlickable
handleSize: 10
}
+
+ Component.onCompleted: terminalList.focusItem()
}
diff --git a/TerminalItem.qml b/TerminalItem.qml
index 9fce337..883d911 100644
--- a/TerminalItem.qml
+++ b/TerminalItem.qml
@@ -8,60 +8,108 @@ Item {
height: elementList.height
- function focus() {
+ function select() {
if ( command.readOnly ) {
- elementList.children[1].focus();
+ elementList.children[1].select();
} else {
- command.forceActiveFocus();
+ highlighter.select();
}
}
- Column {
- id: elementList
-
- function createTerminal(program) {
- var terminal = Qt.createComponent("EmbeddedTerminal.qml");
- var instantiateTerminal = function() {
- terminal.createObject(elementList, {
- "columns": 90,
- "lines": 20,
- "program": program,
- "workingDirectory": "$HOME"
- });
- }
+ function deselect() {
+ if ( command.readOnly ) {
+ elementList.children[1].deselect();
+ } else {
+ highlighter.deselect();
+ }
+ }
- if ( terminal.status == Component.Ready ) {
- instantiateTerminal();
- } else {
- terminal.statusChanged.connect(instantiateTerminal);
- }
+ function forceActiveFocus() {
+ if ( command.readOnly ) {
+ scope.forceActiveFocus();
+ } else {
+ scope.forceActiveFocus();
+ highlighter.select();
+ highlighter.focus();
+ }
+ }
+
+ function unfocus() {
+ if ( !command.readOnly ) {
+ highlighter.unfocus();
}
+ }
- RowLayout {
- width: terminalItem.width
+ FocusScope {
+ id: scope
- Text {
- text: "> "
- font.pointSize: 18
- color: "white"
+ Column {
+ id: elementList
+
+ function createTerminal(program) {
+ var terminal = Qt.createComponent("EmbeddedTerminal.qml");
+ var instantiateTerminal = function() {
+ terminal.createObject(elementList, {
+ "columns": 90,
+ "lines": 20,
+ "program": program,
+ "workingDirectory": "$HOME",
+ "focus": true
+ });
+ }
+
+ if ( terminal.status == Component.Ready ) {
+ instantiateTerminal();
+ } else {
+ terminal.statusChanged.connect(instantiateTerminal);
+ }
}
- TextInput {
- id: command
+ RowLayout {
+ width: terminalItem.width
+
+ Rectangle {
+ id: highlighter
+
+ width: 10
+ height: command.height
+ opacity: 0
+
+ color: "#909636"
+
+ Behavior on opacity {
+ NumberAnimation {
+ duration: 300
+ easing.type: Easing.OutCubic
+ }
+ }
+
+ function select() { opacity = 1 }
+ function deselect() { opacity = 0 }
+ function focus() { color = "#352F6A" }
+ function unfocus() { color = "#909636" }
+ }
+
+ TextInput {
+ id: command
- font.pointSize: 18
- color: "white"
- selectedTextColor: "#161616"
- selectionColor: "white"
- selectByMouse: true
+ font.pointSize: 18
+ color: "white"
+ selectedTextColor: "#161616"
+ selectionColor: "white"
+ selectByMouse: true
+ focus: true
- Layout.fillWidth: true
+ Layout.fillWidth: true
- onAccepted: {
- if ( !readOnly ) {
- readOnly = true;
- elementList.createTerminal(text);
- terminalItem.executed();
+ onAccepted: {
+ if ( !readOnly ) {
+ readOnly = true;
+ focus = false;
+ elementList.createTerminal(text);
+ terminalItem.executed();
+ highlighter.deselect();
+ }
}
}
}