Wire settings panel, keyboard triggers, native menu, and module windows — eliminate 32 dead-code warnings

This commit is contained in:
jess 2026-03-31 17:57:46 -07:00
parent e2dadf1044
commit c6840fe9b3
1 changed files with 176 additions and 2 deletions

View File

@ -1,8 +1,11 @@
use std::path::PathBuf; use std::path::PathBuf;
use chrono::NaiveDateTime; use chrono::NaiveDateTime;
use iced::{Element, Task}; use iced::keyboard::{Key, Modifiers};
use iced::{Element, Subscription, Task};
use crate::behaviors::Action;
use crate::gui::native_menu::{NativeMenu, NativeMenuAction};
use crate::gui::time_utility; use crate::gui::time_utility;
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
@ -24,6 +27,7 @@ pub enum AppState {
ProjectView(ProjectViewState), ProjectView(ProjectViewState),
NewProject(crate::gui::new_project::State), NewProject(crate::gui::new_project::State),
TimeUtility { tapper_state: time_utility::State, return_state: Box<AppState> }, TimeUtility { tapper_state: time_utility::State, return_state: Box<AppState> },
Settings { settings_state: crate::gui::settings::State, return_state: Box<AppState> },
Editor(crate::editor::Editor), Editor(crate::editor::Editor),
} }
@ -59,12 +63,22 @@ pub enum Message {
TimeUtilityCancel, TimeUtilityCancel,
RunTimeUtilityAnalysis, RunTimeUtilityAnalysis,
OpenSettings,
CloseSettings { save: bool },
SettingsMessage(crate::gui::settings::Message),
KeyPressed(Key, Modifiers),
KeyReleased(Key, Modifiers),
WindowClosed(iced::window::Id),
Tick,
EditorMessage(crate::editor::Message), EditorMessage(crate::editor::Message),
} }
pub struct App { pub struct App {
pub state: AppState, pub state: AppState,
pub global_config: crate::config::AudioOxideConfig, pub global_config: crate::config::AudioOxideConfig,
native_menu: NativeMenu,
} }
impl Default for App { impl Default for App {
@ -75,12 +89,17 @@ impl Default for App {
} else { } else {
AppState::ProjectView(ProjectViewState::Splash) AppState::ProjectView(ProjectViewState::Splash)
}; };
Self { state, global_config: config } Self {
state,
global_config: config,
native_menu: NativeMenu::init(),
}
} }
} }
pub fn main() -> iced::Result { pub fn main() -> iced::Result {
iced::application("Audio Oxide", App::update, App::view) iced::application("Audio Oxide", App::update, App::view)
.subscription(App::subscription)
.run() .run()
} }
@ -305,6 +324,80 @@ impl App {
} }
} }
Message::OpenSettings => {
if matches!(self.state, AppState::Settings { .. }) {
return Task::none();
}
let return_state = std::mem::replace(
&mut self.state,
AppState::ProjectView(ProjectViewState::Splash),
);
let settings_state = crate::gui::settings::State::new(&self.global_config);
self.state = AppState::Settings {
settings_state,
return_state: Box::new(return_state),
};
}
Message::CloseSettings { save } => {
if save {
if let AppState::Settings { ref settings_state, .. } = self.state {
self.global_config = settings_state.config.clone();
crate::first_run::save_config(&self.global_config);
}
}
if let Some(rs) = self.take_settings_return() {
self.state = rs;
} else {
self.state = AppState::ProjectView(ProjectViewState::Splash);
}
}
Message::SettingsMessage(settings_msg) => {
if let AppState::Settings { ref mut settings_state, .. } = self.state {
let is_save = matches!(settings_msg, crate::gui::settings::Message::Save);
let is_cancel = matches!(settings_msg, crate::gui::settings::Message::Cancel);
let done = crate::gui::settings::handle_message(settings_state, settings_msg);
if done {
return self.update(Message::CloseSettings { save: is_save && !is_cancel });
}
}
}
Message::KeyPressed(key, modifiers) => {
if let Some(action) = crate::triggers::map_key_press_to_action(&self.state, key, modifiers) {
return self.dispatch_action(action);
}
}
Message::KeyReleased(key, modifiers) => {
if let Some(action) = crate::triggers::map_key_release_to_action(&self.state, key, modifiers) {
return self.dispatch_action(action);
}
}
Message::Tick => {
let menu_actions = self.native_menu.poll_events();
if let Some(first) = menu_actions.into_iter().next() {
match first {
NativeMenuAction::Action(action) => {
return self.dispatch_action(action);
}
NativeMenuAction::ShowNewTrackWizard => {
return self.update(Message::EditorMessage(crate::editor::Message::ShowNewTrackWizard));
}
}
}
}
Message::WindowClosed(window_id) => {
if let AppState::Editor(ref mut editor) = self.state {
if editor.module_for_window(window_id).is_some() {
let title = editor.module_window_title(window_id);
let _had_view = editor.module_window_view(window_id).is_some();
debug_log!("module window closed: {:?} (had_view={})", title, _had_view);
drop(title);
return editor.close_module_window_by_id(window_id).map(Message::EditorMessage);
}
}
}
Message::EditorMessage(editor_msg) => { Message::EditorMessage(editor_msg) => {
if let AppState::Editor(ref mut editor) = self.state { if let AppState::Editor(ref mut editor) = self.state {
return editor.update(editor_msg).map(Message::EditorMessage); return editor.update(editor_msg).map(Message::EditorMessage);
@ -331,12 +424,82 @@ impl App {
AppState::TimeUtility { tapper_state, .. } => { AppState::TimeUtility { tapper_state, .. } => {
time_utility::view(tapper_state) time_utility::view(tapper_state)
} }
AppState::Settings { settings_state, .. } => {
crate::gui::settings::view(settings_state)
.map(Message::SettingsMessage)
}
AppState::Editor(editor) => { AppState::Editor(editor) => {
editor.view().map(Message::EditorMessage) editor.view().map(Message::EditorMessage)
} }
} }
} }
fn subscription(&self) -> Subscription<Message> {
use iced::keyboard;
Subscription::batch([
keyboard::on_key_press(|key, modifiers| Some(Message::KeyPressed(key, modifiers))),
keyboard::on_key_release(|key, modifiers| Some(Message::KeyReleased(key, modifiers))),
iced::window::close_events().map(Message::WindowClosed),
iced::time::every(std::time::Duration::from_millis(100)).map(|_| Message::Tick),
])
}
fn dispatch_action(&mut self, action: Action) -> Task<Message> {
match action {
Action::TimeUtilityTapPressed => self.update(Message::TimeUtilityTapPressed),
Action::TimeUtilityTapReleased => self.update(Message::TimeUtilityTapReleased),
Action::OpenSettings => self.update(Message::OpenSettings),
Action::NewProject => self.update(Message::ViewNewProject),
Action::EditorTogglePlayback => {
self.update(Message::EditorMessage(crate::editor::Message::PlayPressed))
}
Action::EditorStop => {
self.update(Message::EditorMessage(crate::editor::Message::StopPressed))
}
Action::EditorToggleRecord => {
self.update(Message::EditorMessage(crate::editor::Message::RecordPressed))
}
Action::EditorRewind => {
self.update(Message::EditorMessage(crate::editor::Message::RewindPressed))
}
Action::EditorPlayFromBeginning => {
self.update(Message::EditorMessage(crate::editor::Message::RewindPressed))
}
Action::EditorToggleInspector => {
self.update(Message::EditorMessage(crate::editor::Message::ToggleInspector))
}
Action::EditorToggleBottomPanel => {
self.update(Message::EditorMessage(crate::editor::Message::ToggleBottomPanel))
}
Action::EditorToggleMixer => {
self.update(Message::EditorMessage(crate::editor::Message::SetBottomPanelMode(
crate::editor::BottomPanelMode::Mixer,
)))
}
Action::EditorToggleCycle => {
self.update(Message::EditorMessage(crate::editor::Message::CycleToggled))
}
Action::EditorToggleMetronome => {
self.update(Message::EditorMessage(crate::editor::Message::MetronomeToggled))
}
Action::ZoomInH => {
self.update(Message::EditorMessage(crate::editor::Message::ZoomH(1.25)))
}
Action::ZoomOutH => {
self.update(Message::EditorMessage(crate::editor::Message::ZoomH(0.8)))
}
Action::ZoomInV => {
self.update(Message::EditorMessage(crate::editor::Message::ZoomV(1.25)))
}
Action::ZoomOutV => {
self.update(Message::EditorMessage(crate::editor::Message::ZoomV(0.8)))
}
action => {
self.update(Message::EditorMessage(crate::editor::Message::EditAction(action)))
}
}
}
fn take_time_utility_return(&mut self) -> Option<AppState> { fn take_time_utility_return(&mut self) -> Option<AppState> {
let placeholder = AppState::ProjectView(ProjectViewState::Splash); let placeholder = AppState::ProjectView(ProjectViewState::Splash);
let old = std::mem::replace(&mut self.state, placeholder); let old = std::mem::replace(&mut self.state, placeholder);
@ -347,4 +510,15 @@ impl App {
None None
} }
} }
fn take_settings_return(&mut self) -> Option<AppState> {
let placeholder = AppState::ProjectView(ProjectViewState::Splash);
let old = std::mem::replace(&mut self.state, placeholder);
if let AppState::Settings { return_state, .. } = old {
Some(*return_state)
} else {
self.state = old;
None
}
}
} }