diff options
| author | Rubén Beltrán del Río <jj@r.bdr.sh> | 2026-01-17 23:56:42 +0100 |
|---|---|---|
| committer | Rubén Beltrán del Río <jj@r.bdr.sh> | 2026-01-18 00:19:59 +0100 |
| commit | 5ab839d56067e026f07309c7153b5572e725d171 (patch) | |
| tree | bbd83a99abf4868d222d0cb5b5c4114b97323028 /src | |
| parent | bfd56ed050ab5d9a342e28067ec91f7656dc8f0d (diff) | |
Improve font size picker
Diffstat (limited to 'src')
| -rw-r--r-- | src/preferences/pages/editor.rs | 214 |
1 files changed, 135 insertions, 79 deletions
diff --git a/src/preferences/pages/editor.rs b/src/preferences/pages/editor.rs index 65b7d80..27b94da 100644 --- a/src/preferences/pages/editor.rs +++ b/src/preferences/pages/editor.rs @@ -24,9 +24,11 @@ use crate::ui_helpers::create_switch_row; use super::super::models::UserPreferences; use super::super::window::PreferencesInput; +const DEFAULT_FONT_SIZE: f64 = 14.0; + pub struct EditorPage { container: gtk::Box, - font_size_spin: gtk::SpinButton, + font_size_scale: gtk::Scale, soft_wrap_switch: gtk::Switch, custom_font_switch: gtk::Switch, font_button: gtk::FontButton, @@ -41,106 +43,160 @@ impl EditorPage { container.set_margin_end(20); container.set_valign(gtk::Align::Start); - // Font Size section - let font_size_label = gtk::Label::new(Some(&tr!("preferences.editor.font_size.title"))); - font_size_label.add_css_class("heading"); - font_size_label.set_halign(gtk::Align::Start); - container.append(&font_size_label); + let (font_size_box, font_size_scale) = Self::create_font_size_section(preferences); + container.append(&font_size_box); + + let (soft_wrap_switch, custom_font_switch) = + Self::create_style_section(&container, preferences); + + let font_button = Self::create_font_button(preferences); + container.append(&Self::create_font_row(&font_button)); + + Self::connect_signals( + sender, + &font_size_scale, + &soft_wrap_switch, + &custom_font_switch, + &font_button, + ); - let font_size_box = gtk::Box::new(gtk::Orientation::Horizontal, 10); - let font_size_spin = gtk::SpinButton::with_range(7.0, 21.0, 1.0); - font_size_spin.set_value(preferences.editor_font_size); - { - let sender = sender.clone(); - font_size_spin.connect_value_changed(move |spin| { - sender.emit(PreferencesInput::SetEditorFontSize(spin.value())); - }); + Self { + container, + font_size_scale, + soft_wrap_switch, + custom_font_switch, + font_button, } - font_size_box.append(&font_size_spin); - font_size_box.append(>k::Label::new(Some(&tr!( - "preferences.editor.font_size.unit" - )))); - container.append(&font_size_box); + } + + fn create_font_size_section(preferences: &UserPreferences) -> (gtk::Box, gtk::Scale) { + let label = gtk::Label::new(Some(&tr!("preferences.editor.font_size.title"))); + label.add_css_class("heading"); + label.set_halign(gtk::Align::Start); + + let scale = gtk::Scale::with_range(gtk::Orientation::Horizontal, 7.0, 21.0, 1.0); + scale.set_value(preferences.editor_font_size); + scale.set_draw_value(true); + scale.set_hexpand(true); + #[allow(clippy::cast_possible_truncation)] + scale.set_format_value_func(|_, value| { + #[allow(clippy::float_cmp)] + if value == DEFAULT_FONT_SIZE { + format!( + "{} ({})", + value as i32, + tr!("preferences.editor.default_font_size") + ) + } else { + format!("{}", value as i32) + } + }); + + let vbox = gtk::Box::new(gtk::Orientation::Vertical, 10); + vbox.append(&label); + vbox.append(&scale); + + (vbox, scale) + } - // Editor Style section - let style_label = gtk::Label::new(Some(&tr!("preferences.editor.editor_style.title"))); - style_label.add_css_class("heading"); - style_label.set_halign(gtk::Align::Start); - style_label.set_margin_top(10); - container.append(&style_label); + fn create_style_section( + container: >k::Box, + preferences: &UserPreferences, + ) -> (gtk::Switch, gtk::Switch) { + let label = gtk::Label::new(Some(&tr!("preferences.editor.editor_style.title"))); + label.add_css_class("heading"); + label.set_halign(gtk::Align::Start); + label.set_margin_top(10); + container.append(&label); - // Soft Wrap Lines let soft_wrap_row = create_switch_row( &tr!("preferences.editor.editor_style.soft_wrap_lines"), preferences.soft_wrap_lines, ); - let soft_wrap_switch = soft_wrap_row.1.clone(); - { - let sender = sender.clone(); - soft_wrap_switch.connect_state_set(move |_, state| { - sender.emit(PreferencesInput::SetSoftWrapLines(state)); - gtk::glib::Propagation::Proceed - }); - } container.append(&soft_wrap_row.0); - // Use Custom Font let custom_font_row = create_switch_row( &tr!("preferences.editor.editor_style.use_custom_font"), preferences.use_custom_editor_font, ); - let custom_font_switch = custom_font_row.1.clone(); container.append(&custom_font_row.0); - // Font selection - let font_row = gtk::Box::new(gtk::Orientation::Horizontal, 10); - font_row.append(>k::Label::new(Some(&tr!("preferences.editor.font")))); - - let font_button = gtk::FontButton::new(); - font_button.set_use_size(false); + (soft_wrap_row.1, custom_font_row.1) + } + fn create_font_button(preferences: &UserPreferences) -> gtk::FontButton { + let button = gtk::FontButton::new(); #[allow(clippy::cast_possible_truncation)] - font_button.set_font(&format!( + button.set_font(&format!( "{} {}", preferences.custom_editor_font_name, preferences.editor_font_size as i32 )); - font_button.set_sensitive(preferences.use_custom_editor_font); - font_button.set_hexpand(true); - font_button.set_use_font(true); - { - let sender = sender.clone(); - font_button.connect_font_set(move |button| { - if let Some(font) = button.font() { - // Extract font family from the font string - let font_desc = gtk::pango::FontDescription::from_string(&font); - if let Some(family) = font_desc.family() { - sender.emit(PreferencesInput::SetCustomEditorFontName( - family.to_string(), - )); - } + button.set_sensitive(preferences.use_custom_editor_font); + button.set_hexpand(true); + button.set_use_font(true); + button.set_use_size(false); + button + } + + fn create_font_row(font_button: >k::FontButton) -> gtk::Box { + let row = gtk::Box::new(gtk::Orientation::Horizontal, 10); + row.append(>k::Label::new(Some(&tr!("preferences.editor.font")))); + row.append(font_button); + row + } + + fn connect_signals( + sender: &Sender<PreferencesInput>, + font_size_scale: >k::Scale, + soft_wrap_switch: >k::Switch, + custom_font_switch: >k::Switch, + font_button: >k::FontButton, + ) { + let s = sender.clone(); + let fb = font_button.clone(); + font_size_scale.connect_value_changed(move |scale| { + s.emit(PreferencesInput::SetEditorFontSize(scale.value())); + Self::update_font_button_size(&fb, scale.value()); + }); + + let s = sender.clone(); + soft_wrap_switch.connect_state_set(move |_, state| { + s.emit(PreferencesInput::SetSoftWrapLines(state)); + gtk::glib::Propagation::Proceed + }); + + let s = sender.clone(); + let scale = font_size_scale.clone(); + font_button.connect_font_set(move |button| { + if let Some(font) = button.font() { + let font_desc = gtk::pango::FontDescription::from_string(&font); + if let Some(family) = font_desc.family() { + s.emit(PreferencesInput::SetCustomEditorFontName( + family.to_string(), + )); } - }); - } - font_row.append(&font_button); - container.append(&font_row); + let size = font_desc.size() / gtk::pango::SCALE; + if size > 0 { + scale.set_value(f64::from(size)); + } + } + }); - // Connect custom font switch to font button sensitivity - { - let font_button_clone = font_button.clone(); - let sender = sender.clone(); - custom_font_switch.connect_state_set(move |_, state| { - font_button_clone.set_sensitive(state); - sender.emit(PreferencesInput::SetUseCustomEditorFont(state)); - gtk::glib::Propagation::Proceed - }); - } + let s = sender.clone(); + let fb = font_button.clone(); + custom_font_switch.connect_state_set(move |_, state| { + fb.set_sensitive(state); + s.emit(PreferencesInput::SetUseCustomEditorFont(state)); + gtk::glib::Propagation::Proceed + }); + } - Self { - container, - font_size_spin, - soft_wrap_switch, - custom_font_switch, - font_button, + fn update_font_button_size(font_button: >k::FontButton, size: f64) { + if let Some(font) = font_button.font() { + let mut font_desc = gtk::pango::FontDescription::from_string(&font); + #[allow(clippy::cast_possible_truncation)] + font_desc.set_size(size as i32 * gtk::pango::SCALE); + font_button.set_font(&font_desc.to_string()); } } @@ -149,14 +205,14 @@ impl EditorPage { } pub fn sync_from(&self, preferences: &UserPreferences) { - self.font_size_spin.set_value(preferences.editor_font_size); + self.font_size_scale.set_value(preferences.editor_font_size); self.soft_wrap_switch .set_active(preferences.soft_wrap_lines); self.custom_font_switch .set_active(preferences.use_custom_editor_font); self.font_button .set_sensitive(preferences.use_custom_editor_font); - #[allow(clippy::cast_possible_truncation)] // Font size is always a small positive number + #[allow(clippy::cast_possible_truncation)] self.font_button.set_font(&format!( "{} {}", preferences.custom_editor_font_name, preferences.editor_font_size as i32 |