225 lines
9.5 KiB
Rust
225 lines
9.5 KiB
Rust
use crate::app::TextEditor;
|
|
use crate::ui::constants::*;
|
|
use eframe::egui;
|
|
|
|
pub(crate) fn preferences_window(app: &mut TextEditor, ctx: &egui::Context) {
|
|
let visuals = &ctx.style().visuals;
|
|
let screen_rect = ctx.screen_rect();
|
|
let window_width =
|
|
(screen_rect.width() * WINDOW_WIDTH_RATIO).clamp(WINDOW_MIN_WIDTH, WINDOW_MAX_WIDTH);
|
|
let window_height =
|
|
(screen_rect.height() * WINDOW_HEIGHT_RATIO).clamp(WINDOW_MIN_HEIGHT, WINDOW_MAX_HEIGHT);
|
|
let max_size = egui::Vec2::new(window_width, window_height);
|
|
|
|
egui::Window::new("Preferences")
|
|
.collapsible(false)
|
|
.resizable(false)
|
|
.anchor(egui::Align2::CENTER_CENTER, egui::Vec2::ZERO)
|
|
.default_open(true)
|
|
.max_size(max_size)
|
|
.fade_in(true)
|
|
.fade_out(true)
|
|
.frame(egui::Frame {
|
|
fill: visuals.window_fill,
|
|
stroke: visuals.window_stroke,
|
|
corner_radius: egui::CornerRadius::same(CORNER_RADIUS),
|
|
shadow: visuals.window_shadow,
|
|
inner_margin: egui::Margin::same(INNER_MARGIN),
|
|
outer_margin: egui::Margin::same(0),
|
|
})
|
|
.show(ctx, |ui| {
|
|
ui.vertical_centered(|ui| {
|
|
ui.heading("Editor Settings");
|
|
ui.add_space(MEDIUM);
|
|
|
|
ui.horizontal(|ui| {
|
|
ui.vertical(|ui| {
|
|
if ui
|
|
.checkbox(&mut app.state_cache, "Maintain State")
|
|
.on_hover_text("Unsaved changes will be cached between sessions")
|
|
.changed()
|
|
{
|
|
app.save_config();
|
|
if !app.state_cache {
|
|
if let Err(e) = TextEditor::clear_state_cache() {
|
|
eprintln!("Failed to clear state cache: {e}");
|
|
}
|
|
}
|
|
}
|
|
ui.add_space(SMALL);
|
|
if ui
|
|
.checkbox(&mut app.show_line_numbers, "Show Line Numbers")
|
|
.changed()
|
|
{
|
|
app.save_config();
|
|
}
|
|
ui.add_space(SMALL);
|
|
if ui
|
|
.checkbox(&mut app.auto_hide_toolbar, "Auto Hide Toolbar")
|
|
.on_hover_text(
|
|
"Hide the top bar until you move your mouse to the upper edge",
|
|
)
|
|
.changed()
|
|
{
|
|
app.save_config();
|
|
}
|
|
});
|
|
ui.vertical(|ui| {
|
|
if ui.checkbox(&mut app.word_wrap, "Word Wrap").changed() {
|
|
app.save_config();
|
|
}
|
|
ui.add_space(SMALL);
|
|
if ui
|
|
.checkbox(&mut app.syntax_highlighting, "Syntax Highlighting")
|
|
.changed()
|
|
{
|
|
app.save_config();
|
|
}
|
|
ui.add_space(SMALL);
|
|
if ui
|
|
.checkbox(&mut app.hide_tab_bar, "Hide Tab Bar")
|
|
.on_hover_text(
|
|
"Hide the tab bar and show tab title in menu bar instead",
|
|
)
|
|
.changed()
|
|
{
|
|
app.save_config();
|
|
}
|
|
});
|
|
});
|
|
|
|
ui.add_space(SMALL);
|
|
ui.separator();
|
|
ui.add_space(LARGE);
|
|
ui.heading("Font Settings");
|
|
ui.add_space(MEDIUM);
|
|
|
|
ui.horizontal(|ui| {
|
|
ui.vertical(|ui| {
|
|
ui.label("Font Family:");
|
|
ui.add_space(SMALL);
|
|
ui.label("Font Size:");
|
|
});
|
|
|
|
ui.vertical(|ui| {
|
|
let mut changed = false;
|
|
egui::ComboBox::from_id_salt("font_family")
|
|
.selected_text(&app.font_family)
|
|
.show_ui(ui, |ui| {
|
|
if ui
|
|
.selectable_value(
|
|
&mut app.font_family,
|
|
"Proportional".to_string(),
|
|
"Proportional",
|
|
)
|
|
.clicked()
|
|
{
|
|
changed = true;
|
|
}
|
|
if ui
|
|
.selectable_value(
|
|
&mut app.font_family,
|
|
"Monospace".to_string(),
|
|
"Monospace",
|
|
)
|
|
.clicked()
|
|
{
|
|
changed = true;
|
|
}
|
|
});
|
|
|
|
if app.font_size_input.is_none() {
|
|
app.font_size_input = Some(app.font_size.to_string());
|
|
}
|
|
|
|
let mut font_size_text = app
|
|
.font_size_input
|
|
.as_ref()
|
|
.unwrap_or(&DEFAULT_FONT_SIZE_STR.to_string())
|
|
.to_owned();
|
|
ui.add_space(SMALL);
|
|
ui.horizontal(|ui| {
|
|
let response = ui.add(
|
|
egui::TextEdit::singleline(&mut font_size_text)
|
|
.desired_width(FONT_SIZE_INPUT_WIDTH)
|
|
.hint_text(DEFAULT_FONT_SIZE_STR)
|
|
.id(egui::Id::new("font_size_input")),
|
|
);
|
|
|
|
app.font_size_input = Some(font_size_text.to_owned());
|
|
|
|
if response.clicked() {
|
|
response.request_focus();
|
|
}
|
|
|
|
ui.label("px");
|
|
|
|
if response.lost_focus() {
|
|
if let Ok(new_size) = font_size_text.parse::<f32>() {
|
|
let clamped_size = new_size.clamp(MIN_FONT_SIZE, MAX_FONT_SIZE);
|
|
if (app.font_size - clamped_size).abs() > 0.1 {
|
|
app.font_size = clamped_size;
|
|
app.apply_font_settings(ctx);
|
|
}
|
|
}
|
|
app.font_size_input = None;
|
|
}
|
|
|
|
if changed {
|
|
app.apply_font_settings(ctx);
|
|
}
|
|
})
|
|
});
|
|
});
|
|
|
|
ui.add_space(MEDIUM);
|
|
|
|
ui.label("Preview:");
|
|
ui.add_space(SMALL);
|
|
|
|
egui::ScrollArea::vertical()
|
|
.max_height(PREVIEW_AREA_MAX_HEIGHT)
|
|
.show(ui, |ui| {
|
|
egui::Frame::new()
|
|
.fill(visuals.code_bg_color)
|
|
.stroke(visuals.widgets.noninteractive.bg_stroke)
|
|
.inner_margin(egui::Margin::same(INNER_MARGIN))
|
|
.show(ui, |ui| {
|
|
let preview_font = egui::FontId::new(
|
|
app.font_size,
|
|
match app.font_family.as_str() {
|
|
"Monospace" => egui::FontFamily::Monospace,
|
|
_ => egui::FontFamily::Proportional,
|
|
},
|
|
);
|
|
ui.label(
|
|
egui::RichText::new(
|
|
"The quick brown fox jumps over the lazy dog.",
|
|
)
|
|
.font(preview_font.to_owned()),
|
|
);
|
|
ui.label(
|
|
egui::RichText::new("ABCDEFGHIJKLMNOPQRSTUVWXYZ")
|
|
.font(preview_font.to_owned()),
|
|
);
|
|
ui.label(
|
|
egui::RichText::new("abcdefghijklmnopqrstuvwxyz")
|
|
.font(preview_font.to_owned()),
|
|
);
|
|
ui.label(
|
|
egui::RichText::new("1234567890 !@#$%^&*()")
|
|
.font(preview_font.to_owned()),
|
|
);
|
|
});
|
|
});
|
|
|
|
ui.add_space(LARGE);
|
|
|
|
if ui.button("Close").clicked() {
|
|
app.show_preferences = false;
|
|
app.font_size_input = None;
|
|
}
|
|
});
|
|
});
|
|
}
|