aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorRubén Beltrán del Río <jj@r.bdr.sh>2026-01-17 23:56:42 +0100
committerRubén Beltrán del Río <jj@r.bdr.sh>2026-01-18 00:19:59 +0100
commit5ab839d56067e026f07309c7153b5572e725d171 (patch)
treebbd83a99abf4868d222d0cb5b5c4114b97323028 /src
parentbfd56ed050ab5d9a342e28067ec91f7656dc8f0d (diff)
Improve font size picker
Diffstat (limited to 'src')
-rw-r--r--src/preferences/pages/editor.rs214
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(&gtk::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: &gtk::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(&gtk::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: &gtk::FontButton) -> gtk::Box {
+ let row = gtk::Box::new(gtk::Orientation::Horizontal, 10);
+ row.append(&gtk::Label::new(Some(&tr!("preferences.editor.font"))));
+ row.append(font_button);
+ row
+ }
+
+ fn connect_signals(
+ sender: &Sender<PreferencesInput>,
+ font_size_scale: &gtk::Scale,
+ soft_wrap_switch: &gtk::Switch,
+ custom_font_switch: &gtk::Switch,
+ font_button: &gtk::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: &gtk::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