Skip to content
Permalink
Browse files
GUI: Simplification
- remove Kirigami.ApplicationWindow and all it's components and use a simple Window instead
- add rotatePortrait command line option to rotate the GUI 90 degrees
- add webSocket command line option to set the mycroft web socket address (defaults to ws://127.0.0.1
  • Loading branch information
guhl committed May 21, 2020
1 parent f2f6636 commit 9fc8ade8b0d997ef81049f1029bfe3739f3b0651
Show file tree
Hide file tree
Showing 2 changed files with 58 additions and 283 deletions.
@@ -53,10 +53,12 @@ int main(int argc, char *argv[])
auto skillOption = QCommandLineOption(QStringLiteral("skill"), QStringLiteral("Single skill to load"), QStringLiteral("skill"));
auto maximizeOption = QCommandLineOption(QStringLiteral("maximize"), QStringLiteral("When set, start maximized."));
auto rotateScreen = QCommandLineOption(QStringLiteral("rotateScreen"), QStringLiteral("When set, rotate the screen 180 degrees."));
auto rotatePortrait = QCommandLineOption(QStringLiteral("rotatePortrait"), QStringLiteral("When set, rotate the screen 90 degrees."));
auto webSocket = QCommandLineOption(QStringLiteral("webSocket"), QStringLiteral("webSocket of mycroft"), QStringLiteral("webSocket"));
auto helpOption = QCommandLineOption(QStringLiteral("help"), QStringLiteral("Show this help message"));
parser.addOptions({widthOption, heightOption, hideTextInputOption, skillOption,
dpiOption, maximizeOption,
rotateScreen, helpOption});
rotateScreen, rotatePortrait, webSocket, helpOption});
parser.process(arguments);


@@ -87,13 +89,24 @@ int main(int argc, char *argv[])
int width = parser.value(widthOption).toInt();
int height = parser.value(heightOption).toInt();
bool maximize = parser.isSet(maximizeOption);
QString websocket;
int rotation = 0;
if (parser.isSet(rotateScreen))
rotation = 180;
if (parser.isSet(rotatePortrait))
rotation = 90;
if (parser.isSet(webSocket))
websocket = parser.value(webSocket);
else
websocket = QString::fromUtf8("ws://127.0.0.1");

QQmlApplicationEngine engine;
engine.rootContext()->setContextProperty(QStringLiteral("deviceWidth"), width);
engine.rootContext()->setContextProperty(QStringLiteral("deviceHeight"), height);
engine.rootContext()->setContextProperty(QStringLiteral("deviceMaximized"), maximize);
engine.rootContext()->setContextProperty(QStringLiteral("hideTextInput"), parser.isSet(hideTextInputOption));
engine.rootContext()->setContextProperty(QStringLiteral("globalScreenRotation"), parser.isSet(rotateScreen) ? 180 : 0);
engine.rootContext()->setContextProperty(QStringLiteral("globalScreenRotation"), rotation);
engine.rootContext()->setContextProperty(QStringLiteral("globalWebSocket"), websocket);

