import QtQuick import QtQuick.Controls import QtQuick.Layouts import clide.module 1.0 SplitView { Layout.fillHeight: true Layout.fillWidth: true orientation: Qt.Vertical // Customized handle to drag between the Editor and the Console. handle: Rectangle { border.color: SplitHandle.hovered ? "#2b2b2b" : "#3c3f41" color: SplitHandle.pressed ? "#4b4f51" : "#3c3f41" implicitHeight: 8 opacity: SplitHandle.hovered || areaConsole.height < 15 ? 1.0 : 0.0 Behavior on opacity { OpacityAnimator { duration: 1400 } } } RowLayout { // We use a flickable to synchronize the position of the editor and // the line numbers. This is necessary because the line numbers can // extend the available height. Flickable { id: lineNumbers Layout.fillHeight: true Layout.fillWidth: false // Calculate the width based on the logarithmic scale. Layout.preferredWidth: fontMetrics.averageCharacterWidth * (Math.floor(Math.log10(areaText.lineCount)) + 1) + 10 contentY: editorFlickable.contentY interactive: false visible: true Column { anchors.fill: parent topPadding: 6 Repeater { id: repeatedLineNumbers // Each line number in the gutter. delegate: Item { required property int index height: 17 width: parent.width Label { id: numbers color: "white" font: areaText.font height: parent.height horizontalAlignment: Text.AlignLeft text: parent.index + 1 verticalAlignment: Text.AlignVCenter width: parent.width } Rectangle { id: indicator anchors.left: numbers.right color: Qt.darker("#FFF", 3) height: parent.height width: 1 } } model: areaText.lineCount } } } Flickable { id: editorFlickable property alias areaText: areaText Layout.fillHeight: true Layout.fillWidth: true boundsBehavior: Flickable.StopAtBounds height: 650 ScrollBar.horizontal: MyScrollBar { } ScrollBar.vertical: MyScrollBar { } TextArea.flickable: TextArea { id: areaText color: "#ccced3" focus: true persistentSelection: true selectByMouse: true // selectedTextColor: control.palette.highlightedText // selectionColor: control.palette.highlight textFormat: Qt.AutoText wrapMode: TextArea.Wrap background: Rectangle { color: "#2b2b2b" } onLinkActivated: function (link) { Qt.openUrlExternally(link); } // TODO: Handle saving // Component.onCompleted: { // if (Qt.application.arguments.length === 2) // textDocument.source = "file:" + Qt.application.arguments[1] // else // textDocument.source = "qrc:/texteditor.html" // } // textDocument.onStatusChanged: { // // a message lookup table using computed properties: // // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Object_initializer // const statusMessages = { // [ TextDocument.ReadError ]: qsTr("Failed to load “%1”"), // [ TextDocument.WriteError ]: qsTr("Failed to save “%1”"), // [ TextDocument.NonLocalFileError ]: qsTr("Not a local file: “%1”"), // } // const err = statusMessages[textDocument.status] // if (err) { // errorDialog.text = err.arg(textDocument.source) // errorDialog.open() // } // } } FontMetrics { id: fontMetrics font: areaText.font } } } TextArea { id: areaConsole height: 100 placeholderText: qsTr("Placeholder for bash terminal.") placeholderTextColor: "white" readOnly: true wrapMode: TextArea.Wrap background: Rectangle { color: "#2b2b2b" implicitHeight: 100 // border.color: control.enabled ? "#21be2b" : "transparent" } } // We use an inline component to customize the horizontal and vertical // scroll-bars. This is convenient when the component is only used in one file. component MyScrollBar: ScrollBar { id: scrollBar // Scroll bar gutter background: Rectangle { color: "#3b3b3b" implicitHeight: scrollBar.interactive ? 8 : 4 implicitWidth: scrollBar.interactive ? 8 : 4 opacity: scrollBar.active && scrollBar.size < 1.0 ? 1.0 : 0.0 Behavior on opacity { OpacityAnimator { duration: 500 } } } // Scroll bar contentItem: Rectangle { color: "#4b4f51" implicitHeight: scrollBar.interactive ? 8 : 4 implicitWidth: scrollBar.interactive ? 8 : 4 opacity: scrollBar.active && scrollBar.size < 1.0 ? 1.0 : 0.2 Behavior on opacity { OpacityAnimator { duration: 1000 } } } } }