diff --git a/mobile/Lisp.qml b/mobile/Lisp.qml index be922bba9..1e4f3cb37 100644 --- a/mobile/Lisp.qml +++ b/mobile/Lisp.qml @@ -262,7 +262,7 @@ Item { onTriggered: { if (VescIf.isPortConnected() && pollStatsBox.checked && - statsTabItem.visible) { + lispPageCombo.currentIndex === 2) { mCommands.lispGetStats(true) } } @@ -274,11 +274,251 @@ Item { anchors.fill: parent anchors.leftMargin: 10 + notchLeft anchors.rightMargin: 10 + notchRight - anchors.topMargin: 10 - spacing: 8 + spacing: 0 + + ComboBox { + id: lispPageCombo + Layout.fillWidth: true + Layout.bottomMargin: 8 + model: ["Editor", "REPL", "Stats"] + onCurrentIndexChanged: { + var statsActive = currentIndex === 2 + statsPollTimer.running = pollStatsBox.checked && statsActive + if (statsActive) { + mCommands.lispGetStats(true) + } + } + } + + StackLayout { + Layout.fillWidth: true + Layout.fillHeight: true + currentIndex: lispPageCombo.currentIndex + + // === Editor tab === + ColumnLayout { + spacing: 4 + + RowLayout { + Layout.fillWidth: true + + CheckBox { + id: autoRunBox + text: "Auto Run" + checked: true + } + + CheckBox { + id: reduceLispBox + text: "Reduce" + checked: false + } + + Label { + Layout.fillWidth: true + horizontalAlignment: Text.AlignRight + text: currentFilePath.length > 0 ? currentFilePath : "Unnamed" + elide: Text.ElideLeft + } + } + + Label { + text: "Code" + Layout.fillWidth: true + } + + ScrollView { + Layout.fillWidth: true + Layout.fillHeight: true + clip: true + + TextArea { + id: editorText + wrapMode: TextArea.NoWrap + font.family: "DejaVu Sans Mono" + font.pointSize: editorFontSize + selectByMouse: true + persistentSelection: true + color: Utility.getAppHexColor("lightText") + inputMethodHints: Qt.ImhNoPredictiveText + readOnly: false + activeFocusOnPress: true + } + } + } + + // === REPL tab === + ColumnLayout { + RowLayout { + Layout.fillWidth: true + + TextField { + id: replInput + Layout.fillWidth: true + placeholderText: "REPL command" + onAccepted: { + if (text.length > 0) { + mCommands.lispSendReplCmd(text) + text = "" + } + } + } + + Button { + text: "Send" + onClicked: { + if (replInput.text.length > 0) { + mCommands.lispSendReplCmd(replInput.text) + replInput.text = "" + } + } + } + + Button { + text: ":help" + onClicked: mCommands.lispSendReplCmd(":help") + } + } + + RowLayout { + Layout.fillWidth: true + + Button { + text: "Clear" + onClicked: consoleText = "" + } + + Item { + Layout.fillWidth: true + } + + Label { + text: "REPL Console" + color: Utility.getAppHexColor("lightText") + } + } + + ScrollView { + Layout.fillWidth: true + Layout.fillHeight: true + clip: true + + TextArea { + text: consoleText + readOnly: true + wrapMode: TextArea.WrapAnywhere + font.family: "DejaVu Sans Mono" + color: Utility.getAppHexColor("lightText") + } + } + } + + // === Stats tab === + ColumnLayout { + RowLayout { + Layout.fillWidth: true + + CheckBox { + id: pollStatsBox + text: "Auto Poll" + checked: true + onToggled: { + statsPollTimer.running = checked && lispPageCombo.currentIndex === 2 + } + } + + Label { + text: "Hz" + } + + ComboBox { + id: pollHzBox + model: [1, 2, 5, 10] + currentIndex: 1 + onCurrentTextChanged: { + statsPollHz = parseInt(currentText) + if (lispPageCombo.currentIndex === 2 && pollStatsBox.checked) { + statsPollTimer.restart() + } + } + } + + Button { + text: "Refresh" + onClicked: mCommands.lispGetStats(true) + } + } + + Label { + text: "CPU: " + lispCpuUse.toFixed(1) + "%" + } + + ProgressBar { + Layout.fillWidth: true + Layout.preferredHeight: 10 + from: 0 + to: 100 + value: lispCpuUse + } + + Label { + text: "Heap: " + lispHeapUse.toFixed(1) + "%" + } + + ProgressBar { + Layout.fillWidth: true + Layout.preferredHeight: 10 + from: 0 + to: 100 + value: lispHeapUse + } + + Label { + text: "Memory: " + lispMemUse.toFixed(1) + "%" + } + + ProgressBar { + Layout.fillWidth: true + Layout.preferredHeight: 10 + from: 0 + to: 100 + value: lispMemUse + } + + Label { + text: "Global Variables" + Layout.fillWidth: true + } + + ListView { + id: bindingListView + Layout.fillWidth: true + Layout.fillHeight: true + clip: true + spacing: 1 + model: bindingModel + + delegate: Rectangle { + width: bindingListView.width + height: 26 + color: "transparent" + + Label { + anchors.fill: parent + anchors.leftMargin: 4 + anchors.rightMargin: 4 + verticalAlignment: Text.AlignVCenter + elide: Text.ElideRight + text: name + ": " + value + } + } + } + } + } RowLayout { Layout.fillWidth: true + Layout.topMargin: 8 Button { text: "Upload"