mirror of
https://github.com/storytold/effectcraft.git
synced 2026-10-30 04:57:54 -06:00
Merge pull request #2250 from slager2/fix/2172-animation-browse-presets
Fix Animation > Browse Presets command
This commit is contained in:
@@ -488,7 +488,15 @@ pub fn frontend(app: &mut EffectcraftApp, ctx: &egui::Context, id: &str, p: Valu
|
||||
app.ui.home_templates = true;
|
||||
Value::Null
|
||||
}
|
||||
"effect.manage" | "anim.browsePresets" => {
|
||||
"effect.manage" => {
|
||||
app.show_panel(PanelKind::EffectsPresets);
|
||||
Value::Null
|
||||
}
|
||||
"anim.browsePresets" => {
|
||||
app.ui.effects_search.clear();
|
||||
app.ui.effects_view.presets = true;
|
||||
app.ui.effects_open.insert("presets".into());
|
||||
ctx.data_mut(|data| data.insert_temp(egui::Id::unique(crate::panels::effects_presets::REVEAL_PRESETS_ID), true));
|
||||
app.show_panel(PanelKind::EffectsPresets);
|
||||
Value::Null
|
||||
}
|
||||
|
||||
@@ -17,6 +17,7 @@ use crate::{EffectcraftApp, widgets};
|
||||
|
||||
const ROW_H: f32 = 21.0;
|
||||
const RECENT_MAX: usize = 8;
|
||||
pub(crate) const REVEAL_PRESETS_ID: &str = "fx-reveal-presets";
|
||||
|
||||
/// A user animation preset file.
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
@@ -157,6 +158,24 @@ fn folder_row(
|
||||
open
|
||||
}
|
||||
|
||||
/// Number of visible rows before Animation Presets in the current panel state.
|
||||
fn rows_before_presets(favorites: usize, recent: usize, searching: bool, favorites_open: bool, recent_open: bool) -> usize {
|
||||
let mut rows = 0usize;
|
||||
if favorites > 0 {
|
||||
rows = rows.saturating_add(1);
|
||||
if searching || favorites_open {
|
||||
rows = rows.saturating_add(favorites);
|
||||
}
|
||||
}
|
||||
if !searching && recent > 0 {
|
||||
rows = rows.saturating_add(1);
|
||||
if recent_open {
|
||||
rows = rows.saturating_add(recent);
|
||||
}
|
||||
}
|
||||
rows
|
||||
}
|
||||
|
||||
/// An effect row (fx icon, highlighted name, favourite star, 32 bpc badge).
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
fn effect_row(
|
||||
@@ -364,7 +383,7 @@ pub fn show(app: &mut EffectcraftApp, ui: &mut egui::Ui, rect: Rect) {
|
||||
let view = app.ui.effects_view.clone();
|
||||
let list = Rect::from_min_max(pos2(rect.min.x, sr.max.y + 6.0), rect.max);
|
||||
let lp = p.with_clip_rect(list);
|
||||
let scroll = widgets::PanelScroll::begin(ui, egui::Id::unique("fx-scroll"), list);
|
||||
let mut scroll = widgets::PanelScroll::begin(ui, egui::Id::unique("fx-scroll"), list);
|
||||
let query = q.trim().to_lowercase();
|
||||
let searching = !query.is_empty();
|
||||
let mut y = list.min.y - scroll.offset;
|
||||
@@ -378,6 +397,16 @@ pub fn show(app: &mut EffectcraftApp, ui: &mut egui::Ui, rect: Rect) {
|
||||
|
||||
// Favorites and Recently Used.
|
||||
let favs: Vec<_> = app.session.prefs.effects_favorites.iter().filter_map(|id| lookup(id)).filter(|e| keep(e)).collect();
|
||||
let recent: Vec<_> = app.ui.effects_recent.iter().filter_map(|id| lookup(id)).filter(|e| keep(e)).collect();
|
||||
let reveal_presets = ctx.data_mut(|data| data.remove_temp::<bool>(egui::Id::unique(REVEAL_PRESETS_ID))).unwrap_or(false);
|
||||
if reveal_presets {
|
||||
// These rows come before Animation Presets. Scroll past expanded lists so the section is
|
||||
// visible even when Favorites or Recently Used is long.
|
||||
let preceding_rows =
|
||||
rows_before_presets(favs.len(), recent.len(), searching, app.ui.effects_open.contains("favorites"), app.ui.effects_open.contains("recent"));
|
||||
scroll.offset = ROW_H * preceding_rows as f32;
|
||||
y = list.min.y - scroll.offset;
|
||||
}
|
||||
if !favs.is_empty() && folder_row(app, ui, &lp, list, &mut y, "favorites", "Favorites", 0.0, searching, Some(Icon::Star)) {
|
||||
let mut favs = favs;
|
||||
favs.sort_by_key(|e| e.name);
|
||||
@@ -385,7 +414,6 @@ pub fn show(app: &mut EffectcraftApp, ui: &mut egui::Ui, rect: Rect) {
|
||||
effect_row(app, ui, &lp, list, &mut y, e, 0.0, &query, "effects.favorites", &mut apply);
|
||||
}
|
||||
}
|
||||
let recent: Vec<_> = app.ui.effects_recent.iter().filter_map(|id| lookup(id)).filter(|e| keep(e)).collect();
|
||||
if !recent.is_empty() && !searching && folder_row(app, ui, &lp, list, &mut y, "recent", "Recently Used", 0.0, false, None) {
|
||||
for e in recent {
|
||||
effect_row(app, ui, &lp, list, &mut y, e, 0.0, &query, "effects.recent", &mut apply);
|
||||
|
||||
@@ -65,6 +65,47 @@ fn shown(h: &Harness<'_, EffectcraftApp>, label: &str) -> bool {
|
||||
h.query_by_label_contains(label).is_some()
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn browse_presets_clears_search_and_scrolls_to_the_visible_presets_list() {
|
||||
use effectcraft_ui_egui::dock::PanelKind;
|
||||
|
||||
let mut h = harness();
|
||||
let ctx = h.ctx.clone();
|
||||
let favorites: Vec<String> = effectcraft_engine::effects::all().iter().map(|effect| effect.id.to_string()).collect();
|
||||
assert!(!favorites.is_empty(), "the test needs registered effects");
|
||||
let recent: Vec<String> = favorites.iter().take(8).cloned().collect();
|
||||
|
||||
h.state_mut().session.prefs.effects_favorites = favorites;
|
||||
h.state_mut().ui.effects_recent = recent;
|
||||
h.state_mut().ui.effects_open.extend(["favorites".into(), "recent".into()]);
|
||||
h.state_mut().ui.effects_search = "no matching animation preset".into();
|
||||
h.state_mut().ui.effects_view.presets = true;
|
||||
|
||||
let managed = effectcraft_ui_egui::menus::invoke(h.state_mut(), &ctx, "effect.manage", json!({}));
|
||||
assert!(managed.is_ok(), "{managed:?}");
|
||||
assert_eq!(h.state().ui.focused, PanelKind::EffectsPresets);
|
||||
assert_eq!(h.state().ui.effects_search, "no matching animation preset", "Manage Effects keeps its existing search behavior");
|
||||
assert!(h.state().ui.effects_view.presets, "Manage Effects keeps the existing presets setting");
|
||||
|
||||
h.run_steps(3);
|
||||
assert!(h.state().auto.find("effects.category.presets").is_none(), "the unmatched search hides Animation Presets");
|
||||
h.state_mut().ui.effects_view.presets = false;
|
||||
|
||||
let result = effectcraft_ui_egui::menus::invoke(h.state_mut(), &ctx, "anim.browsePresets", json!({}));
|
||||
|
||||
assert!(result.is_ok(), "{result:?}");
|
||||
assert_eq!(h.state().ui.focused, PanelKind::EffectsPresets);
|
||||
assert!(h.state().ui.effects_search.is_empty());
|
||||
assert!(h.state().ui.effects_view.presets);
|
||||
assert!(h.state().ui.effects_open.contains("presets"));
|
||||
|
||||
h.run_steps(3);
|
||||
assert!(
|
||||
h.state().auto.find("effects.category.presets").is_some(),
|
||||
"Animation Presets must be visible after Browse Presets, even below expanded Favorites and Recently Used"
|
||||
);
|
||||
}
|
||||
|
||||
/// Space (or any shortcut) while a menu is open goes to the menu, not the app: it started the
|
||||
/// preview behind the open menu.
|
||||
#[test]
|
||||
|
||||
Reference in New Issue
Block a user