diff --git a/src/coord/category.rs b/src/coord/category.rs index 805bad2c..165090a4 100644 --- a/src/coord/category.rs +++ b/src/coord/category.rs @@ -2,7 +2,7 @@ use std::fmt; use std::ops::Range; use std::rc::Rc; -use super::{AsRangedCoord, Ranged}; +use super::{AsRangedCoord, DiscreteRanged, Ranged}; /// The category coordinate pub struct Category { @@ -22,10 +22,33 @@ impl Clone for Category { } } +impl std::cmp::PartialEq for Category { + fn eq(&self, other: &Self) -> bool { + self.name == other.name && self.elements == other.elements && self.idx == other.idx + } +} + +impl std::hash::Hash for Category { + fn hash(&self, state: &mut H) + where + H: std::hash::Hasher, + { + self.name.hash(state); + self.idx.hash(state); + self.elements.iter().for_each(|ele| ele.hash(state)); + } +} + +impl std::cmp::Eq for Category {} + impl fmt::Debug for Category { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - let element = &self.elements[self.idx as usize]; - write!(f, "{}", element) + if self.idx < 0 { + write!(f, "{}", "NO VALUE") + } else { + let element = &self.elements[self.idx as usize]; + write!(f, "{}", element) + } } } @@ -172,6 +195,37 @@ impl Ranged for Category { } } +impl DiscreteRanged for Category { + type RangeParameter = (); + + fn get_range_parameter(&self) {} + + /// Get the smallest value that is larger than the `this` value + fn next_value(this: &Self::ValueType, _param: &()) -> Self::ValueType { + let mut out = this.clone(); + out.idx = match out.idx { + // Any negative number (ie. -1) should return 0 (the start) + idx if idx < 0 => 0, + // If we've hit the end of the range, start again + idx if idx as usize >= out.elements.len() => 0, + // Otherwise just increase idx + idx => idx + 1, + }; + out + } + + /// Get the largest value that is smaller than `this` value + fn previous_value(this: &Self::ValueType, _param: &()) -> Self::ValueType { + let mut out = this.clone(); + out.idx -= 1; + if out.idx < 0 { + // If we need to wrap around + out.idx = (out.elements.len() - 1) as i32; + } + out + } +} + impl AsRangedCoord for Category { type CoordDescType = Self; type Value = Category; diff --git a/src/drawing/backend_impl/piston.rs b/src/drawing/backend_impl/piston.rs index 4a579056..02605fcb 100644 --- a/src/drawing/backend_impl/piston.rs +++ b/src/drawing/backend_impl/piston.rs @@ -34,6 +34,14 @@ fn make_point_pair(a: BackendCoord, b: BackendCoord, scale: f64) -> [f64; 4] { ] } +fn make_circle(center: BackendCoord, radius: u32, scale: f64) -> [f64; 4] { + circle( + center.0 as f64 * scale, + center.1 as f64 * scale, + radius as f64 * scale, + ) +} + impl<'a, 'b> PistonBackend<'a, 'b> { pub fn new(size: (u32, u32), scale: f64, context: Context, graphics: &'b mut G2d<'a>) -> Self { Self { @@ -150,7 +158,7 @@ impl<'a, 'b> DrawingBackend for PistonBackend<'a, 'b> { style: &S, fill: bool, ) -> Result<(), DrawingErrorKind> { - let rect = circle(center.0 as f64, center.1 as f64, radius as f64); + let rect = make_circle(center, radius, self.scale); if fill { ellipse( make_piston_rgba(&style.as_color()), @@ -204,3 +212,13 @@ pub fn draw_piston_window Result<(), Box