aboutsummaryrefslogtreecommitdiff
path: root/src/components/preference_pages/map.rs
diff options
context:
space:
mode:
authorRubén Beltrán del Río <jj@r.bdr.sh>2026-03-27 16:10:46 +0100
committerRubén Beltrán del Río <jj@r.bdr.sh>2026-03-30 13:39:14 +0200
commitd01a4df546b553128400f6c68eefa8368b4113a8 (patch)
treed290ca78b1215fb450ec7850a74b79fd0ae9707c /src/components/preference_pages/map.rs
parent4dec344a7bcbf1d7d0bbbf985109df816470ecc6 (diff)
Use actual components for preference pages
Diffstat (limited to 'src/components/preference_pages/map.rs')
-rw-r--r--src/components/preference_pages/map.rs231
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: &gtk::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();
+ }
+ }
+ }
+}