use egui::{Color32, Context, Frame, Ui, Window, epaint::Shadow};
use par_term_config::Config;
use crate::{CursorShaderEditorResult, ShaderEditorResult};
use super::SettingsUI;
impl SettingsUI {
fn show_reset_defaults_dialog_window(&mut self, ctx: &Context) {
if !self.show_reset_defaults_dialog {
return;
}
let mut close_dialog = false;
let mut do_reset = false;
egui::Window::new("Reset to Defaults")
.collapsible(false)
.resizable(false)
.order(egui::Order::Foreground)
.anchor(egui::Align2::CENTER_CENTER, [0.0, 0.0])
.show(ctx, |ui| {
ui.vertical_centered(|ui| {
ui.add_space(10.0);
ui.label(
egui::RichText::new("⚠ Warning")
.color(egui::Color32::YELLOW)
.size(18.0)
.strong(),
);
ui.add_space(10.0);
ui.label("This will reset ALL settings to their default values.");
ui.add_space(5.0);
ui.label(
egui::RichText::new(
"Nothing is written until you Save. Revert undoes the reset.",
)
.color(egui::Color32::GRAY),
);
ui.add_space(15.0);
ui.horizontal(|ui| {
let reset_button = egui::Button::new(
egui::RichText::new("Reset").color(egui::Color32::WHITE),
)
.fill(egui::Color32::from_rgb(180, 50, 50));
if ui.add(reset_button).clicked() {
do_reset = true;
close_dialog = true;
}
ui.add_space(10.0);
if ui.button("Cancel").clicked() {
close_dialog = true;
}
});
ui.add_space(10.0);
});
});
if do_reset {
self.reset_all_to_defaults();
}
if close_dialog {
self.show_reset_defaults_dialog = false;
}
}
fn show_config_file_buttons(&mut self, ui: &mut Ui) {
let config_path = Config::config_path();
if ui
.button("Edit Config File")
.on_hover_text(format!(
"Open {} in your default editor",
config_path.display()
))
.clicked()
&& let Err(e) = open::that(&config_path)
{
self.show_error_banner(format!("Could not open {}: {e}", config_path.display()));
}
if ui
.button("Reveal")
.on_hover_text("Show the folder that holds config.yaml")
.clicked()
{
let dir = Config::config_dir();
if let Err(e) = open::that(&dir) {
self.show_error_banner(format!("Could not open {}: {e}", dir.display()));
}
}
ui.label(
egui::RichText::new(config_path.display().to_string())
.small()
.color(Color32::GRAY),
)
.on_hover_text("Settings are saved to this file");
}
pub fn show(
&mut self,
ctx: &Context,
) -> (
Option<Config>,
Option<Config>,
Option<ShaderEditorResult>,
Option<CursorShaderEditorResult>,
) {
if !self.visible && !self.shader_editor_visible && !self.cursor_shader_editor_visible {
return (None, None, None, None);
}
log::info!("SettingsUI.show() called - visible: true");
if ctx.input(|i| i.key_pressed(egui::Key::Escape)) {
if self.cursor_shader_editor_visible {
self.cursor_shader_editor_visible = false;
self.cursor_shader_editor_error = None;
} else if self.shader_editor_visible {
self.shader_editor_visible = false;
self.shader_editor_error = None;
} else if self.visible {
self.visible = false;
return (None, None, None, None);
}
}
let mut style = (*ctx.global_style()).clone();
let solid_bg = Color32::from_rgba_unmultiplied(24, 24, 24, 255);
style.visuals.window_fill = solid_bg;
style.visuals.panel_fill = solid_bg;
style.visuals.widgets.noninteractive.bg_fill = solid_bg;
ctx.set_global_style(style);
let mut save_requested = false;
let mut revert_requested = false;
let mut close_requested = false;
let mut open = true;
let mut changes_this_frame = false;
if self.visible {
let settings_viewport = ctx.input(|i| i.viewport_rect());
Window::new("Settings")
.resizable(true)
.default_width(650.0)
.default_height(700.0)
.default_pos(settings_viewport.center())
.pivot(egui::Align2::CENTER_CENTER)
.open(&mut open)
.frame(
Frame::window(&ctx.global_style())
.fill(solid_bg)
.stroke(egui::Stroke::NONE)
.shadow(Shadow {
offset: [0, 0],
blur: 0,
spread: 0,
color: Color32::TRANSPARENT,
}),
)
.show(ctx, |ui| {
ui.heading("Terminal Settings");
self.show_search_field(ui);
self.render_banner(ui);
ui.separator();
self.show_settings_sections(ui, &mut changes_this_frame);
ui.separator();
ui.horizontal(|ui| {
if ui.button("Save").clicked() {
save_requested = true;
}
if ui
.button("Revert")
.on_hover_text("Restore every window to the last saved settings")
.clicked()
{
revert_requested = true;
}
if ui.button("Close").clicked() {
close_requested = true;
}
ui.separator();
self.show_config_file_buttons(ui);
if ui
.button("Reset to Defaults")
.on_hover_text("Reset all settings to their default values")
.clicked()
{
self.show_reset_defaults_dialog = true;
}
if self.has_unsaved_changes() {
ui.colored_label(egui::Color32::YELLOW, "* Unsaved changes");
}
});
});
}
let shader_apply_result = self.show_shader_editor_window(ctx);
let cursor_shader_apply_result = self.show_cursor_shader_editor_window(ctx);
self.show_create_shader_dialog_window(ctx);
self.show_delete_shader_dialog_window(ctx);
self.show_reset_defaults_dialog_window(ctx);
if self.visible && (!open || close_requested) {
self.visible = false;
}
let config_to_save = if save_requested || std::mem::take(&mut self.global_save_requested) {
self.request_save()
} else {
None
};
if revert_requested {
self.revert_to_baseline();
}
let config_for_live_update = if self.visible {
if (self.config.window.window_opacity - self.last_live_opacity).abs() > f32::EPSILON {
log::info!(
"SettingsUI: live opacity {:.3} (last {:.3})",
self.config.window.window_opacity,
self.last_live_opacity
);
self.last_live_opacity = self.config.window.window_opacity;
}
Some(self.config.clone())
} else {
None
};
(
config_to_save,
config_for_live_update,
shader_apply_result,
cursor_shader_apply_result,
)
}
pub fn show_as_panel(
&mut self,
ctx: &mut Ui,
) -> (
Option<Config>,
Option<Config>,
Option<ShaderEditorResult>,
Option<CursorShaderEditorResult>,
) {
if ctx.input(|i| i.key_pressed(egui::Key::Escape)) {
if self.show_close_prompt {
self.cancel_close_prompt();
} else if self.cursor_shader_editor_visible {
self.cursor_shader_editor_visible = false;
self.cursor_shader_editor_error = None;
} else if self.shader_editor_visible {
self.shader_editor_visible = false;
self.shader_editor_error = None;
}
}
let mut style = (*ctx.global_style()).clone();
let solid_bg = Color32::from_rgba_unmultiplied(24, 24, 24, 255);
style.visuals.window_fill = solid_bg;
style.visuals.panel_fill = solid_bg;
style.visuals.widgets.noninteractive.bg_fill = solid_bg;
ctx.set_global_style(style);
let mut save_requested = false;
let mut revert_requested = false;
let mut changes_this_frame = false;
egui::CentralPanel::default()
.frame(Frame::central_panel(&ctx.global_style()).fill(solid_bg))
.show(ctx, |ui| {
ui.heading("Terminal Settings");
self.show_search_field(ui);
self.render_banner(ui);
ui.separator();
self.show_settings_sections(ui, &mut changes_this_frame);
ui.separator();
ui.horizontal(|ui| {
if ui.button("Save").clicked() {
save_requested = true;
}
if ui
.button("Revert")
.on_hover_text("Restore every window to the last saved settings")
.clicked()
{
revert_requested = true;
}
ui.separator();
self.show_config_file_buttons(ui);
if ui
.button("Reset to Defaults")
.on_hover_text("Reset all settings to their default values")
.clicked()
{
self.show_reset_defaults_dialog = true;
}
if self.has_unsaved_changes() {
ui.colored_label(egui::Color32::YELLOW, "* Unsaved changes");
}
});
});
let shader_apply_result = self.show_shader_editor_window(ctx);
let cursor_shader_apply_result = self.show_cursor_shader_editor_window(ctx);
self.show_create_shader_dialog_window(ctx);
self.show_delete_shader_dialog_window(ctx);
self.show_reset_defaults_dialog_window(ctx);
let close_prompt_save = self.show_close_prompt_window(ctx);
let config_to_save = if save_requested || std::mem::take(&mut self.global_save_requested) {
self.request_save()
} else {
close_prompt_save
};
if revert_requested {
self.revert_to_baseline();
}
let config_for_live_update = {
if (self.config.window.window_opacity - self.last_live_opacity).abs() > f32::EPSILON {
log::info!(
"SettingsUI: live opacity {:.3} (last {:.3})",
self.config.window.window_opacity,
self.last_live_opacity
);
self.last_live_opacity = self.config.window.window_opacity;
}
Some(self.config.clone())
};
(
config_to_save,
config_for_live_update,
shader_apply_result,
cursor_shader_apply_result,
)
}
}