diff options
| author | Rubén Beltrán del Río <jj@r.bdr.sh> | 2026-03-27 16:10:46 +0100 |
|---|---|---|
| committer | Rubén Beltrán del Río <jj@r.bdr.sh> | 2026-03-30 13:39:14 +0200 |
| commit | d01a4df546b553128400f6c68eefa8368b4113a8 (patch) | |
| tree | d290ca78b1215fb450ec7850a74b79fd0ae9707c /src/components/preference_pages/map.rs | |
| parent | 4dec344a7bcbf1d7d0bbbf985109df816470ecc6 (diff) | |
Use actual components for preference pages
Diffstat (limited to 'src/components/preference_pages/map.rs')
| -rw-r--r-- | src/components/preference_pages/map.rs | 231 |
1 files changed, 231 insertions, 0 deletions
diff --git a/src/components/preference_pages/map.rs b/src/components/preference_pages/map.rs new file mode 100644 index 0000000..abeabf9 --- /dev/null +++ b/src/components/preference_pages/map.rs @@ -0,0 +1,231 @@ +// Map, wardley map editor for linux +// Copyright (C) 2026 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 Affero 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 Affero General Public License for more details. + +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see <http://www.gnu.org/licenses/>. + +use gtk::prelude::*; +use relm4::prelude::*; + +use crate::tr; + +use crate::actions::PreferencesAction; +use crate::components::switch; + +pub struct MapInit { + pub show_background: bool, + pub use_smart_label_positioning: bool, + pub use_custom_font: bool, + pub custom_font: String, + pub default_export_format: String, +} +pub struct Map { + show_background_switch: Controller<switch::Switch>, + smart_label_positioning_switch: Controller<switch::Switch>, + custom_font_switch: Controller<switch::Switch>, + show_background: bool, + use_smart_label_positioning: bool, + use_custom_font: bool, + custom_font: String, + default_export_format: String, +} +#[derive(Debug, Clone)] +pub enum MapAction { + SetShowBackground(bool), + SetUseCustomFont(bool), + SetUseSmartLabelPositioning(bool), + SetCustomFont(String), + SetDefaultExportFormat(String), + + // Internal + ChangeShowBackground(bool), + ChangeUseCustomFont(bool), + ChangeUseSmartLabelPositioning(bool), + ChangeFontDescription(gtk::FontDialogButton), + ChangeDefaultExportFormat(String), +} + +#[relm4::component(pub)] +impl SimpleComponent for Map { + type Init = MapInit; + type Input = MapAction; + type Output = PreferencesAction; + view! { + gtk::Box { + set_orientation: gtk::Orientation::Vertical, + set_margin_all: 20, + set_spacing: 20, + set_valign: gtk::Align::Start, + + gtk::Label { + set_label: &tr!("preferences.map.map_style.title"), + add_css_class: "heading", + set_halign: gtk::Align::Start, + }, + model.show_background_switch.widget(), + model.smart_label_positioning_switch.widget(), + model.custom_font_switch.widget(), + + gtk::Box { + set_orientation: gtk::Orientation::Horizontal, + set_spacing: 10, + + gtk::Label { + set_label: &tr!("preferences.map.font"), + }, + + gtk::FontDialogButton::new(Some(gtk::FontDialog::new())) { + #[watch] + #[block_signal(font_handler)] + set_font_desc: >k::pango::FontDescription::from_string(&model.custom_font), + #[watch] + set_sensitive: model.use_custom_font, + set_hexpand: true, + set_use_font: true, + set_use_size: false, + + connect_font_desc_notify[sender] => move |button| { + sender.input(MapAction::ChangeFontDescription(button.clone())); + } @font_handler, + } + }, + + gtk::Label { + set_label: &tr!("preferences.map.export.title"), + add_css_class: "heading", + set_halign: gtk::Align::Start, + set_margin_top: 10, + }, + + gtk::Box { + set_orientation: gtk::Orientation::Horizontal, + set_spacing: 10, + + gtk::Label { + set_label: &tr!("preferences.map.export.default_format"), + }, + gtk::DropDown::new(Some(gtk::StringList::new(&[ + &tr!("export_formats.png"), + &tr!("export_formats.svg"), + ])), None::<gtk::Expression>) { + #[watch] + #[block_signal(export_handler)] + set_selected: match model.default_export_format.as_str() { + "svg" => 1, + _ => 0 + }, + connect_selected_notify[sender] => move |dropdown| { + let format = match dropdown.selected() { + 1 => "svg", + _ => "png", + }; + sender.input(MapAction::ChangeDefaultExportFormat(format.to_string())); + } @export_handler, + } + }, + } + } + + fn init( + init: Self::Init, + root: Self::Root, + sender: ComponentSender<Self>, + ) -> ComponentParts<Self> { + let show_background_switch = switch::Switch::builder() + .launch(switch::SwitchInit { + label: tr!("preferences.map.map_style.show_background"), + state: init.show_background, + }) + .forward(sender.input_sender(), move |output| match output { + switch::SwitchOutput::SetState(state) => MapAction::ChangeShowBackground(state), + }); + + let custom_font_switch = switch::Switch::builder() + .launch(switch::SwitchInit { + label: tr!("preferences.map.map_style.use_custom_font"), + state: init.use_custom_font, + }) + .forward(sender.input_sender(), move |output| match output { + switch::SwitchOutput::SetState(state) => MapAction::ChangeUseCustomFont(state), + }); + + let smart_label_positioning_switch = switch::Switch::builder() + .launch(switch::SwitchInit { + label: tr!("preferences.map.map_style.use_smart_label_positioning"), + state: init.use_smart_label_positioning, + }) + .forward(sender.input_sender(), move |output| match output { + switch::SwitchOutput::SetState(state) => { + MapAction::ChangeUseSmartLabelPositioning(state) + } + }); + + let model = Self { + show_background: init.show_background, + use_smart_label_positioning: init.use_smart_label_positioning, + use_custom_font: init.use_custom_font, + custom_font: init.custom_font, + default_export_format: init.default_export_format, + show_background_switch, + smart_label_positioning_switch, + custom_font_switch, + }; + + let widgets = view_output!(); + ComponentParts { model, widgets } + } + + fn update(&mut self, message: Self::Input, sender: ComponentSender<Self>) { + match message { + MapAction::SetUseCustomFont(use_custom_font) => self.use_custom_font = use_custom_font, + MapAction::SetShowBackground(show_background) => self.show_background = show_background, + MapAction::SetUseSmartLabelPositioning(use_smart_label_positioning) => { + self.use_smart_label_positioning = use_smart_label_positioning + } + MapAction::SetCustomFont(custom_font) => self.custom_font = custom_font, + MapAction::SetDefaultExportFormat(default_export_format) => { + self.default_export_format = default_export_format + } + + MapAction::ChangeFontDescription(button) => { + if let Some(font) = button.font_desc() + && let Some(family) = font.family() + { + sender + .output(PreferencesAction::SetCustomFontName(family.to_string())) + .ok(); + } + } + MapAction::ChangeShowBackground(state) => { + sender + .output(PreferencesAction::SetShowMapBackground(state)) + .ok(); + } + MapAction::ChangeUseCustomFont(state) => { + sender + .output(PreferencesAction::SetUseCustomFont(state)) + .ok(); + } + MapAction::ChangeUseSmartLabelPositioning(state) => { + sender + .output(PreferencesAction::SetUseSmartLabelPositioning(state)) + .ok(); + } + MapAction::ChangeDefaultExportFormat(format) => { + sender + .output(PreferencesAction::SetDefaultExportFormat(format)) + .ok(); + } + } + } +} |