oxihuman_viewer/
modifier_stack_view.rs1#![allow(dead_code)]
2#[allow(dead_code)]
9#[derive(Debug, Clone)]
10pub struct ModifierSlot {
11 pub id: u32,
12 pub name: String,
13 pub enabled: bool,
14 pub expanded: bool,
15 pub order: u32,
16}
17
18#[allow(dead_code)]
20#[derive(Debug, Clone, Default)]
21pub struct ModifierStackView {
22 pub modifiers: Vec<ModifierSlot>,
23}
24
25#[allow(dead_code)]
27pub fn new_modifier_stack_view() -> ModifierStackView {
28 ModifierStackView::default()
29}
30
31#[allow(dead_code)]
33pub fn add_modifier_slot(view: &mut ModifierStackView, id: u32, name: &str) {
34 let order = view.modifiers.len() as u32;
35 view.modifiers.push(ModifierSlot {
36 id,
37 name: name.to_string(),
38 enabled: true,
39 expanded: false,
40 order,
41 });
42}
43
44#[allow(dead_code)]
46pub fn toggle_modifier(view: &mut ModifierStackView, id: u32) {
47 if let Some(slot) = view.modifiers.iter_mut().find(|m| m.id == id) {
48 slot.enabled = !slot.enabled;
49 }
50}
51
52#[allow(dead_code)]
54pub fn move_modifier_up(view: &mut ModifierStackView, id: u32) {
55 if let Some(pos) = view.modifiers.iter().position(|m| m.id == id) {
56 if pos > 0 {
57 view.modifiers.swap(pos, pos - 1);
58 for (i, m) in view.modifiers.iter_mut().enumerate() {
60 m.order = i as u32;
61 }
62 }
63 }
64}
65
66#[allow(dead_code)]
68pub fn modifier_count(view: &ModifierStackView) -> usize {
69 view.modifiers.len()
70}
71
72#[cfg(test)]
74mod tests {
75 use super::*;
76
77 #[test]
78 fn new_view_is_empty() {
79 let v = new_modifier_stack_view();
80 assert_eq!(modifier_count(&v), 0);
81 }
82
83 #[test]
84 fn add_modifier_increments_count() {
85 let mut v = new_modifier_stack_view();
86 add_modifier_slot(&mut v, 0, "Subsurf");
87 assert_eq!(modifier_count(&v), 1);
88 }
89
90 #[test]
91 fn added_modifier_is_enabled() {
92 let mut v = new_modifier_stack_view();
93 add_modifier_slot(&mut v, 0, "Armature");
94 assert!(v.modifiers[0].enabled);
95 }
96
97 #[test]
98 fn toggle_modifier_flips_enabled() {
99 let mut v = new_modifier_stack_view();
100 add_modifier_slot(&mut v, 1, "Mirror");
101 toggle_modifier(&mut v, 1);
102 assert!(!v.modifiers[0].enabled);
103 }
104
105 #[test]
106 fn toggle_modifier_unknown_id_no_panic() {
107 let mut v = new_modifier_stack_view();
108 toggle_modifier(&mut v, 99); }
110
111 #[test]
112 fn move_modifier_up_changes_order() {
113 let mut v = new_modifier_stack_view();
114 add_modifier_slot(&mut v, 10, "A");
115 add_modifier_slot(&mut v, 11, "B");
116 move_modifier_up(&mut v, 11);
117 assert_eq!(v.modifiers[0].id, 11);
118 }
119
120 #[test]
121 fn move_modifier_up_top_no_change() {
122 let mut v = new_modifier_stack_view();
123 add_modifier_slot(&mut v, 10, "A");
124 move_modifier_up(&mut v, 10); assert_eq!(v.modifiers[0].id, 10);
126 }
127
128 #[test]
129 fn move_modifier_up_unknown_no_panic() {
130 let mut v = new_modifier_stack_view();
131 move_modifier_up(&mut v, 99); }
133
134 #[test]
135 fn modifier_count_multiple() {
136 let mut v = new_modifier_stack_view();
137 for i in 0..5u32 {
138 add_modifier_slot(&mut v, i, "mod");
139 }
140 assert_eq!(modifier_count(&v), 5);
141 }
142
143 #[test]
144 fn order_assigned_sequentially() {
145 let mut v = new_modifier_stack_view();
146 add_modifier_slot(&mut v, 0, "A");
147 add_modifier_slot(&mut v, 1, "B");
148 assert_eq!(v.modifiers[0].order, 0);
149 assert_eq!(v.modifiers[1].order, 1);
150 }
151}