use crate::app::RunUblxParams;
use crate::config::{
UblxOverlay, UblxPaths, ensure_global_config_file_with_defaults, load_ublx_toml,
};
use crate::layout::setup::{SettingsConfigScope, SettingsPaneState, UblxState};
use crate::themes::default_theme_for_new_config_file;
use crate::utils::opacity_is_solid;
#[must_use]
pub fn resolve_config_path(
paths_ref: &UblxPaths,
scope: SettingsConfigScope,
) -> Option<std::path::PathBuf> {
match scope {
SettingsConfigScope::Global => paths_ref.global_config(),
SettingsConfigScope::Local => Some(paths_ref.local_config_path_for_write()),
}
}
#[must_use]
pub fn local_edit_context(paths_ref: &UblxPaths) -> (Option<UblxOverlay>, UblxOverlay) {
let global_o = load_ublx_toml(paths_ref.global_config(), None);
let local_o = paths_ref
.toml_path()
.and_then(|p| load_ublx_toml(Some(p), None));
let merged = UblxOverlay::merge(global_o, local_o.clone());
(local_o, merged)
}
#[must_use]
pub fn merged_overlay_before_write(
paths: &UblxPaths,
scope: SettingsConfigScope,
overlay: &UblxOverlay,
) -> UblxOverlay {
match scope {
SettingsConfigScope::Local => {
let global_o = load_ublx_toml(paths.global_config(), None);
UblxOverlay::merge(global_o, Some(overlay.clone()))
}
SettingsConfigScope::Global => overlay.clone(),
}
}
#[must_use]
pub fn layout_overlay_for_local_editing<'a>(
local: Option<&'a UblxOverlay>,
merged: &'a UblxOverlay,
) -> &'a UblxOverlay {
match local {
Some(l) if l.layout.is_some() => l,
_ => merged,
}
}
#[must_use]
pub fn local_layout_is_explicit(local: Option<&UblxOverlay>) -> bool {
local.is_some_and(|l| l.layout.is_some())
}
#[must_use]
pub fn local_opacity_is_explicit(local: Option<&UblxOverlay>) -> bool {
local.is_some_and(|l| l.bg_opacity.is_some())
}
#[must_use]
pub fn opacity_overlay_for_local_editing<'a>(
local: Option<&'a UblxOverlay>,
merged: &'a UblxOverlay,
) -> &'a UblxOverlay {
match local {
Some(l) if l.bg_opacity.is_some() => l,
_ => merged,
}
}
pub fn sync_layout_buffers_from_overlay(
settings_mut: &mut SettingsPaneState,
overlay_ref: &UblxOverlay,
) {
let lo = overlay_ref.layout.clone().unwrap_or_default();
settings_mut.layout_left_buf = lo.left_pct.to_string();
settings_mut.layout_mid_buf = lo.middle_pct.to_string();
settings_mut.layout_right_buf = lo.right_pct.to_string();
}
pub fn sync_opacity_buffer_from_overlay(
settings_mut: &mut SettingsPaneState,
overlay_ref: &UblxOverlay,
) {
let v = overlay_ref.bg_opacity.unwrap_or(1.0);
settings_mut.opacity_buf = format_opacity_buf(v);
}
fn format_opacity_buf(v: f32) -> String {
if opacity_is_solid(v) {
"1".to_string()
} else if v == 0.0 {
"0".to_string()
} else {
format!("{v:.2}")
}
}
fn sync_layout_buffers_for_scope(
settings_mut: &mut SettingsPaneState,
paths_ref: &UblxPaths,
scope: SettingsConfigScope,
) {
match scope {
SettingsConfigScope::Global => {
if let Some(path) = settings_mut.editing_path.clone()
&& let Some(o) = load_ublx_toml(Some(path), None)
{
sync_layout_buffers_from_overlay(settings_mut, &o);
sync_opacity_buffer_from_overlay(settings_mut, &o);
}
}
SettingsConfigScope::Local => {
let (local_o, merged) = local_edit_context(paths_ref);
let lay_src = layout_overlay_for_local_editing(local_o.as_ref(), &merged);
sync_layout_buffers_from_overlay(settings_mut, lay_src);
let op_src = opacity_overlay_for_local_editing(local_o.as_ref(), &merged);
sync_opacity_buffer_from_overlay(settings_mut, op_src);
}
}
}
pub fn refresh_editing_metadata(state_mut: &mut UblxState, params_ref: &RunUblxParams<'_>) {
let paths = UblxPaths::new(¶ms_ref.dir_to_ublx);
let scope = state_mut.settings.scope;
if scope == SettingsConfigScope::Global
&& let Some(g) = paths.global_config()
{
ensure_global_config_file_with_defaults(&g, default_theme_for_new_config_file());
}
state_mut.settings.editing_path = resolve_config_path(&paths, scope);
sync_layout_buffers_for_scope(&mut state_mut.settings, &paths, scope);
}