aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/file_registry.rs22
-rw-r--r--src/handlers/view.rs5
-rw-r--r--src/main.rs39
-rw-r--r--src/preferences/pages/stages.rs6
-rw-r--r--src/preferences/window.rs13
5 files changed, 65 insertions, 20 deletions
diff --git a/src/file_registry.rs b/src/file_registry.rs
index 6ebf986..7f062c8 100644
--- a/src/file_registry.rs
+++ b/src/file_registry.rs
@@ -5,11 +5,11 @@
use std::cell::RefCell;
use std::path::PathBuf;
-use relm4::ComponentController;
use relm4::component::Controller;
use relm4::gtk;
use crate::AppModel;
+use crate::actions::Action;
thread_local! {
/// Keeps window controllers alive for the lifetime of each window.
@@ -17,6 +17,9 @@ thread_local! {
/// Tracks which files are currently open to prevent duplicate windows.
static OPEN_FILES: RefCell<Vec<(PathBuf, gtk::Window)>> = const { RefCell::new(Vec::new()) };
+
+ /// Stores senders for all windows (including main window) to enable broadcasting.
+ static WINDOW_SENDERS: RefCell<Vec<relm4::Sender<Action>>> = const { RefCell::new(Vec::new()) };
}
/// Stores a window controller to keep it alive.
@@ -52,11 +55,18 @@ pub fn unregister_file(path: &PathBuf) {
});
}
-/// Broadcasts a message to all windows.
-pub fn broadcast_to_all_windows(message: crate::actions::Action) {
- WINDOW_CONTROLLERS.with_borrow(|controllers| {
- for controller in controllers {
- controller.sender().emit(message.clone());
+/// Registers a window's sender for broadcasting.
+pub fn register_sender(sender: relm4::Sender<Action>) {
+ WINDOW_SENDERS.with_borrow_mut(|senders| {
+ senders.push(sender);
+ });
+}
+
+/// Broadcasts a message to all windows via their registered senders.
+pub fn broadcast_to_all_windows(message: Action) {
+ WINDOW_SENDERS.with_borrow(|senders| {
+ for sender in senders {
+ sender.emit(message.clone());
}
});
}
diff --git a/src/handlers/view.rs b/src/handlers/view.rs
index 57f526a..020b756 100644
--- a/src/handlers/view.rs
+++ b/src/handlers/view.rs
@@ -1,7 +1,6 @@
use relm4::gtk;
use crate::AppModel;
-use crate::stages::ALL_STAGE_TYPES;
/// Toggles between horizontal and vertical layout orientation.
pub fn change_orientation(model: &mut AppModel) {
@@ -13,8 +12,8 @@ pub fn change_orientation(model: &mut AppModel) {
/// Updates the selected stage type from dropdown selection.
pub fn stage_type_selected(model: &mut AppModel, index: usize) {
- if index < ALL_STAGE_TYPES.len() {
- model.stage_type = ALL_STAGE_TYPES[index].clone();
+ if index < model.available_stage_types.len() {
+ model.stage_type = model.available_stage_types[index].clone();
model.update_image();
}
}
diff --git a/src/main.rs b/src/main.rs
index 6a7bd34..1b15b22 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -161,6 +161,7 @@ struct AppInit {
struct AppModel {
orientation: gtk::Orientation,
stage_type_list: gtk::StringList,
+ available_stage_types: Vec<StageType>,
stage_type: StageType,
source: sourceview5::Buffer,
source_view: sourceview5::View,
@@ -276,6 +277,35 @@ impl AppModel {
}
}
+ fn rebuild_stage_type_list(&mut self) {
+ // Build list: built-in stage types + custom stages from preferences
+ let mut stage_types: Vec<StageType> = ALL_STAGE_TYPES.to_vec();
+
+ // Add custom stages from preferences
+ for custom in &self.preferences.custom_stages {
+ stage_types.push(StageType::Custom {
+ name: custom.name.clone(),
+ i: custom.stage.i.clone(),
+ ii: custom.stage.ii.clone(),
+ iii: custom.stage.iii.clone(),
+ iv: custom.stage.iv.clone(),
+ });
+ }
+
+ // Update the StringList for the dropdown
+ // Clear existing items
+ while self.stage_type_list.n_items() > 0 {
+ self.stage_type_list.remove(0);
+ }
+
+ // Add all stage type names
+ for stage_type in &stage_types {
+ self.stage_type_list.append(stage_type.name());
+ }
+
+ self.available_stage_types = stage_types;
+ }
+
pub fn open_new_window(file_path: Option<PathBuf>) {
let controller = AppModel::builder()
.launch(AppInit {
@@ -516,6 +546,7 @@ impl SimpleComponent for AppModel {
let mut model = AppModel {
orientation: gtk::Orientation::Horizontal,
stage_type_list,
+ available_stage_types: ALL_STAGE_TYPES.to_vec(),
stage_type,
source,
source_view: source_view.clone(),
@@ -536,10 +567,14 @@ impl SimpleComponent for AppModel {
editor_css_provider,
};
- // Apply preferences
+ // Apply preferences and rebuild stage type list
model.apply_preferences();
+ model.rebuild_stage_type_list();
model.update_image();
+ // Register this window's sender for broadcasting
+ file_registry::register_sender(sender.input_sender().clone());
+
{
let sender = sender.clone();
glib::idle_add_local_once(move || {
@@ -635,6 +670,7 @@ impl SimpleComponent for AppModel {
Action::PreferencesChanged(prefs) => {
self.preferences = prefs;
self.apply_preferences();
+ self.rebuild_stage_type_list();
self.update_image();
// Broadcast to all other windows to reload preferences
file_registry::broadcast_to_all_windows(Action::ReloadPreferences);
@@ -646,6 +682,7 @@ impl SimpleComponent for AppModel {
// Reload preferences from disk (another window changed them)
self.preferences = preferences::storage::load();
self.apply_preferences();
+ self.rebuild_stage_type_list();
self.update_image();
}
}
diff --git a/src/preferences/pages/stages.rs b/src/preferences/pages/stages.rs
index c7fa494..c002bdb 100644
--- a/src/preferences/pages/stages.rs
+++ b/src/preferences/pages/stages.rs
@@ -195,7 +195,7 @@ impl StagesPage {
ii_entry.connect_changed(move |entry| {
sender.emit(PreferencesInput::SetCustomStageLabel(
id,
- StageLabel::II,
+ StageLabel::Ii,
entry.text().to_string(),
));
});
@@ -211,7 +211,7 @@ impl StagesPage {
iii_entry.connect_changed(move |entry| {
sender.emit(PreferencesInput::SetCustomStageLabel(
id,
- StageLabel::III,
+ StageLabel::Iii,
entry.text().to_string(),
));
});
@@ -227,7 +227,7 @@ impl StagesPage {
iv_entry.connect_changed(move |entry| {
sender.emit(PreferencesInput::SetCustomStageLabel(
id,
- StageLabel::IV,
+ StageLabel::Iv,
entry.text().to_string(),
));
});
diff --git a/src/preferences/window.rs b/src/preferences/window.rs
index d3874f2..7daa926 100644
--- a/src/preferences/window.rs
+++ b/src/preferences/window.rs
@@ -67,12 +67,11 @@ pub enum PreferencesInput {
/// Which stage label to update (Roman numerals I-IV)
#[derive(Debug, Clone, Copy)]
-#[allow(clippy::upper_case_acronyms)]
pub enum StageLabel {
I,
- II,
- III,
- IV,
+ Ii,
+ Iii,
+ Iv,
}
/// Output messages to parent app
@@ -300,9 +299,9 @@ impl SimpleComponent for PreferencesWindow {
{
match label {
StageLabel::I => stage.stage.i = value,
- StageLabel::II => stage.stage.ii = value,
- StageLabel::III => stage.stage.iii = value,
- StageLabel::IV => stage.stage.iv = value,
+ StageLabel::Ii => stage.stage.ii = value,
+ StageLabel::Iii => stage.stage.iii = value,
+ StageLabel::Iv => stage.stage.iv = value,
}
self.save_and_notify(&sender);
}