Refactor RenderContext construction into EditorApp::build_frame
Extract the ~80-field SharedPaneState/RenderContext literal from update() into EditorApp::build_frame, returning a FrameBundle that also carries the layout-editing borrows (current_layout, drag_state, etc.). Per-frame locals move into a FrameScratch struct so the bundle can borrow both self and the scratch under one lifetime. This is a behavior-preserving refactor that gives the upcoming mobile UI path a single shared construction site for SharedPaneState instead of duplicating the literal.
This commit is contained in:
parent
fd582828c2
commit
da0b39fef0
|
|
@ -6535,38 +6535,20 @@ impl eframe::App for EditorApp {
|
||||||
|
|
||||||
// Main pane area (editor mode)
|
// Main pane area (editor mode)
|
||||||
let mut layout_action: Option<LayoutAction> = None;
|
let mut layout_action: Option<LayoutAction> = None;
|
||||||
let mut clipboard_consumed = false;
|
// Per-frame scratch consumed by the post-render drain (see FrameScratch).
|
||||||
|
// Declared outside the closure because some of it (clipboard_consumed) is read
|
||||||
|
// after the panel closes.
|
||||||
|
let mut scratch = FrameScratch::default();
|
||||||
|
#[cfg(debug_assertions)]
|
||||||
|
{
|
||||||
|
scratch.synthetic_input = test_mode_replay.synthetic_input;
|
||||||
|
}
|
||||||
egui::CentralPanel::default().show(ctx, |ui| {
|
egui::CentralPanel::default().show(ctx, |ui| {
|
||||||
let available_rect = ui.available_rect_before_wrap();
|
let available_rect = ui.available_rect_before_wrap();
|
||||||
|
|
||||||
// Reset hovered divider each frame
|
// Reset hovered divider each frame
|
||||||
self.hovered_divider = None;
|
self.hovered_divider = None;
|
||||||
|
|
||||||
// Track fallback pane priority for view actions (reset each frame)
|
|
||||||
let mut fallback_pane_priority: Option<u32> = None;
|
|
||||||
|
|
||||||
// Registry for view action handlers (two-phase dispatch)
|
|
||||||
let mut pending_handlers: Vec<panes::ViewActionHandler> = Vec::new();
|
|
||||||
|
|
||||||
// Registry for actions to execute after rendering (two-phase dispatch)
|
|
||||||
let mut pending_actions: Vec<Box<dyn lightningbeam_core::action::Action>> = Vec::new();
|
|
||||||
|
|
||||||
// Menu actions queued by pane context menus
|
|
||||||
let mut pending_menu_actions: Vec<MenuAction> = Vec::new();
|
|
||||||
|
|
||||||
// Editing context navigation requests from stage pane
|
|
||||||
let mut pending_enter_clip: Option<(Uuid, Uuid, Uuid)> = None;
|
|
||||||
let mut pending_exit_clip = false;
|
|
||||||
|
|
||||||
// Synthetic input from test mode replay (debug builds only)
|
|
||||||
#[cfg(debug_assertions)]
|
|
||||||
let mut synthetic_input_storage: Option<test_mode::SyntheticInput> = test_mode_replay.synthetic_input;
|
|
||||||
|
|
||||||
// Queue for effect thumbnail requests (collected during rendering)
|
|
||||||
let mut effect_thumbnail_requests: Vec<Uuid> = Vec::new();
|
|
||||||
// Empty cache fallback if generator not initialized
|
|
||||||
let empty_thumbnail_cache: HashMap<Uuid, Vec<u8>> = HashMap::new();
|
|
||||||
|
|
||||||
// Sync clip instance transforms from animation data at current playback time.
|
// Sync clip instance transforms from animation data at current playback time.
|
||||||
// This ensures selection boxes, hit testing, and interactive editing see the
|
// This ensures selection boxes, hit testing, and interactive editing see the
|
||||||
// animated transform values, not just the base values on the ClipInstance struct.
|
// animated transform values, not just the base values on the ClipInstance struct.
|
||||||
|
|
@ -6601,133 +6583,36 @@ impl eframe::App for EditorApp {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create render context
|
// Build the per-frame context (single source of truth for SharedPaneState,
|
||||||
let mut ctx = RenderContext {
|
// shared with the mobile path). The bundle borrows `self` + `scratch`; it
|
||||||
shared: panes::SharedPaneState {
|
// is dropped before the post-render drain below re-touches them.
|
||||||
container_path: self.current_file_path.clone(),
|
let mut bundle = self.build_frame(&mut scratch);
|
||||||
onion: {
|
|
||||||
// Onion skinning is disabled during playback.
|
|
||||||
let mut o = self.onion_skin;
|
|
||||||
o.enabled = o.enabled && !self.is_playing;
|
|
||||||
o
|
|
||||||
},
|
|
||||||
onion_skin: &mut self.onion_skin,
|
|
||||||
tool_icon_cache: &mut self.tool_icon_cache,
|
|
||||||
icon_cache: &mut self.icon_cache,
|
|
||||||
selected_tool: &mut self.selected_tool,
|
|
||||||
fill_color: &mut self.fill_color,
|
|
||||||
stroke_color: &mut self.stroke_color,
|
|
||||||
active_color_mode: &mut self.active_color_mode,
|
|
||||||
pending_view_action: &mut self.pending_view_action,
|
|
||||||
fallback_pane_priority: &mut fallback_pane_priority,
|
|
||||||
pending_handlers: &mut pending_handlers,
|
|
||||||
theme: &self.theme,
|
|
||||||
action_executor: &mut self.action_executor,
|
|
||||||
selection: &mut self.selection,
|
|
||||||
focus: &mut self.focus,
|
|
||||||
editing_clip_id: self.editing_context.current_clip_id(),
|
|
||||||
editing_instance_id: self.editing_context.current_instance_id(),
|
|
||||||
editing_parent_layer_id: self.editing_context.current_parent_layer_id(),
|
|
||||||
pending_enter_clip: &mut pending_enter_clip,
|
|
||||||
pending_exit_clip: &mut pending_exit_clip,
|
|
||||||
active_layer_id: &mut self.active_layer_id,
|
|
||||||
tool_state: &mut self.tool_state,
|
|
||||||
pending_actions: &mut pending_actions,
|
|
||||||
draw_simplify_mode: &mut self.draw_simplify_mode,
|
|
||||||
rdp_tolerance: &mut self.rdp_tolerance,
|
|
||||||
schneider_max_error: &mut self.schneider_max_error,
|
|
||||||
raster_settings: &mut self.raster_settings,
|
|
||||||
audio_controller: self.audio_controller.as_ref(),
|
|
||||||
clip_snapshot: self.audio_controller.as_ref().map(|arc| {
|
|
||||||
arc.lock().unwrap().clip_snapshot()
|
|
||||||
}),
|
|
||||||
audio_input_opener: &mut self.audio_input,
|
|
||||||
audio_input_stream: &mut self.audio_input_stream,
|
|
||||||
audio_buffer_size: self.audio_buffer_size,
|
|
||||||
video_manager: &self.video_manager,
|
|
||||||
playback_time: &mut self.playback_time,
|
|
||||||
is_playing: &mut self.is_playing,
|
|
||||||
is_recording: &mut self.is_recording,
|
|
||||||
metronome_enabled: &mut self.metronome_enabled,
|
|
||||||
count_in_enabled: &mut self.count_in_enabled,
|
|
||||||
recording_clips: &mut self.recording_clips,
|
|
||||||
recording_start_time: &mut self.recording_start_time,
|
|
||||||
recording_layer_ids: &mut self.recording_layer_ids,
|
|
||||||
dragging_asset: &mut self.dragging_asset,
|
|
||||||
stroke_width: &mut self.stroke_width,
|
|
||||||
fill_enabled: &mut self.fill_enabled,
|
|
||||||
snap_enabled: &mut self.snap_enabled,
|
|
||||||
paint_bucket_gap_tolerance: &mut self.paint_bucket_gap_tolerance,
|
|
||||||
polygon_sides: &mut self.polygon_sides,
|
|
||||||
layer_to_track_map: &self.layer_to_track_map,
|
|
||||||
clip_instance_to_backend_map: &self.clip_instance_to_backend_map,
|
|
||||||
midi_event_cache: &mut self.midi_event_cache,
|
|
||||||
audio_pools_with_new_waveforms: &self.audio_pools_with_new_waveforms,
|
|
||||||
raw_audio_cache: &self.raw_audio_cache,
|
|
||||||
waveform_gpu_dirty: &mut self.waveform_gpu_dirty,
|
|
||||||
waveform_minmax_pools: &self.waveform_minmax_pools,
|
|
||||||
raster_fault_requests: &self.raster_fault_requests,
|
|
||||||
effect_to_load: &mut self.effect_to_load,
|
|
||||||
effect_thumbnail_requests: &mut effect_thumbnail_requests,
|
|
||||||
effect_thumbnail_cache: self.effect_thumbnail_generator.as_ref()
|
|
||||||
.map(|g| g.thumbnail_cache())
|
|
||||||
.unwrap_or(&empty_thumbnail_cache),
|
|
||||||
effect_thumbnails_to_invalidate: &mut self.effect_thumbnails_to_invalidate,
|
|
||||||
webcam_frame: self.webcam_frame.clone(),
|
|
||||||
webcam_record_command: &mut self.webcam_record_command,
|
|
||||||
target_format: self.target_format,
|
|
||||||
pending_menu_actions: &mut pending_menu_actions,
|
|
||||||
clipboard_manager: &mut self.clipboard_manager,
|
|
||||||
input_level: self.input_level,
|
|
||||||
output_level: self.output_level,
|
|
||||||
track_levels: &self.track_levels,
|
|
||||||
track_to_layer_map: &self.track_to_layer_map,
|
|
||||||
waveform_stereo: self.config.waveform_stereo,
|
|
||||||
project_generation: &mut self.project_generation,
|
|
||||||
graph_topology_generation: &mut self.graph_topology_generation,
|
|
||||||
script_to_edit: &mut self.script_to_edit,
|
|
||||||
script_saved: &mut self.script_saved,
|
|
||||||
pending_region_cut_base: &mut self.pending_region_cut_base,
|
|
||||||
region_select_mode: &mut self.region_select_mode,
|
|
||||||
lasso_mode: &mut self.lasso_mode,
|
|
||||||
pending_graph_loads: &self.pending_graph_loads,
|
|
||||||
clipboard_consumed: &mut clipboard_consumed,
|
|
||||||
keymap: &self.keymap,
|
|
||||||
pending_node_group: &mut self.pending_node_group,
|
|
||||||
pending_node_ungroup: &mut self.pending_node_ungroup,
|
|
||||||
#[cfg(debug_assertions)]
|
|
||||||
test_mode: &mut self.test_mode,
|
|
||||||
#[cfg(debug_assertions)]
|
|
||||||
synthetic_input: &mut synthetic_input_storage,
|
|
||||||
brush_preview_pixels: &self.brush_preview_pixels,
|
|
||||||
},
|
|
||||||
pane_instances: &mut self.pane_instances,
|
|
||||||
};
|
|
||||||
|
|
||||||
render_layout_node(
|
render_layout_node(
|
||||||
ui,
|
ui,
|
||||||
&mut self.current_layout,
|
bundle.current_layout,
|
||||||
available_rect,
|
available_rect,
|
||||||
&mut self.drag_state,
|
bundle.drag_state,
|
||||||
&mut self.hovered_divider,
|
bundle.hovered_divider,
|
||||||
&mut self.selected_pane,
|
bundle.selected_pane,
|
||||||
&mut layout_action,
|
&mut layout_action,
|
||||||
&mut self.split_preview_mode,
|
bundle.split_preview_mode,
|
||||||
&Vec::new(), // Root path
|
&Vec::new(), // Root path
|
||||||
&mut ctx,
|
&mut bundle.rc,
|
||||||
);
|
);
|
||||||
|
drop(bundle);
|
||||||
|
|
||||||
// Process collected effect thumbnail requests
|
// Process collected effect thumbnail requests
|
||||||
if !effect_thumbnail_requests.is_empty() {
|
if !scratch.effect_thumbnail_requests.is_empty() {
|
||||||
if let Some(generator) = &mut self.effect_thumbnail_generator {
|
if let Some(generator) = &mut self.effect_thumbnail_generator {
|
||||||
generator.request_thumbnails(&effect_thumbnail_requests);
|
generator.request_thumbnails(&scratch.effect_thumbnail_requests);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Execute action on the best handler (two-phase dispatch)
|
// Execute action on the best handler (two-phase dispatch)
|
||||||
if let Some(action) = &self.pending_view_action {
|
if let Some(action) = &self.pending_view_action {
|
||||||
if let Some(best_handler) = pending_handlers.iter().min_by_key(|h| h.priority) {
|
if let Some(best_handler) = scratch.pending_handlers.iter().min_by_key(|h| h.priority) {
|
||||||
// Look up the pane instance and execute the action
|
// Look up the pane instance and execute the action
|
||||||
if let Some(pane_instance) = self.pane_instances.get_mut(&best_handler.pane_path) {
|
if let Some(pane_instance) = self.pane_instances.get_mut(&best_handler.pane_path) {
|
||||||
match pane_instance {
|
match pane_instance {
|
||||||
|
|
@ -6748,7 +6633,7 @@ impl eframe::App for EditorApp {
|
||||||
self.sync_audio_layers_to_backend();
|
self.sync_audio_layers_to_backend();
|
||||||
|
|
||||||
// Execute all pending actions (two-phase dispatch)
|
// Execute all pending actions (two-phase dispatch)
|
||||||
for action in pending_actions {
|
for action in std::mem::take(&mut scratch.pending_actions) {
|
||||||
// Record action for test mode (debug builds only)
|
// Record action for test mode (debug builds only)
|
||||||
#[cfg(debug_assertions)]
|
#[cfg(debug_assertions)]
|
||||||
let action_desc = action.description();
|
let action_desc = action.description();
|
||||||
|
|
@ -6780,7 +6665,7 @@ impl eframe::App for EditorApp {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Process menu actions queued by pane context menus
|
// Process menu actions queued by pane context menus
|
||||||
for action in pending_menu_actions {
|
for action in std::mem::take(&mut scratch.pending_menu_actions) {
|
||||||
self.handle_menu_action(action);
|
self.handle_menu_action(action);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -6942,7 +6827,7 @@ impl eframe::App for EditorApp {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Process editing context navigation (enter/exit movie clips)
|
// Process editing context navigation (enter/exit movie clips)
|
||||||
if let Some((clip_id, instance_id, parent_layer_id)) = pending_enter_clip {
|
if let Some((clip_id, instance_id, parent_layer_id)) = scratch.pending_enter_clip {
|
||||||
let entry = EditingContextEntry {
|
let entry = EditingContextEntry {
|
||||||
clip_id,
|
clip_id,
|
||||||
instance_id,
|
instance_id,
|
||||||
|
|
@ -6966,7 +6851,7 @@ impl eframe::App for EditorApp {
|
||||||
self.commit_raster_floating();
|
self.commit_raster_floating();
|
||||||
}
|
}
|
||||||
|
|
||||||
if pending_exit_clip {
|
if scratch.pending_exit_clip {
|
||||||
if let Some(entry) = self.editing_context.pop() {
|
if let Some(entry) = self.editing_context.pop() {
|
||||||
self.selection.clear();
|
self.selection.clear();
|
||||||
self.active_layer_id = entry.saved_active_layer_id;
|
self.active_layer_id = entry.saved_active_layer_id;
|
||||||
|
|
@ -7030,8 +6915,8 @@ impl eframe::App for EditorApp {
|
||||||
// Event::Copy/Cut/Paste instead of regular key events, so
|
// Event::Copy/Cut/Paste instead of regular key events, so
|
||||||
// check_shortcuts won't see them via key_pressed().
|
// check_shortcuts won't see them via key_pressed().
|
||||||
// Skip if a pane (e.g. piano roll) already handled the clipboard event.
|
// Skip if a pane (e.g. piano roll) already handled the clipboard event.
|
||||||
let mut clipboard_handled = clipboard_consumed;
|
let mut clipboard_handled = scratch.clipboard_consumed;
|
||||||
if !clipboard_consumed {
|
if !scratch.clipboard_consumed {
|
||||||
for event in &i.events {
|
for event in &i.events {
|
||||||
match event {
|
match event {
|
||||||
egui::Event::Copy => {
|
egui::Event::Copy => {
|
||||||
|
|
@ -7194,6 +7079,156 @@ struct RenderContext<'a> {
|
||||||
pane_instances: &'a mut HashMap<NodePath, PaneInstance>,
|
pane_instances: &'a mut HashMap<NodePath, PaneInstance>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Per-frame scratch state used to build the `RenderContext`. These values live only
|
||||||
|
/// for the duration of one `update()` frame: panes write into them during rendering
|
||||||
|
/// and the post-render drain consumes them. Grouping them lets [`EditorApp::build_frame`]
|
||||||
|
/// hand back a context that borrows both `self` and this scratch, so the desktop and
|
||||||
|
/// mobile render paths share one construction site for the ~80-field `SharedPaneState`.
|
||||||
|
#[derive(Default)]
|
||||||
|
struct FrameScratch {
|
||||||
|
fallback_pane_priority: Option<u32>,
|
||||||
|
pending_handlers: Vec<panes::ViewActionHandler>,
|
||||||
|
pending_enter_clip: Option<(Uuid, Uuid, Uuid)>,
|
||||||
|
pending_exit_clip: bool,
|
||||||
|
pending_actions: Vec<Box<dyn lightningbeam_core::action::Action>>,
|
||||||
|
pending_menu_actions: Vec<MenuAction>,
|
||||||
|
effect_thumbnail_requests: Vec<Uuid>,
|
||||||
|
clipboard_consumed: bool,
|
||||||
|
empty_thumbnail_cache: HashMap<Uuid, Vec<u8>>,
|
||||||
|
#[cfg(debug_assertions)]
|
||||||
|
synthetic_input: Option<test_mode::SyntheticInput>,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Everything `update()` hands to a per-frame layout renderer: the [`RenderContext`]
|
||||||
|
/// plus the layout-editing borrows that ride alongside it (these are passed to
|
||||||
|
/// `render_layout_node` as separate `&mut` args and are disjoint from `SharedPaneState`).
|
||||||
|
/// Built by [`EditorApp::build_frame`] from a single `&mut self`, which is what lets the
|
||||||
|
/// huge `SharedPaneState` literal have one home shared by the desktop and mobile paths.
|
||||||
|
struct FrameBundle<'a> {
|
||||||
|
rc: RenderContext<'a>,
|
||||||
|
current_layout: &'a mut LayoutNode,
|
||||||
|
drag_state: &'a mut DragState,
|
||||||
|
hovered_divider: &'a mut Option<(NodePath, bool)>,
|
||||||
|
selected_pane: &'a mut Option<NodePath>,
|
||||||
|
split_preview_mode: &'a mut SplitPreviewMode,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl EditorApp {
|
||||||
|
/// Build the per-frame [`FrameBundle`]. The returned bundle borrows `self` and
|
||||||
|
/// `scratch` for `'a`; it must be dropped before the post-render drain touches
|
||||||
|
/// `self`/`scratch` again. This is the single source of truth for `SharedPaneState`.
|
||||||
|
fn build_frame<'a>(&'a mut self, scratch: &'a mut FrameScratch) -> FrameBundle<'a> {
|
||||||
|
FrameBundle {
|
||||||
|
rc: RenderContext {
|
||||||
|
shared: panes::SharedPaneState {
|
||||||
|
container_path: self.current_file_path.clone(),
|
||||||
|
onion: {
|
||||||
|
// Onion skinning is disabled during playback.
|
||||||
|
let mut o = self.onion_skin;
|
||||||
|
o.enabled = o.enabled && !self.is_playing;
|
||||||
|
o
|
||||||
|
},
|
||||||
|
onion_skin: &mut self.onion_skin,
|
||||||
|
tool_icon_cache: &mut self.tool_icon_cache,
|
||||||
|
icon_cache: &mut self.icon_cache,
|
||||||
|
selected_tool: &mut self.selected_tool,
|
||||||
|
fill_color: &mut self.fill_color,
|
||||||
|
stroke_color: &mut self.stroke_color,
|
||||||
|
active_color_mode: &mut self.active_color_mode,
|
||||||
|
pending_view_action: &mut self.pending_view_action,
|
||||||
|
fallback_pane_priority: &mut scratch.fallback_pane_priority,
|
||||||
|
pending_handlers: &mut scratch.pending_handlers,
|
||||||
|
theme: &self.theme,
|
||||||
|
action_executor: &mut self.action_executor,
|
||||||
|
selection: &mut self.selection,
|
||||||
|
focus: &mut self.focus,
|
||||||
|
editing_clip_id: self.editing_context.current_clip_id(),
|
||||||
|
editing_instance_id: self.editing_context.current_instance_id(),
|
||||||
|
editing_parent_layer_id: self.editing_context.current_parent_layer_id(),
|
||||||
|
pending_enter_clip: &mut scratch.pending_enter_clip,
|
||||||
|
pending_exit_clip: &mut scratch.pending_exit_clip,
|
||||||
|
active_layer_id: &mut self.active_layer_id,
|
||||||
|
tool_state: &mut self.tool_state,
|
||||||
|
pending_actions: &mut scratch.pending_actions,
|
||||||
|
draw_simplify_mode: &mut self.draw_simplify_mode,
|
||||||
|
rdp_tolerance: &mut self.rdp_tolerance,
|
||||||
|
schneider_max_error: &mut self.schneider_max_error,
|
||||||
|
raster_settings: &mut self.raster_settings,
|
||||||
|
audio_controller: self.audio_controller.as_ref(),
|
||||||
|
clip_snapshot: self.audio_controller.as_ref().map(|arc| {
|
||||||
|
arc.lock().unwrap().clip_snapshot()
|
||||||
|
}),
|
||||||
|
audio_input_opener: &mut self.audio_input,
|
||||||
|
audio_input_stream: &mut self.audio_input_stream,
|
||||||
|
audio_buffer_size: self.audio_buffer_size,
|
||||||
|
video_manager: &self.video_manager,
|
||||||
|
playback_time: &mut self.playback_time,
|
||||||
|
is_playing: &mut self.is_playing,
|
||||||
|
is_recording: &mut self.is_recording,
|
||||||
|
metronome_enabled: &mut self.metronome_enabled,
|
||||||
|
count_in_enabled: &mut self.count_in_enabled,
|
||||||
|
recording_clips: &mut self.recording_clips,
|
||||||
|
recording_start_time: &mut self.recording_start_time,
|
||||||
|
recording_layer_ids: &mut self.recording_layer_ids,
|
||||||
|
dragging_asset: &mut self.dragging_asset,
|
||||||
|
stroke_width: &mut self.stroke_width,
|
||||||
|
fill_enabled: &mut self.fill_enabled,
|
||||||
|
snap_enabled: &mut self.snap_enabled,
|
||||||
|
paint_bucket_gap_tolerance: &mut self.paint_bucket_gap_tolerance,
|
||||||
|
polygon_sides: &mut self.polygon_sides,
|
||||||
|
layer_to_track_map: &self.layer_to_track_map,
|
||||||
|
clip_instance_to_backend_map: &self.clip_instance_to_backend_map,
|
||||||
|
midi_event_cache: &mut self.midi_event_cache,
|
||||||
|
audio_pools_with_new_waveforms: &self.audio_pools_with_new_waveforms,
|
||||||
|
raw_audio_cache: &self.raw_audio_cache,
|
||||||
|
waveform_gpu_dirty: &mut self.waveform_gpu_dirty,
|
||||||
|
waveform_minmax_pools: &self.waveform_minmax_pools,
|
||||||
|
raster_fault_requests: &self.raster_fault_requests,
|
||||||
|
effect_to_load: &mut self.effect_to_load,
|
||||||
|
effect_thumbnail_requests: &mut scratch.effect_thumbnail_requests,
|
||||||
|
effect_thumbnail_cache: self.effect_thumbnail_generator.as_ref()
|
||||||
|
.map(|g| g.thumbnail_cache())
|
||||||
|
.unwrap_or(&scratch.empty_thumbnail_cache),
|
||||||
|
effect_thumbnails_to_invalidate: &mut self.effect_thumbnails_to_invalidate,
|
||||||
|
webcam_frame: self.webcam_frame.clone(),
|
||||||
|
webcam_record_command: &mut self.webcam_record_command,
|
||||||
|
target_format: self.target_format,
|
||||||
|
pending_menu_actions: &mut scratch.pending_menu_actions,
|
||||||
|
clipboard_manager: &mut self.clipboard_manager,
|
||||||
|
input_level: self.input_level,
|
||||||
|
output_level: self.output_level,
|
||||||
|
track_levels: &self.track_levels,
|
||||||
|
track_to_layer_map: &self.track_to_layer_map,
|
||||||
|
waveform_stereo: self.config.waveform_stereo,
|
||||||
|
project_generation: &mut self.project_generation,
|
||||||
|
graph_topology_generation: &mut self.graph_topology_generation,
|
||||||
|
script_to_edit: &mut self.script_to_edit,
|
||||||
|
script_saved: &mut self.script_saved,
|
||||||
|
pending_region_cut_base: &mut self.pending_region_cut_base,
|
||||||
|
region_select_mode: &mut self.region_select_mode,
|
||||||
|
lasso_mode: &mut self.lasso_mode,
|
||||||
|
pending_graph_loads: &self.pending_graph_loads,
|
||||||
|
clipboard_consumed: &mut scratch.clipboard_consumed,
|
||||||
|
keymap: &self.keymap,
|
||||||
|
pending_node_group: &mut self.pending_node_group,
|
||||||
|
pending_node_ungroup: &mut self.pending_node_ungroup,
|
||||||
|
#[cfg(debug_assertions)]
|
||||||
|
test_mode: &mut self.test_mode,
|
||||||
|
#[cfg(debug_assertions)]
|
||||||
|
synthetic_input: &mut scratch.synthetic_input,
|
||||||
|
brush_preview_pixels: &self.brush_preview_pixels,
|
||||||
|
},
|
||||||
|
pane_instances: &mut self.pane_instances,
|
||||||
|
},
|
||||||
|
current_layout: &mut self.current_layout,
|
||||||
|
drag_state: &mut self.drag_state,
|
||||||
|
hovered_divider: &mut self.hovered_divider,
|
||||||
|
selected_pane: &mut self.selected_pane,
|
||||||
|
split_preview_mode: &mut self.split_preview_mode,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Find which GroupLayer (if any) contains the given layer as a direct child.
|
/// Find which GroupLayer (if any) contains the given layer as a direct child.
|
||||||
/// Returns None if the layer is at document root level.
|
/// Returns None if the layer is at document root level.
|
||||||
fn find_parent_group_id(doc: &lightningbeam_core::document::Document, layer_id: &uuid::Uuid) -> Option<uuid::Uuid> {
|
fn find_parent_group_id(doc: &lightningbeam_core::document::Document, layer_id: &uuid::Uuid) -> Option<uuid::Uuid> {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue