1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110
macro_rules! vectors { ($([$size:tt $type:ident $kind:ident]),+$(,)*) => {$(paste::item!{ mod [<$kind$type$size>] { use crate::prelude::*; impl<'control, 'resource: 'control> InspectControl<'control, 'resource> for &'control mut [<Vector$size>]<$type> { type SystemData = (); type Builder = Builder<'control>; } pub struct Builder<'control> { pub value: &'control mut [<Vector$size>]<$type>, pub label: Option<&'control imgui::ImStr>, pub speed: f32, pub null_to: $type, pub changed: Option<&'control mut bool>, } impl<'control, 'resource: 'control> InspectControlBuilder<'control, 'resource, &'control mut [<Vector$size>]<$type>> for Builder<'control> { fn new(value: &'control mut [<Vector$size>]<$type>) -> Self { Self { value, label: None, speed: 1., null_to: <$type as Default>::default(), changed: None } } fn label(mut self, label: &'control imgui::ImStr) -> Self { self.label = Some(label); self } fn changed(mut self, changed: &'control mut bool) -> Self { self.changed = Some(changed); self } fn build(self) { amethyst_imgui::with(|ui| { let mut changed = false; let label = self.label.unwrap(); ui.push_id(label); let spacing = ui.imgui().style().item_inner_spacing.x; let width = ((ui.get_window_size().0 - spacing * (($size - 1) as f32 * 1.5)) * 0.65) / $size as f32; for i in 0 .. $size { ui.with_id(i as i32, || { ui.with_item_width(width, || { let mut v = self.value[i as usize] as _; changed = ui.[<drag_$kind>](im_str!(""), &mut v).speed(self.speed).min(std::$type::MIN as _).max(std::$type::MAX as _).build() || changed; self.value[i as usize] = v as _; if ui.is_item_hovered() && ui.imgui().is_mouse_down(imgui::ImMouseButton::Right) { changed = true; self.value[i as usize] = self.null_to; } ui.same_line_spacing(0., spacing); }); }); } ui.text(label); ui.pop_id(); if let Some(x) = self.changed { *x = *x || changed }; }); } } impl<'control> Builder<'control> { pub fn speed(mut self, speed: f32) -> Self { self.speed = speed; self } pub fn null_to(mut self, null_to: $type) -> Self { self.null_to = null_to; self } } } })+}; } vectors![ [2 f32 float], [3 f32 float], [4 f32 float], [2 f64 float], [3 f64 float], [4 f64 float], [2 u8 int], [3 u8 int], [4 u8 int], [2 u16 int], [3 u16 int], [4 u16 int], [2 u32 int], [3 u32 int], [4 u32 int], [2 u64 int], [3 u64 int], [4 u64 int], [2 usize int], [3 usize int], [4 usize int], [2 i8 int], [3 i8 int], [4 i8 int], [2 i16 int], [3 i16 int], [4 i16 int], [2 i32 int], [3 i32 int], [4 i32 int], [2 i64 int], [3 i64 int], [4 i64 int], ];