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],
];