mirror of
https://github.com/storytold/soundcraft.git
synced 2026-11-11 12:52:20 +00:00
Merge pull request #576 from colliderman/fix/edit-track-header-alignments
fix(ui): center track names in edit window and remove unnecessary spacing for Solo and Mute buttons in Master tracks
This commit is contained in:
2 files changed
+72
-6
No files matched your search
@@ -115,8 +115,18 @@ fn name_plate(app: &mut SoundApp, ui: &mut Ui, track: &Track, head: Rect, select
|
||||
track.name.clone()
|
||||
};
|
||||
let name_color = if selected { t.text_dark } else { t.text.lerp_to_gamma(t.text_dim, 0.4) };
|
||||
ui.painter().with_clip_rect(name_r).text(pos2(name_r.min.x + 1.5, name_r.center().y), Align2::LEFT_CENTER, &shown_name, bold(12.5), name_color);
|
||||
let nresp = ui.interact(name_r, ui.scope_id().with(("name", id.0)), Sense::click_and_drag());
|
||||
let font = bold(12.5);
|
||||
let galley = ui.painter().layout_no_wrap(shown_name.clone(), font.clone(), name_color);
|
||||
let overflows = galley.size().x > name_r.width() - 3.0;
|
||||
let (text_pos, align) =
|
||||
if overflows { (pos2(name_r.min.x + 1.5, name_r.center().y), Align2::LEFT_CENTER) } else { (name_r.center(), Align2::CENTER_CENTER) };
|
||||
ui.painter().with_clip_rect(name_r).text(text_pos, align, &shown_name, font, name_color);
|
||||
let mut nresp = ui.interact(name_r, ui.scope_id().with(("name", id.0)), Sense::click_and_drag());
|
||||
if overflows {
|
||||
nresp = nresp.on_hover_ui(|ui| {
|
||||
ui.label(&shown_name);
|
||||
});
|
||||
}
|
||||
if nresp.double_clicked() {
|
||||
app.dialogs.open_rename_track(id, &track.name);
|
||||
} else if nresp.clicked() {
|
||||
@@ -190,8 +200,9 @@ fn toggle_keys(app: &mut SoundApp, ui: &mut Ui, track: &Track, head: Rect) {
|
||||
let h = head.height();
|
||||
let at = |x: f32, y: f32, w: f32, h: f32| Rect::from_min_size(pos2(head.min.x + x, head.min.y + y), vec2(w, h));
|
||||
let m = &track.mixer;
|
||||
if h >= 37.0 {
|
||||
let (records, mixes) = (track.kind.has_playlist(), track.kind != TrackKind::Master);
|
||||
let is_master = track.kind == TrackKind::Master;
|
||||
if h >= 37.0 && !is_master {
|
||||
let (records, mixes) = (track.kind.has_playlist(), true);
|
||||
let implied = !m.solo && app.engine.session().tracks.iter().any(|t| t.mixer.solo);
|
||||
let keys = [
|
||||
(HeaderKey::Rec, m.record_arm, false, "mix.record_arm", records),
|
||||
@@ -213,10 +224,13 @@ fn view_selector(app: &mut SoundApp, ui: &mut Ui, track: &Track, head: Rect) {
|
||||
let id = track.id;
|
||||
let h = head.height();
|
||||
let at = |x: f32, y: f32, w: f32, h: f32| Rect::from_min_size(pos2(head.min.x + x, head.min.y + y), vec2(w, h));
|
||||
if h >= 58.0 {
|
||||
let is_master = track.kind == TrackKind::Master;
|
||||
let view_y = if is_master { 20.0 } else { 39.0 };
|
||||
let view_min_h = if is_master { 37.0 } else { 58.0 };
|
||||
if h >= view_min_h {
|
||||
let vresp = header_selector(
|
||||
ui,
|
||||
at(17.0, 39.0, 105.0, 17.0),
|
||||
at(17.0, view_y, 105.0, 17.0),
|
||||
ui.scope_id().with(("view", id.0)),
|
||||
&view_label(&track.view),
|
||||
t.text,
|
||||
@@ -225,10 +239,32 @@ fn view_selector(app: &mut SoundApp, ui: &mut Ui, track: &Track, head: Rect) {
|
||||
);
|
||||
egui::Popup::menu(&vresp).show(|ui| view_menu(app, ui, track));
|
||||
}
|
||||
if is_master && h >= 58.0 {
|
||||
let mode = track.mixer.automation_mode;
|
||||
let col = match mode {
|
||||
soundcraft_model::AutomationMode::Read => t.auto_read,
|
||||
soundcraft_model::AutomationMode::Write => t.auto_write,
|
||||
soundcraft_model::AutomationMode::Touch | soundcraft_model::AutomationMode::TouchLatch => t.auto_touch,
|
||||
soundcraft_model::AutomationMode::Latch => t.auto_latch,
|
||||
_ => t.text_dim,
|
||||
};
|
||||
let mode_name = format!("Automation mode for {}", track.name);
|
||||
let aresp = header_selector(ui, at(17.0, 39.0, 105.0, 17.0), ui.scope_id().with(("auto_mode", id.0)), mode.label(), col, true, &mode_name);
|
||||
egui::Popup::menu(&aresp).show(|ui| {
|
||||
for m in soundcraft_model::AutomationMode::ALL {
|
||||
if ui.selectable_label(m == mode, m.label()).clicked() {
|
||||
let _ = app.run("mix.automation_mode", json!({"track": id.0, "mode": m.label()}));
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/// Freeze, voice and automation mode.
|
||||
fn voice_row(app: &mut SoundApp, ui: &mut Ui, track: &Track, head: Rect) {
|
||||
if track.kind == TrackKind::Master {
|
||||
return;
|
||||
}
|
||||
let t = Tokens::current();
|
||||
let id = track.id;
|
||||
let h = head.height();
|
||||
|
||||
@@ -1525,3 +1525,33 @@ fn alt_click_on_a_marker_deletes_it() {
|
||||
assert_eq!(h.state().engine.session().markers.len(), before - 1);
|
||||
assert!(!h.state().engine.session().markers.iter().any(|m| m.name == "Alt-delete me"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn short_track_name_is_centered_and_long_name_is_left_aligned() {
|
||||
let mut h = harness(2);
|
||||
let s = h.state().engine.session_arc();
|
||||
let first = s.tracks[0].id.0;
|
||||
let second = s.tracks[1].id.0;
|
||||
h.state_mut().run("track.rename", json!({"track": first, "name": "Vocal"})).unwrap();
|
||||
h.state_mut().run("track.rename", json!({"track": second, "name": "A Very Long Track Name That Exceeds Header Width"})).unwrap();
|
||||
h.step();
|
||||
|
||||
let r0 = row(&h, 0);
|
||||
let r1 = row(&h, 1);
|
||||
|
||||
let first_text = h.output().shapes.iter().find_map(|s| match &s.shape {
|
||||
Shape::Text(t) if t.galley.text() == "Vocal" && s.clip_rect.intersects(r0) => Some((t.pos, t.galley.size())),
|
||||
_ => None,
|
||||
});
|
||||
let long_text = h.output().shapes.iter().find_map(|s| match &s.shape {
|
||||
Shape::Text(t) if t.galley.text() == "A Very Long Track Name That Exceeds Header Width" && s.clip_rect.intersects(r1) => Some(t.pos),
|
||||
_ => None,
|
||||
});
|
||||
|
||||
let (first_pos, first_size) = first_text.expect("short track name should be rendered in edit header");
|
||||
let long_pos = long_text.expect("long track name should be rendered in edit header");
|
||||
|
||||
assert_eq!(long_pos.x, r1.min.x + 17.5);
|
||||
let first_center_x = first_pos.x + first_size.x * 0.5;
|
||||
assert!((first_center_x - (r0.min.x + 64.5)).abs() <= 0.1, "short name should be centered (center was at {first_center_x})");
|
||||
}
|
||||
Reference in new issue
Block a user