Sort folders first
This commit is contained in:
parent
05368dea2c
commit
0117a7bc02
2 changed files with 49 additions and 43 deletions
44
src/main.rs
44
src/main.rs
|
|
@ -126,7 +126,7 @@ impl App {
|
||||||
nodes.push(node);
|
nodes.push(node);
|
||||||
}
|
}
|
||||||
|
|
||||||
nodes.sort_by(|a, b| a.name().cmp(b.name()));
|
nodes.sort();
|
||||||
|
|
||||||
for node in nodes {
|
for node in nodes {
|
||||||
self.nav_model
|
self.nav_model
|
||||||
|
|
@ -143,34 +143,34 @@ impl App {
|
||||||
|
|
||||||
pub fn open_project<P: AsRef<Path>>(&mut self, path: P) {
|
pub fn open_project<P: AsRef<Path>>(&mut self, path: P) {
|
||||||
let node = match ProjectNode::new(&path) {
|
let node = match ProjectNode::new(&path) {
|
||||||
Ok(ok) => ok,
|
Ok(mut node) => {
|
||||||
|
match &mut node {
|
||||||
|
ProjectNode::Folder { open, root, .. } => {
|
||||||
|
*open = true;
|
||||||
|
*root = true;
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
log::error!(
|
||||||
|
"failed to open project {:?}: not a directory",
|
||||||
|
path.as_ref()
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
node
|
||||||
|
}
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
log::error!("failed to open project {:?}: {}", path.as_ref(), err);
|
log::error!("failed to open project {:?}: {}", path.as_ref(), err);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let project = match node {
|
|
||||||
ProjectNode::Folder { name, path, .. } => ProjectNode::Root {
|
|
||||||
name,
|
|
||||||
path,
|
|
||||||
open: true,
|
|
||||||
},
|
|
||||||
_ => {
|
|
||||||
log::error!(
|
|
||||||
"failed to open project {:?}: not a directory",
|
|
||||||
path.as_ref()
|
|
||||||
);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
let id = self
|
let id = self
|
||||||
.nav_model
|
.nav_model
|
||||||
.insert()
|
.insert()
|
||||||
.icon(icon::from_name(project.icon_name()).size(16).icon())
|
.icon(icon::from_name(node.icon_name()).size(16).icon())
|
||||||
.text(project.name().to_string())
|
.text(node.name().to_string())
|
||||||
.data(project)
|
.data(node)
|
||||||
.id();
|
.id();
|
||||||
|
|
||||||
let position = self.nav_model.position(id).unwrap_or(0);
|
let position = self.nav_model.position(id).unwrap_or(0);
|
||||||
|
|
@ -283,10 +283,6 @@ impl cosmic::Application for App {
|
||||||
.icon_set(id, icon::from_name(node.icon_name()).size(16).icon());
|
.icon_set(id, icon::from_name(node.icon_name()).size(16).icon());
|
||||||
|
|
||||||
match node {
|
match node {
|
||||||
ProjectNode::Root { .. } => {
|
|
||||||
log::warn!("TODO: root node click");
|
|
||||||
Command::none()
|
|
||||||
}
|
|
||||||
ProjectNode::Folder { path, open, .. } => {
|
ProjectNode::Folder { path, open, .. } => {
|
||||||
let position = self.nav_model.position(id).unwrap_or(0);
|
let position = self.nav_model.position(id).unwrap_or(0);
|
||||||
let indent = self.nav_model.indent(id).unwrap_or(0);
|
let indent = self.nav_model.indent(id).unwrap_or(0);
|
||||||
|
|
|
||||||
|
|
@ -1,21 +1,18 @@
|
||||||
// SPDX-License-Identifier: GPL-3.0-only
|
// SPDX-License-Identifier: GPL-3.0-only
|
||||||
|
|
||||||
use std::{
|
use std::{
|
||||||
|
cmp::Ordering,
|
||||||
fs, io,
|
fs, io,
|
||||||
path::{Path, PathBuf},
|
path::{Path, PathBuf},
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug, Eq, PartialEq)]
|
||||||
pub enum ProjectNode {
|
pub enum ProjectNode {
|
||||||
Root {
|
|
||||||
name: String,
|
|
||||||
path: PathBuf,
|
|
||||||
open: bool,
|
|
||||||
},
|
|
||||||
Folder {
|
Folder {
|
||||||
name: String,
|
name: String,
|
||||||
path: PathBuf,
|
path: PathBuf,
|
||||||
open: bool,
|
open: bool,
|
||||||
|
root: bool,
|
||||||
},
|
},
|
||||||
File {
|
File {
|
||||||
name: String,
|
name: String,
|
||||||
|
|
@ -43,6 +40,7 @@ impl ProjectNode {
|
||||||
path,
|
path,
|
||||||
name,
|
name,
|
||||||
open: false,
|
open: false,
|
||||||
|
root: false,
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
Self::File { path, name }
|
Self::File { path, name }
|
||||||
|
|
@ -51,30 +49,42 @@ impl ProjectNode {
|
||||||
|
|
||||||
pub fn icon_name(&self) -> &str {
|
pub fn icon_name(&self) -> &str {
|
||||||
match self {
|
match self {
|
||||||
//TODO: different icon for project?
|
//TODO: different icon for project root?
|
||||||
ProjectNode::Root { open, .. } => {
|
Self::Folder { open, .. } => {
|
||||||
if *open {
|
if *open {
|
||||||
"go-down-symbolic"
|
"go-down-symbolic"
|
||||||
} else {
|
} else {
|
||||||
"go-next-symbolic"
|
"go-next-symbolic"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ProjectNode::Folder { open, .. } => {
|
Self::File { .. } => "text-x-generic",
|
||||||
if *open {
|
|
||||||
"go-down-symbolic"
|
|
||||||
} else {
|
|
||||||
"go-next-symbolic"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ProjectNode::File { .. } => "text-x-generic",
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn name(&self) -> &str {
|
pub fn name(&self) -> &str {
|
||||||
match self {
|
match self {
|
||||||
ProjectNode::Root { name, .. } => name,
|
Self::Folder { name, .. } => name,
|
||||||
ProjectNode::Folder { name, .. } => name,
|
Self::File { name, .. } => name,
|
||||||
ProjectNode::File { name, .. } => name,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Ord for ProjectNode {
|
||||||
|
fn cmp(&self, other: &Self) -> Ordering {
|
||||||
|
match self {
|
||||||
|
// Folders are always before files
|
||||||
|
Self::Folder { .. } => match other {
|
||||||
|
Self::File { .. } => return Ordering::Less,
|
||||||
|
_ => {}
|
||||||
|
},
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
self.name().cmp(other.name())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl PartialOrd for ProjectNode {
|
||||||
|
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
|
||||||
|
Some(self.cmp(other))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue