mirror of
https://gitlab.com/eql/lqml.git
synced 2026-03-21 05:51:51 -07:00
example 'cl-repl': add resize handle above line edit; fix mobile QML auto reload
This commit is contained in:
parent
4059f5593f
commit
8d026cf2f0
7 changed files with 361 additions and 329 deletions
|
|
@ -16,5 +16,6 @@
|
|||
(:file "lisp/eval")
|
||||
(:file "lisp/curl")
|
||||
(:file "lisp/dialogs")
|
||||
(:file "lisp/editor")))
|
||||
(:file "lisp/editor")
|
||||
(:file "lisp/main")))
|
||||
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ android {
|
|||
lisp.commands = ecl.exe -shell $$PWD/make.lisp
|
||||
}
|
||||
|
||||
lisp.input = LISP_FILES
|
||||
lisp.input = LISP_FILES
|
||||
|
||||
win32: lisp.output = tmp/app.lib
|
||||
!win32: lisp.output = tmp/libapp.a
|
||||
|
|
@ -86,8 +86,9 @@ ios {
|
|||
LIBS += -lasdf -lecl-help -ldeflate -lecl-cdb -lecl-curl -lql-minitar -lsockets
|
||||
LIBS += -L../../../platforms/ios/lib
|
||||
|
||||
assets.files = $$files($$PWD/platforms/ios/assets)
|
||||
QMAKE_BUNDLE_DATA += assets
|
||||
assets.files = $$files($$PWD/platforms/ios/assets)
|
||||
QMAKE_BUNDLE_DATA += assets
|
||||
QMAKE_ASSET_CATALOGS += platforms/ios/Assets.xcassets
|
||||
}
|
||||
|
||||
32bit {
|
||||
|
|
|
|||
3
examples/cl-repl/build-android/install-run.sh
Executable file
3
examples/cl-repl/build-android/install-run.sh
Executable file
|
|
@ -0,0 +1,3 @@
|
|||
# install/update (keeps app data)
|
||||
adb install -r android-build/*.apk
|
||||
adb shell am start -n org.qtproject.example.repl/org.qtproject.qt5.android.bindings.QtActivity # Qt5
|
||||
|
|
@ -97,7 +97,7 @@ QVariant QT::block2(const QVariant& vCursor) {
|
|||
QTextCursor* cursor = VAL(vCursor, TextCursor*);
|
||||
if (cursor != nullptr) {
|
||||
TextBlock* tmp = new TextBlock(cursor->block());
|
||||
tmp->deleteLater();
|
||||
QTimer::singleShot(0, tmp, &QObject::deleteLater);
|
||||
return VAR(TextBlock*, tmp);
|
||||
}
|
||||
return QVariant();
|
||||
|
|
@ -173,7 +173,7 @@ QVariant QT::findBlockByLineNumber(const QVariant& vDocument, const QVariant& vN
|
|||
QTextDocument* document = VAL(vDocument, QTextDocument*);
|
||||
if (document != nullptr) {
|
||||
TextBlock* tmp = new TextBlock(document->findBlockByLineNumber(vNumber.toInt()));
|
||||
tmp->deleteLater();
|
||||
QTimer::singleShot(0, tmp, &QObject::deleteLater);
|
||||
return VAR(TextBlock*, tmp);
|
||||
}
|
||||
return QVariant();
|
||||
|
|
@ -191,7 +191,7 @@ QVariant QT::next(const QVariant& vBlock) {
|
|||
QTextBlock* block = VAL(vBlock, TextBlock*);
|
||||
if (block != nullptr) {
|
||||
TextBlock* tmp = new TextBlock(block->next());
|
||||
tmp->deleteLater();
|
||||
QTimer::singleShot(0, tmp, &QObject::deleteLater);
|
||||
return VAR(TextBlock*, tmp);
|
||||
}
|
||||
return QVariant();
|
||||
|
|
@ -217,7 +217,7 @@ QVariant QT::previous(const QVariant& vBlock) {
|
|||
QTextBlock* block = VAL(vBlock, TextBlock*);
|
||||
if (block != nullptr) {
|
||||
TextBlock* tmp = new TextBlock(block->previous());
|
||||
tmp->deleteLater();
|
||||
QTimer::singleShot(0, tmp, &QObject::deleteLater);
|
||||
return VAR(TextBlock*, tmp);
|
||||
}
|
||||
return QVariant();
|
||||
|
|
|
|||
|
|
@ -14,4 +14,6 @@ to store their pointer values in a `QVariant`.
|
|||
If we need to return a non `QObject` value to Lisp (not a pointer or primitive
|
||||
value, but a class like `TextBlock` in this example, that is a `QTextBlock`
|
||||
extended with a `QObject`), a new instance is created on the heap, calling
|
||||
`deleteLater()` on it, which should be sufficient in most cases.
|
||||
`QTimer::singleShot(0, tmp, &QObject::deleteLater)` on it, which should be
|
||||
sufficient in any circumstance. The additional timer is need here because of
|
||||
`SplitView`, which delays certain events.
|
||||
|
|
|
|||
|
|
@ -0,0 +1,5 @@
|
|||
(in-package :editor)
|
||||
|
||||
#+(or android ios)
|
||||
(when qml::*remote-ip*
|
||||
(qsingle-shot 1000 'auto-reload-qml))
|
||||
|
|
@ -14,6 +14,7 @@ StackView {
|
|||
|
||||
property bool small: (Math.max(width, height) < 1000)
|
||||
property bool skipEnsureVisible: false
|
||||
property double editorHeight: 0.5 // preferred initial height (50%)
|
||||
|
||||
function availableHeight() {
|
||||
var h = Math.round(Qt.inputMethod.keyboardRectangle.y /
|
||||
|
|
@ -21,10 +22,10 @@ StackView {
|
|||
return (h === 0) ? main.height : h
|
||||
}
|
||||
|
||||
function halfHeight() { return (availableHeight() - rectCommand.height) / 2 }
|
||||
function isLandscape() { return (Screen.primaryOrientation === Qt.LandscapeOrientation) }
|
||||
function keyboardVisible() { return Qt.inputMethod.visible }
|
||||
function showKeyboard(show) { show ? Qt.inputMethod.show() : Qt.inputMethod.hide() }
|
||||
function divideHeight(factor) { return (availableHeight() - rectCommand.height) * factor }
|
||||
function isLandscape() { return (Screen.primaryOrientation === Qt.LandscapeOrientation) }
|
||||
function keyboardVisible() { return Qt.inputMethod.visible }
|
||||
function showKeyboard(show) { show ? Qt.inputMethod.show() : Qt.inputMethod.hide() }
|
||||
|
||||
// show/hide dialogs
|
||||
|
||||
|
|
@ -129,81 +130,356 @@ StackView {
|
|||
Rectangle {
|
||||
id: mainRect
|
||||
|
||||
Rectangle {
|
||||
id: rectEdit
|
||||
objectName: "rect_edit"
|
||||
width: main.width
|
||||
height: main.halfHeight()
|
||||
SplitView {
|
||||
id: splitView
|
||||
anchors.fill: parent
|
||||
orientation: Qt.Vertical
|
||||
|
||||
Ext.Flickable {
|
||||
id: flickEdit
|
||||
objectName: "flick_edit"
|
||||
anchors.fill: parent
|
||||
contentWidth: edit.paintedWidth
|
||||
contentHeight: edit.paintedHeight
|
||||
property double handleHeight: 10
|
||||
|
||||
TextEdit {
|
||||
id: edit
|
||||
objectName: "edit"
|
||||
width: flickEdit.width
|
||||
height: flickEdit.height
|
||||
leftPadding: 2
|
||||
font.family: "Hack"
|
||||
font.pixelSize: 18
|
||||
selectionColor: "firebrick"
|
||||
inputMethodHints: Qt.ImhNoAutoUppercase | Qt.ImhNoPredictiveText | Qt.ImhNoTextHandles | Qt.ImhNoEditMenu
|
||||
cursorDelegate: cursor
|
||||
handle: Rectangle {
|
||||
implicitHeight: splitView.handleHeight
|
||||
color: SplitHandle.pressed ? Qt.darker(rectOutput.color) : rectOutput.color
|
||||
}
|
||||
|
||||
Keys.onTabPressed: command.forceActiveFocus()
|
||||
Rectangle {
|
||||
id: rectEdit
|
||||
objectName: "rect_edit"
|
||||
width: main.width
|
||||
SplitView.preferredHeight: divideHeight(editorHeight)
|
||||
|
||||
onCursorRectangleChanged: flickEdit.ensureVisible(cursorRectangle)
|
||||
Ext.Flickable {
|
||||
id: flickEdit
|
||||
objectName: "flick_edit"
|
||||
anchors.fill: parent
|
||||
contentWidth: edit.paintedWidth
|
||||
contentHeight: edit.paintedHeight
|
||||
|
||||
Component.onCompleted: later(function() {
|
||||
Lisp.call(textDocument, "editor:set-text-document", objectName)
|
||||
})
|
||||
TextEdit {
|
||||
id: edit
|
||||
objectName: "edit"
|
||||
width: flickEdit.width
|
||||
height: flickEdit.height
|
||||
leftPadding: 2
|
||||
font.family: "Hack"
|
||||
font.pixelSize: 18
|
||||
selectionColor: "firebrick"
|
||||
inputMethodHints: Qt.ImhNoAutoUppercase | Qt.ImhNoPredictiveText | Qt.ImhNoTextHandles | Qt.ImhNoEditMenu
|
||||
cursorDelegate: cursor
|
||||
|
||||
// for external keyboard
|
||||
Shortcut {
|
||||
sequence: "Ctrl+E" // E for Expression
|
||||
onActivated: Lisp.call("editor:select-expression")
|
||||
}
|
||||
Shortcut {
|
||||
sequence: "Ctrl+L" // L for Lambda
|
||||
onActivated: Lisp.call("editor:eval-single-expression")
|
||||
}
|
||||
Keys.onTabPressed: command.forceActiveFocus()
|
||||
|
||||
MouseArea {
|
||||
width: Math.max(rectEdit.width, edit.paintedWidth)
|
||||
height: Math.max(rectEdit.height, edit.paintedHeight)
|
||||
onCursorRectangleChanged: flickEdit.ensureVisible(cursorRectangle)
|
||||
|
||||
onPressed: {
|
||||
// seems necessary to consistently move cursor by tapping
|
||||
edit.forceActiveFocus()
|
||||
edit.cursorPosition = edit.positionAt(mouse.x, mouse.y)
|
||||
Qt.inputMethod.show() // needed for edge case (since we have 2 input fields)
|
||||
Lisp.call("editor:set-focus-editor", edit.objectName)
|
||||
Component.onCompleted: later(function() {
|
||||
Lisp.call(textDocument, "editor:set-text-document", objectName)
|
||||
})
|
||||
|
||||
// for external keyboard
|
||||
Shortcut {
|
||||
sequence: "Ctrl+E" // E for Expression
|
||||
onActivated: Lisp.call("editor:select-expression")
|
||||
}
|
||||
Shortcut {
|
||||
sequence: "Ctrl+L" // L for Lambda
|
||||
onActivated: Lisp.call("editor:eval-single-expression")
|
||||
}
|
||||
|
||||
onPressAndHold: Lisp.call("editor:copy-paste", edit.cursorPosition)
|
||||
MouseArea {
|
||||
width: Math.max(rectEdit.width, edit.paintedWidth)
|
||||
height: Math.max(rectEdit.height, edit.paintedHeight)
|
||||
|
||||
onPressed: {
|
||||
// seems necessary to consistently move cursor by tapping
|
||||
edit.forceActiveFocus()
|
||||
edit.cursorPosition = edit.positionAt(mouse.x, mouse.y)
|
||||
Qt.inputMethod.show() // needed for edge case (since we have 2 input fields)
|
||||
Lisp.call("editor:set-focus-editor", edit.objectName)
|
||||
}
|
||||
|
||||
onPressAndHold: Lisp.call("editor:copy-paste", edit.cursorPosition)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Item {
|
||||
id: bottomItem
|
||||
width: parent.width
|
||||
|
||||
Rectangle {
|
||||
id: rectCommand
|
||||
objectName: "rect_command"
|
||||
width: parent.width
|
||||
height: command.font.pixelSize + 11
|
||||
border.width: 2
|
||||
border.color: command.focus ? "#0066ff" : "lightgray"
|
||||
|
||||
Ext.Flickable {
|
||||
id: flickCommand
|
||||
objectName: "flick_command"
|
||||
anchors.fill: parent
|
||||
contentWidth: command.paintedWidth
|
||||
contentHeight: command.paintedHeight
|
||||
|
||||
TextEdit {
|
||||
id: command
|
||||
objectName: "command"
|
||||
width: flickCommand.width
|
||||
height: flickCommand.height
|
||||
padding: 4
|
||||
font.family: "Hack"
|
||||
font.pixelSize: 18
|
||||
selectionColor: "firebrick"
|
||||
inputMethodHints: Qt.ImhNoAutoUppercase | Qt.ImhNoPredictiveText | Qt.ImhNoTextHandles | Qt.ImhNoEditMenu
|
||||
cursorDelegate: cursor
|
||||
focus: true
|
||||
|
||||
Keys.onUpPressed: Lisp.call("editor:history-move", "back")
|
||||
Keys.onDownPressed: Lisp.call("editor:history-move", "forward")
|
||||
Keys.onTabPressed: edit.forceActiveFocus()
|
||||
|
||||
onCursorRectangleChanged: flickCommand.ensureVisible(cursorRectangle)
|
||||
|
||||
Component.onCompleted: later(function() {
|
||||
Lisp.call(textDocument, "editor:set-text-document", objectName)
|
||||
})
|
||||
|
||||
MouseArea {
|
||||
width: Math.max(rectCommand.width, command.paintedWidth)
|
||||
height: Math.max(rectCommand.height, command.paintedHeight)
|
||||
|
||||
onPressed: {
|
||||
// seems necessary to consistently move cursor by tapping
|
||||
command.forceActiveFocus()
|
||||
command.cursorPosition = command.positionAt(mouse.x, mouse.y)
|
||||
Qt.inputMethod.show() // needed for edge case (since we have 2 input fields)
|
||||
Lisp.call("editor:set-focus-editor", command.objectName)
|
||||
Lisp.call("editor:ensure-output-visible")
|
||||
}
|
||||
|
||||
onPressAndHold: Lisp.call("editor:copy-paste", command.cursorPosition)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Component {
|
||||
id: cursor
|
||||
Rectangle {
|
||||
id: rectOutput
|
||||
objectName: "rect_output"
|
||||
y: rectCommand.height
|
||||
width: main.width
|
||||
// calculate manually (for virtual keyboard)
|
||||
height: main.availableHeight() - rectEdit.height - rectCommand.height - splitView.handleHeight
|
||||
|
||||
Rectangle {
|
||||
width: 2
|
||||
color: "blue"
|
||||
visible: parent.activeFocus
|
||||
ListView {
|
||||
id: output
|
||||
objectName: "output"
|
||||
anchors.fill: parent
|
||||
contentWidth: parent.width * 5
|
||||
clip: true
|
||||
model: outputModel
|
||||
flickableDirection: Flickable.HorizontalAndVerticalFlick
|
||||
|
||||
SequentialAnimation on opacity {
|
||||
running: true
|
||||
loops: Animation.Infinite
|
||||
property string fontFamily: "Hack"
|
||||
property int fontSize: 18
|
||||
|
||||
NumberAnimation { to: 0; duration: 500; easing.type: "OutQuad" }
|
||||
NumberAnimation { to: 1; duration: 500; easing.type: "InQuad" }
|
||||
delegate: Column {
|
||||
Rectangle {
|
||||
width: output.contentWidth
|
||||
height: mLine ? 2 : 0
|
||||
color: "#c0c0ff"
|
||||
}
|
||||
|
||||
Text {
|
||||
x: 2
|
||||
padding: 2
|
||||
textFormat: Text.PlainText
|
||||
font.family: output.fontFamily
|
||||
font.pixelSize: output.fontSize
|
||||
text: mRichText ? "" : mText
|
||||
color: mColor
|
||||
font.bold: mBold
|
||||
visible: !mRichText
|
||||
}
|
||||
|
||||
Text {
|
||||
x: 2
|
||||
padding: 2
|
||||
textFormat: Text.RichText
|
||||
font.family: output.fontFamily
|
||||
font.pixelSize: output.fontSize
|
||||
text: mRichText ? mText : ""
|
||||
color: mColor
|
||||
font.bold: mBold
|
||||
visible: mRichText
|
||||
|
||||
MouseArea {
|
||||
width: parent.paintedWidth
|
||||
height: parent.paintedHeight
|
||||
|
||||
onPressed: {
|
||||
// custom link handling, since 'onLinkActivated' does not work within a Flickable
|
||||
var link = parent.linkAt(mouse.x, mouse.y)
|
||||
if(link.length) {
|
||||
Qt.openUrlExternally(link)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
onFlickStarted: forceActiveFocus()
|
||||
|
||||
Component.onCompleted: later(function () {
|
||||
Lisp.call("editor:delayed-ini")
|
||||
})
|
||||
}
|
||||
|
||||
ListModel {
|
||||
id: outputModel
|
||||
objectName: "output_model"
|
||||
|
||||
function appendOutput(text) {
|
||||
append(text)
|
||||
output.contentX = 0
|
||||
output.positionViewAtEnd()
|
||||
}
|
||||
}
|
||||
|
||||
ProgressBar {
|
||||
objectName: "progress"
|
||||
width: main.width
|
||||
z: 1
|
||||
indeterminate: true
|
||||
enabled: visible
|
||||
visible: false
|
||||
}
|
||||
|
||||
// move history buttons
|
||||
|
||||
Rectangle {
|
||||
id: buttonsBottom
|
||||
width: rowButtonsBottom.width
|
||||
height: rowButtonsBottom.height
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
opacity: 0.7
|
||||
visible: command.activeFocus
|
||||
|
||||
Row {
|
||||
id: rowButtonsBottom
|
||||
padding: 4
|
||||
spacing: 6
|
||||
|
||||
Ext.MenuButton {
|
||||
objectName: "history_back"
|
||||
text: "\uf100"
|
||||
}
|
||||
Ext.MenuButton {
|
||||
objectName: "history_forward"
|
||||
text: "\uf101"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// paren buttons (above keyboard)
|
||||
|
||||
Rectangle {
|
||||
objectName: "rect_paren_buttons"
|
||||
width: rowParens.width
|
||||
height: rowParens.height
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
anchors.bottom: parent.bottom
|
||||
color: "transparent"
|
||||
visible: Qt.inputMethod.visible
|
||||
|
||||
Row {
|
||||
id: rowParens
|
||||
padding: 5
|
||||
spacing: 5
|
||||
|
||||
Ext.ParenButton {
|
||||
source: "img/paren-open.png"
|
||||
onClicked: Lisp.call("editor:insert", "(")
|
||||
}
|
||||
Ext.ParenButton {
|
||||
source: "img/paren-close.png"
|
||||
onClicked: Lisp.call("editor:insert", ")")
|
||||
onPressAndHold: Lisp.call("editor:close-all-parens")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// arrow buttons (cursor movement)
|
||||
|
||||
Rectangle {
|
||||
id: rectArrows
|
||||
objectName: "rect_arrows"
|
||||
width: arrows.width + 20
|
||||
height: width
|
||||
anchors.right: rectOutput.right
|
||||
anchors.bottom: rectOutput.bottom
|
||||
color: "transparent"
|
||||
visible: Qt.inputMethod.visible
|
||||
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
onPressed: Lisp.call("editor:ensure-focus")
|
||||
}
|
||||
|
||||
Item {
|
||||
id: arrows
|
||||
width: up.width * 3
|
||||
height: width
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
|
||||
Ext.ArrowButton {
|
||||
id: up
|
||||
objectName: "up"
|
||||
text: "\uf139"
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
}
|
||||
|
||||
Ext.ArrowButton {
|
||||
objectName: "left"
|
||||
text: "\uf137"
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
}
|
||||
|
||||
Ext.ArrowButton {
|
||||
objectName: "right"
|
||||
text: "\uf138"
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
anchors.right: parent.right
|
||||
}
|
||||
|
||||
Ext.ArrowButton {
|
||||
objectName: "down"
|
||||
text: "\uf13a"
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
anchors.bottom: parent.bottom
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Component {
|
||||
id: cursor
|
||||
|
||||
Rectangle {
|
||||
width: 2
|
||||
color: "blue"
|
||||
visible: parent.activeFocus
|
||||
|
||||
SequentialAnimation on opacity {
|
||||
running: true
|
||||
loops: Animation.Infinite
|
||||
|
||||
NumberAnimation { to: 0; duration: 500; easing.type: "OutQuad" }
|
||||
NumberAnimation { to: 1; duration: 500; easing.type: "InQuad" }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -245,161 +521,11 @@ StackView {
|
|||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
id: rectCommand
|
||||
objectName: "rect_command"
|
||||
y: flickEdit.height
|
||||
width: parent.width
|
||||
height: command.font.pixelSize + 11
|
||||
border.width: 2
|
||||
border.color: command.focus ? "#0066ff" : "lightgray"
|
||||
|
||||
Ext.Flickable {
|
||||
id: flickCommand
|
||||
objectName: "flick_command"
|
||||
anchors.fill: parent
|
||||
contentWidth: command.paintedWidth
|
||||
contentHeight: command.paintedHeight
|
||||
|
||||
TextEdit {
|
||||
id: command
|
||||
objectName: "command"
|
||||
width: flickCommand.width
|
||||
height: flickCommand.height
|
||||
padding: 4
|
||||
font.family: "Hack"
|
||||
font.pixelSize: 18
|
||||
selectionColor: "firebrick"
|
||||
inputMethodHints: Qt.ImhNoAutoUppercase | Qt.ImhNoPredictiveText | Qt.ImhNoTextHandles | Qt.ImhNoEditMenu
|
||||
cursorDelegate: cursor
|
||||
focus: true
|
||||
|
||||
Keys.onUpPressed: Lisp.call("editor:history-move", "back")
|
||||
Keys.onDownPressed: Lisp.call("editor:history-move", "forward")
|
||||
Keys.onTabPressed: edit.forceActiveFocus()
|
||||
|
||||
onCursorRectangleChanged: flickCommand.ensureVisible(cursorRectangle)
|
||||
|
||||
Component.onCompleted: later(function() {
|
||||
Lisp.call(textDocument, "editor:set-text-document", objectName)
|
||||
})
|
||||
|
||||
MouseArea {
|
||||
width: Math.max(rectCommand.width, command.paintedWidth)
|
||||
height: Math.max(rectCommand.height, command.paintedHeight)
|
||||
|
||||
onPressed: {
|
||||
// seems necessary to consistently move cursor by tapping
|
||||
command.forceActiveFocus()
|
||||
command.cursorPosition = command.positionAt(mouse.x, mouse.y)
|
||||
Qt.inputMethod.show() // needed for edge case (since we have 2 input fields)
|
||||
Lisp.call("editor:set-focus-editor", command.objectName)
|
||||
Lisp.call("editor:ensure-output-visible")
|
||||
}
|
||||
|
||||
onPressAndHold: Lisp.call("editor:copy-paste", command.cursorPosition)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ProgressBar {
|
||||
objectName: "progress"
|
||||
anchors.top: rectCommand.bottom
|
||||
width: main.width
|
||||
z: 1
|
||||
indeterminate: true
|
||||
enabled: visible
|
||||
visible: false
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
id: rectOutput
|
||||
objectName: "rect_output"
|
||||
y: flickEdit.height + rectCommand.height
|
||||
width: main.width
|
||||
height: main.halfHeight()
|
||||
|
||||
ListView {
|
||||
id: output
|
||||
objectName: "output"
|
||||
anchors.fill: parent
|
||||
contentWidth: parent.width * 5
|
||||
clip: true
|
||||
model: outputModel
|
||||
flickableDirection: Flickable.HorizontalAndVerticalFlick
|
||||
|
||||
property string fontFamily: "Hack"
|
||||
property int fontSize: 18
|
||||
|
||||
delegate: Column {
|
||||
Rectangle {
|
||||
width: output.contentWidth
|
||||
height: mLine ? 2 : 0
|
||||
color: "#c0c0ff"
|
||||
}
|
||||
|
||||
Text {
|
||||
x: 2
|
||||
padding: 2
|
||||
textFormat: Text.PlainText
|
||||
font.family: output.fontFamily
|
||||
font.pixelSize: output.fontSize
|
||||
text: mRichText ? "" : mText
|
||||
color: mColor
|
||||
font.bold: mBold
|
||||
visible: !mRichText
|
||||
}
|
||||
|
||||
Text {
|
||||
x: 2
|
||||
padding: 2
|
||||
textFormat: Text.RichText
|
||||
font.family: output.fontFamily
|
||||
font.pixelSize: output.fontSize
|
||||
text: mRichText ? mText : ""
|
||||
color: mColor
|
||||
font.bold: mBold
|
||||
visible: mRichText
|
||||
|
||||
MouseArea {
|
||||
width: parent.paintedWidth
|
||||
height: parent.paintedHeight
|
||||
|
||||
onPressed: {
|
||||
// custom link handling, since 'onLinkActivated' does not work within a Flickable
|
||||
var link = parent.linkAt(mouse.x, mouse.y)
|
||||
if(link.length) {
|
||||
Qt.openUrlExternally(link)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
onFlickStarted: forceActiveFocus()
|
||||
|
||||
Component.onCompleted: later(function () {
|
||||
Lisp.call("editor:delayed-ini")
|
||||
})
|
||||
}
|
||||
|
||||
ListModel {
|
||||
id: outputModel
|
||||
objectName: "output_model"
|
||||
|
||||
function appendOutput(text) {
|
||||
append(text)
|
||||
output.contentX = 0
|
||||
output.positionViewAtEnd()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Ext.MenuButton {
|
||||
id: showMenu
|
||||
objectName: "show_menu"
|
||||
x: parent.width - width - 4
|
||||
anchors.right: parent.right
|
||||
anchors.rightMargin: 4
|
||||
y: 4
|
||||
opacity: 0.7
|
||||
text: "\uf142"
|
||||
|
|
@ -454,31 +580,6 @@ StackView {
|
|||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
id: buttonsBottom
|
||||
width: rowButtonsBottom.width
|
||||
height: rowButtonsBottom.height
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
anchors.top: rectOutput.top
|
||||
opacity: 0.7
|
||||
visible: command.activeFocus
|
||||
|
||||
Row {
|
||||
id: rowButtonsBottom
|
||||
padding: 4
|
||||
spacing: 6
|
||||
|
||||
Ext.MenuButton {
|
||||
objectName: "history_back"
|
||||
text: "\uf100"
|
||||
}
|
||||
Ext.MenuButton {
|
||||
objectName: "history_forward"
|
||||
text: "\uf101"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// animations for showing/hiding editor menu buttons
|
||||
|
||||
NumberAnimation {
|
||||
|
|
@ -522,93 +623,12 @@ StackView {
|
|||
duration: 500
|
||||
easing.type: Easing.InExpo
|
||||
}
|
||||
|
||||
// paren buttons (above keyboard)
|
||||
|
||||
Rectangle {
|
||||
objectName: "rect_paren_buttons"
|
||||
width: rowParens.width
|
||||
height: rowParens.height
|
||||
anchors.horizontalCenter: rectOutput.horizontalCenter
|
||||
anchors.bottom: rectOutput.bottom
|
||||
color: "transparent"
|
||||
visible: Qt.inputMethod.visible
|
||||
|
||||
Row {
|
||||
id: rowParens
|
||||
padding: 5
|
||||
spacing: 5
|
||||
|
||||
Ext.ParenButton {
|
||||
source: "img/paren-open.png"
|
||||
onClicked: Lisp.call("editor:insert", "(")
|
||||
}
|
||||
Ext.ParenButton {
|
||||
source: "img/paren-close.png"
|
||||
onClicked: Lisp.call("editor:insert", ")")
|
||||
onPressAndHold: Lisp.call("editor:close-all-parens")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// arrow buttons (cursor movement)
|
||||
|
||||
Rectangle {
|
||||
id: rectArrows
|
||||
objectName: "rect_arrows"
|
||||
width: arrows.width + 20
|
||||
height: width
|
||||
anchors.right: rectOutput.right
|
||||
anchors.bottom: rectOutput.bottom
|
||||
color: "transparent"
|
||||
visible: Qt.inputMethod.visible
|
||||
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
onPressed: Lisp.call("editor:ensure-focus")
|
||||
}
|
||||
|
||||
Item {
|
||||
id: arrows
|
||||
width: up.width * 3
|
||||
height: width
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
|
||||
Ext.ArrowButton {
|
||||
id: up
|
||||
objectName: "up"
|
||||
text: "\uf139"
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
}
|
||||
|
||||
Ext.ArrowButton {
|
||||
objectName: "left"
|
||||
text: "\uf137"
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
}
|
||||
|
||||
Ext.ArrowButton {
|
||||
objectName: "right"
|
||||
text: "\uf138"
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
anchors.right: parent.right
|
||||
}
|
||||
|
||||
Ext.ArrowButton {
|
||||
objectName: "down"
|
||||
text: "\uf13a"
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
anchors.bottom: parent.bottom
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// custom font loader
|
||||
|
||||
function loadFont(file) {
|
||||
var font = Qt.createQmlObject("import QtQuick 2.10; FontLoader { source: '" + file + "' }", main)
|
||||
var font = Qt.createQmlObject("import QtQuick 2.15; FontLoader { source: '" + file + "' }", main)
|
||||
return font.name
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue