mirror of
https://github.com/storytold/soundcraft.git
synced 2026-11-10 04:14:22 +00:00
Merge pull request #1280 from TheGalitube/fix/1252-tracks-nested-in-a-folder-are-no
Indent tracks nested in folders
This commit is contained in:
2 files changed
+66
-4
No files matched your search
@@ -46,9 +46,28 @@ pub fn tracks_and_groups(app: &mut SoundApp, ui: &mut Ui) {
|
||||
if crate::widgets::icon_button(&mut ui.new_child(egui::UiBuilder::new().max_rect(plus)), plus.size(), "plus", false, &tip).clicked() {
|
||||
let _ = app.dialogs.open_for_command(&app.engine, "track.new");
|
||||
}
|
||||
let tracks: Vec<(u64, String, bool, [u8; 3], bool)> = {
|
||||
let tracks: Vec<(u64, String, bool, [u8; 3], bool, usize)> = {
|
||||
let s = app.engine.session();
|
||||
s.tracks.iter().map(|x| (x.id.0, x.name.clone(), !x.hidden, x.color, s.edit.selected_tracks.contains(&x.id))).collect()
|
||||
s.tracks
|
||||
.iter()
|
||||
.map(|x| {
|
||||
let mut current = x.folder;
|
||||
let mut depth = 0;
|
||||
let mut seen = Vec::new();
|
||||
while let Some(folder_id) = current {
|
||||
if seen.contains(&folder_id) {
|
||||
break;
|
||||
}
|
||||
seen.push(folder_id);
|
||||
let Some(folder) = s.track(folder_id) else {
|
||||
break;
|
||||
};
|
||||
depth += 1;
|
||||
current = folder.folder;
|
||||
}
|
||||
(x.id.0, x.name.clone(), !x.hidden, x.color, s.edit.selected_tracks.contains(&x.id), depth)
|
||||
})
|
||||
.collect()
|
||||
};
|
||||
let hidden = egui::scroll_area::ScrollBarVisibility::AlwaysHidden;
|
||||
let lists = with_pending_offset(egui::ScrollArea::vertical().id_salt("tracks_scroll"), ui, "tracks_scroll")
|
||||
@@ -56,7 +75,7 @@ pub fn tracks_and_groups(app: &mut SoundApp, ui: &mut Ui) {
|
||||
.auto_shrink([false, false])
|
||||
.scroll_bar_visibility(hidden);
|
||||
let out = lists.show(ui, |ui| {
|
||||
for (id, name, shown, color, sel) in tracks {
|
||||
for (id, name, shown, color, sel, depth) in tracks {
|
||||
let (r, resp) = ui.allocate_exact_size(vec2(ui.available_width(), 17.0), Sense::click_and_drag());
|
||||
resp.widget_info(|| egui::WidgetInfo::selected(egui::Role::Button, true, sel, &name));
|
||||
if sel {
|
||||
@@ -70,7 +89,8 @@ pub fn tracks_and_groups(app: &mut SoundApp, ui: &mut Ui) {
|
||||
}
|
||||
ui.painter().rect_filled(Rect::from_min_size(pos2(r.min.x + 20.0, r.min.y + 3.0), vec2(4.0, 11.0)), 0.0, rgb(color));
|
||||
ui.painter().with_clip_rect(r).text(
|
||||
pos2(r.min.x + 30.0, r.center().y),
|
||||
// Indent stops growing at eight levels so a deep name keeps room in the column.
|
||||
pos2(r.min.x + 30.0 + depth.min(8) as f32 * 10.0, r.center().y),
|
||||
Align2::LEFT_CENTER,
|
||||
&name,
|
||||
regular(11.5),
|
||||
|
||||
@@ -50,6 +50,16 @@ impl Rig {
|
||||
.expect("row not in the Tracks list")
|
||||
}
|
||||
|
||||
fn text_x(&self, name: &str) -> f32 {
|
||||
self.shapes
|
||||
.iter()
|
||||
.find_map(|c| match &c.shape {
|
||||
Shape::Text(t) if t.galley.text() == name && t.pos.x < 150.0 => Some(t.pos.x),
|
||||
_ => None,
|
||||
})
|
||||
.expect("text not in the Tracks list")
|
||||
}
|
||||
|
||||
fn press(&mut self, at: Pos2, pressed: bool) {
|
||||
self.frame(vec![
|
||||
Event::PointerMoved(at),
|
||||
@@ -90,3 +100,35 @@ fn clicking_a_track_list_row_still_selects_the_track() {
|
||||
r.press(at, false);
|
||||
assert_eq!(r.app.engine.session().edit.selected_tracks, vec![r.order()[2]]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn a_track_inside_a_folder_is_indented_in_the_track_list() {
|
||||
let mut r = Rig::new();
|
||||
let child = r.order()[1];
|
||||
let child_name = r.app.engine.session().track(child).unwrap().name.clone();
|
||||
r.app.run("track.move_to_new_folder", json!({"tracks": [child.0], "name": "Folder"})).unwrap();
|
||||
r.frame(vec![]);
|
||||
let folder = r.app.engine.session().tracks.iter().find(|track| track.is_folder()).unwrap();
|
||||
|
||||
assert!(r.text_x(&child_name) > r.text_x(&folder.name), "child is not indented under the folder");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn deeply_nested_tracks_keep_indenting_past_six_folders() {
|
||||
let mut r = Rig::new();
|
||||
let child = r.order()[1];
|
||||
let child_name = r.app.engine.session().track(child).unwrap().name.clone();
|
||||
r.app.run("track.move_to_new_folder", json!({"tracks": [child.0], "name": "Folder 1"})).unwrap();
|
||||
|
||||
let mut parent = r.app.engine.session().tracks.iter().find(|track| track.name == "Folder 1").unwrap().id;
|
||||
for depth in 2..=7 {
|
||||
r.app.run("track.move_to_new_folder", json!({"tracks": [parent.0], "name": format!("Folder {depth}")})).unwrap();
|
||||
parent = r.app.engine.session().tracks.iter().find(|track| track.name == format!("Folder {depth}")).unwrap().id;
|
||||
}
|
||||
r.frame(vec![]);
|
||||
|
||||
// "Folder 1" is the child's own folder and the seventh level; "Folder 7" is the outermost.
|
||||
assert_eq!(r.app.engine.session().track(parent).unwrap().name, "Folder 7");
|
||||
assert!(r.text_x(&child_name) > r.text_x("Folder 1"), "deeply nested child is not indented under its own folder");
|
||||
assert!(r.text_x("Folder 1") > r.text_x("Folder 2"), "each level indents further");
|
||||
}
|
||||
Reference in new issue
Block a user