// 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 . use gtk::prelude::*; use relm4::prelude::*; use crate::icon_names::shipped::RIGHT; use crate::preferences::models::Template; use crate::tr; #[derive(Debug)] pub struct TemplateRow { pub template: Template, focus_controller: gtk::EventControllerFocus, is_arrow_shown: bool, } #[derive(Debug, Clone)] pub enum TemplateRowAction { ShowArrow, HideArrow, } #[derive(Debug)] pub enum TemplateRowOutput { SetDefault(DynamicIndex), SetName(DynamicIndex, String), Focus(DynamicIndex), Activate(DynamicIndex), } #[relm4::factory(pub)] impl FactoryComponent for TemplateRow { type Init = Template; type Input = TemplateRowAction; type Output = TemplateRowOutput; type CommandOutput = (); type ParentWidget = gtk::ListBox; view! { #[root] gtk::ListBoxRow { set_focus_on_click: true, gtk::Box { set_orientation: gtk::Orientation::Horizontal, set_margin_all: 5, set_spacing: 5, gtk::Button { add_css_class: "flat", #[watch] set_icon_name: if self.template.is_default { "radio-checked-symbolic" } else { "radio-symbolic" }, #[watch] set_tooltip_text: Some(&if self.template.is_default { tr!("preferences.templates.help.default") } else { tr!("preferences.templates.help.set_as_default") }), connect_clicked[sender, index] => move |_| { sender.output(TemplateRowOutput::SetDefault(index.clone())).ok(); } }, #[name="entry"] gtk::Entry { set_text: &self.template.name, set_hexpand: true, connect_changed[sender, index] => move |entry| { sender.output(TemplateRowOutput::SetName( index.clone(), entry.text().to_string() )).ok(); }, add_controller: self.focus_controller.clone() }, gtk::Button::from_icon_name(RIGHT) { set_tooltip_text: Some(&tr!("preferences.templates.help.activate")), #[watch] set_visible: self.is_arrow_shown, connect_clicked[sender, index] => move |_| { sender.output(TemplateRowOutput::Activate(index.clone())).ok(); } } }, } } fn init_model(template: Self::Init, index: &DynamicIndex, sender: FactorySender) -> Self { let focus_controller = gtk::EventControllerFocus::new(); { let sender = sender.clone(); let index = index.clone(); focus_controller.connect_enter(move |_| { sender.output(TemplateRowOutput::Focus(index.clone())).ok(); }); } Self { template, focus_controller, is_arrow_shown: true, } } fn update(&mut self, message: Self::Input, _sender: FactorySender) { match message { TemplateRowAction::ShowArrow => self.is_arrow_shown = true, TemplateRowAction::HideArrow => self.is_arrow_shown = false, } } }