use crate::cli::shared;
use crate::cli::shared::InputReverseKey;
use crate::handle::get_monitors;
use crate::{GuiConfig, SubmapConfig};
use clap::{Args, ValueEnum};
use hyprswitch::CloseType;
use serde::{Deserialize, Serialize};
use std::str::FromStr;
#[derive(Args, Debug, Clone)]
pub struct SubmapInfo {
#[arg(long, conflicts_with_all = ["mod_key", "key", "close"])]
pub submap: String,
}
#[derive(Args, Debug, Clone)]
pub struct SubmapConf {
#[clap(long, value_enum)]
pub mod_key: shared::InputModKey,
#[arg(long)]
pub key: String,
#[clap(long, default_value_t, value_enum)]
pub close: InputCloseType,
}
#[derive(Args, Debug, Clone)]
pub struct GuiConf {
#[arg(long, default_value = "6", value_parser = clap::value_parser!(u8).range(0..=9))]
pub max_switch_offset: u8,
#[arg(long, default_value = "false", action = clap::ArgAction::Set, default_missing_value = "true", num_args= 0..=1
)]
pub hide_active_window_border: bool,
#[arg(long, value_delimiter = ',', value_parser = clap::value_parser!(Monitors))]
pub monitors: Option<Monitors>,
#[arg(long, default_value = "false", action = clap::ArgAction::Set, default_missing_value = "true", num_args=0..=1
)]
pub show_workspaces_on_all_monitors: bool,
#[arg(long, default_value = "false", action = clap::ArgAction::Set, default_missing_value = "true", num_args=0..=1
)]
pub show_launcher: bool,
}
impl From<GuiConf> for GuiConfig {
fn from(opts: GuiConf) -> Self {
Self {
max_switch_offset: opts.max_switch_offset,
hide_active_window_border: opts.hide_active_window_border,
monitors: opts.monitors.map(|m| m.0),
show_workspaces_on_all_monitors: opts.show_workspaces_on_all_monitors,
show_launcher: opts.show_launcher,
}
}
}
impl SubmapInfo {
#[allow(dead_code)]
pub fn into_submap_info(self, reverse_key: InputReverseKey) -> SubmapConfig {
SubmapConfig::Name {
name: self.submap,
reverse_key: reverse_key.into(),
}
}
}
impl SubmapConf {
pub fn into_submap_conf(self, reverse_key: InputReverseKey) -> SubmapConfig {
SubmapConfig::Config {
mod_key: self.mod_key.into(),
key: self.key,
close: self.close.into(),
reverse_key: reverse_key.into(),
}
}
}
#[derive(ValueEnum, Clone, Default, Debug, Serialize, Deserialize, PartialEq)]
pub enum InputCloseType {
#[default]
Default,
ModKeyRelease,
}
impl From<InputCloseType> for CloseType {
fn from(s: InputCloseType) -> Self {
match s {
InputCloseType::Default => Self::Default,
InputCloseType::ModKeyRelease => Self::ModKeyRelease,
}
}
}
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
pub struct Monitors(pub Vec<String>);
impl FromStr for Monitors {
type Err = String;
fn from_str(s: &str) -> Result<Self, Self::Err> {
let available: Vec<hyprland::data::Monitor> = get_monitors();
let mut vec = Vec::new();
for monitor in s.split(',') {
if let Some(m) = available.iter().find(|m| m.name == monitor) {
vec.push(m.name.clone())
} else {
return Err(format!(
"{s} not found in {:?}",
available.iter().map(|a| a.name.clone()).collect::<Vec<_>>()
));
}
}
Ok(Self(vec))
}
}