pub mod camera;
pub mod data;
pub mod formats;
pub mod grid;
pub mod help;
#[cfg(feature = "images")]
pub mod image;
pub mod input;
pub mod menu;
pub mod overlay;
#[cfg(feature = "mermaid-preview")]
pub mod preview;
pub mod render;
pub mod selection;
pub mod state;
pub mod textsel;
pub mod theme;
use anyhow::{Context, Result};
use ratatui::style::Color;
use std::path::Path;
pub use input::{
ActionCtx, ActionOutcome, MouseOutcome, PinstarAction, apply_action, execute_menu_action,
handle_pinstar_event, handle_pinstar_mouse,
};
pub use menu::{
MenuItemSpec, PinstarContextMenu, PinstarMenuType, menu_item_shortcut_char, menu_specs,
};
pub use overlay::{MarqueeState, draw_canvas_rect_filled, muted_canvas_selection_fill};
pub use render::draw_pinstar_view;
pub use selection::Selection;
pub use state::{PinstarHelpTab, PinstarSnapshot, PinstarState, RenameMode};
pub use textsel::MouseTextSelection;
pub use theme::ThemeColors;
#[derive(Debug, Clone)]
pub struct Settings {
pub enable_image_nodes: bool,
pub image_cache_size: usize,
pub rename_uses_id: bool,
pub show_hints: bool,
}
impl Default for Settings {
fn default() -> Self {
Self {
enable_image_nodes: false,
image_cache_size: 32,
rename_uses_id: false,
show_hints: true,
}
}
}
pub const TRANSFORM_SETTLE: std::time::Duration = std::time::Duration::from_millis(150);
pub const COLOR_PICKER_PALETTE: &[(&str, &str, Color)] = &[
("Red", "#ff5252", Color::Rgb(255, 82, 82)),
("Orange", "#ff9800", Color::Rgb(255, 152, 0)),
("Yellow", "#ffeb3b", Color::Rgb(255, 235, 59)),
("Green", "#4caf50", Color::Rgb(76, 175, 80)),
("Cyan", "#00bcd4", Color::Rgb(0, 188, 212)),
("Purple", "#9c27b0", Color::Rgb(156, 39, 176)),
("Blue", "#2196f3", Color::Rgb(33, 150, 243)),
("Magenta", "#e91e63", Color::Rgb(233, 30, 99)),
("White", "#ffffff", Color::Rgb(255, 255, 255)),
];
pub fn atomic_write(path: &Path, content: &str) -> Result<()> {
let parent = path.parent().unwrap_or_else(|| Path::new("."));
let tmp = parent.join(format!(
".{}.{}.tmp",
path.file_name().and_then(|s| s.to_str()).unwrap_or("tmp"),
uuid::Uuid::new_v4()
));
std::fs::write(&tmp, content).with_context(|| format!("failed to write {}", tmp.display()))?;
#[cfg(unix)]
{
let f = std::fs::File::open(&tmp).context("failed to open temp file for syncing")?;
f.sync_all().context("failed to sync temp file")?;
drop(f);
}
std::fs::rename(&tmp, path).with_context(|| {
format!(
"failed to rename temp file {} to {}",
tmp.display(),
path.display()
)
})?;
Ok(())
}