From d01a4df546b553128400f6c68eefa8368b4113a8 Mon Sep 17 00:00:00 2001 From: Rubén Beltrán del Río Date: Fri, 27 Mar 2026 16:10:46 +0100 Subject: Use actual components for preference pages --- src/preferences/pages/templates.rs | 349 ------------------------------------- 1 file changed, 349 deletions(-) delete mode 100644 src/preferences/pages/templates.rs (limited to 'src/preferences/pages/templates.rs') diff --git a/src/preferences/pages/templates.rs b/src/preferences/pages/templates.rs deleted file mode 100644 index 029b3e9..0000000 --- a/src/preferences/pages/templates.rs +++ /dev/null @@ -1,349 +0,0 @@ -// 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 std::cell::RefCell; -use std::rc::Rc; - -use relm4::Sender; -use relm4::gtk; -use sourceview5::prelude::*; -use uuid::Uuid; - -use crate::tr; - -use super::super::models::{Template, UserPreferences}; -use super::super::window::PreferencesInput; - -pub struct TemplatesPage { - container: gtk::Box, - list_box: gtk::ListBox, - #[allow(dead_code)] - editor: sourceview5::View, - editor_buffer: sourceview5::Buffer, - selected_id: Rc>>, - sender: Sender, -} - -impl TemplatesPage { - pub fn new(prefs: &UserPreferences, sender: Sender) -> Self { - let container = gtk::Box::new(gtk::Orientation::Horizontal, 0); - container.set_margin_top(10); - container.set_margin_bottom(10); - container.set_margin_start(10); - container.set_margin_end(10); - - let selected_id: Rc>> = Rc::new(RefCell::new(None)); - - // Left sidebar - let sidebar = gtk::Box::new(gtk::Orientation::Vertical, 5); - sidebar.set_width_request(200); - - let sidebar_label = gtk::Label::new(Some(&tr!("preferences.templates.title"))); - sidebar_label.add_css_class("heading"); - sidebar_label.set_halign(gtk::Align::Start); - sidebar_label.set_margin_start(5); - sidebar.append(&sidebar_label); - - // Template list - let scrolled = gtk::ScrolledWindow::new(); - scrolled.set_vexpand(true); - - let list_box = gtk::ListBox::new(); - list_box.set_selection_mode(gtk::SelectionMode::Single); - list_box.add_css_class("boxed-list"); - - scrolled.set_child(Some(&list_box)); - sidebar.append(&scrolled); - - // Sidebar buttons - let button_box = gtk::Box::new(gtk::Orientation::Horizontal, 5); - button_box.set_halign(gtk::Align::End); - button_box.set_margin_top(5); - - let add_button = gtk::Button::from_icon_name("list-add-symbolic"); - add_button.set_tooltip_text(Some(&tr!("preferences.templates.help.add"))); - { - let sender = sender.clone(); - add_button.connect_clicked(move |_| { - sender.emit(PreferencesInput::AddTemplate(tr!( - "dialog.template.default_label" - ))); - }); - } - button_box.append(&add_button); - - let remove_button = gtk::Button::from_icon_name("list-remove-symbolic"); - remove_button.set_tooltip_text(Some(&tr!("preferences.templates.help.remove"))); - { - let sender = sender.clone(); - let selected_id = selected_id.clone(); - remove_button.connect_clicked(move |_| { - if let Some(id) = *selected_id.borrow() { - sender.emit(PreferencesInput::RemoveTemplate(id)); - } - }); - } - button_box.append(&remove_button); - - sidebar.append(&button_box); - container.append(&sidebar); - - // Separator - let separator = gtk::Separator::new(gtk::Orientation::Vertical); - separator.set_margin_start(10); - separator.set_margin_end(10); - container.append(&separator); - - // Right side: editor - let editor_box = gtk::Box::new(gtk::Orientation::Vertical, 5); - editor_box.set_hexpand(true); - - let editor_label = gtk::Label::new(Some(&tr!("preferences.templates.content"))); - editor_label.add_css_class("heading"); - editor_label.set_halign(gtk::Align::Start); - editor_box.append(&editor_label); - - let editor_scrolled = gtk::ScrolledWindow::new(); - editor_scrolled.set_vexpand(true); - editor_scrolled.set_hexpand(true); - - let editor_buffer = sourceview5::Buffer::new(None); - editor_buffer.set_highlight_syntax(true); - - // Try to set wmap language - let language_manager = sourceview5::LanguageManager::default(); - if let Some(language) = language_manager.language("wmap") { - editor_buffer.set_language(Some(&language)); - } - - let editor = sourceview5::View::with_buffer(&editor_buffer); - editor.set_monospace(true); - editor.set_show_line_numbers(true); - editor.set_tab_width(2); - - // Connect buffer changes to save - { - let sender = sender.clone(); - let selected_id = selected_id.clone(); - editor_buffer.connect_changed(move |buffer| { - if let Some(id) = *selected_id.borrow() { - let start = buffer.start_iter(); - let end = buffer.end_iter(); - let content = buffer.text(&start, &end, false).to_string(); - sender.emit(PreferencesInput::SetTemplateContent(id, content)); - } - }); - } - - editor_scrolled.set_child(Some(&editor)); - editor_box.append(&editor_scrolled); - container.append(&editor_box); - - let page = Self { - container, - list_box, - editor, - editor_buffer, - selected_id, - sender, - }; - - page.populate_templates(prefs); - - // Select first template if available - if let Some(first) = prefs.map_templates.first() { - *page.selected_id.borrow_mut() = Some(first.id); - page.editor_buffer.set_text(&first.content); - } - - page - } - - pub fn widget(&self) -> gtk::Box { - self.container.clone() - } - - pub fn refresh(&self, prefs: &UserPreferences) { - // Check if we need to recreate rows (templates added/removed/reordered) - let current_row_count = { - let mut count = 0; - let mut child = self.list_box.first_child(); - while child.is_some() { - count += 1; - child = child.and_then(|c| c.next_sibling()); - } - count - }; - - let needs_recreate = current_row_count != prefs.map_templates.len(); - - if needs_recreate { - // Clear existing rows - while let Some(child) = self.list_box.first_child() { - self.list_box.remove(&child); - } - self.populate_templates(prefs); - } else { - // Just update existing rows in place - let mut child = self.list_box.first_child(); - let mut index = 0; - while let Some(row) = child { - if let Some(template) = prefs.map_templates.get(index) { - TemplatesPage::update_template_row(&row, template); - } - child = row.next_sibling(); - index += 1; - } - } - - // Update editor if selected template still exists - let selected = *self.selected_id.borrow(); - if let Some(id) = selected { - if let Some(template) = prefs.map_templates.iter().find(|t| t.id == id) { - // Only update if content differs to avoid cursor jumping - let current = { - let start = self.editor_buffer.start_iter(); - let end = self.editor_buffer.end_iter(); - self.editor_buffer.text(&start, &end, false).to_string() - }; - if current != template.content { - self.editor_buffer.set_text(&template.content); - } - } else { - // Selected template was deleted, select first - if let Some(first) = prefs.map_templates.first() { - *self.selected_id.borrow_mut() = Some(first.id); - self.editor_buffer.set_text(&first.content); - } else { - *self.selected_id.borrow_mut() = None; - self.editor_buffer.set_text(""); - } - } - } - } - - fn populate_templates(&self, prefs: &UserPreferences) { - for template in &prefs.map_templates { - let row = self.create_template_row(template); - self.list_box.append(&row); - } - - // Connect selection changed - { - let selected_id = self.selected_id.clone(); - let editor_buffer = self.editor_buffer.clone(); - let _sender = self.sender.clone(); - - // We need to store templates for the closure - let templates: Vec