Add clickable bread crumbs.
Clicking a parent path changes the root project directory.
This commit is contained in:
1
build.rs
1
build.rs
@@ -14,6 +14,7 @@ fn main() {
|
|||||||
"qml/Components/ClideHandle.qml",
|
"qml/Components/ClideHandle.qml",
|
||||||
"qml/Components/ClideMenu.qml",
|
"qml/Components/ClideMenu.qml",
|
||||||
"qml/Components/ClideMenuItem.qml",
|
"qml/Components/ClideMenuItem.qml",
|
||||||
|
"qml/Components/ClideBreadCrumbs.qml",
|
||||||
"qml/Logger/Logger.qml",
|
"qml/Logger/Logger.qml",
|
||||||
]))
|
]))
|
||||||
// Link Qt's Network library
|
// Link Qt's Network library
|
||||||
|
|||||||
@@ -48,40 +48,17 @@ SplitView {
|
|||||||
ColumnLayout {
|
ColumnLayout {
|
||||||
spacing: 2
|
spacing: 2
|
||||||
|
|
||||||
// TODO: Make a ClideBreadCrumb element to support select parent paths as root
|
ClideBreadCrumbs {
|
||||||
Rectangle {
|
|
||||||
color: RustColors.explorer_background
|
|
||||||
height: 25
|
|
||||||
width: navigationView.width
|
|
||||||
|
|
||||||
Text {
|
|
||||||
id: breadCrumb
|
id: breadCrumb
|
||||||
|
|
||||||
anchors.fill: parent
|
Layout.bottomMargin: 5
|
||||||
color: RustColors.explorer_text
|
Layout.leftMargin: 15
|
||||||
elide: Text.ElideLeft
|
Layout.topMargin: 5
|
||||||
horizontalAlignment: Text.AlignHCenter
|
path: clideTreeView.rootDirectory
|
||||||
text: clideTreeView.rootDirectory
|
|
||||||
verticalAlignment: Text.AlignVCenter
|
|
||||||
}
|
|
||||||
TapHandler {
|
|
||||||
acceptedButtons: Qt.RightButton
|
|
||||||
|
|
||||||
onSingleTapped: (eventPoint, button) => contextMenu.popup()
|
onCrumbClicked: path => {
|
||||||
}
|
Logger.trace("Crumb clicked: " + path);
|
||||||
ClideMenu {
|
clideTreeView.rootDirectory = path;
|
||||||
id: contextMenu
|
|
||||||
|
|
||||||
ClideMenuItem {
|
|
||||||
action: Action {
|
|
||||||
text: qsTr("Reset root")
|
|
||||||
|
|
||||||
onTriggered: {
|
|
||||||
Logger.log("Resetting root directory: " + clideTreeView.originalRootDirectory);
|
|
||||||
clideTreeView.rootDirectory = clideTreeView.originalRootDirectory;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ClideTreeView {
|
ClideTreeView {
|
||||||
@@ -97,7 +74,7 @@ SplitView {
|
|||||||
onFileClicked: path => clideEditor.filePath = path
|
onFileClicked: path => clideEditor.filePath = path
|
||||||
onRootDirectoryChanged: {
|
onRootDirectoryChanged: {
|
||||||
Logger.log("Setting root directory: " + clideTreeView.rootDirectory);
|
Logger.log("Setting root directory: " + clideTreeView.rootDirectory);
|
||||||
breadCrumb.text = clideTreeView.rootDirectory;
|
breadCrumb.path = clideTreeView.rootDirectory;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
109
qml/Components/ClideBreadCrumbs.qml
Normal file
109
qml/Components/ClideBreadCrumbs.qml
Normal 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -5,9 +5,10 @@ import clide.module 1.0
|
|||||||
|
|
||||||
Menu {
|
Menu {
|
||||||
background: Rectangle {
|
background: Rectangle {
|
||||||
border.color: Qt.darker(RustColors.menubar, 2)
|
border.color: RustColors.hovered
|
||||||
|
border.width: 10
|
||||||
color: RustColors.menubar
|
color: RustColors.menubar
|
||||||
implicitWidth: 100
|
implicitWidth: 100
|
||||||
radius: 2
|
radius: 5
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,3 +2,4 @@ ClideScrollBar ClideScrollBar.qml
|
|||||||
ClideHandle ClideHandle.qml
|
ClideHandle ClideHandle.qml
|
||||||
ClideMenu ClideMenu.qml
|
ClideMenu ClideMenu.qml
|
||||||
ClideMenuItem ClideMenuItem.qml
|
ClideMenuItem ClideMenuItem.qml
|
||||||
|
ClideBreadCrumbs ClideBreadCrumbs.qml
|
||||||
|
|||||||
BIN
resources/SauceCodeProNerdFont-Black.ttf
Normal file
BIN
resources/SauceCodeProNerdFont-Black.ttf
Normal file
Binary file not shown.
BIN
resources/SauceCodeProNerdFont-ExtraLight.ttf
Normal file
BIN
resources/SauceCodeProNerdFont-ExtraLight.ttf
Normal file
Binary file not shown.
BIN
resources/SauceCodeProNerdFont-Light.ttf
Normal file
BIN
resources/SauceCodeProNerdFont-Light.ttf
Normal file
Binary file not shown.
Reference in New Issue
Block a user