use crate::prelude::*;
use crate::render::primitive_kind::PrimitiveKind;
use crate::widget;
use crate::draw::shape::triangle::Triangle;
use crate::render::util::new_primitive;
use crate::draw::shape::circumference::{Circumference, Triangles};
#[derive(Debug, Clone, Widget)]
pub struct Oval<S, GS> where S: 'static + Clone, GS: GlobalState {
pub id: Uuid,
pub resolution: usize,
pub section: S,
position: Point,
dimension: Dimensions,
color: Color,
pub children: Vec<Box<dyn Widget<GS>>>
}
impl<S: 'static + Clone, GS: GlobalState> WidgetExt<GS> for Oval<S, GS> {}
impl<S: 'static + Clone, GS: GlobalState> Layout<GS> for Oval<S, GS> {
fn flexibility(&self) -> u32 {
0
}
fn calculate_size(&mut self, requested_size: Dimensions, env: &Environment<GS>) -> Dimensions {
for child in &mut self.children {
child.calculate_size(requested_size, env);
}
self.dimension = requested_size;
requested_size
}
fn position_children(&mut self) {
let positioning = BasicLayouter::Center.position();
let position = self.position;
let dimension = self.dimension;
for child in &mut self.children {
positioning(position, dimension, child);
child.position_children();
}
}
}
impl<S: 'static + Clone, K: GlobalState> CommonWidget<K> for Oval<S, K> {
fn get_id(&self) -> Uuid {
self.id
}
fn get_flag(&self) -> Flags {
Flags::EMPTY
}
fn get_children(&self) -> WidgetIter<K> {
self.children
.iter()
.rfold(WidgetIter::Empty, |acc, x| {
if x.get_flag() == Flags::PROXY {
WidgetIter::Multi(Box::new(x.get_children()), Box::new(acc))
} else {
WidgetIter::Single(x, Box::new(acc))
}
})
}
fn get_children_mut(&mut self) -> WidgetIterMut<K> {
self.children
.iter_mut()
.rfold(WidgetIterMut::Empty, |acc, x| {
if x.get_flag() == Flags::PROXY {
WidgetIterMut::Multi(Box::new(x.get_children_mut()), Box::new(acc))
} else {
WidgetIterMut::Single(x, Box::new(acc))
}
})
}
fn get_proxied_children(&mut self) -> WidgetIterMut<K> {
self.children.iter_mut()
.rfold(WidgetIterMut::Empty, |acc, x| {
WidgetIterMut::Single(x, Box::new(acc))
})
}
fn get_position(&self) -> Point {
self.position
}
fn set_position(&mut self, position: Dimensions) {
self.position = position;
}
fn get_dimension(&self) -> Dimensions {
self.dimension
}
fn set_dimension(&mut self, dimensions: Dimensions) {
self.dimension = dimensions
}
}
impl<S: 'static + Clone, GS: GlobalState> Render<GS> for Oval<S, GS> {
fn get_primitives(&mut self, fonts: &text::font::Map) -> Vec<Primitive> {
let points = widget::oval::circumference(Rect::new(self.position, self.dimension), DEFAULT_RESOLUTION);
let mut triangles: Vec<Triangle<Point>> = Vec::new();
triangles.extend(points.triangles());
let kind = PrimitiveKind::TrianglesSingleColor {
color: self.color.to_rgb(),
triangles,
};
let mut prims: Vec<Primitive> = vec![new_primitive(kind, Rect::new(self.position, self.dimension))];
prims.extend(Rectangle::<GS>::debug_outline(Rect::new(self.position, self.dimension), 1.0));
let children: Vec<Primitive> = self.get_children_mut().flat_map(|f| f.get_primitives(fonts)).collect();
prims.extend(children);
return prims;
}
}
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub struct Full;
#[derive(Copy, Clone, Debug, PartialEq)]
pub struct Section {
pub radians: Scalar,
pub offset_radians: Scalar,
}
#[derive(Copy, Clone, Debug, PartialEq)]
pub struct State<S> {
pub resolution: usize,
pub section: S,
}
pub const DEFAULT_RESOLUTION: usize = 50;
impl<S: GlobalState> Oval<Full, S> {
pub fn fill(mut self, color: Color) -> Box<Self> {
self.color = color;
Box::new(self)
}
pub fn initialize(children: Vec<Box<dyn Widget<S>>>) -> Box<Oval<Full, S>> {
Box::new(Oval {
id: Uuid::new_v4(),
resolution: 0,
section: Full,
position: [0.0, 0.0],
dimension: [100.0,100.0],
color: Color::random(),
children
})
}
pub fn new(position: Point, dimension: Dimensions, children: Vec<Box<dyn Widget<S>>>) -> Box<Oval<Full, S>> {
Box::new(Oval {
id: Uuid::new_v4(),
children,
position,
dimension,
resolution: 0,
section: Full,
color: Color::random()
})
}
}
impl<S: Clone, K: GlobalState> Oval<S, K> {
pub fn resolution(mut self, resolution: usize) -> Self {
self.resolution = resolution;
self
}
pub fn section(self, radians: Scalar) -> Oval<Section, K> {
let Oval { resolution, .. } = self;
let section = Section { radians, offset_radians: 0.0 };
Oval { id: Uuid::new_v4(), resolution, section, position: [10.0, 10.0], dimension: [10.0,10.0], color: Color::random(), children: vec![] }
}
}
impl<K: GlobalState> Oval<Section, K> {
pub fn offset_radians(mut self, offset_radians: Scalar) -> Self {
self.section.offset_radians = offset_radians;
self
}
}
pub fn circumference(rect: Rect, resolution: usize) -> Circumference {
Circumference::new(rect, resolution)
}
pub fn triangles(rect: Rect, resolution: usize) -> Triangles {
circumference(rect, resolution).triangles()
}
impl Iterator for Triangles {
type Item = Triangle<Point>;
fn next(&mut self) -> Option<Self::Item> {
let Triangles { ref mut points, ref mut last } = *self;
points.next().map(|next| {
let triangle = Triangle([points.point, *last, next]);
*last = next;
triangle
})
}
}