Add clickable bread crumbs.

Clicking a parent path changes the root project directory.
This commit is contained in:
2026-02-07 21:17:27 -05:00
parent aa42ec6072
commit f918d65888
8 changed files with 124 additions and 35 deletions

View File

@@ -14,6 +14,7 @@ fn main() {
"qml/Components/ClideHandle.qml",
"qml/Components/ClideMenu.qml",
"qml/Components/ClideMenuItem.qml",
"qml/Components/ClideBreadCrumbs.qml",
"qml/Logger/Logger.qml",
]))
// Link Qt's Network library

View File

@@ -48,40 +48,17 @@ SplitView {
ColumnLayout {
spacing: 2
// TODO: Make a ClideBreadCrumb element to support select parent paths as root
Rectangle {
color: RustColors.explorer_background
height: 25
width: navigationView.width
ClideBreadCrumbs {
id: breadCrumb
Text {
id: breadCrumb
Layout.bottomMargin: 5
Layout.leftMargin: 15
Layout.topMargin: 5
path: clideTreeView.rootDirectory
anchors.fill: parent
color: RustColors.explorer_text
elide: Text.ElideLeft
horizontalAlignment: Text.AlignHCenter
text: clideTreeView.rootDirectory
verticalAlignment: Text.AlignVCenter
}
TapHandler {
acceptedButtons: Qt.RightButton
onSingleTapped: (eventPoint, button) => contextMenu.popup()
}
ClideMenu {
id: contextMenu
ClideMenuItem {
action: Action {
text: qsTr("Reset root")
onTriggered: {
Logger.log("Resetting root directory: " + clideTreeView.originalRootDirectory);
clideTreeView.rootDirectory = clideTreeView.originalRootDirectory;
}
}
}
onCrumbClicked: path => {
Logger.trace("Crumb clicked: " + path);
clideTreeView.rootDirectory = path;
}
}
ClideTreeView {
@@ -97,7 +74,7 @@ SplitView {
onFileClicked: path => clideEditor.filePath = path
onRootDirectoryChanged: {
Logger.log("Setting root directory: " + clideTreeView.rootDirectory);
breadCrumb.text = clideTreeView.rootDirectory;
breadCrumb.path = clideTreeView.rootDirectory;
}
}
}

View File

@@ -0,0 +1,109 @@
import QtQuick 2.15
import QtQuick.Controls 2.15
import QtQuick.Layouts 1.15
import clide.module 1.0
import Logger 1.0
Item {
id: root
property var fullPaths: []
required property string path
property var segments: []
signal crumbClicked(string path)
function rebuildSegments() {
var cleaned = path;
if (cleaned.endsWith("/"))
cleaned = cleaned.slice(0, -1);
var parts = cleaned.split("/");
root.segments = [];
root.fullPaths = [];
var current = "";
Logger.trace("Building segments for path: " + cleaned);
for (var i = 0; i < parts.length; ++i) {
if (parts[i] === "") {
current = "/";
root.segments.push("/");
root.fullPaths.push("/");
} else {
if (current === "/")
current += parts[i];
else
current += "/" + parts[i];
Logger.trace("Pushing path: " + parts[i] + " Current: " + current);
root.segments.push(parts[i]);
root.fullPaths.push(current);
}
}
rep.model = root.segments;
}
anchors.leftMargin: 20
height: breadcrumbRow.implicitHeight
width: parent.width
Component.onCompleted: rebuildSegments()
onPathChanged: rebuildSegments()
Flow {
id: breadcrumbRow
Repeater {
id: rep
model: root.segments
delegate: Text {
id: linkText
required property string modelData
function getText() {
if (modelData === "/") {
return modelData;
}
Logger.trace("Getting valid text:" + modelData);
return modelData + "/";
}
color: mouseArea.containsMouse ? "#2a7fff" : RustColors.explorer_text
font.underline: mouseArea.containsMouse
text: getText()
MouseArea {
id: mouseArea
anchors.fill: parent
hoverEnabled: true
onClicked: {
console.log("Breadcrumb clicked:", root.fullPaths[root.segments.indexOf(modelData)]);
root.crumbClicked(root.fullPaths[root.segments.indexOf(modelData)]);
}
}
}
}
}
TapHandler {
acceptedButtons: Qt.RightButton
onSingleTapped: (eventPoint, button) => contextMenu.popup()
}
ClideMenu {
id: contextMenu
ClideMenuItem {
action: Action {
text: qsTr("Reset root")
onTriggered: {
Logger.log("Resetting root directory: " + clideTreeView.originalRootDirectory);
clideTreeView.rootDirectory = clideTreeView.originalRootDirectory;
}
}
}
}
}

View File

@@ -5,9 +5,10 @@ import clide.module 1.0
Menu {
background: Rectangle {
border.color: Qt.darker(RustColors.menubar, 2)
border.color: RustColors.hovered
border.width: 10
color: RustColors.menubar
implicitWidth: 100
radius: 2
radius: 5
}
}

View File

@@ -2,3 +2,4 @@ ClideScrollBar ClideScrollBar.qml
ClideHandle ClideHandle.qml
ClideMenu ClideMenu.qml
ClideMenuItem ClideMenuItem.qml
ClideBreadCrumbs ClideBreadCrumbs.qml

Binary file not shown.

Binary file not shown.

Binary file not shown.