chore: inital commit
Split project into a Cargo workspace with two crates: - core/ (noctua_core): UI-independent document library - ui/ (noctua_ui): COSMIC application scaffold (empty) justfile for workspace (run, run-cli, check, test, build)
This commit is contained in:
commit
c85f35310e
31 changed files with 9768 additions and 0 deletions
147
core/examples/cli.rs
Normal file
147
core/examples/cli.rs
Normal file
|
|
@ -0,0 +1,147 @@
|
|||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
// examples/cli.rs
|
||||
//
|
||||
// CLI test harness for the noctua_core document foundation.
|
||||
|
||||
use clap::{ArgGroup, Parser};
|
||||
use noctua_core::document::manager::{DocumentCommand, DocumentManager, DocumentState};
|
||||
use noctua_core::document::session::SessionKind;
|
||||
use std::path::PathBuf;
|
||||
|
||||
#[derive(Parser, Debug)]
|
||||
#[command(
|
||||
name = "noctua",
|
||||
about = "A document viewer for the COSMIC desktop",
|
||||
group(
|
||||
ArgGroup::new("source")
|
||||
.required(true)
|
||||
.args(["open_document", "open_directory", "open_session"])
|
||||
)
|
||||
)]
|
||||
struct Cli {
|
||||
/// Open a document (Raster, Vector, Portable)
|
||||
#[arg(long, value_name = "PATH")]
|
||||
open_document: Option<PathBuf>,
|
||||
|
||||
/// Open a directory
|
||||
#[arg(long, value_name = "PATH")]
|
||||
open_directory: Option<PathBuf>,
|
||||
|
||||
/// Open a session file (.ron)
|
||||
#[arg(long, value_name = "PATH")]
|
||||
open_session: Option<PathBuf>,
|
||||
}
|
||||
|
||||
fn main() {
|
||||
env_logger::init();
|
||||
|
||||
let cli = Cli::parse();
|
||||
let mut manager = DocumentManager::new();
|
||||
|
||||
if let Some(path) = cli.open_session {
|
||||
manager.handle(DocumentCommand::OpenSession(path));
|
||||
} else if let Some(path) = cli.open_document {
|
||||
let dir = path
|
||||
.parent()
|
||||
.map(|p| p.to_path_buf())
|
||||
.unwrap_or_else(|| PathBuf::from("."));
|
||||
|
||||
let session_name = dir
|
||||
.file_name()
|
||||
.and_then(|n| n.to_str())
|
||||
.unwrap_or("Browse")
|
||||
.to_string();
|
||||
|
||||
if manager.session(&session_name).is_none() {
|
||||
manager.handle(DocumentCommand::CreateSession {
|
||||
name: session_name.clone(),
|
||||
kind: SessionKind::DirectoryBrowser,
|
||||
path: Some(dir.clone()),
|
||||
});
|
||||
manager.handle(DocumentCommand::ScanDirectory {
|
||||
session: session_name.clone(),
|
||||
dir,
|
||||
});
|
||||
}
|
||||
|
||||
manager.handle(DocumentCommand::AddFileToSession {
|
||||
session: session_name,
|
||||
path,
|
||||
});
|
||||
} else if let Some(path) = cli.open_directory {
|
||||
let session_name = path
|
||||
.file_name()
|
||||
.and_then(|n| n.to_str())
|
||||
.unwrap_or("Browse")
|
||||
.to_string();
|
||||
|
||||
if manager.session(&session_name).is_none() {
|
||||
manager.handle(DocumentCommand::CreateSession {
|
||||
name: session_name.clone(),
|
||||
kind: SessionKind::DirectoryBrowser,
|
||||
path: Some(path.clone()),
|
||||
});
|
||||
manager.handle(DocumentCommand::ScanDirectory {
|
||||
session: session_name.clone(),
|
||||
dir: path,
|
||||
});
|
||||
}
|
||||
|
||||
manager.handle(DocumentCommand::SetActive(session_name));
|
||||
}
|
||||
|
||||
match &manager.state {
|
||||
DocumentState::Empty => println!("UI: No document loaded."),
|
||||
DocumentState::Loading => println!("UI: Loading..."),
|
||||
DocumentState::Error(err) => eprintln!("UI: Error -> {err}"),
|
||||
DocumentState::Loaded(_) => {
|
||||
println!("UI: Document loaded.");
|
||||
|
||||
if let Some(name) = manager.active_session_name.clone() {
|
||||
if let Some(session) = manager.session(&name) {
|
||||
println!(
|
||||
"UI: Session '{}' ({:?}) has {} items, current index: {:?}",
|
||||
session.name,
|
||||
session.kind,
|
||||
session.items.len(),
|
||||
session.current_index
|
||||
);
|
||||
|
||||
match session.kind {
|
||||
SessionKind::DirectoryBrowser => {
|
||||
println!("UI: Display as directory browser (thumbnails in left panel)");
|
||||
}
|
||||
SessionKind::DocumentCollection => {
|
||||
println!("UI: Display as document collection (pages)");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
println!("\nUI: Test navigation...");
|
||||
manager.handle(DocumentCommand::NavigateNext);
|
||||
if let Some(session) = manager.session(&name) {
|
||||
println!(
|
||||
"UI: After NavigateNext -> index {:?}",
|
||||
session.current_index
|
||||
);
|
||||
}
|
||||
|
||||
manager.handle(DocumentCommand::NavigatePrevious);
|
||||
if let Some(session) = manager.session(&name) {
|
||||
println!(
|
||||
"UI: After NavigatePrevious -> index {:?}",
|
||||
session.current_index
|
||||
);
|
||||
}
|
||||
|
||||
manager.handle(DocumentCommand::SelectItem(0));
|
||||
if let Some(session) = manager.session(&name) {
|
||||
println!(
|
||||
"UI: After SelectItem(0) -> index {:?}",
|
||||
session.current_index
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue