gled-core 2.31.2

The engine of gled without a user interface: inputs, timing, rendering, Art-Net/DMX output and storage
Documentation
//! Actions on scene instances: placing them in the grid, selecting them and
//! their own settings and inputs.

use std::sync::Arc;

use crate::action::{UiAction, location_by_target, scene_instance_by_target, set_scene_opacity};
use crate::engine::Engine;
use crate::storage::asset::curve::multiplied_curve::MultipliedCurve;

use super::ignore_without_project;

impl Engine {
    /// Places, selects and edits scene instances.
    pub(super) fn apply_scene_action(&mut self, action: UiAction) {
        match (self.project.as_mut().map(Arc::make_mut), action) {
            (Some(project), UiAction::AddScene(pos, scene)) => {
                project.add_scene(pos, scene, &self.collections);
            }
            (Some(project), UiAction::DeleteSceneInstance { location }) => {
                project.remove_scene_instance(location);
            }
            (Some(project), UiAction::DeleteSceneInstancePath(path)) => {
                if let Some(location) =
                    location_by_target(project, path, self.selected_scene_instance)
                {
                    project.remove_scene_instance(location);
                }
            }
            (Some(project), UiAction::CloneSceneInstance(location)) => {
                if let Some(scene_instance) = project
                    .get_scenes_instance(&location)
                    .map(|scene_instance| scene_instance.cloned_with_new_id())
                {
                    let target = project.next_empty_grid_location(location);
                    project.add_scene_instance(target, scene_instance);
                }
            }
            (Some(project), UiAction::CloneSceneInstancePath(path)) => {
                if let Some(location) =
                    location_by_target(project, path, self.selected_scene_instance)
                    && let Some(scene_instance) = project
                        .get_scenes_instance(&location)
                        .map(|scene_instance| scene_instance.cloned_with_new_id())
                {
                    let target = project.next_empty_grid_location(location);
                    project.add_scene_instance(target, scene_instance);
                }
            }
            (Some(project), UiAction::SetSceneOpacity(path, opacity)) => {
                if let Some(scene_instance) =
                    scene_instance_by_target(project, path, self.selected_scene_instance)
                {
                    set_scene_opacity(scene_instance, opacity);
                }
            }
            (Some(project), UiAction::ToggleSceneActive(location)) => {
                if let Some(scene_instance) =
                    scene_instance_by_target(project, location, self.selected_scene_instance)
                {
                    scene_instance.active = !scene_instance.active;
                }
            }
            (Some(project), UiAction::SetSceneActive(location, active)) => {
                if let Some(scene_instance) =
                    scene_instance_by_target(project, location, self.selected_scene_instance)
                {
                    scene_instance.active = active;
                }
            }
            (Some(project), UiAction::SetSceneFlash(location, flash)) => {
                if let Some(scene_instance) =
                    scene_instance_by_target(project, location, self.selected_scene_instance)
                {
                    scene_instance.flash = flash;
                }
            }
            (Some(project), UiAction::SelectScene(location)) => {
                if let Some(pos) =
                    location_by_target(project, location, self.selected_scene_instance)
                {
                    self.selected_scene_instance = pos;
                }
            }
            (Some(project), UiAction::SelectSceneByLocation(location)) => {
                if project.scenes_instances_grid.contains_key(&location) {
                    self.selected_scene_instance = location;
                }
            }
            (Some(project), UiAction::SwapScenes(from, to)) => {
                let to_item = project.remove_scene_instance(to);
                let from_item = project.remove_scene_instance(from);
                if let Some(from_item) = from_item {
                    project.add_scene_instance(to, from_item);
                }
                if let Some(to_item) = to_item {
                    project.add_scene_instance(from, to_item);
                }
                self.selected_scene_instance = to;
            }
            (Some(project), UiAction::SetSceneName(path, name)) => {
                if let Some(scene_instance) =
                    scene_instance_by_target(project, path, self.selected_scene_instance)
                {
                    scene_instance.name = name;
                }
            }
            (Some(project), UiAction::SetSceneColor(path, color)) => {
                if let Some(scene_instance) =
                    scene_instance_by_target(project, path, self.selected_scene_instance)
                {
                    scene_instance.color = color;
                }
            }
            (Some(project), UiAction::SetSceneInputDimmer(path, dimmer)) => {
                if let Some(scene_instance) =
                    scene_instance_by_target(project, path, self.selected_scene_instance)
                {
                    scene_instance.input_dimmer = dimmer;
                }
            }
            (Some(project), UiAction::SetSceneIgnoreMainDimmer(path, ignore)) => {
                if let Some(scene_instance) =
                    scene_instance_by_target(project, path, self.selected_scene_instance)
                {
                    scene_instance.ignore_main_dimmer = ignore;
                }
            }
            (Some(project), UiAction::SetSceneBeatOffset(path, beat_offset)) => {
                if let Some(scene_instance) =
                    scene_instance_by_target(project, path, self.selected_scene_instance)
                {
                    scene_instance.beat_progression_offset =
                        MultipliedCurve::new_multiplier(beat_offset);
                }
            }
            (Some(project), UiAction::SetSceneOpacityMultiplier(path, value)) => {
                if let Some(scene_instance) =
                    scene_instance_by_target(project, path, self.selected_scene_instance)
                {
                    scene_instance.opacity.set_multiplier(value);
                }
            }
            (Some(project), UiAction::SetSceneOpacityCurve(path, curve)) => {
                if let Some(scene_instance) =
                    scene_instance_by_target(project, path, self.selected_scene_instance)
                {
                    scene_instance.opacity.set_curve(curve);
                }
            }
            (Some(project), UiAction::SetSceneBeatOffsetMultiplier(path, value)) => {
                if let Some(scene_instance) =
                    scene_instance_by_target(project, path, self.selected_scene_instance)
                {
                    scene_instance.beat_progression_offset.set_multiplier(value);
                }
            }
            (Some(project), UiAction::SetSceneBeatOffsetCurve(path, curve)) => {
                if let Some(scene_instance) =
                    scene_instance_by_target(project, path, self.selected_scene_instance)
                {
                    scene_instance.beat_progression_offset.set_curve(curve);
                }
            }
            (Some(project), UiAction::SetSceneSetOffsetOnFlash(path, set_offset_on_flash)) => {
                if let Some(scene_instance) =
                    scene_instance_by_target(project, path, self.selected_scene_instance)
                {
                    scene_instance.set_offset_on_flash = set_offset_on_flash;
                }
            }
            (Some(project), UiAction::SetSceneActivationInput(path, input_event)) => {
                if let Some(scene_instance) =
                    scene_instance_by_target(project, path, self.selected_scene_instance)
                {
                    scene_instance.activation_input = input_event;
                }
            }
            (Some(project), UiAction::SetSceneFlashInput(path, input_event)) => {
                if let Some(scene_instance) =
                    scene_instance_by_target(project, path, self.selected_scene_instance)
                {
                    scene_instance.flash_input = input_event;
                }
            }
            (Some(project), UiAction::SetSceneDimmerInput(path, input_event)) => {
                if let Some(scene_instance) =
                    scene_instance_by_target(project, path, self.selected_scene_instance)
                {
                    scene_instance.dimmer_input = input_event;
                }
            }
            (Some(project), UiAction::ReplaceSceneInstance(location, scene_instance)) => {
                match scene_instance {
                    Some(scene_instance) => project.add_scene_instance(location, *scene_instance),
                    None => {
                        project.remove_scene_instance(location);
                    }
                }
            }
            (None, _) => ignore_without_project(),
            // `apply_action` routes only scene instance actions here.
            (Some(_), _) => {}
        }
    }
}