aboutsummaryrefslogtreecommitdiff
path: root/src/preferences/pages/map.rs
diff options
context:
space:
mode:
authorRubén Beltrán del Río <jj@r.bdr.sh>2026-01-16 08:26:35 +0100
committerRubén Beltrán del Río <jj@r.bdr.sh>2026-01-16 11:57:13 +0100
commit81cd06b3334f2f91f6a1ab62a28e11c7d0c677eb (patch)
treef0b0cf37b406eda2dec8db4382aeb5f606cd1f0d /src/preferences/pages/map.rs
parent4211b2ae06777d5bbe8261a1ab5c0dd057829a35 (diff)
Add preferences
Diffstat (limited to 'src/preferences/pages/map.rs')
-rw-r--r--src/preferences/pages/map.rs187
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(&gtk::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(&gtk::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(&gtk::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)
+}