QString singleSkill = parser.value(skillOption);
if (singleSkill.endsWith(QStringLiteral(".home"))) {
@@ -25,31 +25,18 @@ import QtQuick.Window 2.2
import Mycroft 1.0 as Mycroft
import org.kde.private.mycroftgui 1.0 as MycroftGui

Kirigami.ApplicationWindow {
Window {
id: root
visible: true

minimumHeight : deviceHeight || undefined
maximumHeight : deviceHeight || undefined
minimumWidth : deviceWidth || undefined
maximumWidth : deviceWidth || undefined
height : deviceHeight || 480
width : deviceWidth || 800
x: deviceWidth ? Screen.desktopAvailableHeight - width : undefined
y: deviceHeight ? Screen.desktopAvailableHeight - height : undefined

//HACK!! needs proper api in kirigami
Component.onCompleted: {
globalDrawer.handle.handleAnchor = handleAnchor;

// Maximize and auto connect if set
if (deviceMaximized) {
showMaximized()
}

//FIXME
if (qinput.visible) {
qinput.forceActiveFocus();
}

Mycroft.GlobalSettings.webSocketAddress = globalWebSocket || "ws://127.0.0.1"
console.info("Mycroft.GlobalSettings.webSocketAddress=", Mycroft.GlobalSettings.webSocketAddress)
Mycroft.MycroftController.reconnect()
if (singleSkillHome.length > 0 && Mycroft.MycroftController.status === Mycroft.MycroftController.Open) {
Mycroft.MycroftController.sendRequest(singleSkillHome, {});
}
@@ -63,89 +50,6 @@ Kirigami.ApplicationWindow {
}
}
}
// Uses Android's voice popup for speech recognition
MycroftGui.SpeechIntent {
id: speechIntent
title: "Say something to Mycroft" // TODO i18n
onSpeechRecognized: {
Mycroft.MycroftController.sendText(text)
}
//onRecognitionFailed: console.log("SPEECH FAILED")
//onRecognitionCanceled: console.log("SPEECH CANCELED")
//onNothingRecognized: console.log("SPEECH NOTHING")
}

//HACK
Connections {
target: root.pageStack.layers
onDepthChanged: {
if (root.pageStack.layers.depth == 1) {
globalDrawer.handle.handleAnchor = handleAnchor;
} else {
globalDrawer.handle.handleAnchor = null;
}
}
}

globalDrawer: Kirigami.GlobalDrawer {
bannerImageSource: "banner.png"
handleVisible: !hideTextInput

actions: [
Kirigami.Action {
text: "Hints"
iconName: "help-hint"
checked: pageStack.layers.currentItem.objectName == "hints"
onTriggered: {
if (checked) {
pageStack.layers.pop(pageStack.layers.initialItem);
} else if (pageStack.layers.depth > 1) {
pageStack.layers.replace(Qt.resolvedUrl("HintsPage.qml"));
} else {
pageStack.layers.push(Qt.resolvedUrl("HintsPage.qml"));
}
}
},
Kirigami.Action {
text: "Settings"
iconName: "configure"
checked: pageStack.layers.currentItem.objectName == "Settings"
onTriggered: {
if (checked) {
pageStack.layers.pop(pageStack.layers.initialItem);
} else if (pageStack.layers.depth > 1) {
pageStack.layers.replace(Qt.resolvedUrl("SettingsPage.qml"));
} else {
pageStack.layers.push(Qt.resolvedUrl("SettingsPage.qml"));
}
}
}
]
Switch {
id: remoteSTTSwitch
text: "Remote STT"
checked: applicationSettings.usesRemoteSTT
onCheckedChanged: applicationSettings.usesRemoteSTT = checked
visible: Mycroft.GlobalSettings.displayRemoteConfig
}
Switch {
text: "Remote TTS"
checked: Mycroft.GlobalSettings.usesRemoteTTS
onCheckedChanged: Mycroft.GlobalSettings.usesRemoteTTS = checked
visible: Mycroft.GlobalSettings.displayRemoteConfig
}
Switch {
id: nightSwitch
text: "Dark Mode"
checked: applicationSettings.darkMode
onCheckedChanged: applicationSettings.darkMode = checked
}
Switch {
text: "Connect Automatically"
checked: Mycroft.GlobalSettings.autoConnect
onCheckedChanged: Mycroft.GlobalSettings.autoConnect = checked
}
}

Timer {
interval: 20000
@@ -157,192 +61,50 @@ Kirigami.ApplicationWindow {
}
}

pageStack.globalToolBar.style: pageStack.layers.depth == 1 ? Kirigami.ApplicationHeaderStyle.None : Kirigami.ApplicationHeaderStyle.Auto

pageStack.initialPage: Kirigami.Page {
leftPadding: 0
rightPadding: 0
topPadding: 0
bottomPadding: 0
onBackRequested: {
if (mainView.active) {
event.accepted = true;
mainView.goBack();
}
}
Rectangle {
color: nightSwitch.checked ? "black" : Kirigami.Theme.backgroundColor
rotation: globalScreenRotation || 0
Rectangle {
id: page
height: globalScreenRotation == 90 ? root.width : root.height
width: globalScreenRotation == 90 ? root.height : root.width
color: "black"
anchors.centerIn: parent
transform: Rotation { origin.x: page.width/2; origin.y: page.height/2; angle: globalScreenRotation }
Image {
visible: singleSkill.length === 0
source: "background.png"
fillMode: Image.PreserveAspectFit
anchors.fill: parent
Image {
visible: singleSkill.length === 0
source: "background.png"
fillMode: Image.PreserveAspectFit
anchors.fill: parent
opacity: !mainView.currentItem
Behavior on opacity {
OpacityAnimator {
duration: Kirigami.Units.longDuration
easing.type: Easing.InQuad
}
}
}

Popup {
id: audioRecorder
width: 300
height: 125
closePolicy: Popup.CloseOnEscape | Popup.CloseOnPressOutsideParent
x: (root.width - width) / 2
y: (root.height - height) / 2

RemoteStt {
id: remoteSttInstance
}

onOpenedChanged: {
if(audioRecorder.opened){
remoteSttInstance.record = true;
} else {
remoteSttInstance.record = false;
}
}
}

Mycroft.SkillView {
id: mainView
activeSkills.whiteList: singleSkill.length > 0 ? singleSkill : null
Kirigami.Theme.colorSet: nightSwitch.checked ? Kirigami.Theme.Complementary : Kirigami.Theme.View
anchors.fill: parent
}
Button {
anchors.centerIn: parent
text: "start"
visible: Mycroft.MycroftController.status == Mycroft.MycroftController.Closed
onClicked: Mycroft.MycroftController.start();
}

Mycroft.StatusIndicator {
id: si
//visible: false
anchors {
top: parent.top
right: parent.right
margins: Kirigami.Units.largeSpacing
}
z: 999
}
Kirigami.Heading {
id: inputQuery
Kirigami.Theme.colorSet: mainView.Kirigami.Theme.colorSet
anchors.right: si.left
anchors.rightMargin: Kirigami.Units.largeSpacing
anchors.verticalCenter: si.verticalCenter
level: 3
opacity: 0
onTextChanged: {
opacity = 1;
utteranceTimer.restart();
}
Timer {
id: utteranceTimer
interval: 8000
onTriggered: {
inputQuery.text = "";
inputQuery.opacity = 0
}
}
Behavior on opacity {
OpacityAnimator {
duration: Kirigami.units.longDuration
easing.type: Easing.InOutQuad
}
}

Connections {
target: Mycroft.MycroftController
onIntentRecevied: {
if(type == "recognizer_loop:utterance") {
inputQuery.text = data.utterances[0]
}
}
opacity: !mainView.currentItem
Behavior on opacity {
OpacityAnimator {
duration: Kirigami.Units.longDuration
easing.type: Easing.InQuad
}
}
}

//Note: a custom control as ToolBar on Android has a funny color
footer: Control {
Kirigami.Theme.colorSet: nightSwitch.checked ? Kirigami.Theme.Complementary : Kirigami.Theme.Window
visible: !hideTextInput
height: hideTextInput ? 0 : implicitHeight
implicitHeight: contentItem.implicitHeight + topPadding + bottomPadding
contentItem: RowLayout {
Item {
id: handleAnchor
Layout.fillHeight: true
Layout.preferredWidth: height
}
TextField {
id: qinput
Layout.fillWidth: true

placeholderText: "Ask Mycroft..."
onAccepted: {
Mycroft.MycroftController.sendText(qinput.text)
}

Connections {
target: speechIntent
onSpeechRecognized: qinput.text = text
}
onFocusChanged: {
if (focus) {
selectAll();
}
}
}
Button {
text: "Speak" // TODO generic microphone icon
onClicked: {
if(applicationSettings.usesRemoteSTT){
audioRecorder.open()
} else {
speechIntent.start()
}
}
visible: speechIntent.supported || applicationSettings.usesRemoteSTT
}
}
background: Rectangle {
color: Kirigami.Theme.backgroundColor
LinearGradient {
anchors {
left: parent.left
right: parent.right
bottom: parent.top
}
implicitHeight: Kirigami.Units.gridUnit/2
Mycroft.SkillView {
id: mainView
activeSkills.whiteList: singleSkill.length > 0 ? singleSkill : null
// Kirigami.Theme.colorSet: nightSwitch.checked ? Kirigami.Theme.Complementary : Kirigami.Theme.View
Kirigami.Theme.colorSet: Kirigami.Theme.Complementary
anchors.fill: parent
}
Button {
anchors.centerIn: parent
text: "start"
visible: Mycroft.MycroftController.status == Mycroft.MycroftController.Closed
onClicked: Mycroft.MycroftController.start();
}

start: Qt.point(0, height)
end: Qt.point(0, 0)
gradient: Gradient {
GradientStop {
position: 0.0
color: Qt.rgba(0, 0, 0, 0.2)
}
GradientStop {
position: 0.3
color: Qt.rgba(0, 0, 0, 0.1)
}
GradientStop {
position: 1.0
color: "transparent"
}
}
}
Mycroft.StatusIndicator {
id: si
anchors {
top: parent.top
right: parent.right
margins: Kirigami.Units.largeSpacing
}
// z: 999
}

}
}


0 comments on commit 9fc8ade

Please sign in to comment.