use crate::config::Config;
use crate::ui::Screen as ScreenId;
use anyhow::Result;
use crossterm::event::Event;
use ratatui::layout::Rect;
use ratatui::Frame;
use std::path::PathBuf;
use syntect::highlighting::{Theme, ThemeSet};
use syntect::parsing::SyntaxSet;
pub struct RenderContext<'a> {
pub config: &'a Config,
pub syntax_set: &'a SyntaxSet,
pub theme_set: &'a ThemeSet,
pub syntax_theme: &'a Theme,
}
impl<'a> RenderContext<'a> {
pub fn new(
config: &'a Config,
syntax_set: &'a SyntaxSet,
theme_set: &'a ThemeSet,
syntax_theme: &'a Theme,
) -> Self {
Self {
config,
syntax_set,
theme_set,
syntax_theme,
}
}
}
pub struct ScreenContext<'a> {
pub config: &'a Config,
pub config_path: &'a std::path::Path,
pub repo_path: &'a std::path::Path,
pub active_profile: &'a str,
}
impl<'a> ScreenContext<'a> {
#[must_use]
pub fn new(config: &'a Config, config_path: &'a std::path::Path) -> Self {
Self {
config,
config_path,
repo_path: &config.repo_path,
active_profile: &config.active_profile,
}
}
}
#[derive(Debug, Clone, Default)]
pub enum ScreenAction {
#[default]
None,
Navigate(ScreenId),
NavigateWithMessage {
screen: ScreenId,
title: String,
message: String,
},
ShowMessage { title: String, content: String },
ShowToast {
message: String,
variant: crate::widgets::ToastVariant,
},
Quit,
Refresh,
SetHasChanges(bool),
ConfigUpdated,
ShowHelp,
SaveLocalRepoConfig {
repo_path: PathBuf,
profiles: Vec<String>,
},
StartGitHubSetup {
token: String,
repo_name: String,
is_private: bool,
},
UpdateGitHubToken {
token: String,
},
ShowProfileSelection {
profiles: Vec<String>,
},
CreateAndActivateProfile {
name: String,
},
ActivateProfile {
name: String,
},
ScanDotfiles,
RefreshFileBrowser,
ToggleFileSync {
file_index: usize,
is_synced: bool,
},
AddCustomFileToSync {
full_path: PathBuf,
relative_path: String,
},
SetBackupEnabled {
enabled: bool,
},
RemoveCustomFile {
file_index: usize,
},
MoveToCommon {
file_index: usize,
is_common: bool,
profiles_to_cleanup: Vec<String>,
},
CreateProfile {
name: String,
description: Option<String>,
inherits: Option<String>,
copy_from: Option<usize>,
},
SwitchProfile {
name: String,
},
RenameProfile {
old_name: String,
new_name: String,
},
DeleteProfile {
name: String,
},
InstallMissingPackages,
UpdateSetting {
setting: String,
option_index: usize,
},
}
#[derive(Debug, Clone, Default)]
pub enum ActionResult {
#[default]
None,
ShowToast {
message: String,
variant: crate::widgets::ToastVariant,
},
ShowDialog {
title: String,
content: String,
variant: crate::widgets::DialogVariant,
},
Navigate(ScreenId),
ConfigUpdated,
}
pub trait Screen {
fn render(&mut self, frame: &mut Frame, area: Rect, ctx: &RenderContext) -> Result<()>;
fn handle_event(&mut self, event: Event, ctx: &ScreenContext) -> Result<ScreenAction>;
fn is_input_focused(&self) -> bool {
false
}
fn on_enter(&mut self, _ctx: &ScreenContext) -> Result<()> {
Ok(())
}
fn on_exit(&mut self, _ctx: &ScreenContext) -> Result<()> {
Ok(())
}
}