aboutsummaryrefslogtreecommitdiff
path: root/src/preferences
diff options
context:
space:
mode:
Diffstat (limited to 'src/preferences')
-rw-r--r--src/preferences/pages/editor.rs13
-rw-r--r--src/preferences/pages/general.rs30
-rw-r--r--src/preferences/pages/map.rs17
-rw-r--r--src/preferences/pages/stages.rs22
-rw-r--r--src/preferences/pages/templates.rs77
-rw-r--r--src/preferences/window.rs15
6 files changed, 73 insertions, 101 deletions
diff --git a/src/preferences/pages/editor.rs b/src/preferences/pages/editor.rs
index 9f10d43..d4acb94 100644
--- a/src/preferences/pages/editor.rs
+++ b/src/preferences/pages/editor.rs
@@ -18,6 +18,7 @@ use gtk::prelude::*;
use relm4::Sender;
use relm4::gtk;
+use crate::tr;
use crate::ui_helpers::create_switch_row;
use super::super::models::UserPreferences;
@@ -41,7 +42,7 @@ impl EditorPage {
container.set_valign(gtk::Align::Start);
// Font Size section
- let font_size_label = gtk::Label::new(Some("Font Size"));
+ let font_size_label = gtk::Label::new(Some(&tr!("preferences.editor.font_size.title")));
font_size_label.add_css_class("heading");
font_size_label.set_halign(gtk::Align::Start);
container.append(&font_size_label);
@@ -56,18 +57,18 @@ impl EditorPage {
});
}
font_size_box.append(&font_size_spin);
- font_size_box.append(&gtk::Label::new(Some("pt")));
+ font_size_box.append(&gtk::Label::new(Some(&tr!("preferences.editor.font_size.unit"))));
container.append(&font_size_box);
// Editor Style section
- let style_label = gtk::Label::new(Some("Editor Style"));
+ let style_label = gtk::Label::new(Some(&tr!("preferences.editor.editor_style.title")));
style_label.add_css_class("heading");
style_label.set_halign(gtk::Align::Start);
style_label.set_margin_top(10);
container.append(&style_label);
// Soft Wrap Lines
- let soft_wrap_row = create_switch_row("Soft Wrap Lines", preferences.soft_wrap_lines);
+ let soft_wrap_row = create_switch_row(&tr!("preferences.editor.editor_style.soft_wrap_lines"), preferences.soft_wrap_lines);
let soft_wrap_switch = soft_wrap_row.1.clone();
{
let sender = sender.clone();
@@ -80,13 +81,13 @@ impl EditorPage {
// Use Custom Font
let custom_font_row =
- create_switch_row("Use Custom Editor Font", preferences.use_custom_editor_font);
+ create_switch_row(&tr!("preferences.editor.editor_style.use_custom_font"), preferences.use_custom_editor_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")));
+ font_row.append(&gtk::Label::new(Some(&tr!("preferences.editor.font"))));
let font_button = gtk::FontButton::new();
font_button.set_font(&format!(
diff --git a/src/preferences/pages/general.rs b/src/preferences/pages/general.rs
index 43cd784..d70e9e6 100644
--- a/src/preferences/pages/general.rs
+++ b/src/preferences/pages/general.rs
@@ -19,6 +19,8 @@ use gtk::prelude::*;
use relm4::Sender;
use relm4::gtk;
+use crate::tr;
+
use super::super::window::PreferencesInput;
pub struct GeneralPage {
@@ -35,7 +37,7 @@ impl GeneralPage {
container.set_valign(gtk::Align::Start);
// Preferences section
- let prefs_label = gtk::Label::new(Some("Preferences"));
+ let prefs_label = gtk::Label::new(Some(&tr!("preferences.general.preferences.title")));
prefs_label.add_css_class("heading");
prefs_label.set_halign(gtk::Align::Start);
container.append(&prefs_label);
@@ -43,7 +45,7 @@ impl GeneralPage {
let button_box = gtk::Box::new(gtk::Orientation::Horizontal, 10);
// Export button
- let export_button = gtk::Button::with_label("Export...");
+ let export_button = gtk::Button::with_label(&tr!("preferences.general.preferences.export"));
{
let sender = sender.clone();
export_button.connect_clicked(move |_| {
@@ -53,7 +55,7 @@ impl GeneralPage {
button_box.append(&export_button);
// Import button
- let import_button = gtk::Button::with_label("Import...");
+ let import_button = gtk::Button::with_label(&tr!("preferences.general.preferences.import"));
{
let sender = sender.clone();
import_button.connect_clicked(move |_| {
@@ -63,7 +65,7 @@ impl GeneralPage {
button_box.append(&import_button);
// Reset button
- let reset_button = gtk::Button::with_label("Reset to Defaults");
+ let reset_button = gtk::Button::with_label(&tr!("preferences.general.preferences.reset"));
reset_button.add_css_class("destructive-action");
{
let sender = sender.clone();
@@ -76,9 +78,7 @@ impl GeneralPage {
container.append(&button_box);
// Help text
- let help_label = gtk::Label::new(Some(
- "Export your preferences to share with others or back up your settings.\nImport preferences from a file to restore settings.",
- ));
+ let help_label = gtk::Label::new(Some(&tr!("preferences.general.explanation")));
help_label.add_css_class("dim-label");
help_label.set_halign(gtk::Align::Start);
help_label.set_wrap(true);
@@ -95,15 +95,15 @@ impl GeneralPage {
pub fn show_export_dialog(sender: &Sender<PreferencesInput>, window: &gtk::Window) {
let filter = FileFilter::new();
filter.add_pattern("*.json");
- filter.set_name(Some("JSON files"));
+ filter.set_name(Some(&tr!("dialog.file_type.json")));
let dialog = gtk::FileChooserDialog::new(
- Some("Export Preferences"),
+ Some(&tr!("dialog.export_preferences.title")),
Some(window),
gtk::FileChooserAction::Save,
&[
- ("Cancel", gtk::ResponseType::Cancel),
- ("Save", gtk::ResponseType::Accept),
+ (&tr!("dialog.action.cancel"), gtk::ResponseType::Cancel),
+ (&tr!("dialog.action.save"), gtk::ResponseType::Accept),
],
);
dialog.set_current_name("preferences.json");
@@ -127,15 +127,15 @@ pub fn show_export_dialog(sender: &Sender<PreferencesInput>, window: &gtk::Windo
pub fn show_import_dialog(sender: &Sender<PreferencesInput>, window: &gtk::Window) {
let filter = FileFilter::new();
filter.add_pattern("*.json");
- filter.set_name(Some("JSON files"));
+ filter.set_name(Some(&tr!("dialog.file_type.json")));
let dialog = gtk::FileChooserDialog::new(
- Some("Import Preferences"),
+ Some(&tr!("dialog.import_preferences.title")),
Some(window),
gtk::FileChooserAction::Open,
&[
- ("Cancel", gtk::ResponseType::Cancel),
- ("Open", gtk::ResponseType::Accept),
+ (&tr!("dialog.action.cancel"), gtk::ResponseType::Cancel),
+ (&tr!("dialog.action.open"), gtk::ResponseType::Accept),
],
);
dialog.add_filter(&filter);
diff --git a/src/preferences/pages/map.rs b/src/preferences/pages/map.rs
index 8deae20..5ffd04a 100644
--- a/src/preferences/pages/map.rs
+++ b/src/preferences/pages/map.rs
@@ -18,6 +18,7 @@ use gtk::prelude::*;
use relm4::Sender;
use relm4::gtk;
+use crate::tr;
use crate::ui_helpers::create_switch_row;
use super::super::models::UserPreferences;
@@ -42,14 +43,14 @@ impl MapPage {
container.set_valign(gtk::Align::Start);
// Map Style section
- let style_label = gtk::Label::new(Some("Map Style"));
+ let style_label = gtk::Label::new(Some(&tr!("preferences.map.map_style.title")));
style_label.add_css_class("heading");
style_label.set_halign(gtk::Align::Start);
container.append(&style_label);
// Show Background
let background_row =
- create_switch_row("Show Map Background", preferences.show_map_background);
+ create_switch_row(&tr!("preferences.map.map_style.show_background"), preferences.show_map_background);
let show_background_switch = background_row.1.clone();
{
let sender = sender.clone();
@@ -62,7 +63,7 @@ impl MapPage {
// Smart Label Positioning
let smart_row = create_switch_row(
- "Use Smart Label Positioning",
+ &tr!("preferences.map.map_style.use_smart_label_positioning"),
preferences.use_smart_label_positioning,
);
let smart_positioning_switch = smart_row.1.clone();
@@ -76,13 +77,13 @@ impl MapPage {
container.append(&smart_row.0);
// Use Custom Font
- let custom_font_row = create_switch_row("Use Custom Font", preferences.use_custom_font);
+ let custom_font_row = create_switch_row(&tr!("preferences.map.map_style.use_custom_font"), preferences.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")));
+ font_row.append(&gtk::Label::new(Some(&tr!("preferences.map.font"))));
let font_button = gtk::FontButton::new();
font_button.set_font(&preferences.custom_font_name);
@@ -115,16 +116,16 @@ impl MapPage {
}
// Export section
- let export_label = gtk::Label::new(Some("Export"));
+ let export_label = gtk::Label::new(Some(&tr!("preferences.map.export.title")));
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")));
+ export_row.append(&gtk::Label::new(Some(&tr!("preferences.map.export.default_format"))));
- let formats = gtk::StringList::new(&["PNG", "SVG"]);
+ let formats = gtk::StringList::new(&[&tr!("export_formats.png"), &tr!("export_formats.svg")]);
let export_format_dropdown = gtk::DropDown::new(Some(formats), None::<gtk::Expression>);
let selected = match preferences.default_export_format.as_str() {
"svg" => 1,
diff --git a/src/preferences/pages/stages.rs b/src/preferences/pages/stages.rs
index 6f4121e..9f0685d 100644
--- a/src/preferences/pages/stages.rs
+++ b/src/preferences/pages/stages.rs
@@ -19,6 +19,8 @@ use relm4::Sender;
use relm4::gtk;
use uuid::Uuid;
+use crate::tr;
+
use super::super::models::UserPreferences;
use super::super::window::{PreferencesInput, StageLabel};
@@ -37,14 +39,12 @@ impl StagesPage {
container.set_margin_end(20);
// Header
- let header_label = gtk::Label::new(Some("Custom Stages"));
+ let header_label = gtk::Label::new(Some(&tr!("preferences.stages.title")));
header_label.add_css_class("heading");
header_label.set_halign(gtk::Align::Start);
container.append(&header_label);
- let help_label = gtk::Label::new(Some(
- "Custom stages allow you to define your own evolution axis labels. These will be available for rendering when the renderer supports custom stages.",
- ));
+ let help_label = gtk::Label::new(Some(&tr!("preferences.stages.explanation")));
help_label.add_css_class("dim-label");
help_label.set_halign(gtk::Align::Start);
help_label.set_wrap(true);
@@ -55,27 +55,27 @@ impl StagesPage {
let header_row = gtk::Box::new(gtk::Orientation::Horizontal, 5);
header_row.add_css_class("dim-label");
- let name_header = gtk::Label::new(Some("Name"));
+ let name_header = gtk::Label::new(Some(&tr!("preferences.stages.column.name")));
name_header.set_width_chars(15);
name_header.set_xalign(0.0);
header_row.append(&name_header);
- let i_header = gtk::Label::new(Some("Stage I"));
+ let i_header = gtk::Label::new(Some(&tr!("preferences.stages.column.stage_i")));
i_header.set_width_chars(12);
i_header.set_xalign(0.0);
header_row.append(&i_header);
- let ii_header = gtk::Label::new(Some("Stage II"));
+ let ii_header = gtk::Label::new(Some(&tr!("preferences.stages.column.stage_ii")));
ii_header.set_width_chars(12);
ii_header.set_xalign(0.0);
header_row.append(&ii_header);
- let iii_header = gtk::Label::new(Some("Stage III"));
+ let iii_header = gtk::Label::new(Some(&tr!("preferences.stages.column.stage_iii")));
iii_header.set_width_chars(12);
iii_header.set_xalign(0.0);
header_row.append(&iii_header);
- let iv_header = gtk::Label::new(Some("Stage IV"));
+ let iv_header = gtk::Label::new(Some(&tr!("preferences.stages.column.stage_iv")));
iv_header.set_width_chars(12);
iv_header.set_xalign(0.0);
header_row.append(&iv_header);
@@ -104,7 +104,7 @@ impl StagesPage {
button_box.set_halign(gtk::Align::End);
let add_button = gtk::Button::from_icon_name("list-add-symbolic");
- add_button.set_tooltip_text(Some("Add custom stage"));
+ add_button.set_tooltip_text(Some(&tr!("preferences.stages.help.add")));
{
let sender = sender.clone();
add_button.connect_clicked(move |_| {
@@ -238,7 +238,7 @@ impl StagesPage {
// Delete button
let delete_button = gtk::Button::from_icon_name("list-remove-symbolic");
delete_button.add_css_class("flat");
- delete_button.set_tooltip_text(Some("Remove stage"));
+ delete_button.set_tooltip_text(Some(&tr!("preferences.stages.help.remove")));
{
let sender = self.sender.clone();
delete_button.connect_clicked(move |_| {
diff --git a/src/preferences/pages/templates.rs b/src/preferences/pages/templates.rs
index da3cafc..acc679f 100644
--- a/src/preferences/pages/templates.rs
+++ b/src/preferences/pages/templates.rs
@@ -22,6 +22,8 @@ use relm4::gtk;
use sourceview5::prelude::*;
use uuid::Uuid;
+use crate::tr;
+
use super::super::models::{Template, UserPreferences};
use super::super::window::PreferencesInput;
@@ -49,7 +51,7 @@ impl TemplatesPage {
let sidebar = gtk::Box::new(gtk::Orientation::Vertical, 5);
sidebar.set_width_request(200);
- let sidebar_label = gtk::Label::new(Some("Templates"));
+ 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);
@@ -72,18 +74,19 @@ impl TemplatesPage {
button_box.set_margin_top(5);
let add_button = gtk::Button::from_icon_name("list-add-symbolic");
- add_button.set_tooltip_text(Some("Add template"));
+ add_button.set_tooltip_text(Some(&tr!("preferences.templates.help.add")));
{
let sender = sender.clone();
add_button.connect_clicked(move |_| {
- // Show a simple dialog to get the template name
- show_add_template_dialog(sender.clone());
+ 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("Remove template"));
+ remove_button.set_tooltip_text(Some(&tr!("preferences.templates.help.remove")));
{
let sender = sender.clone();
let selected_id = selected_id.clone();
@@ -108,7 +111,7 @@ impl TemplatesPage {
let editor_box = gtk::Box::new(gtk::Orientation::Vertical, 5);
editor_box.set_hexpand(true);
- let editor_label = gtk::Label::new(Some("Template Content"));
+ 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);
@@ -245,10 +248,10 @@ impl TemplatesPage {
let default_button = gtk::Button::new();
if template.is_default {
default_button.set_icon_name("emblem-default-symbolic");
- default_button.set_tooltip_text(Some("Default template"));
+ default_button.set_tooltip_text(Some(&tr!("preferences.templates.help.default")));
} else {
default_button.set_icon_name("radio-symbolic");
- default_button.set_tooltip_text(Some("Set as default"));
+ default_button.set_tooltip_text(Some(&tr!("preferences.templates.help.set_as_default")));
}
default_button.add_css_class("flat");
{
@@ -260,54 +263,20 @@ impl TemplatesPage {
}
hbox.append(&default_button);
- // Template name
- let name_label = gtk::Label::new(Some(&template.name));
- name_label.set_hexpand(true);
- name_label.set_xalign(0.0);
- hbox.append(&name_label);
+ // Template name (editable)
+ let name_entry = gtk::Entry::new();
+ name_entry.set_text(&template.name);
+ name_entry.set_hexpand(true);
+ {
+ let sender = self.sender.clone();
+ let id = template.id;
+ name_entry.connect_changed(move |entry| {
+ sender.emit(PreferencesInput::SetTemplateName(id, entry.text().to_string()));
+ });
+ }
+ hbox.append(&name_entry);
row.set_child(Some(&hbox));
row
}
}
-
-fn show_add_template_dialog(sender: Sender<PreferencesInput>) {
- let dialog = gtk::Dialog::with_buttons(
- Some("New Template"),
- None::<&gtk::Window>,
- gtk::DialogFlags::MODAL | gtk::DialogFlags::DESTROY_WITH_PARENT,
- &[
- ("Cancel", gtk::ResponseType::Cancel),
- ("Add", gtk::ResponseType::Accept),
- ],
- );
- dialog.set_default_response(gtk::ResponseType::Accept);
-
- let content = dialog.content_area();
- content.set_margin_top(10);
- content.set_margin_bottom(10);
- content.set_margin_start(10);
- content.set_margin_end(10);
- content.set_spacing(10);
-
- let label = gtk::Label::new(Some("Template name:"));
- label.set_halign(gtk::Align::Start);
- content.append(&label);
-
- let entry = gtk::Entry::new();
- entry.set_placeholder_text(Some("My Template"));
- entry.set_activates_default(true);
- content.append(&entry);
-
- dialog.connect_response(move |dialog, response| {
- if response == gtk::ResponseType::Accept {
- let name = entry.text().to_string();
- if !name.is_empty() {
- sender.emit(PreferencesInput::AddTemplate(name));
- }
- }
- dialog.close();
- });
-
- dialog.present();
-}
diff --git a/src/preferences/window.rs b/src/preferences/window.rs
index 8b38c29..2118056 100644
--- a/src/preferences/window.rs
+++ b/src/preferences/window.rs
@@ -22,6 +22,8 @@ use std::path::PathBuf;
use gtk::prelude::*;
use relm4::{ComponentParts, ComponentSender, SimpleComponent, gtk};
+use crate::tr;
+
use super::models::UserPreferences;
use super::pages::{editor, general, map, stages, templates};
use super::storage;
@@ -52,7 +54,6 @@ pub enum PreferencesInput {
AddTemplate(String),
RemoveTemplate(uuid::Uuid),
SetTemplateContent(uuid::Uuid, String),
- #[allow(dead_code)]
SetTemplateName(uuid::Uuid, String),
SetDefaultTemplate(uuid::Uuid),
@@ -101,7 +102,7 @@ impl SimpleComponent for PreferencesWindow {
view! {
gtk::Window {
- set_title: Some("Preferences"),
+ set_title: Some(&tr!("preferences.title")),
set_default_width: 700,
set_default_height: 500,
set_modal: true,
@@ -127,11 +128,11 @@ impl SimpleComponent for PreferencesWindow {
set_transition_type: gtk::StackTransitionType::SlideLeftRight,
set_vexpand: true,
- add_titled[Some("general"), "General"] = &model.general_page.widget() -> gtk::Box {},
- add_titled[Some("editor"), "Editor"] = &model.editor_page.widget() -> gtk::Box {},
- add_titled[Some("map"), "Map"] = &model.map_page.widget() -> gtk::Box {},
- add_titled[Some("stages"), "Stages"] = &model.stages_page.widget() -> gtk::Box {},
- add_titled[Some("templates"), "Templates"] = &model.templates_page.widget() -> gtk::Box {},
+ add_titled[Some("general"), &tr!("preferences.menu.general")] = &model.general_page.widget() -> gtk::Box {},
+ add_titled[Some("editor"), &tr!("preferences.menu.editor")] = &model.editor_page.widget() -> gtk::Box {},
+ add_titled[Some("map"), &tr!("preferences.menu.map")] = &model.map_page.widget() -> gtk::Box {},
+ add_titled[Some("stages"), &tr!("preferences.menu.stages")] = &model.stages_page.widget() -> gtk::Box {},
+ add_titled[Some("templates"), &tr!("preferences.menu.templates")] = &model.templates_page.widget() -> gtk::Box {},
},
},
}