Merge pull request #433 from storytold/fix/402-no-row-separators
UI: no parameter row separators, as in After Effects (#402 follow-up)
This commit is contained in:
commit
f08d090cd8
|
|
@ -146,7 +146,6 @@ page!(Appearance {
|
|||
brightness: f64 = 0.0,
|
||||
/// The size of the whole interface in percent (75–200), on top of the display's own scale.
|
||||
ui_scale: u32 = 100,
|
||||
parameter_row_separators: bool = true,
|
||||
use_label_color_for_handles: bool = true,
|
||||
use_label_color_for_tabs: bool = true,
|
||||
cycle_mask_colors: bool = true,
|
||||
|
|
@ -1023,7 +1022,6 @@ pub fn pages() -> Vec<Page> {
|
|||
s("appearance.useLabelColorForTabs", "Use Label Color for Related Tabs", B, true),
|
||||
s("appearance.cycleMaskColors", "Cycle Mask Colors", B, true),
|
||||
s("appearance.useGradients", "Use Gradients", B, true),
|
||||
s("appearance.parameterRowSeparators", "Show Parameter Row Separators", B, true),
|
||||
Section("Menu Bar"),
|
||||
s("appearance.inWindowMenuBarMac", "Use In-Window Menu Bar on macOS", B, true),
|
||||
],
|
||||
|
|
|
|||
|
|
@ -567,8 +567,6 @@ fn group_rows(
|
|||
}
|
||||
}
|
||||
}
|
||||
// Expanded sliders/dials belong to their parameter; separate after the whole block.
|
||||
widgets::parameter_separator(p, Rect::from_min_max(r.min, pos2(r.max.x, *y)), &t);
|
||||
}
|
||||
Node::Group(sg) => {
|
||||
// Paint strokes live in the Timeline only (AE's Paint shows Paint on Transparent).
|
||||
|
|
@ -577,7 +575,6 @@ fn group_rows(
|
|||
}
|
||||
*y += ROW;
|
||||
let open = !app.ui.fx_closed.contains(&sg.uid);
|
||||
widgets::parameter_separator(p, r, &t);
|
||||
let tw = Rect::from_center_size(pos2(r.min.x + PARAM_NAME_X - 12.0 + TREE_INDENT * depth as f32, r.center().y), vec2(12.0, 12.0));
|
||||
if r.max.y >= rect.min.y && r.min.y <= rect.max.y {
|
||||
app.auto.add(&format!("effectControls.row.{}", sg.uid), r, &sg.name);
|
||||
|
|
|
|||
|
|
@ -2458,10 +2458,6 @@ pub fn show(app: &mut EffectcraftApp, ui: &mut egui::Ui, rect: Rect) {
|
|||
}
|
||||
}
|
||||
}
|
||||
if !matches!(row.kind, RowKind::Layer) {
|
||||
widgets::parameter_separator(&lp, left, &t);
|
||||
widgets::parameter_separator(&gp, Rect::from_min_max(pos2(graph_x0, r.min.y), r.max), &t);
|
||||
}
|
||||
}
|
||||
ui.set_clip_rect(full_clip);
|
||||
// The background responses sit below rows, bars and editors, preserving their menus.
|
||||
|
|
|
|||
|
|
@ -75,7 +75,6 @@ pub struct Tokens {
|
|||
pub gap: f32,
|
||||
pub tab_h: f32,
|
||||
pub row_h: f32,
|
||||
pub parameter_separators: bool,
|
||||
/// Settings ▸ Appearance ▸ Use Gradients: panel tab strips and buttons get a soft vertical
|
||||
/// gradient (off: flat fills).
|
||||
pub gradients: bool,
|
||||
|
|
@ -147,7 +146,6 @@ impl Tokens {
|
|||
gap: 4.0,
|
||||
tab_h: 30.0,
|
||||
row_h: 19.0,
|
||||
parameter_separators: true,
|
||||
gradients: true,
|
||||
};
|
||||
match kind {
|
||||
|
|
@ -218,7 +216,6 @@ impl Tokens {
|
|||
pub fn from_prefs(p: &effectcraft_engine::prefs::Prefs) -> Tokens {
|
||||
let kind = ThemeKind::from_name(&p.appearance.theme).unwrap_or_default();
|
||||
let mut t = Tokens::for_kind(kind).with_brightness(p.appearance.brightness as f32);
|
||||
t.parameter_separators = p.appearance.parameter_row_separators;
|
||||
for (i, l) in effectcraft_color::Label::ALL.iter().enumerate() {
|
||||
let [r, g, b] = p.label_rgb(*l);
|
||||
t.labels[i] = Color32::from_rgb(r, g, b);
|
||||
|
|
|
|||
|
|
@ -112,14 +112,6 @@ pub fn select_all(ctx: &egui::Context, id: egui::Id, text: &str) {
|
|||
state.store(ctx, id);
|
||||
}
|
||||
|
||||
/// A parameter boundary. It only paints: row layout owns both drawing and hit testing.
|
||||
pub fn parameter_separator(p: &egui::Painter, r: Rect, t: &Tokens) {
|
||||
let y = r.max.y - 0.5;
|
||||
if t.parameter_separators && p.clip_rect().y_range().contains(y) {
|
||||
p.line_segment([pos2(r.min.x, y), pos2(r.max.x, y)], Stroke::new(1.0, t.app_bg));
|
||||
}
|
||||
}
|
||||
|
||||
/// A colour swatch; returns the response (click opens the picker in the caller).
|
||||
pub fn swatch(ui: &mut Ui, rect: Rect, c: [f32; 4], id: egui::Id, t: &Tokens) -> Response {
|
||||
let resp = ui.interact(rect, id, Sense::click());
|
||||
|
|
|
|||
|
|
@ -1,10 +1,5 @@
|
|||
use effectcraft_engine::{Session, prefs::Prefs};
|
||||
use effectcraft_ui_egui::{
|
||||
EffectcraftApp,
|
||||
dock::PanelKind,
|
||||
theme::{ThemeKind, Tokens},
|
||||
widgets,
|
||||
};
|
||||
use effectcraft_engine::Session;
|
||||
use effectcraft_ui_egui::{EffectcraftApp, dock::PanelKind};
|
||||
use egui::{Event, Modifiers, PointerButton, pos2, vec2};
|
||||
use egui_kittest::Harness;
|
||||
use serde_json::json;
|
||||
|
|
@ -54,66 +49,6 @@ fn fixed_compact_rows_preserve_checkbox_and_point_hit_targets() {
|
|||
assert!(h.state().ui.fx_pick.is_none());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn separator_preference_is_saved_and_resettable() {
|
||||
let mut p = Prefs::default();
|
||||
p.set("appearance.parameterRowSeparators", json!(false)).unwrap();
|
||||
assert_eq!(Prefs::from_json(&p.to_json()), p);
|
||||
assert!(!Tokens::from_prefs(&p).parameter_separators);
|
||||
p.reset(Some("appearance")).unwrap();
|
||||
assert!(p.appearance.parameter_row_separators);
|
||||
assert!(Prefs::from_json(r#"{"appearance":{"theme":"light"}}"#).appearance.parameter_row_separators);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn cancelling_separator_preview_preserves_fixed_row_geometry_and_project() {
|
||||
let (a, _, checkbox, _) = setup();
|
||||
let mut h = Harness::builder().with_size(vec2(1500.0, 1000.0)).build_eframe(|_| a);
|
||||
h.run_steps(4);
|
||||
let row = format!("effectControls.row.{checkbox}");
|
||||
let before = h.state().auto.find(&row).unwrap().rect;
|
||||
let project = h.state().session.project.clone();
|
||||
let ctx = h.ctx.clone();
|
||||
effectcraft_ui_egui::menus::invoke(h.state_mut(), &ctx, "app.settings", json!({"page":"appearance"})).unwrap();
|
||||
h.state_mut().session.execute("prefs.set", json!({"key":"appearance.parameterRowSeparators","value":false})).unwrap();
|
||||
h.run_steps(3);
|
||||
assert!(!h.state().tokens.parameter_separators);
|
||||
assert_eq!(h.state().auto.find(&row).unwrap().rect, before);
|
||||
click(&mut h, "settings.cancel");
|
||||
assert!(h.state().tokens.parameter_separators);
|
||||
assert_eq!(h.state().auto.find(&row).unwrap().rect, before);
|
||||
assert!(std::sync::Arc::ptr_eq(&project, &h.state().session.project));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn row_separator_uses_the_theme_and_can_be_disabled() {
|
||||
for kind in [ThemeKind::Dark, ThemeKind::Darker, ThemeKind::Light] {
|
||||
for enabled in [true, false] {
|
||||
let ctx = egui::Context::default();
|
||||
let mut t = Tokens::for_kind(kind);
|
||||
t.parameter_separators = enabled;
|
||||
let mut out = ctx.run_ui(Default::default(), |_| {
|
||||
let painter = ctx.layer_painter(egui::LayerId::background());
|
||||
widgets::parameter_separator(&painter, egui::Rect::from_min_size(pos2(10.0, 20.0), vec2(200.0, 24.0)), &t);
|
||||
});
|
||||
let lines: Vec<_> = out
|
||||
.shapes
|
||||
.iter()
|
||||
.filter_map(|s| match s.shape {
|
||||
egui::Shape::LineSegment { points, stroke } => Some((points, stroke)),
|
||||
_ => None,
|
||||
})
|
||||
.collect();
|
||||
assert_eq!(lines.len(), usize::from(enabled));
|
||||
if enabled {
|
||||
assert_eq!(lines[0].0, [pos2(10.0, 43.5), pos2(210.0, 43.5)]);
|
||||
assert_eq!(lines[0].1.color, t.app_bg);
|
||||
}
|
||||
out.textures_delta.clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn nested_groups_keep_indentation_value_alignment_and_effect_gaps_at_fixed_compact_spacing() {
|
||||
let mut s = Session::default();
|
||||
|
|
|
|||
|
|
@ -58,7 +58,6 @@ Commands (CLI, MCP, control channel):
|
|||
- `appearance.brightness`: Brightness
|
||||
- `appearance.uiScale`: UI Scale, the size of the whole interface (75–200 %, on top of the
|
||||
display's own scaling), applied as soon as it is chosen
|
||||
- `appearance.parameterRowSeparators`: thin dark boundaries between parameter/group rows in Effect Controls and the timeline (default on). Expanded sliders and dials are kept within their parameter block. Effect Controls indents each group level beneath its effect, aligns sibling names and values, and preserves the gap before the next effect.
|
||||
- `appearance.useLabelColorForHandles`: Use Label Color for Layer Handles and Paths
|
||||
- `grids.gridColor`: Color
|
||||
- `grids.gridSpacing`: Gridline Every
|
||||
|
|
@ -166,7 +165,7 @@ step with the schema.
|
|||
- `scripting.enableJsDebugger`: the JavaScript engine has no step debugger; script errors report
|
||||
their file and line in the Script Console.
|
||||
|
||||
Effect Controls uses compact, fixed 20 pt parameter rows; the timeline keeps its fixed 19 pt rows. These logical sizes follow the existing whole-interface UI Scale. The separator preference previews immediately; Cancel restores it and OK saves it. Painting and mouse hit tests use the same row geometry. These UI changes do not alter project values or render output.
|
||||
Effect Controls uses compact, fixed 20 pt parameter rows, as After Effects does: each group level is indented beneath its effect, sibling names and values align, and a gap separates effects. The timeline keeps its fixed 19 pt rows. Both follow the whole-interface UI Scale.
|
||||
|
||||
## Keyboard shortcuts
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue