diff options
| author | Rubén Beltrán del Río <jj@r.bdr.sh> | 2026-01-16 08:26:35 +0100 |
|---|---|---|
| committer | Rubén Beltrán del Río <jj@r.bdr.sh> | 2026-01-16 11:57:13 +0100 |
| commit | 81cd06b3334f2f91f6a1ab62a28e11c7d0c677eb (patch) | |
| tree | f0b0cf37b406eda2dec8db4382aeb5f606cd1f0d /src/preferences/pages/map.rs | |
| parent | 4211b2ae06777d5bbe8261a1ab5c0dd057829a35 (diff) | |
Add preferences
Diffstat (limited to 'src/preferences/pages/map.rs')
| -rw-r--r-- | src/preferences/pages/map.rs | 187 |
1 files changed, 187 insertions, 0 deletions
diff --git a/src/preferences/pages/map.rs b/src/preferences/pages/map.rs new file mode 100644 index 0000000..f3537c0 --- /dev/null +++ b/src/preferences/pages/map.rs @@ -0,0 +1,187 @@ +// Copyright (C) 2024 Rubén Beltrán del Río + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this program. If not, see https://map.tranquil.systems. + +use gtk::prelude::*; +use relm4::Sender; +use relm4::gtk; + +use super::super::models::UserPreferences; +use super::super::window::PreferencesInput; + +pub struct MapPage { + container: gtk::Box, + show_background_switch: gtk::Switch, + smart_positioning_switch: gtk::Switch, + custom_font_switch: gtk::Switch, + font_button: gtk::FontButton, + export_format_dropdown: gtk::DropDown, +} + +impl MapPage { + pub fn new(prefs: &UserPreferences, sender: Sender<PreferencesInput>) -> Self { + let container = gtk::Box::new(gtk::Orientation::Vertical, 20); + container.set_margin_top(20); + container.set_margin_bottom(20); + container.set_margin_start(20); + container.set_margin_end(20); + container.set_valign(gtk::Align::Start); + + // Map Style section + let style_label = gtk::Label::new(Some("Map Style")); + style_label.add_css_class("heading"); + style_label.set_halign(gtk::Align::Start); + container.append(&style_label); + + // Show Background + let bg_row = create_switch_row("Show Map Background", prefs.show_map_background); + let show_background_switch = bg_row.1.clone(); + { + let sender = sender.clone(); + show_background_switch.connect_state_set(move |_, state| { + sender.emit(PreferencesInput::SetShowMapBackground(state)); + gtk::glib::Propagation::Proceed + }); + } + container.append(&bg_row.0); + + // Smart Label Positioning + let smart_row = create_switch_row( + "Use Smart Label Positioning", + prefs.use_smart_label_positioning, + ); + let smart_positioning_switch = smart_row.1.clone(); + { + let sender = sender.clone(); + smart_positioning_switch.connect_state_set(move |_, state| { + sender.emit(PreferencesInput::SetUseSmartLabelPositioning(state)); + gtk::glib::Propagation::Proceed + }); + } + container.append(&smart_row.0); + + // Use Custom Font + let custom_font_row = create_switch_row("Use Custom Font", prefs.use_custom_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("Font"))); + + let font_button = gtk::FontButton::new(); + font_button.set_font(&prefs.custom_font_name); + font_button.set_sensitive(prefs.use_custom_font); + font_button.set_hexpand(true); + font_button.set_use_font(true); + { + let sender = sender.clone(); + font_button.connect_font_set(move |btn| { + if let Some(font) = btn.font() { + let font_desc = gtk::pango::FontDescription::from_string(&font); + if let Some(family) = font_desc.family() { + sender.emit(PreferencesInput::SetCustomFontName(family.to_string())); + } + } + }); + } + font_row.append(&font_button); + container.append(&font_row); + + // 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::SetUseCustomFont(state)); + gtk::glib::Propagation::Proceed + }); + } + + // Export section + let export_label = gtk::Label::new(Some("Export")); + export_label.add_css_class("heading"); + export_label.set_halign(gtk::Align::Start); + export_label.set_margin_top(10); + container.append(&export_label); + + let export_row = gtk::Box::new(gtk::Orientation::Horizontal, 10); + export_row.append(>k::Label::new(Some("Default Export Format"))); + + let formats = gtk::StringList::new(&["PNG", "SVG"]); + let export_format_dropdown = gtk::DropDown::new(Some(formats), None::<gtk::Expression>); + let selected = match prefs.default_export_format.as_str() { + "svg" => 1, + _ => 0, + }; + export_format_dropdown.set_selected(selected); + { + let sender = sender.clone(); + export_format_dropdown.connect_selected_notify(move |dropdown| { + let format = match dropdown.selected() { + 1 => "svg", + _ => "png", + }; + sender.emit(PreferencesInput::SetDefaultExportFormat(format.to_string())); + }); + } + export_row.append(&export_format_dropdown); + container.append(&export_row); + + Self { + container, + show_background_switch, + smart_positioning_switch, + custom_font_switch, + font_button, + export_format_dropdown, + } + } + + pub fn widget(&self) -> gtk::Box { + self.container.clone() + } + + pub fn sync_from(&self, prefs: &UserPreferences) { + self.show_background_switch + .set_active(prefs.show_map_background); + self.smart_positioning_switch + .set_active(prefs.use_smart_label_positioning); + self.custom_font_switch.set_active(prefs.use_custom_font); + self.font_button.set_sensitive(prefs.use_custom_font); + self.font_button.set_font(&prefs.custom_font_name); + + let selected = match prefs.default_export_format.as_str() { + "svg" => 1, + _ => 0, + }; + self.export_format_dropdown.set_selected(selected); + } +} + +fn create_switch_row(label: &str, initial_state: bool) -> (gtk::Box, gtk::Switch) { + let row = gtk::Box::new(gtk::Orientation::Horizontal, 10); + row.append(>k::Label::new(Some(label))); + + let spacer = gtk::Box::new(gtk::Orientation::Horizontal, 0); + spacer.set_hexpand(true); + row.append(&spacer); + + let switch = gtk::Switch::new(); + switch.set_active(initial_state); + row.append(&switch); + + (row, switch) +} |