mirror of
https://github.com/storytold/effectcraft.git
synced 2026-10-29 12:37:08 -06:00
Merge pull request #122 from storytold/claude/issue-117-render-settings-templates
Render Queue: Render Settings templates apply from the menu (#117)
This commit is contained in:
@@ -287,7 +287,7 @@ pub fn color_popup(ui: &mut egui::Ui, id: egui::Id, pos: egui::Pos2, c: &mut [f3
|
||||
}
|
||||
});
|
||||
});
|
||||
if ui.input(|i| i.pointer.any_pressed()) && !area.response.contains_pointer() || ui.input(|i| i.key_pressed(egui::Key::Escape)) {
|
||||
if widgets::pressed_outside(ui.ctx(), &area.response) || ui.input(|i| i.key_pressed(egui::Key::Escape)) {
|
||||
ui.data_mut(|d| d.insert_temp(open_id, false));
|
||||
}
|
||||
changed
|
||||
|
||||
@@ -285,8 +285,7 @@ fn dropdown_row(app: &mut EffectcraftApp, ui: &mut egui::Ui, r: Rect, key: &str,
|
||||
}
|
||||
});
|
||||
});
|
||||
let outside =
|
||||
ui.input(|i| i.pointer.any_pressed()) && !area.response.contains_pointer() && !r.contains(ui.input(|i| i.pointer.interact_pos()).unwrap_or_default());
|
||||
let outside = widgets::pressed_outside(ui.ctx(), &area.response) && !r.contains(ui.input(|i| i.pointer.interact_pos()).unwrap_or_default());
|
||||
if chosen.is_some() || outside || ui.input(|i| i.key_pressed(egui::Key::Escape)) {
|
||||
ui.data_mut(|d| d.insert_temp(pid.with("open"), false));
|
||||
}
|
||||
|
||||
@@ -184,7 +184,7 @@ pub fn panel_menu_popup(app: &mut EffectcraftApp, ui: &mut egui::Ui) {
|
||||
}
|
||||
});
|
||||
});
|
||||
if close || (ui.input(|i| i.pointer.any_pressed()) && !area.response.contains_pointer() && !area.response.hovered()) {
|
||||
if close || crate::widgets::pressed_outside(ui.ctx(), &area.response) {
|
||||
ui.ctx().data_mut(|d| d.remove::<(PanelKind, egui::Pos2)>(id));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -304,7 +304,7 @@ pub fn mini_flowchart(app: &mut EffectcraftApp, ctx: &egui::Context) {
|
||||
}
|
||||
});
|
||||
});
|
||||
let outside = ctx.input(|i| i.pointer.any_pressed()) && !area.response.contains_pointer();
|
||||
let outside = crate::widgets::pressed_outside(ctx, &area.response);
|
||||
if let Some(id) = open {
|
||||
app.session.open_comp(id);
|
||||
close = true;
|
||||
|
||||
@@ -387,7 +387,7 @@ fn opentype_popup(app: &mut EffectcraftApp, ui: &mut egui::Ui, id: egui::Id, pos
|
||||
for (aid, r, label) in rects {
|
||||
app.auto.add(&aid, r, &label);
|
||||
}
|
||||
let outside = ui.input(|i| i.pointer.any_pressed()) && !area.response.contains_pointer() && !area.response.hovered();
|
||||
let outside = widgets::pressed_outside(ui.ctx(), &area.response);
|
||||
if outside || ui.input(|i| i.key_pressed(egui::Key::Escape)) {
|
||||
ui.data_mut(|d| d.insert_temp(open_id, false));
|
||||
}
|
||||
@@ -584,7 +584,7 @@ fn font_popup(app: &EffectcraftApp, ui: &mut egui::Ui, id: egui::Id, pos: egui::
|
||||
});
|
||||
});
|
||||
});
|
||||
let outside = ui.input(|i| i.pointer.any_pressed()) && !area.response.contains_pointer() && !area.response.hovered();
|
||||
let outside = widgets::pressed_outside(ui.ctx(), &area.response);
|
||||
if chosen.is_some() || outside || ui.input(|i| i.key_pressed(egui::Key::Escape)) {
|
||||
ui.data_mut(|d| d.insert_temp(id.with("open"), false));
|
||||
}
|
||||
|
||||
@@ -454,9 +454,7 @@ fn popup(app: &mut EffectcraftApp, ui: &mut egui::Ui, id: &str, anchor: Rect, it
|
||||
}
|
||||
});
|
||||
});
|
||||
let outside = ui.input(|i| i.pointer.any_pressed())
|
||||
&& !area.response.contains_pointer()
|
||||
&& !anchor.contains(ui.input(|i| i.pointer.interact_pos()).unwrap_or_default());
|
||||
let outside = widgets::pressed_outside(ui.ctx(), &area.response) && !anchor.contains(ui.input(|i| i.pointer.interact_pos()).unwrap_or_default());
|
||||
if chosen.is_some() || outside || ui.input(|i| i.key_pressed(egui::Key::Escape)) {
|
||||
ui.data_mut(|d| d.insert_temp(pid.with("open"), false));
|
||||
}
|
||||
|
||||
@@ -229,6 +229,15 @@ pub fn checkbox(ui: &mut Ui, rect: Rect, on: bool, t: &Tokens, id: egui::Id) ->
|
||||
resp
|
||||
}
|
||||
|
||||
/// A pointer press this frame landed outside a popup `Area` (its `show` response). egui
|
||||
/// hit-tests a fixed-position area where it was asked to go, not where it was moved to fit the
|
||||
/// window, so `contains_pointer` / `hovered` are false over a menu shifted up from the bottom of
|
||||
/// the window and the menu would close on the press before its entry is clicked (#117). The
|
||||
/// area's response rect is where it was drawn.
|
||||
pub fn pressed_outside(ctx: &egui::Context, area: &Response) -> bool {
|
||||
ctx.input(|i| i.pointer.any_pressed() && !i.pointer.interact_pos().is_some_and(|p| area.rect.contains(p)))
|
||||
}
|
||||
|
||||
/// Show a popup menu anchored at `pos` with string options; returns the chosen index.
|
||||
pub fn popup_menu(ui: &mut Ui, id: egui::Id, pos: egui::Pos2, options: &[String], current: Option<usize>) -> Option<usize> {
|
||||
let mut chosen = None;
|
||||
@@ -254,7 +263,7 @@ pub fn popup_menu(ui: &mut Ui, id: egui::Id, pos: egui::Pos2, options: &[String]
|
||||
});
|
||||
});
|
||||
});
|
||||
let clicked_outside = ui.input(|i| i.pointer.any_pressed()) && !area.response.contains_pointer() && !area.response.hovered();
|
||||
let clicked_outside = pressed_outside(ui.ctx(), &area.response);
|
||||
if chosen.is_some() || clicked_outside || ui.input(|i| i.key_pressed(egui::Key::Escape)) {
|
||||
ui.data_mut(|d| d.insert_temp(open_id, false));
|
||||
}
|
||||
|
||||
@@ -0,0 +1,46 @@
|
||||
//! Render Queue panel input: choosing a Render Settings template from an item's menu (#117).
|
||||
|
||||
use effectcraft_engine::Session;
|
||||
use effectcraft_engine::project::render_queue::RenderQuality;
|
||||
use effectcraft_ui_egui::EffectcraftApp;
|
||||
use effectcraft_ui_egui::dock::PanelKind;
|
||||
use egui::{Event, Modifiers, Pos2, pos2};
|
||||
use egui_kittest::Harness;
|
||||
use egui_kittest::kittest::Queryable;
|
||||
use serde_json::json;
|
||||
|
||||
fn click_at(h: &mut Harness<'_, EffectcraftApp>, p: Pos2) {
|
||||
h.input_mut().events.push(Event::PointerMoved(p));
|
||||
h.input_mut().events.push(Event::PointerButton { pos: p, button: egui::PointerButton::Primary, pressed: true, modifiers: Modifiers::NONE });
|
||||
h.step();
|
||||
h.input_mut().events.push(Event::PointerButton { pos: p, button: egui::PointerButton::Primary, pressed: false, modifiers: Modifiers::NONE });
|
||||
h.run_steps(2);
|
||||
}
|
||||
|
||||
/// The Render Settings menu is taller than the room below the item, so it is moved up to fit
|
||||
/// the window; its entries must still take the click instead of the menu closing on the press.
|
||||
#[test]
|
||||
fn render_settings_template_applies_from_a_menu_moved_to_fit_the_window() {
|
||||
let mut s = Session::default();
|
||||
s.execute("file.openDemoProject", json!({})).unwrap();
|
||||
s.execute("renderQueue.add", json!({})).unwrap();
|
||||
let id = s.project.render_queue[0].id;
|
||||
assert_eq!(s.project.render_queue[0].settings.name, "Best Settings");
|
||||
let mut app = Some(EffectcraftApp::new(s));
|
||||
let mut h = Harness::builder().with_size(egui::vec2(1600.0, 1000.0)).build_eframe(|_| app.take().expect("app"));
|
||||
// Twirl the item open, as clicking its twirl does.
|
||||
h.ctx.data_mut(|d| d.insert_temp(egui::Id::new("rq-ui"), (vec![id], None::<u64>)));
|
||||
h.state_mut().show_panel(PanelKind::RenderQueue);
|
||||
h.run_steps(4);
|
||||
let dd = h.state().auto.find(&format!("renderQueue.item.{id}.renderSettings")).expect("Render Settings menu").clone();
|
||||
let dd_center = pos2(dd.rect[0] + dd.rect[2] / 2.0, dd.rect[1] + dd.rect[3] / 2.0);
|
||||
click_at(&mut h, dd_center);
|
||||
let entry = h.query_by_label_contains("Draft Settings").expect("the Draft Settings entry").rect();
|
||||
assert!(entry.max.y < dd_center.y, "the menu was moved up to fit the window (entry {entry:?}, menu button at {dd_center:?})");
|
||||
click_at(&mut h, entry.center());
|
||||
let it = &h.state().session.project.render_queue[0];
|
||||
assert_eq!(it.settings.name, "Draft Settings");
|
||||
assert_eq!(it.settings.quality, RenderQuality::Draft);
|
||||
assert_eq!(it.settings.resolution, 0.5);
|
||||
assert!(h.query_by_label_contains("Quality: Draft").is_none(), "the menu closed after the choice");
|
||||
}
|
||||
Reference in New Issue
Block a user