Skip to content

Commit

Permalink
Fix Oval::is_over to correctly distinguish between OvalSections
Browse files Browse the repository at this point in the history
  • Loading branch information
mitchmindtree committed Dec 6, 2017
1 parent 59dbfab commit f3e6c0a
Showing 1 changed file with 35 additions and 4 deletions.
39 changes: 35 additions & 4 deletions src/widget/primitive/shape/oval.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,15 +23,20 @@ pub struct Oval<S> {
}

/// Types that may be used to describe the visible section of the `Oval`.
pub trait OvalSection: 'static + Copy + PartialEq + Send {}
pub trait OvalSection: 'static + Copy + PartialEq + Send {
/// The function used to determine if a point is over the oval section widget.
const IS_OVER: widget::IsOverFn;
}

/// The entire `Oval` will be drawn.
///
/// To draw only a section of the oval, use the `section` builder method.
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub struct Full;

impl OvalSection for Full {}
impl OvalSection for Full {
const IS_OVER: widget::IsOverFn = is_over_widget;
}

/// A section of the oval will be drawn where the section is specified by the given radians.
///
Expand All @@ -46,7 +51,9 @@ pub struct Section {
pub offset_radians: Scalar,
}

impl OvalSection for Section {}
impl OvalSection for Section {
const IS_OVER: widget::IsOverFn = is_over_section_widget;
}

/// Unique state for the **Oval**.
#[derive(Copy, Clone, Debug, PartialEq)]
Expand Down Expand Up @@ -141,14 +148,17 @@ where
}

fn is_over(&self) -> widget::IsOverFn {
is_over_widget
S::IS_OVER
}

fn update(self, args: widget::UpdateArgs<Self>) -> Self::Event {
let widget::UpdateArgs { state, .. } = args;
if state.resolution != self.resolution {
state.update(|state| state.resolution = self.resolution);
}
if state.section != self.section {
state.update(|state| state.section = self.section);
}
}
}

Expand Down Expand Up @@ -305,3 +315,24 @@ pub fn is_over(r: Rect, p: Point) -> bool {
pub fn is_over_widget(widget: &graph::Container, point: Point, _: &Theme) -> widget::IsOver {
is_over(widget.rect, point).into()
}

/// Returns whether or not the given point is over the section described
pub fn is_over_section(circumference: Circumference, p: Point) -> bool {
widget::triangles::is_over(circumference.triangles(), p)
}

/// The function to use for picking whether a given point is over the oval section.
pub fn is_over_section_widget(widget: &graph::Container, p: Point, _: &Theme) -> widget::IsOver {
widget
.state_and_style::<State<Section>, Style>()
.map(|unique| {
let res = unique.state.resolution;
let offset_rad = unique.state.section.offset_radians;
let rad = unique.state.section.radians;
let circumference = Circumference::new_section(widget.rect, res, rad)
.offset_radians(offset_rad);
is_over_section(circumference, p)
})
.unwrap_or_else(|| widget.rect.is_over(p))
.into()
}

0 comments on commit f3e6c0a

Please sign in to comment.