TUI #1

Merged
shaunrd0 merged 73 commits from ui into master 2026-01-25 20:57:37 +00:00
3 changed files with 36 additions and 21 deletions
Showing only changes of commit 365940267f - Show all commits

View File

@ -35,31 +35,36 @@ SplitView {
// extend the available height. // extend the available height.
Flickable { Flickable {
id: lineNumbers id: lineNumbers
Layout.fillHeight: true Layout.fillHeight: true
Layout.fillWidth: false Layout.fillWidth: false
// Calculating the width correctly is important as the number grows.
// Calculate the width based on the logarithmic scale. // We need to ensure space required to show N line number digits.
// We use log10 to find how many digits are needed in a line number.
// log10(9) ~= .95; log10(10) = 1.0; log10(100) = 2.0 ...etc
// We +1 to ensure space for at least 1 digit, as floor(1.95) = 1.
// The +10 is additional spacing and can be adjusted.
Layout.preferredWidth: fontMetrics.averageCharacterWidth * (Math.floor(Math.log10(textArea.lineCount)) + 1) + 10 Layout.preferredWidth: fontMetrics.averageCharacterWidth * (Math.floor(Math.log10(textArea.lineCount)) + 1) + 10
contentY: editorFlickable.contentY contentY: editorFlickable.contentY
interactive: false interactive: false
visible: true
Column { Column {
anchors.fill: parent anchors.fill: parent
topPadding: 6 topPadding: textArea.topPadding
Repeater { Repeater {
id: repeatedLineNumbers id: repeatedLineNumbers
// TODO: Bug where text wrapping shows as new line number.
model: textArea.lineCount
// Each line number in the gutter. // This Item is used for each line number in the gutter.
delegate: Item { delegate: Item {
required property int index // Calculates the height of each line in the text area.
// Calculate the height of each line in the text area.
height: textArea.contentHeight / textArea.lineCount height: textArea.contentHeight / textArea.lineCount
width: parent.width width: parent.width
required property int index
// Show the line number.
Label { Label {
id: numbers id: numbers
@ -69,8 +74,9 @@ SplitView {
horizontalAlignment: Text.AlignLeft horizontalAlignment: Text.AlignLeft
text: parent.index + 1 text: parent.index + 1
verticalAlignment: Text.AlignVCenter verticalAlignment: Text.AlignVCenter
width: parent.width width: parent.width - indicator.width
} }
// Draw edge along the right side of the line number.
Rectangle { Rectangle {
id: indicator id: indicator
@ -80,14 +86,11 @@ SplitView {
width: 1 width: 1
} }
} }
// TODO: Bug where text wrapping shows as new line number.
model: textArea.lineCount
} }
} }
} }
Flickable { Flickable {
id: editorFlickable id: editorFlickable
Layout.fillHeight: true Layout.fillHeight: true
Layout.fillWidth: true Layout.fillWidth: true
boundsBehavior: Flickable.StopAtBounds boundsBehavior: Flickable.StopAtBounds
@ -97,6 +100,7 @@ SplitView {
} }
ScrollBar.vertical: MyScrollBar { ScrollBar.vertical: MyScrollBar {
} }
TextArea.flickable: TextArea { TextArea.flickable: TextArea {
id: textArea id: textArea
@ -104,8 +108,8 @@ SplitView {
focus: true focus: true
persistentSelection: true persistentSelection: true
selectByMouse: true selectByMouse: true
// selectedTextColor: RustColors.editor_highlighted_text selectedTextColor: RustColors.editor_highlighted_text
// selectionColor: RustColors.editor_highlight selectionColor: RustColors.editor_highlight
textFormat: Qt.AutoText textFormat: Qt.AutoText
wrapMode: TextArea.Wrap wrapMode: TextArea.Wrap
text: FileSystem.readFile(root.filePath) text: FileSystem.readFile(root.filePath)

View File

@ -77,7 +77,7 @@ impl Default for RustColorsImpl {
active: QColor::try_from("#a9acb0").unwrap(), active: QColor::try_from("#a9acb0").unwrap(),
inactive: QColor::try_from("#FFF").unwrap(), inactive: QColor::try_from("#FFF").unwrap(),
editor_background: QColor::try_from("#2b2b2b").unwrap(), editor_background: QColor::try_from("#2b2b2b").unwrap(),
editor_text: QColor::try_from("#ccced3").unwrap(), editor_text: QColor::try_from("#acaea3").unwrap(),
editor_highlighted_text: QColor::try_from("#ccced3").unwrap(), editor_highlighted_text: QColor::try_from("#ccced3").unwrap(),
editor_highlight: QColor::try_from("#ccced3").unwrap(), editor_highlight: QColor::try_from("#ccced3").unwrap(),
gutter: QColor::try_from("#1e1f22").unwrap(), gutter: QColor::try_from("#1e1f22").unwrap(),

View File

@ -42,6 +42,8 @@ pub mod qobject {
use cxx_qt_lib::{QModelIndex, QString}; use cxx_qt_lib::{QModelIndex, QString};
use dirs; use dirs;
use std::fs; use std::fs;
use std::fs::FileType;
use log::warn;
// TODO: Impleent a provider for QFileSystemModel::setIconProvider for icons. // TODO: Impleent a provider for QFileSystemModel::setIconProvider for icons.
pub struct FileSystemImpl { pub struct FileSystemImpl {
@ -64,11 +66,20 @@ impl qobject::FileSystem {
if path.is_empty() { if path.is_empty() {
return QString::default(); return QString::default();
} }
// TODO: What if the file is binary or something horrible? // TODO: Use syntect for syntax highlighting?
// https://github.com/trishume/syntect/blob/master/examples/syncat.rs
if fs::metadata(path.to_string())
.expect(format!("Failed to get file metadata {}", path).as_str())
.is_file()
{
QString::from( QString::from(
fs::read_to_string(path.to_string()) fs::read_to_string(path.to_string())
.expect(format!("Failed to read file {}", path).as_str()), .expect(format!("Failed to read file {}", path).as_str()),
) )
} else {
warn!("Attempted to open file {} that is not a valid file", path);
QString::default()
}
} }
// There will never be more than one column. // There will never be more than one column.