use widget;
use Ui;
pub use self::range::{Edge, Range};
pub use self::rect::{Corner, Rect};
pub mod range;
pub mod rect;
pub type Scalar = f64;
pub type Depth = f32;
pub type Dimensions = [Scalar; 2];
pub type Point = [Scalar; 2];
pub type Margin = Scalar;
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub enum Axis {
X,
Y,
}
#[derive(Copy, Clone, Debug, PartialEq)]
pub enum Position {
Absolute(Scalar),
Relative(Relative, Option<widget::Id>),
}
#[derive(Copy, Clone, Debug, PartialEq)]
pub enum Relative {
Scalar(Scalar),
Align(Align),
Direction(Direction, Scalar),
Place(Place),
}
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub enum Direction {
Forwards,
Backwards,
}
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub enum Align {
Start,
Middle,
End,
}
#[derive(Copy, Clone, Debug, PartialEq)]
pub enum Place {
Start(Option<Margin>),
Middle,
End(Option<Margin>),
}
#[derive(Copy, Clone, Debug, PartialEq)]
pub enum Dimension {
Absolute(Scalar),
Of(widget::Id, Option<Scalar>),
KidAreaOf(widget::Id, Option<Scalar>),
}
pub trait Positionable: Sized {
fn x_position(self, x: Position) -> Self;
fn y_position(self, y: Position) -> Self;
fn get_x_position(&self, ui: &Ui) -> Position;
fn get_y_position(&self, ui: &Ui) -> Position;
fn x(self, x: Scalar) -> Self {
self.x_position(Position::Absolute(x))
}
fn y(self, y: Scalar) -> Self {
self.y_position(Position::Absolute(y))
}
fn xy(self, point: Point) -> Self {
self.x(point[0]).y(point[1])
}
fn x_y(self, x: Scalar, y: Scalar) -> Self {
self.xy([x, y])
}
fn x_position_relative(self, x: Relative) -> Self {
self.x_position(Position::Relative(x, None))
}
fn y_position_relative(self, y: Relative) -> Self {
self.y_position(Position::Relative(y, None))
}
fn x_y_position_relative(self, x: Relative, y: Relative) -> Self {
self.x_position_relative(x).y_position_relative(y)
}
fn x_position_relative_to(self, other: widget::Id, x: Relative) -> Self {
self.x_position(Position::Relative(x, Some(other)))
}
fn y_position_relative_to(self, other: widget::Id, y: Relative) -> Self {
self.y_position(Position::Relative(y, Some(other)))
}
fn x_y_position_relative_to(self, other: widget::Id, x: Relative, y: Relative) -> Self {
self.x_position_relative_to(other, x)
.y_position_relative_to(other, y)
}
fn x_relative(self, x: Scalar) -> Self {
self.x_position_relative(Relative::Scalar(x))
}
fn y_relative(self, y: Scalar) -> Self {
self.y_position_relative(Relative::Scalar(y))
}
fn xy_relative(self, point: Point) -> Self {
self.x_relative(point[0]).y_relative(point[1])
}
fn x_y_relative(self, x: Scalar, y: Scalar) -> Self {
self.xy_relative([x, y])
}
fn x_relative_to(self, other: widget::Id, x: Scalar) -> Self {
self.x_position_relative_to(other, Relative::Scalar(x))
}
fn y_relative_to(self, other: widget::Id, y: Scalar) -> Self {
self.y_position_relative_to(other, Relative::Scalar(y))
}
fn xy_relative_to(self, other: widget::Id, xy: Point) -> Self {
self.x_relative_to(other, xy[0]).y_relative_to(other, xy[1])
}
fn x_y_relative_to(self, other: widget::Id, x: Scalar, y: Scalar) -> Self {
self.xy_relative_to(other, [x, y])
}
fn x_direction(self, direction: Direction, x: Scalar) -> Self {
self.x_position_relative(Relative::Direction(direction, x))
}
fn y_direction(self, direction: Direction, y: Scalar) -> Self {
self.y_position_relative(Relative::Direction(direction, y))
}
fn down(self, y: Scalar) -> Self {
self.y_direction(Direction::Backwards, y)
}
fn up(self, y: Scalar) -> Self {
self.y_direction(Direction::Forwards, y)
}
fn left(self, x: Scalar) -> Self {
self.x_direction(Direction::Backwards, x)
}
fn right(self, x: Scalar) -> Self {
self.x_direction(Direction::Forwards, x)
}
fn x_direction_from(self, other: widget::Id, direction: Direction, x: Scalar) -> Self {
self.x_position_relative_to(other, Relative::Direction(direction, x))
}
fn y_direction_from(self, other: widget::Id, direction: Direction, y: Scalar) -> Self {
self.y_position_relative_to(other, Relative::Direction(direction, y))
}
fn down_from(self, other: widget::Id, y: Scalar) -> Self {
self.y_direction_from(other, Direction::Backwards, y)
}
fn up_from(self, other: widget::Id, y: Scalar) -> Self {
self.y_direction_from(other, Direction::Forwards, y)
}
fn left_from(self, other: widget::Id, x: Scalar) -> Self {
self.x_direction_from(other, Direction::Backwards, x)
}
fn right_from(self, other: widget::Id, x: Scalar) -> Self {
self.x_direction_from(other, Direction::Forwards, x)
}
fn x_align(self, align: Align) -> Self {
self.x_position_relative(Relative::Align(align))
}
fn y_align(self, align: Align) -> Self {
self.y_position_relative(Relative::Align(align))
}
fn align_left(self) -> Self {
self.x_align(Align::Start)
}
fn align_middle_x(self) -> Self {
self.x_align(Align::Middle)
}
fn align_right(self) -> Self {
self.x_align(Align::End)
}
fn align_top(self) -> Self {
self.y_align(Align::End)
}
fn align_middle_y(self) -> Self {
self.y_align(Align::Middle)
}
fn align_bottom(self) -> Self {
self.y_align(Align::Start)
}
fn x_align_to(self, other: widget::Id, align: Align) -> Self {
self.x_position_relative_to(other, Relative::Align(align))
}
fn y_align_to(self, other: widget::Id, align: Align) -> Self {
self.y_position_relative_to(other, Relative::Align(align))
}
fn align_left_of(self, other: widget::Id) -> Self {
self.x_align_to(other, Align::Start)
}
fn align_middle_x_of(self, other: widget::Id) -> Self {
self.x_align_to(other, Align::Middle)
}
fn align_right_of(self, other: widget::Id) -> Self {
self.x_align_to(other, Align::End)
}
fn align_top_of(self, other: widget::Id) -> Self {
self.y_align_to(other, Align::End)
}
fn align_middle_y_of(self, other: widget::Id) -> Self {
self.y_align_to(other, Align::Middle)
}
fn align_bottom_of(self, other: widget::Id) -> Self {
self.y_align_to(other, Align::Start)
}
fn x_place_on(self, other: widget::Id, place: Place) -> Self {
self.x_position_relative_to(other, Relative::Place(place))
}
fn y_place_on(self, other: widget::Id, place: Place) -> Self {
self.y_position_relative_to(other, Relative::Place(place))
}
fn middle_of(self, other: widget::Id) -> Self {
self.x_place_on(other, Place::Middle)
.y_place_on(other, Place::Middle)
}
fn top_left_of(self, other: widget::Id) -> Self {
self.x_place_on(other, Place::Start(None))
.y_place_on(other, Place::End(None))
}
fn top_left_with_margin_on(self, other: widget::Id, mgn: Scalar) -> Self {
self.x_place_on(other, Place::Start(Some(mgn)))
.y_place_on(other, Place::End(Some(mgn)))
}
fn top_left_with_margins_on(self, other: widget::Id, top: Scalar, left: Scalar) -> Self {
self.x_place_on(other, Place::Start(Some(left)))
.y_place_on(other, Place::End(Some(top)))
}
fn top_right_of(self, other: widget::Id) -> Self {
self.x_place_on(other, Place::End(None))
.y_place_on(other, Place::End(None))
}
fn top_right_with_margin_on(self, other: widget::Id, mgn: Scalar) -> Self {
self.x_place_on(other, Place::End(Some(mgn)))
.y_place_on(other, Place::End(Some(mgn)))
}
fn top_right_with_margins_on(self, other: widget::Id, top: Scalar, right: Scalar) -> Self {
self.x_place_on(other, Place::End(Some(right)))
.y_place_on(other, Place::End(Some(top)))
}
fn bottom_left_of(self, other: widget::Id) -> Self {
self.x_place_on(other, Place::Start(None))
.y_place_on(other, Place::Start(None))
}
fn bottom_left_with_margin_on(self, other: widget::Id, mgn: Scalar) -> Self {
self.x_place_on(other, Place::Start(Some(mgn)))
.y_place_on(other, Place::Start(Some(mgn)))
}
fn bottom_left_with_margins_on(self, other: widget::Id, bottom: Scalar, left: Scalar) -> Self {
self.x_place_on(other, Place::Start(Some(left)))
.y_place_on(other, Place::Start(Some(bottom)))
}
fn bottom_right_of(self, other: widget::Id) -> Self {
self.x_place_on(other, Place::End(None))
.y_place_on(other, Place::Start(None))
}
fn bottom_right_with_margin_on(self, other: widget::Id, mgn: Scalar) -> Self {
self.x_place_on(other, Place::End(Some(mgn)))
.y_place_on(other, Place::Start(Some(mgn)))
}
fn bottom_right_with_margins_on(
self,
other: widget::Id,
bottom: Scalar,
right: Scalar,
) -> Self {
self.x_place_on(other, Place::End(Some(right)))
.y_place_on(other, Place::Start(Some(bottom)))
}
fn mid_top_of(self, other: widget::Id) -> Self {
self.x_place_on(other, Place::Middle)
.y_place_on(other, Place::End(None))
}
fn mid_top_with_margin_on(self, other: widget::Id, mgn: Scalar) -> Self {
self.x_place_on(other, Place::Middle)
.y_place_on(other, Place::End(Some(mgn)))
}
fn mid_bottom_of(self, other: widget::Id) -> Self {
self.x_place_on(other, Place::Middle)
.y_place_on(other, Place::Start(None))
}
fn mid_bottom_with_margin_on(self, other: widget::Id, mgn: Scalar) -> Self {
self.x_place_on(other, Place::Middle)
.y_place_on(other, Place::Start(Some(mgn)))
}
fn mid_left_of(self, other: widget::Id) -> Self {
self.x_place_on(other, Place::Start(None))
.y_place_on(other, Place::Middle)
}
fn mid_left_with_margin_on(self, other: widget::Id, mgn: Scalar) -> Self {
self.x_place_on(other, Place::Start(Some(mgn)))
.y_place_on(other, Place::Middle)
}
fn mid_right_of(self, other: widget::Id) -> Self {
self.x_place_on(other, Place::End(None))
.y_place_on(other, Place::Middle)
}
fn mid_right_with_margin_on(self, other: widget::Id, mgn: Scalar) -> Self {
self.x_place_on(other, Place::End(Some(mgn)))
.y_place_on(other, Place::Middle)
}
fn x_place(self, place: Place) -> Self {
self.x_position_relative(Relative::Place(place))
}
fn y_place(self, place: Place) -> Self {
self.y_position_relative(Relative::Place(place))
}
fn middle(self) -> Self {
self.x_place(Place::Middle).y_place(Place::Middle)
}
fn top_left(self) -> Self {
self.x_place(Place::Start(None)).y_place(Place::End(None))
}
fn top_left_with_margin(self, mgn: Scalar) -> Self {
self.x_place(Place::Start(Some(mgn)))
.y_place(Place::End(Some(mgn)))
}
fn top_left_with_margins(self, top: Scalar, left: Scalar) -> Self {
self.x_place(Place::Start(Some(left)))
.y_place(Place::End(Some(top)))
}
fn top_right(self) -> Self {
self.x_place(Place::End(None)).y_place(Place::End(None))
}
fn top_right_with_margin(self, mgn: Scalar) -> Self {
self.x_place(Place::End(Some(mgn)))
.y_place(Place::End(Some(mgn)))
}
fn top_right_with_margins(self, top: Scalar, right: Scalar) -> Self {
self.x_place(Place::End(Some(right)))
.y_place(Place::End(Some(top)))
}
fn bottom_left(self) -> Self {
self.x_place(Place::Start(None)).y_place(Place::Start(None))
}
fn bottom_left_with_margin(self, mgn: Scalar) -> Self {
self.x_place(Place::Start(Some(mgn)))
.y_place(Place::Start(Some(mgn)))
}
fn bottom_left_with_margins(self, bottom: Scalar, left: Scalar) -> Self {
self.x_place(Place::Start(Some(left)))
.y_place(Place::Start(Some(bottom)))
}
fn bottom_right(self) -> Self {
self.x_place(Place::End(None)).y_place(Place::Start(None))
}
fn bottom_right_with_margin(self, mgn: Scalar) -> Self {
self.x_place(Place::End(Some(mgn)))
.y_place(Place::Start(Some(mgn)))
}
fn bottom_right_with_margins(self, bottom: Scalar, right: Scalar) -> Self {
self.x_place(Place::End(Some(right)))
.y_place(Place::Start(Some(bottom)))
}
fn mid_top(self) -> Self {
self.x_place(Place::Middle).y_place(Place::End(None))
}
fn mid_top_with_margin(self, mgn: Scalar) -> Self {
self.x_place(Place::Middle).y_place(Place::End(Some(mgn)))
}
fn mid_bottom(self) -> Self {
self.x_place(Place::Middle).y_place(Place::Start(None))
}
fn mid_bottom_with_margin(self, mgn: Scalar) -> Self {
self.x_place(Place::Middle).y_place(Place::Start(Some(mgn)))
}
fn mid_left(self) -> Self {
self.x_place(Place::Start(None)).y_place(Place::Middle)
}
fn mid_left_with_margin(self, mgn: Scalar) -> Self {
self.x_place(Place::Start(Some(mgn))).y_place(Place::Middle)
}
fn mid_right(self) -> Self {
self.x_place(Place::End(None)).y_place(Place::Middle)
}
fn mid_right_with_margin(self, mgn: Scalar) -> Self {
self.x_place(Place::End(Some(mgn))).y_place(Place::Middle)
}
fn depth(self, depth: Depth) -> Self;
fn get_depth(&self) -> Depth;
}
pub trait Sizeable: Sized {
fn x_dimension(self, x: Dimension) -> Self;
fn y_dimension(self, x: Dimension) -> Self;
fn get_x_dimension(&self, ui: &Ui) -> Dimension;
fn get_y_dimension(&self, ui: &Ui) -> Dimension;
fn w(self, w: Scalar) -> Self {
self.x_dimension(Dimension::Absolute(w))
}
fn h(self, h: Scalar) -> Self {
self.y_dimension(Dimension::Absolute(h))
}
fn wh(self, wh: Dimensions) -> Self {
self.w(wh[0]).h(wh[1])
}
fn w_h(self, width: Scalar, height: Scalar) -> Self {
self.wh([width, height])
}
fn w_of(self, idx: widget::Id) -> Self {
self.x_dimension(Dimension::Of(idx.into(), None))
}
fn padded_w_of(self, idx: widget::Id, pad: Scalar) -> Self {
self.x_dimension(Dimension::Of(idx.into(), Some(pad)))
}
fn h_of(self, idx: widget::Id) -> Self {
self.y_dimension(Dimension::Of(idx.into(), None))
}
fn padded_h_of(self, idx: widget::Id, pad: Scalar) -> Self {
self.y_dimension(Dimension::Of(idx.into(), Some(pad)))
}
fn wh_of(self, idx: widget::Id) -> Self {
self.w_of(idx).h_of(idx)
}
fn padded_wh_of(self, idx: widget::Id, pad: Scalar) -> Self {
self.padded_w_of(idx, pad).padded_h_of(idx, pad)
}
fn kid_area_w_of(self, idx: widget::Id) -> Self {
self.x_dimension(Dimension::KidAreaOf(idx.into(), None))
}
fn padded_kid_area_w_of(self, idx: widget::Id, pad: Scalar) -> Self {
self.x_dimension(Dimension::KidAreaOf(idx.into(), Some(pad)))
}
fn kid_area_h_of(self, idx: widget::Id) -> Self {
self.y_dimension(Dimension::KidAreaOf(idx.into(), None))
}
fn padded_kid_area_h_of(self, idx: widget::Id, pad: Scalar) -> Self {
self.y_dimension(Dimension::KidAreaOf(idx.into(), Some(pad)))
}
fn kid_area_wh_of(self, idx: widget::Id) -> Self {
self.kid_area_w_of(idx).kid_area_h_of(idx)
}
fn padded_kid_area_wh_of(self, idx: widget::Id, pad: Scalar) -> Self {
self.padded_kid_area_w_of(idx, pad)
.padded_kid_area_h_of(idx, pad)
}
fn get_w(&self, ui: &Ui) -> Option<Scalar> {
match self.get_x_dimension(ui) {
Dimension::Absolute(width) => Some(width),
Dimension::Of(idx, None) => ui.w_of(idx),
Dimension::Of(idx, Some(pad)) => ui.w_of(idx).map(|w| w - pad * 2.0),
Dimension::KidAreaOf(idx, None) => ui.kid_area_of(idx).map(|r| r.w()),
Dimension::KidAreaOf(idx, Some(pad)) => ui.kid_area_of(idx).map(|r| r.w() - pad * 2.0),
}
}
fn get_h(&self, ui: &Ui) -> Option<Scalar> {
match self.get_y_dimension(ui) {
Dimension::Absolute(height) => Some(height),
Dimension::Of(idx, None) => ui.h_of(idx),
Dimension::Of(idx, Some(pad)) => ui.h_of(idx).map(|w| w - pad * 2.0),
Dimension::KidAreaOf(idx, None) => ui.kid_area_of(idx).map(|r| r.h()),
Dimension::KidAreaOf(idx, Some(pad)) => ui.kid_area_of(idx).map(|r| r.h() - pad * 2.0),
}
}
fn get_wh(&self, ui: &Ui) -> Option<Dimensions> {
self.get_w(ui).and_then(|w| self.get_h(ui).map(|h| [w, h]))
}
}
#[derive(Copy, Clone, Debug, PartialEq)]
pub struct Padding {
pub x: Range,
pub y: Range,
}
impl Padding {
pub fn none() -> Padding {
Padding {
x: Range::new(0.0, 0.0),
y: Range::new(0.0, 0.0),
}
}
}