Add LineCount module.
This commit is contained in:
140
qml/Menu/ClideMenuBar.qml.autosave
Normal file
140
qml/Menu/ClideMenuBar.qml.autosave
Normal file
@@ -0,0 +1,140 @@
|
||||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
|
||||
MenuBar {
|
||||
background: Rectangle {
|
||||
color: "#3c3f41"
|
||||
border.color: "#575757"
|
||||
}
|
||||
|
||||
Action {
|
||||
id: actionNewProject
|
||||
|
||||
text: qsTr("&New Project...")
|
||||
}
|
||||
Action {
|
||||
id: actionOpen
|
||||
|
||||
text: qsTr("&Open...")
|
||||
}
|
||||
Action {
|
||||
id: actionSave
|
||||
|
||||
text: qsTr("&Save")
|
||||
}
|
||||
Action {
|
||||
id: actionExit
|
||||
|
||||
text: qsTr("&Exit")
|
||||
|
||||
onTriggered: Qt.quit()
|
||||
}
|
||||
ClideMenu {
|
||||
title: qsTr("&File")
|
||||
|
||||
ClideMenuBarItem {
|
||||
action: actionNewProject
|
||||
}
|
||||
ClideMenuBarItem {
|
||||
action: actionOpen
|
||||
}
|
||||
ClideMenuBarItem {
|
||||
action: actionSave
|
||||
}
|
||||
MenuSeparator {
|
||||
background: Rectangle {
|
||||
border.color: color
|
||||
color: "#3c3f41"
|
||||
implicitHeight: 3
|
||||
implicitWidth: 200
|
||||
}
|
||||
}
|
||||
ClideMenuBarItem {
|
||||
action: actionExit
|
||||
}
|
||||
}
|
||||
Action {
|
||||
id: actionUndo
|
||||
|
||||
text: qsTr("&Undo")
|
||||
}
|
||||
Action {
|
||||
id: actionRedo
|
||||
|
||||
text: qsTr("&Redo")
|
||||
}
|
||||
Action {
|
||||
id: actionCut
|
||||
|
||||
text: qsTr("&Cut")
|
||||
}
|
||||
Action {
|
||||
id: actionCopy
|
||||
|
||||
text: qsTr("&Copy")
|
||||
}
|
||||
Action {
|
||||
id: actionPaste
|
||||
|
||||
text: qsTr("&Paste")
|
||||
}
|
||||
ClideMenu {
|
||||
title: qsTr("&Edit")
|
||||
|
||||
ClideMenuBarItem {
|
||||
action: actionUndo
|
||||
}
|
||||
ClideMenuBarItem {
|
||||
action: actionRedo
|
||||
}
|
||||
ClideMenuBarItem {
|
||||
action: actionCut
|
||||
}
|
||||
ClideMenuBarItem {
|
||||
action: actionCopy
|
||||
}
|
||||
ClideMenuBarItem {
|
||||
action: actionPaste
|
||||
}
|
||||
}
|
||||
Action {
|
||||
id: actionToolWindows
|
||||
|
||||
text: qsTr("&Tool Windows")
|
||||
}
|
||||
Action {
|
||||
id: actionAppearance
|
||||
|
||||
text: qsTr("&Appearance")
|
||||
}
|
||||
ClideMenu {
|
||||
title: qsTr("&View")
|
||||
|
||||
ClideMenuBarItem {
|
||||
action: actionToolWindows
|
||||
}
|
||||
ClideMenuBarItem {
|
||||
action: actionAppearance
|
||||
}
|
||||
}
|
||||
Action {
|
||||
id: actionDocumentation
|
||||
|
||||
text: qsTr("&Documentation")
|
||||
}
|
||||
Action {
|
||||
id: actionAbout
|
||||
|
||||
text: qsTr("&About")
|
||||
}
|
||||
ClideMenu {
|
||||
title: qsTr("&Help")
|
||||
|
||||
ClideMenuBarItem {
|
||||
action: actionDocumentation
|
||||
}
|
||||
ClideMenuBarItem {
|
||||
action: actionAbout
|
||||
}
|
||||
}
|
||||
}
|
||||
193
qml/main.qml
193
qml/main.qml
@@ -5,6 +5,8 @@ import QtQuick.Dialogs
|
||||
|
||||
import "Menu"
|
||||
|
||||
import clide.module 1.0
|
||||
|
||||
ApplicationWindow {
|
||||
id: appWindow
|
||||
|
||||
@@ -51,7 +53,7 @@ ApplicationWindow {
|
||||
id: navigationView
|
||||
|
||||
SplitView.fillHeight: true
|
||||
SplitView.preferredWidth: 250
|
||||
SplitView.preferredWidth: 200
|
||||
color: "#303234"
|
||||
|
||||
StackLayout {
|
||||
@@ -59,9 +61,9 @@ ApplicationWindow {
|
||||
|
||||
// Shows the help text.
|
||||
TextArea {
|
||||
readOnly: true
|
||||
placeholderText: qsTr("File system view placeholder")
|
||||
placeholderTextColor: "white"
|
||||
readOnly: true
|
||||
wrapMode: TextArea.Wrap
|
||||
}
|
||||
|
||||
@@ -92,55 +94,134 @@ ApplicationWindow {
|
||||
}
|
||||
}
|
||||
|
||||
TextArea {
|
||||
id: areaText
|
||||
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
|
||||
|
||||
color: "#ccced3"
|
||||
focus: true
|
||||
persistentSelection: true
|
||||
selectByMouse: true
|
||||
// selectedTextColor: control.palette.highlightedText
|
||||
// selectionColor: control.palette.highlight
|
||||
textFormat: Qt.AutoText
|
||||
wrapMode: TextArea.Wrap
|
||||
Layout.fillHeight: true
|
||||
Layout.fillWidth: false
|
||||
|
||||
background: Rectangle {
|
||||
color: "#2b2b2b"
|
||||
implicitHeight: 650
|
||||
// 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
|
||||
|
||||
Repeater {
|
||||
id: repeatedLineNumbers
|
||||
|
||||
delegate: Item {
|
||||
required property int index
|
||||
|
||||
height: Math.ceil(fontMetrics.lineSpacing)
|
||||
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: LineCount {
|
||||
id: lineCountModel
|
||||
|
||||
// This count sets the max line numbers shown in the gutter.
|
||||
count: areaText.lineCount
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Flickable {
|
||||
id: editorFlickable
|
||||
|
||||
onLinkActivated: function (link) {
|
||||
Qt.openUrlExternally(link);
|
||||
height: 650
|
||||
|
||||
property alias areaText: areaText
|
||||
|
||||
Layout.fillHeight: true
|
||||
Layout.fillWidth: true
|
||||
boundsBehavior: Flickable.StopAtBounds
|
||||
|
||||
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
|
||||
}
|
||||
}
|
||||
|
||||
// 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()
|
||||
// }
|
||||
// }
|
||||
}
|
||||
TextArea {
|
||||
id: areaConsole
|
||||
|
||||
height: 100
|
||||
placeholderText: qsTr("Placeholder for bash terminal.")
|
||||
placeholderTextColor: "white"
|
||||
height: 100
|
||||
readOnly: true
|
||||
wrapMode: TextArea.Wrap
|
||||
|
||||
@@ -153,4 +234,36 @@ ApplicationWindow {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 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
|
||||
|
||||
background: Rectangle {
|
||||
color: "#2b2b2b"
|
||||
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
|
||||
}
|
||||
}
|
||||
}
|
||||
contentItem: Rectangle {
|
||||
color: "#4b4f51"
|
||||
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: 1000
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user