diff --git a/src/main.rs b/src/main.rs index ef219b0..850268f 100644 --- a/src/main.rs +++ b/src/main.rs @@ -126,7 +126,7 @@ impl App { nodes.push(node); } - nodes.sort_by(|a, b| a.name().cmp(b.name())); + nodes.sort(); for node in nodes { self.nav_model @@ -143,34 +143,34 @@ impl App { pub fn open_project>(&mut self, path: P) { 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) => { log::error!("failed to open project {:?}: {}", path.as_ref(), err); 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 .nav_model .insert() - .icon(icon::from_name(project.icon_name()).size(16).icon()) - .text(project.name().to_string()) - .data(project) + .icon(icon::from_name(node.icon_name()).size(16).icon()) + .text(node.name().to_string()) + .data(node) .id(); 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()); match node { - ProjectNode::Root { .. } => { - log::warn!("TODO: root node click"); - Command::none() - } ProjectNode::Folder { path, open, .. } => { let position = self.nav_model.position(id).unwrap_or(0); let indent = self.nav_model.indent(id).unwrap_or(0); diff --git a/src/project.rs b/src/project.rs index b95900e..e44de90 100644 --- a/src/project.rs +++ b/src/project.rs @@ -1,21 +1,18 @@ // SPDX-License-Identifier: GPL-3.0-only use std::{ + cmp::Ordering, fs, io, path::{Path, PathBuf}, }; -#[derive(Clone, Debug)] +#[derive(Clone, Debug, Eq, PartialEq)] pub enum ProjectNode { - Root { - name: String, - path: PathBuf, - open: bool, - }, Folder { name: String, path: PathBuf, open: bool, + root: bool, }, File { name: String, @@ -43,6 +40,7 @@ impl ProjectNode { path, name, open: false, + root: false, } } else { Self::File { path, name } @@ -51,30 +49,42 @@ impl ProjectNode { pub fn icon_name(&self) -> &str { match self { - //TODO: different icon for project? - ProjectNode::Root { open, .. } => { + //TODO: different icon for project root? + Self::Folder { open, .. } => { if *open { "go-down-symbolic" } else { "go-next-symbolic" } } - ProjectNode::Folder { open, .. } => { - if *open { - "go-down-symbolic" - } else { - "go-next-symbolic" - } - } - ProjectNode::File { .. } => "text-x-generic", + Self::File { .. } => "text-x-generic", } } pub fn name(&self) -> &str { match self { - ProjectNode::Root { name, .. } => name, - ProjectNode::Folder { name, .. } => name, - ProjectNode::File { name, .. } => name, + Self::Folder { name, .. } => name, + Self::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 { + Some(self.cmp(other)) + } +}