From ffc13f71b7ccee3762f5c2da19057a72c0f3ffa7 Mon Sep 17 00:00:00 2001 From: purian23 Date: Sat, 20 Sep 2025 19:06:58 -0400 Subject: [PATCH] feat: Add line numbers toggle to Notepad settings --- Common/SettingsData.qml | 4 ++ Modules/Notepad/NotepadSettings.qml | 12 ++++ Modules/Notepad/NotepadTextEditor.qml | 90 ++++++++++++++++++++++++++- Widgets/DankScrollbar.qml | 2 +- 4 files changed, 104 insertions(+), 4 deletions(-) diff --git a/Common/SettingsData.qml b/Common/SettingsData.qml index a3a44d29..729d7458 100644 --- a/Common/SettingsData.qml +++ b/Common/SettingsData.qml @@ -87,9 +87,11 @@ Singleton { property bool notepadUseMonospace: true property string notepadFontFamily: "" property real notepadFontSize: 14 + property bool notepadShowLineNumbers: false onNotepadUseMonospaceChanged: saveSettings() onNotepadFontFamilyChanged: saveSettings() onNotepadFontSizeChanged: saveSettings() + onNotepadShowLineNumbersChanged: saveSettings() property bool gtkThemingEnabled: false property bool qtThemingEnabled: false property bool showDock: false @@ -264,6 +266,7 @@ Singleton { notepadUseMonospace = settings.notepadUseMonospace !== undefined ? settings.notepadUseMonospace : true notepadFontFamily = settings.notepadFontFamily !== undefined ? settings.notepadFontFamily : "" notepadFontSize = settings.notepadFontSize !== undefined ? settings.notepadFontSize : 14 + notepadShowLineNumbers = settings.notepadShowLineNumbers !== undefined ? settings.notepadShowLineNumbers : false gtkThemingEnabled = settings.gtkThemingEnabled !== undefined ? settings.gtkThemingEnabled : false qtThemingEnabled = settings.qtThemingEnabled !== undefined ? settings.qtThemingEnabled : false showDock = settings.showDock !== undefined ? settings.showDock : false @@ -370,6 +373,7 @@ Singleton { "notepadUseMonospace": notepadUseMonospace, "notepadFontFamily": notepadFontFamily, "notepadFontSize": notepadFontSize, + "notepadShowLineNumbers": notepadShowLineNumbers, "gtkThemingEnabled": gtkThemingEnabled, "qtThemingEnabled": qtThemingEnabled, "showDock": showDock, diff --git a/Modules/Notepad/NotepadSettings.qml b/Modules/Notepad/NotepadSettings.qml index 1bca53d2..3fcc893e 100644 --- a/Modules/Notepad/NotepadSettings.qml +++ b/Modules/Notepad/NotepadSettings.qml @@ -143,6 +143,18 @@ Item { } } + DankToggle { + anchors.left: parent.left + anchors.leftMargin: -Theme.spacingM + width: parent.width + Theme.spacingM + text: "Show Line Numbers" + description: "Display line numbers in editor" + checked: SettingsData.notepadShowLineNumbers + onToggled: checked => { + SettingsData.notepadShowLineNumbers = checked + } + } + Rectangle { width: parent.width height: visible ? (fontDropdown.height + Theme.spacingS) : 0 diff --git a/Modules/Notepad/NotepadTextEditor.qml b/Modules/Notepad/NotepadTextEditor.qml index 52ab4661..9f157f26 100644 --- a/Modules/Notepad/NotepadTextEditor.qml +++ b/Modules/Notepad/NotepadTextEditor.qml @@ -63,6 +63,26 @@ Column { saveCurrentTabContent() } + function setTextDocumentLineHeight() { + return + } + + property string lastTextForLineModel: "" + property var lineModel: [] + + function updateLineModel() { + if (!SettingsData.notepadShowLineNumbers) { + lineModel = [] + lastTextForLineModel = "" + return + } + + if (textArea.text !== lastTextForLineModel || lineModel.length === 0) { + lastTextForLineModel = textArea.text + lineModel = textArea.text.split('\n') + } + } + spacing: Theme.spacingM StyledRect { @@ -73,16 +93,70 @@ Column { border.width: 1 radius: Theme.cornerRadius - ScrollView { + DankFlickable { + id: flickable anchors.fill: parent anchors.margins: 1 clip: true + contentWidth: width - 11 - TextArea { + Rectangle { + id: lineNumberArea + anchors.left: parent.left + anchors.top: parent.top + width: SettingsData.notepadShowLineNumbers ? Math.max(30, 32 + Theme.spacingXS) : 0 + height: textArea.contentHeight + textArea.topPadding + textArea.bottomPadding + color: "transparent" + visible: SettingsData.notepadShowLineNumbers + + ListView { + id: lineNumberList + anchors.top: parent.top + anchors.topMargin: textArea.topPadding + anchors.right: parent.right + anchors.rightMargin: 2 + width: 32 + height: textArea.contentHeight + model: SettingsData.notepadShowLineNumbers ? root.lineModel : [] + interactive: false + spacing: 0 + + delegate: Item { + id: lineDelegate + required property int index + required property string modelData + width: 32 + height: measuringText.contentHeight + + Text { + id: measuringText + width: textArea.width - textArea.leftPadding - textArea.rightPadding + text: modelData || " " + font: textArea.font + wrapMode: Text.Wrap + visible: false + } + + StyledText { + anchors.right: parent.right + anchors.rightMargin: 4 + anchors.top: parent.top + text: index + 1 + font.family: textArea.font.family + font.pixelSize: textArea.font.pixelSize + color: Qt.rgba(Theme.surfaceText.r, Theme.surfaceText.g, Theme.surfaceText.b, 0.4) + horizontalAlignment: Text.AlignRight + } + } + } + } + + TextArea.flickable: TextArea { id: textArea placeholderText: qsTr("Start typing your notes here...") font.family: SettingsData.notepadUseMonospace ? SettingsData.monoFontFamily : (SettingsData.notepadFontFamily || SettingsData.fontFamily) font.pixelSize: SettingsData.notepadFontSize * SettingsData.fontScale + font.letterSpacing: 0 color: Theme.surfaceText selectByMouse: true selectByKeyboard: true @@ -93,13 +167,15 @@ Column { inputMethodHints: Qt.ImhNoPredictiveText | Qt.ImhNoAutoUppercase persistentSelection: true tabStopDistance: 40 - leftPadding: Theme.spacingM + leftPadding: (SettingsData.notepadShowLineNumbers ? lineNumberArea.width + Theme.spacingXS : Theme.spacingM) topPadding: Theme.spacingM rightPadding: Theme.spacingM bottomPadding: Theme.spacingM Component.onCompleted: { loadCurrentTabContent() + setTextDocumentLineHeight() + root.updateLineModel() } Connections { @@ -114,11 +190,19 @@ Column { } } + Connections { + target: SettingsData + function onNotepadShowLineNumbersChanged() { + root.updateLineModel() + } + } + onTextChanged: { if (contentLoaded && text !== lastSavedContent) { autoSaveTimer.restart() } root.contentChanged() + root.updateLineModel() } Keys.onEscapePressed: (event) => { diff --git a/Widgets/DankScrollbar.qml b/Widgets/DankScrollbar.qml index 2a19e4e3..275ab4a7 100644 --- a/Widgets/DankScrollbar.qml +++ b/Widgets/DankScrollbar.qml @@ -12,7 +12,7 @@ ScrollBar { policy: (parent && parent.contentHeight > parent.height) ? ScrollBar.AsNeeded : ScrollBar.AlwaysOff minimumSize: 0.08 - implicitWidth: 10 + implicitWidth: 8 interactive: true hoverEnabled: true z: 1000