refactor: share preview studio control update helpers
Deduplicate the preview panel's repeated control-sync and runtime-update paths so built-in preview setups and individual runtime controls all go through the same widget/state wiring.
This commit is contained in:
+172
-102
@@ -224,6 +224,48 @@ impl PreviewSessionWidgets {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
struct PreviewStudioControlWidgets {
|
||||
scene_dropdown: gtk4::DropDown,
|
||||
fps_spin: gtk4::SpinButton,
|
||||
particle_count_spin: gtk4::SpinButton,
|
||||
particle_size_spin: gtk4::SpinButton,
|
||||
gpu_passes_spin: gtk4::SpinButton,
|
||||
interaction_spin: gtk4::SpinButton,
|
||||
vram_spin: gtk4::SpinButton,
|
||||
vsync_switch: gtk4::Switch,
|
||||
pause_switch: gtk4::Switch,
|
||||
width_spin: gtk4::SpinButton,
|
||||
height_spin: gtk4::SpinButton,
|
||||
}
|
||||
|
||||
impl PreviewStudioControlWidgets {
|
||||
fn apply_studio_runtime(&self, studio: &PreviewStudioOptions) {
|
||||
if let Some(index) = StudioScene::all()
|
||||
.iter()
|
||||
.position(|scene| *scene == studio.scene)
|
||||
{
|
||||
self.scene_dropdown.set_selected(index as u32);
|
||||
}
|
||||
self.fps_spin.set_value(studio.fps_cap.unwrap_or(0) as f64);
|
||||
self.particle_count_spin
|
||||
.set_value(studio.particle_count as f64);
|
||||
self.particle_size_spin
|
||||
.set_value(studio.particle_size as f64);
|
||||
self.gpu_passes_spin.set_value(studio.gpu_passes as f64);
|
||||
self.interaction_spin
|
||||
.set_value(studio.interaction_steps as f64);
|
||||
self.vram_spin.set_value(studio.vram_pressure_mb as f64);
|
||||
self.vsync_switch.set_active(studio.vsync);
|
||||
self.pause_switch.set_active(studio.paused);
|
||||
}
|
||||
|
||||
fn apply_window_size(&self, width: i32, height: i32) {
|
||||
self.width_spin.set_value(width as f64);
|
||||
self.height_spin.set_value(height as f64);
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn build_preview_panel(ctx: &PageBuildContext) -> gtk4::Box {
|
||||
let panel = gtk4::Box::new(gtk4::Orientation::Vertical, 10);
|
||||
panel.add_css_class("dashboard-stack");
|
||||
@@ -640,6 +682,20 @@ pub(crate) fn build_preview_panel(ctx: &PageBuildContext) -> gtk4::Box {
|
||||
interaction_row.append(&interaction_controls);
|
||||
cpu_body.append(&interaction_row);
|
||||
|
||||
let control_widgets = PreviewStudioControlWidgets {
|
||||
scene_dropdown: scene_dropdown.clone(),
|
||||
fps_spin: fps_spin.clone(),
|
||||
particle_count_spin: particle_count_spin.clone(),
|
||||
particle_size_spin: particle_size_spin.clone(),
|
||||
gpu_passes_spin: gpu_passes_spin.clone(),
|
||||
interaction_spin: interaction_spin.clone(),
|
||||
vram_spin: vram_spin.clone(),
|
||||
vsync_switch: vsync_switch.clone(),
|
||||
pause_switch: pause_switch.clone(),
|
||||
width_spin: width_spin.clone(),
|
||||
height_spin: height_spin.clone(),
|
||||
};
|
||||
|
||||
let (setup_group, setup_body) = preview_group(
|
||||
"Preview setups",
|
||||
"Apply a built-in workload shape quickly, or reset everything back to the Studio defaults.",
|
||||
@@ -658,35 +714,12 @@ pub(crate) fn build_preview_panel(ctx: &PageBuildContext) -> gtk4::Box {
|
||||
let preview_controls = preview_controls.clone();
|
||||
let studio_defaults = studio_defaults.clone();
|
||||
let control_sync = control_sync.clone();
|
||||
let scene_dropdown = scene_dropdown.clone();
|
||||
let fps_spin = fps_spin.clone();
|
||||
let particle_count_spin = particle_count_spin.clone();
|
||||
let particle_size_spin = particle_size_spin.clone();
|
||||
let gpu_passes_spin = gpu_passes_spin.clone();
|
||||
let interaction_spin = interaction_spin.clone();
|
||||
let vram_spin = vram_spin.clone();
|
||||
let vsync_switch = vsync_switch.clone();
|
||||
let pause_switch = pause_switch.clone();
|
||||
let control_widgets = control_widgets.clone();
|
||||
button.connect_clicked(move |_| {
|
||||
let studio = profile.studio();
|
||||
studio_defaults.replace(studio.clone());
|
||||
persist_studio_options(&studio);
|
||||
control_sync.set(true);
|
||||
if let Some(index) = StudioScene::all()
|
||||
.iter()
|
||||
.position(|scene| *scene == studio.scene)
|
||||
{
|
||||
scene_dropdown.set_selected(index as u32);
|
||||
}
|
||||
fps_spin.set_value(studio.fps_cap.unwrap_or(0) as f64);
|
||||
particle_count_spin.set_value(studio.particle_count as f64);
|
||||
particle_size_spin.set_value(studio.particle_size as f64);
|
||||
gpu_passes_spin.set_value(studio.gpu_passes as f64);
|
||||
interaction_spin.set_value(studio.interaction_steps as f64);
|
||||
vram_spin.set_value(studio.vram_pressure_mb as f64);
|
||||
vsync_switch.set_active(studio.vsync);
|
||||
pause_switch.set_active(studio.paused);
|
||||
control_sync.set(false);
|
||||
apply_preview_control_state(&control_sync, &control_widgets, &studio, None);
|
||||
maybe_apply_studio_preview_runtime(&ctx, &preview_controls, studio);
|
||||
});
|
||||
profile_rows.attach(&button, (index % 2) as i32, (index / 2) as i32, 1, 1);
|
||||
@@ -697,17 +730,7 @@ pub(crate) fn build_preview_panel(ctx: &PageBuildContext) -> gtk4::Box {
|
||||
let preview_controls_reset = preview_controls.clone();
|
||||
let studio_defaults_reset = studio_defaults.clone();
|
||||
let control_sync_reset = control_sync.clone();
|
||||
let scene_dropdown_reset = scene_dropdown.clone();
|
||||
let fps_spin_reset = fps_spin.clone();
|
||||
let particle_count_spin_reset = particle_count_spin.clone();
|
||||
let particle_size_spin_reset = particle_size_spin.clone();
|
||||
let gpu_passes_spin_reset = gpu_passes_spin.clone();
|
||||
let interaction_spin_reset = interaction_spin.clone();
|
||||
let vram_spin_reset = vram_spin.clone();
|
||||
let vsync_switch_reset = vsync_switch.clone();
|
||||
let pause_switch_reset = pause_switch.clone();
|
||||
let width_spin_reset = width_spin.clone();
|
||||
let height_spin_reset = height_spin.clone();
|
||||
let control_widgets_reset = control_widgets.clone();
|
||||
reset_preview_button.connect_clicked(move |_| {
|
||||
let studio = PreviewStudioOptions::default();
|
||||
let (default_width, default_height) = default_preview_window_size();
|
||||
@@ -715,24 +738,12 @@ pub(crate) fn build_preview_panel(ctx: &PageBuildContext) -> gtk4::Box {
|
||||
persist_studio_options(&studio);
|
||||
persist_preview_window_width(default_width);
|
||||
persist_preview_window_height(default_height);
|
||||
control_sync_reset.set(true);
|
||||
if let Some(index) = StudioScene::all()
|
||||
.iter()
|
||||
.position(|scene| *scene == studio.scene)
|
||||
{
|
||||
scene_dropdown_reset.set_selected(index as u32);
|
||||
}
|
||||
fps_spin_reset.set_value(studio.fps_cap.unwrap_or(0) as f64);
|
||||
particle_count_spin_reset.set_value(studio.particle_count as f64);
|
||||
particle_size_spin_reset.set_value(studio.particle_size as f64);
|
||||
gpu_passes_spin_reset.set_value(studio.gpu_passes as f64);
|
||||
interaction_spin_reset.set_value(studio.interaction_steps as f64);
|
||||
vram_spin_reset.set_value(studio.vram_pressure_mb as f64);
|
||||
vsync_switch_reset.set_active(studio.vsync);
|
||||
pause_switch_reset.set_active(studio.paused);
|
||||
width_spin_reset.set_value(default_width as f64);
|
||||
height_spin_reset.set_value(default_height as f64);
|
||||
control_sync_reset.set(false);
|
||||
apply_preview_control_state(
|
||||
&control_sync_reset,
|
||||
&control_widgets_reset,
|
||||
&studio,
|
||||
Some((default_width, default_height)),
|
||||
);
|
||||
maybe_restart_active_preview(&ctx_reset, &preview_controls_reset, studio);
|
||||
});
|
||||
setup_body.append(&profile_rows);
|
||||
@@ -753,19 +764,22 @@ pub(crate) fn build_preview_panel(ctx: &PageBuildContext) -> gtk4::Box {
|
||||
let ctx = ctx.clone();
|
||||
let preview_controls = preview_controls.clone();
|
||||
scene_dropdown.connect_selected_notify(move |dropdown| {
|
||||
if control_sync.get() {
|
||||
return;
|
||||
}
|
||||
let Some(scene) = StudioScene::all()
|
||||
.get(dropdown.selected() as usize)
|
||||
.copied()
|
||||
else {
|
||||
return;
|
||||
};
|
||||
let mut studio = studio_defaults.borrow_mut();
|
||||
update_studio_runtime_setting(
|
||||
&control_sync,
|
||||
&ctx,
|
||||
&preview_controls,
|
||||
&studio_defaults,
|
||||
move |studio| {
|
||||
studio.scene = scene;
|
||||
persist_preview_studio_scene(scene);
|
||||
maybe_apply_studio_preview_runtime(&ctx, &preview_controls, studio.clone());
|
||||
},
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -775,14 +789,17 @@ pub(crate) fn build_preview_panel(ctx: &PageBuildContext) -> gtk4::Box {
|
||||
let ctx = ctx.clone();
|
||||
let preview_controls = preview_controls.clone();
|
||||
fps_spin.connect_value_changed(move |spin| {
|
||||
if control_sync.get() {
|
||||
return;
|
||||
}
|
||||
let value = spin.value().round().clamp(0.0, 1000.0) as i32;
|
||||
let mut studio = studio_defaults.borrow_mut();
|
||||
update_studio_runtime_setting(
|
||||
&control_sync,
|
||||
&ctx,
|
||||
&preview_controls,
|
||||
&studio_defaults,
|
||||
move |studio| {
|
||||
studio.fps_cap = if value <= 0 { None } else { Some(value as u32) };
|
||||
persist_studio_fps_cap(value);
|
||||
maybe_apply_studio_preview_runtime(&ctx, &preview_controls, studio.clone());
|
||||
},
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -792,14 +809,17 @@ pub(crate) fn build_preview_panel(ctx: &PageBuildContext) -> gtk4::Box {
|
||||
let ctx = ctx.clone();
|
||||
let preview_controls = preview_controls.clone();
|
||||
particle_count_spin.connect_value_changed(move |spin| {
|
||||
if control_sync.get() {
|
||||
return;
|
||||
}
|
||||
let count = spin.value().round().clamp(100.0, 500_000.0) as i32;
|
||||
let mut studio = studio_defaults.borrow_mut();
|
||||
update_studio_runtime_setting(
|
||||
&control_sync,
|
||||
&ctx,
|
||||
&preview_controls,
|
||||
&studio_defaults,
|
||||
move |studio| {
|
||||
studio.particle_count = count as u32;
|
||||
persist_studio_particle_count(count);
|
||||
maybe_apply_studio_preview_runtime(&ctx, &preview_controls, studio.clone());
|
||||
},
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -809,14 +829,17 @@ pub(crate) fn build_preview_panel(ctx: &PageBuildContext) -> gtk4::Box {
|
||||
let ctx = ctx.clone();
|
||||
let preview_controls = preview_controls.clone();
|
||||
particle_size_spin.connect_value_changed(move |spin| {
|
||||
if control_sync.get() {
|
||||
return;
|
||||
}
|
||||
let size = spin.value().clamp(0.01, 5.0);
|
||||
let mut studio = studio_defaults.borrow_mut();
|
||||
update_studio_runtime_setting(
|
||||
&control_sync,
|
||||
&ctx,
|
||||
&preview_controls,
|
||||
&studio_defaults,
|
||||
move |studio| {
|
||||
studio.particle_size = size as f32;
|
||||
persist_studio_particle_size(size);
|
||||
maybe_apply_studio_preview_runtime(&ctx, &preview_controls, studio.clone());
|
||||
},
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -826,14 +849,17 @@ pub(crate) fn build_preview_panel(ctx: &PageBuildContext) -> gtk4::Box {
|
||||
let ctx = ctx.clone();
|
||||
let preview_controls = preview_controls.clone();
|
||||
gpu_passes_spin.connect_value_changed(move |spin| {
|
||||
if control_sync.get() {
|
||||
return;
|
||||
}
|
||||
let passes = spin.value().round().clamp(1.0, 64.0) as i32;
|
||||
let mut studio = studio_defaults.borrow_mut();
|
||||
update_studio_runtime_setting(
|
||||
&control_sync,
|
||||
&ctx,
|
||||
&preview_controls,
|
||||
&studio_defaults,
|
||||
move |studio| {
|
||||
studio.gpu_passes = passes as u32;
|
||||
persist_studio_gpu_passes(passes);
|
||||
maybe_apply_studio_preview_runtime(&ctx, &preview_controls, studio.clone());
|
||||
},
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -843,14 +869,17 @@ pub(crate) fn build_preview_panel(ctx: &PageBuildContext) -> gtk4::Box {
|
||||
let ctx = ctx.clone();
|
||||
let preview_controls = preview_controls.clone();
|
||||
interaction_spin.connect_value_changed(move |spin| {
|
||||
if control_sync.get() {
|
||||
return;
|
||||
}
|
||||
let steps = spin.value().round().clamp(0.0, 256.0) as i32;
|
||||
let mut studio = studio_defaults.borrow_mut();
|
||||
update_studio_runtime_setting(
|
||||
&control_sync,
|
||||
&ctx,
|
||||
&preview_controls,
|
||||
&studio_defaults,
|
||||
move |studio| {
|
||||
studio.interaction_steps = steps as u32;
|
||||
persist_studio_interaction_steps(steps);
|
||||
maybe_apply_studio_preview_runtime(&ctx, &preview_controls, studio.clone());
|
||||
},
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -860,14 +889,17 @@ pub(crate) fn build_preview_panel(ctx: &PageBuildContext) -> gtk4::Box {
|
||||
let ctx = ctx.clone();
|
||||
let preview_controls = preview_controls.clone();
|
||||
vram_spin.connect_value_changed(move |spin| {
|
||||
if control_sync.get() {
|
||||
return;
|
||||
}
|
||||
let mb = spin.value().round().clamp(0.0, 4096.0) as i32;
|
||||
let mut studio = studio_defaults.borrow_mut();
|
||||
update_studio_runtime_setting(
|
||||
&control_sync,
|
||||
&ctx,
|
||||
&preview_controls,
|
||||
&studio_defaults,
|
||||
move |studio| {
|
||||
studio.vram_pressure_mb = mb as u32;
|
||||
persist_studio_vram_pressure(mb);
|
||||
maybe_apply_studio_preview_runtime(&ctx, &preview_controls, studio.clone());
|
||||
},
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -877,13 +909,17 @@ pub(crate) fn build_preview_panel(ctx: &PageBuildContext) -> gtk4::Box {
|
||||
let ctx = ctx.clone();
|
||||
let preview_controls = preview_controls.clone();
|
||||
vsync_switch.connect_active_notify(move |switch| {
|
||||
if control_sync.get() {
|
||||
return;
|
||||
}
|
||||
let mut studio = studio_defaults.borrow_mut();
|
||||
studio.vsync = switch.is_active();
|
||||
persist_preview_vsync(switch.is_active());
|
||||
maybe_apply_studio_preview_runtime(&ctx, &preview_controls, studio.clone());
|
||||
let active = switch.is_active();
|
||||
update_studio_runtime_setting(
|
||||
&control_sync,
|
||||
&ctx,
|
||||
&preview_controls,
|
||||
&studio_defaults,
|
||||
move |studio| {
|
||||
studio.vsync = active;
|
||||
persist_preview_vsync(active);
|
||||
},
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -893,12 +929,16 @@ pub(crate) fn build_preview_panel(ctx: &PageBuildContext) -> gtk4::Box {
|
||||
let ctx = ctx.clone();
|
||||
let preview_controls = preview_controls.clone();
|
||||
pause_switch.connect_active_notify(move |switch| {
|
||||
if control_sync.get() {
|
||||
return;
|
||||
}
|
||||
let mut studio = studio_defaults.borrow_mut();
|
||||
studio.paused = switch.is_active();
|
||||
maybe_apply_studio_preview_runtime(&ctx, &preview_controls, studio.clone());
|
||||
let active = switch.is_active();
|
||||
update_studio_runtime_setting(
|
||||
&control_sync,
|
||||
&ctx,
|
||||
&preview_controls,
|
||||
&studio_defaults,
|
||||
move |studio| {
|
||||
studio.paused = active;
|
||||
},
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -1163,6 +1203,36 @@ fn persist_preview_vsync(enabled: bool) {
|
||||
}
|
||||
}
|
||||
|
||||
fn apply_preview_control_state(
|
||||
control_sync: &Cell<bool>,
|
||||
controls: &PreviewStudioControlWidgets,
|
||||
studio: &PreviewStudioOptions,
|
||||
window_size: Option<(i32, i32)>,
|
||||
) {
|
||||
control_sync.set(true);
|
||||
controls.apply_studio_runtime(studio);
|
||||
if let Some((width, height)) = window_size {
|
||||
controls.apply_window_size(width, height);
|
||||
}
|
||||
control_sync.set(false);
|
||||
}
|
||||
|
||||
fn update_studio_runtime_setting(
|
||||
control_sync: &Cell<bool>,
|
||||
ctx: &PageBuildContext,
|
||||
preview_controls: &PreviewSessionWidgets,
|
||||
studio_defaults: &Rc<RefCell<PreviewStudioOptions>>,
|
||||
update: impl FnOnce(&mut PreviewStudioOptions),
|
||||
) {
|
||||
if control_sync.get() {
|
||||
return;
|
||||
}
|
||||
|
||||
let mut studio = studio_defaults.borrow_mut();
|
||||
update(&mut studio);
|
||||
maybe_apply_studio_preview_runtime(ctx, preview_controls, studio.clone());
|
||||
}
|
||||
|
||||
pub(super) fn preview_window_settings(
|
||||
_scene: PreviewScene,
|
||||
config: &AnnotatedConfig,
|
||||
|
||||
Reference in New Issue
Block a user