use graphics::character::CharacterCache;
use theme::Theme;
use ui::GlyphCache;
use widget;
pub use graphics::math::Scalar;
pub use self::matrix::Matrix;
pub type Depth = f32;
pub type Dimensions = [Scalar; 2];
pub type Point = [Scalar; 2];
#[derive(Copy, Clone, Debug, PartialEq, RustcEncodable, RustcDecodable)]
pub enum Position {
Absolute(Scalar, Scalar),
Relative(Scalar, Scalar, Option<widget::Index>),
Direction(Direction, Scalar, Option<widget::Index>),
Place(Place, Option<widget::Index>),
}
impl Position {
pub fn default() -> Position{
Position::Direction(Direction::Down, 20.0, None)
}
}
#[derive(Copy, Clone, Debug, RustcEncodable, RustcDecodable, PartialEq, Eq)]
pub enum Direction {
Up,
Down,
Left,
Right,
}
#[derive(Copy, Clone, Debug, RustcEncodable, RustcDecodable, PartialEq, Eq)]
pub struct HorizontalAlign(pub Horizontal, pub Option<widget::Index>);
#[derive(Copy, Clone, Debug, RustcEncodable, RustcDecodable, PartialEq, Eq)]
pub enum Horizontal {
Left,
Middle,
Right,
}
#[derive(Copy, Clone, Debug, RustcEncodable, RustcDecodable, PartialEq, Eq)]
pub struct VerticalAlign(pub Vertical, pub Option<widget::Index>);
#[derive(Copy, Clone, Debug, RustcEncodable, RustcDecodable, PartialEq, Eq)]
pub enum Vertical {
Top,
Middle,
Bottom,
}
#[derive(Copy, Clone, Debug, RustcEncodable, RustcDecodable, PartialEq, Eq)]
pub enum Place {
Middle,
TopLeft,
TopRight,
BottomLeft,
BottomRight,
MidTop,
MidBottom,
MidLeft,
MidRight,
}
pub trait Positionable: Sized {
fn position(self, pos: Position) -> Self;
fn get_position(&self, theme: &Theme) -> Position;
fn point(self, point: Point) -> Self {
self.position(Position::Absolute(point[0], point[1]))
}
fn xy(self, x: Scalar, y: Scalar) -> Self {
self.position(Position::Absolute(x, y))
}
fn relative(self, point: Point) -> Self {
self.position(Position::Relative(point[0], point[1], None))
}
fn relative_xy(self, x: Scalar, y: Scalar) -> Self {
self.position(Position::Relative(x, y, None))
}
fn relative_to<I: Into<widget::Index>>(self, other: I, point: Point) -> Self {
self.position(Position::Relative(point[0], point[1], Some(other.into())))
}
fn relative_xy_to<I: Into<widget::Index>>(self, other: I, x: Scalar, y: Scalar) -> Self {
self.position(Position::Relative(x, y, Some(other.into())))
}
fn down(self, pixels: Scalar) -> Self {
self.position(Position::Direction(Direction::Down, pixels, None))
}
fn up(self, pixels: Scalar) -> Self {
self.position(Position::Direction(Direction::Up, pixels, None))
}
fn left(self, pixels: Scalar) -> Self {
self.position(Position::Direction(Direction::Left, pixels, None))
}
fn right(self, pixels: Scalar) -> Self {
self.position(Position::Direction(Direction::Right, pixels, None))
}
fn down_from<I: Into<widget::Index>>(self, other: I, pixels: Scalar) -> Self {
self.position(Position::Direction(Direction::Down, pixels, Some(other.into())))
}
fn up_from<I: Into<widget::Index>>(self, other: I, pixels: Scalar) -> Self {
self.position(Position::Direction(Direction::Up, pixels, Some(other.into())))
}
fn left_from<I: Into<widget::Index>>(self, other: I, pixels: Scalar) -> Self {
self.position(Position::Direction(Direction::Left, pixels, Some(other.into())))
}
fn right_from<I: Into<widget::Index>>(self, other: I, pixels: Scalar) -> Self {
self.position(Position::Direction(Direction::Right, pixels, Some(other.into())))
}
fn horizontal_align(self, align: HorizontalAlign) -> Self;
fn vertical_align(self, align: VerticalAlign) -> Self;
fn get_horizontal_align(&self, theme: &Theme) -> HorizontalAlign;
fn get_vertical_align(&self, theme: &Theme) -> VerticalAlign;
fn get_alignment(&self, theme: &Theme) -> (HorizontalAlign, VerticalAlign) {
(self.get_horizontal_align(theme), self.get_vertical_align(theme))
}
fn align_left(self) -> Self {
self.horizontal_align(HorizontalAlign(Horizontal::Left, None))
}
fn align_middle_x(self) -> Self {
self.horizontal_align(HorizontalAlign(Horizontal::Middle, None))
}
fn align_right(self) -> Self {
self.horizontal_align(HorizontalAlign(Horizontal::Right, None))
}
fn align_top(self) -> Self {
self.vertical_align(VerticalAlign(Vertical::Top, None))
}
fn align_middle_y(self) -> Self {
self.vertical_align(VerticalAlign(Vertical::Middle, None))
}
fn align_bottom(self) -> Self {
self.vertical_align(VerticalAlign(Vertical::Bottom, None))
}
fn align_left_of<I: Into<widget::Index>>(self, other: I) -> Self {
self.horizontal_align(HorizontalAlign(Horizontal::Left, Some(other.into())))
}
fn align_middle_x_of<I: Into<widget::Index>>(self, other: I) -> Self {
self.horizontal_align(HorizontalAlign(Horizontal::Middle, Some(other.into())))
}
fn align_right_of<I: Into<widget::Index>>(self, other: I) -> Self {
self.horizontal_align(HorizontalAlign(Horizontal::Right, Some(other.into())))
}
fn align_top_of<I: Into<widget::Index>>(self, other: I) -> Self {
self.vertical_align(VerticalAlign(Vertical::Top, Some(other.into())))
}
fn align_middle_y_of<I: Into<widget::Index>>(self, other: I) -> Self {
self.vertical_align(VerticalAlign(Vertical::Middle, Some(other.into())))
}
fn align_bottom_of<I: Into<widget::Index>>(self, other: I) -> Self {
self.vertical_align(VerticalAlign(Vertical::Bottom, Some(other.into())))
}
fn place(self, place: Place, maybe_idx: Option<widget::Index>) -> Self {
self.position(Position::Place(place, maybe_idx))
}
fn middle_of<I: Into<widget::Index>>(self, other: I) -> Self {
self.place(Place::Middle, Some(other.into()))
}
fn top_left_of<I: Into<widget::Index>>(self, other: I) -> Self {
self.place(Place::TopLeft, Some(other.into()))
}
fn top_right_of<I: Into<widget::Index>>(self, other: I) -> Self {
self.place(Place::TopRight, Some(other.into()))
}
fn bottom_left_of<I: Into<widget::Index>>(self, other: I) -> Self {
self.place(Place::BottomLeft, Some(other.into()))
}
fn bottom_right_of<I: Into<widget::Index>>(self, other: I) -> Self {
self.place(Place::BottomRight, Some(other.into()))
}
fn mid_top_of<I: Into<widget::Index>>(self, other: I) -> Self {
self.place(Place::MidTop, Some(other.into()))
}
fn mid_bottom_of<I: Into<widget::Index>>(self, other: I) -> Self {
self.place(Place::MidBottom, Some(other.into()))
}
fn mid_left_of<I: Into<widget::Index>>(self, other: I) -> Self {
self.place(Place::MidLeft, Some(other.into()))
}
fn mid_right_of<I: Into<widget::Index>>(self, other: I) -> Self {
self.place(Place::MidRight, Some(other.into()))
}
fn middle(self) -> Self { self.place(Place::Middle, None) }
fn top_left(self) -> Self { self.place(Place::TopLeft, None) }
fn top_right(self) -> Self { self.place(Place::TopRight, None) }
fn bottom_left(self) -> Self { self.place(Place::BottomLeft, None) }
fn bottom_right(self) -> Self { self.place(Place::BottomRight, None) }
fn mid_top(self) -> Self { self.place(Place::MidTop, None) }
fn mid_bottom(self) -> Self { self.place(Place::MidBottom, None) }
fn mid_left(self) -> Self { self.place(Place::MidLeft, None) }
fn mid_right(self) -> Self { self.place(Place::MidRight, None) }
fn depth(self, depth: Depth) -> Self;
fn get_depth(&self) -> Depth;
}
pub trait Sizeable: Sized {
fn width(self, width: Scalar) -> Self;
fn height(self, height: Scalar) -> Self;
fn get_width<C: CharacterCache>(&self, theme: &Theme, glyph_cache: &GlyphCache<C>) -> Scalar;
fn get_height(&self, theme: &Theme) -> Scalar;
#[inline]
fn dim(self, dim: Dimensions) -> Self {
self.width(dim[0]).height(dim[1])
}
#[inline]
fn dimensions(self, width: Scalar, height: Scalar) -> Self {
self.dim([width, height])
}
fn get_dimensions<C: CharacterCache>(&self, theme: &Theme, glyph_cache: &GlyphCache<C>)
-> Dimensions
{
[self.get_width(theme, glyph_cache), self.get_height(theme)]
}
}
#[derive(Copy, Clone)]
pub enum Corner {
TopLeft,
TopRight,
BottomLeft,
BottomRight,
}
pub fn corner(xy: Point, dim: Dimensions) -> Corner {
use utils::map_range;
let x_perc = map_range(xy[0], -dim[0] / 2.0, dim[0] / 2.0, -1.0, 1.0);
let y_perc = map_range(xy[1], -dim[1] / 2.0, dim[1] / 2.0, -1.0, 1.0);
if x_perc <= 0.0 && y_perc <= 0.0 { Corner::BottomLeft }
else if x_perc > 0.0 && y_perc <= 0.0 { Corner::BottomRight }
else if x_perc <= 0.0 && y_perc > 0.0 { Corner::TopLeft }
else { Corner::TopRight }
}
pub fn align_left_of(target_width: Scalar, width: Scalar) -> Scalar {
width / 2.0 - target_width / 2.0
}
pub fn align_right_of(target_width: Scalar, width: Scalar) -> Scalar {
target_width / 2.0 - width / 2.0
}
pub fn align_bottom_of(target_height: Scalar, height: Scalar) -> Scalar {
height / 2.0 - target_height / 2.0
}
pub fn align_top_of(target_height: Scalar, height: Scalar) -> Scalar {
target_height / 2.0 - height / 2.0
}
impl Horizontal {
pub fn to(&self, target_width: Scalar, width: Scalar) -> Scalar {
match *self {
Horizontal::Left => align_left_of(target_width, width),
Horizontal::Right => align_right_of(target_width, width),
Horizontal::Middle => 0.0,
}
}
}
impl Vertical {
pub fn to(&self, target_height: Scalar, height: Scalar) -> Scalar {
match *self {
Vertical::Top => align_top_of(target_height, height),
Vertical::Bottom => align_bottom_of(target_height, height),
Vertical::Middle => 0.0,
}
}
}
pub fn middle_of(_target: Dimensions, _dim: Dimensions) -> Point {
[0.0, 0.0]
}
pub fn top_left_of(target: Dimensions, dim: Dimensions) -> Point {
[align_left_of(target[0], dim[0]), align_top_of(target[1], dim[1])]
}
pub fn top_right_of(target: Dimensions, dim: Dimensions) -> Point {
[align_right_of(target[0], dim[0]), align_top_of(target[1], dim[1])]
}
pub fn bottom_left_of(target: Dimensions, dim: Dimensions) -> Point {
[align_left_of(target[0], dim[0]), align_bottom_of(target[1], dim[1])]
}
pub fn bottom_right_of(target: Dimensions, dim: Dimensions) -> Point {
[align_right_of(target[0], dim[0]), align_bottom_of(target[1], dim[1])]
}
pub fn mid_top_of(target: Dimensions, dim: Dimensions) -> Point {
[0.0, align_top_of(target[1], dim[1])]
}
pub fn mid_bottom_of(target: Dimensions, dim: Dimensions) -> Point {
[0.0, align_bottom_of(target[1], dim[1])]
}
pub fn mid_left_of(target: Dimensions, dim: Dimensions) -> Point {
[align_left_of(target[0], dim[0]), 0.0]
}
pub fn mid_right_of(target: Dimensions, dim: Dimensions) -> Point {
[align_right_of(target[0], dim[0]), 0.0]
}
impl Place {
pub fn within(&self, target_dim: Dimensions, dim: Dimensions) -> Point {
match *self {
Place::Middle => middle_of(target_dim, dim),
Place::TopLeft => top_left_of(target_dim, dim),
Place::TopRight => top_right_of(target_dim, dim),
Place::BottomLeft => bottom_left_of(target_dim, dim),
Place::BottomRight => bottom_right_of(target_dim, dim),
Place::MidTop => mid_top_of(target_dim, dim),
Place::MidBottom => mid_bottom_of(target_dim, dim),
Place::MidLeft => mid_left_of(target_dim, dim),
Place::MidRight => mid_right_of(target_dim, dim),
}
}
}
#[derive(Copy, Clone, Debug, PartialEq, RustcEncodable, RustcDecodable)]
pub struct Padding {
pub top: f64,
pub bottom: f64,
pub left: f64,
pub right: f64,
}
impl Padding {
pub fn none() -> Padding {
Padding { top: 0.0, bottom: 0.0, left: 0.0, right: 0.0 }
}
pub fn offset_from(&self, place: Place) -> Point {
match place {
Place::Middle => [0.0, 0.0],
Place::TopLeft => [self.left, -self.top],
Place::TopRight => [-self.right, -self.top],
Place::BottomLeft => [self.left, self.bottom],
Place::BottomRight => [-self.right, self.bottom],
Place::MidTop => [0.0, -self.top],
Place::MidBottom => [0.0, self.bottom],
Place::MidLeft => [self.left, 0.0],
Place::MidRight => [-self.right, 0.0],
}
}
}
#[derive(Copy, Clone, Debug, RustcEncodable, RustcDecodable)]
pub struct Margin {
pub top: f64,
pub bottom: f64,
pub left: f64,
pub right: f64,
}
impl Margin {
pub fn none() -> Margin {
Margin { top: 0.0, bottom: 0.0, left: 0.0, right: 0.0 }
}
}
#[derive(Copy, Clone, Debug, PartialEq)]
pub struct Range {
pub start: Scalar,
pub end: Scalar,
}
impl Range {
pub fn new(range: ::std::ops::Range<Scalar>) -> Range {
Range { start: range.start, end: range.end }
}
pub fn from_pos_and_len(pos: Scalar, len: Scalar) -> Range {
let half_len = len / 2.0;
let start = pos - half_len;
let end = pos + half_len;
Range::new(start..end)
}
pub fn magnitude(&self) -> Scalar {
self.end - self.start
}
pub fn len(&self) -> Scalar {
self.magnitude().abs()
}
pub fn middle(&self) -> Scalar {
(self.end + self.start) / 2.0
}
pub fn invert(self) -> Range {
Range { start: self.end, end: self.start }
}
pub fn map_value_to(&self, value: Scalar, other: &Range) -> Scalar {
::utils::map_range(value, self.start, self.end, other.start, other.end)
}
pub fn shift(self, amount: Scalar) -> Range {
Range { start: self.start + amount, end: self.end + amount }
}
pub fn direction(&self) -> Scalar {
if self.start < self.end { 1.0 }
else if self.start > self.end { -1.0 }
else { 0.0 }
}
pub fn undirected(self) -> Range {
if self.start > self.end { self.invert() } else { self }
}
pub fn max(self, other: Range) -> Range {
let start = self.start.min(self.end).min(other.start).min(other.end);
let end = self.start.max(self.end).max(other.start).max(other.end);
Range::new(start..end)
}
pub fn overlap(mut self, mut other: Range) -> Option<Range> {
self = self.undirected();
other = other.undirected();
let start = ::utils::partial_max(self.start, other.start);
let end = ::utils::partial_min(self.end, other.end);
let magnitude = end - start;
if magnitude > 0.0 {
Some(Range::new(start..end))
} else {
None
}
}
pub fn max_directed(self, other: Range) -> Range {
if self.start <= self.end { self.max(other) }
else { self.max(other).invert() }
}
pub fn is_over(&self, pos: Scalar) -> bool {
let Range { start, end } = self.undirected();
pos >= start && pos <= end
}
pub fn round(self) -> Range {
Range::new(self.start.round()..self.end.round())
}
pub fn floor(self) -> Range {
Range::new(self.start.floor()..self.end.floor())
}
pub fn sub_frame(self, frame: Scalar) -> Range {
self.pad(frame)
}
pub fn add_frame(self, frame: Scalar) -> Range {
self.pad(-frame)
}
pub fn pad_start(mut self, pad: Scalar) -> Range {
self.start += if self.start <= self.end { pad } else { -pad };
self
}
pub fn pad_end(mut self, pad: Scalar) -> Range {
self.end += if self.start <= self.end { -pad } else { pad };
self
}
pub fn pad(self, pad: Scalar) -> Range {
self.pad_start(pad).pad_end(pad)
}
pub fn padding(self, start: Scalar, end: Scalar) -> Range {
self.pad_start(start).pad_end(end)
}
}
impl ::std::ops::Add<Range> for Range {
type Output = Range;
fn add(self, rhs: Range) -> Range {
Range::new(self.start + rhs.start .. self.end + rhs.end)
}
}
impl ::std::ops::Sub<Range> for Range {
type Output = Range;
fn sub(self, rhs: Range) -> Range {
Range::new(self.start - rhs.start .. self.end - rhs.end)
}
}
pub type Bounds = Range;
#[derive(Copy, Clone, Debug, PartialEq)]
pub struct Rect {
pub x: Bounds,
pub y: Bounds,
}
impl Rect {
pub fn from_xy_dim(xy: Point, dim: Dimensions) -> Rect {
Rect {
x: Range::from_pos_and_len(xy[0], dim[0]),
y: Range::from_pos_and_len(xy[1], dim[1]),
}
}
pub fn overlap(self, other: Rect) -> Option<Rect> {
self.x.overlap(other.x).and_then(|x| self.y.overlap(other.y).map(|y| Rect { x: x, y: y }))
}
pub fn max(self, other: Rect) -> Rect {
Rect {
x: self.x.max(other.x),
y: self.y.max(other.y),
}
}
pub fn x(&self) -> Scalar {
self.x.middle()
}
pub fn y(&self) -> Scalar {
self.y.middle()
}
pub fn xy(&self) -> Point {
[self.x(), self.y()]
}
pub fn x_y(&self) -> (Scalar, Scalar) {
(self.x(), self.y())
}
pub fn w(&self) -> Scalar {
self.x.len()
}
pub fn h(&self) -> Scalar {
self.y.len()
}
pub fn dim(&self) -> Dimensions {
[self.w(), self.h()]
}
pub fn w_h(&self) -> (Scalar, Scalar) {
(self.w(), self.h())
}
pub fn xy_dim(&self) -> (Point, Dimensions) {
(self.xy(), self.dim())
}
pub fn x_y_w_h(&self) -> (Scalar, Scalar, Scalar, Scalar) {
let (xy, dim) = self.xy_dim();
(xy[0], xy[1], dim[0], dim[1])
}
pub fn len(&self) -> Scalar {
::utils::partial_max(self.w(), self.h())
}
pub fn bottom(&self) -> Scalar {
self.y.undirected().start
}
pub fn top(&self) -> Scalar {
self.y.undirected().end
}
pub fn left(&self) -> Scalar {
self.x.undirected().start
}
pub fn right(&self) -> Scalar {
self.x.undirected().end
}
pub fn shift_x(self, x: Scalar) -> Rect {
Rect { x: self.x.shift(x), ..self }
}
pub fn shift_y(self, y: Scalar) -> Rect {
Rect { y: self.y.shift(y), ..self }
}
pub fn shift(self, xy: Point) -> Rect {
self.shift_x(xy[0]).shift_y(xy[1])
}
pub fn is_over(&self, xy: Point) -> bool {
self.x.is_over(xy[0]) && self.y.is_over(xy[1])
}
pub fn sub_frame(self, frame: Scalar) -> Rect {
Rect {
x: self.x.sub_frame(frame),
y: self.y.sub_frame(frame),
}
}
pub fn add_frame(self, frame: Scalar) -> Rect {
Rect {
x: self.x.add_frame(frame),
y: self.y.add_frame(frame),
}
}
pub fn pad_left(self, pad: Scalar) -> Rect {
Rect { x: self.x.pad_start(pad), ..self }
}
pub fn pad_right(self, pad: Scalar) -> Rect {
Rect { x: self.x.pad_end(pad), ..self }
}
pub fn pad_bottom(self, pad: Scalar) -> Rect {
Rect { y: self.y.pad_start(pad), ..self }
}
pub fn pad_top(self, pad: Scalar) -> Rect {
Rect { y: self.y.pad_end(pad), ..self }
}
pub fn pad(self, pad: Scalar) -> Rect {
let Rect { x, y } = self;
Rect { x: x.pad(pad), y: y.pad(pad) }
}
pub fn padding(self, padding: Padding) -> Rect {
Rect {
x: self.x.padding(padding.left, padding.right),
y: self.y.padding(padding.bottom, padding.top),
}
}
}
impl ::std::ops::Add<Rect> for Rect {
type Output = Rect;
fn add(self, rhs: Rect) -> Rect {
Rect {
x: self.x + rhs.x,
y: self.y + rhs.y,
}
}
}
impl ::std::ops::Sub<Rect> for Rect {
type Output = Rect;
fn sub(self, rhs: Rect) -> Rect {
Rect {
x: self.x - rhs.x,
y: self.y - rhs.y,
}
}
}
pub fn is_over_rect(rect_xy: Point, rect_dim: Dimensions, xy: Point) -> bool {
Rect::from_xy_dim(rect_xy, rect_dim).is_over(xy)
}
pub mod matrix {
use ::{CharacterCache, GlyphCache};
use super::{Depth, Dimensions, HorizontalAlign, VerticalAlign, Point, Position, Positionable,
Scalar, Sizeable};
use theme::Theme;
use ui::{self, Ui};
pub type WidgetNum = usize;
pub type ColNum = usize;
pub type RowNum = usize;
pub type Width = f64;
pub type Height = f64;
pub type PosX = f64;
pub type PosY = f64;
#[derive(Copy, Clone, Debug)]
pub struct Matrix {
cols: usize,
rows: usize,
maybe_position: Option<Position>,
maybe_width: Option<Scalar>,
maybe_height: Option<Scalar>,
maybe_h_align: Option<HorizontalAlign>,
maybe_v_align: Option<VerticalAlign>,
cell_pad_w: Scalar,
cell_pad_h: Scalar,
}
impl Matrix {
pub fn new(cols: usize, rows: usize) -> Matrix {
Matrix {
cols: cols,
rows: rows,
maybe_position: None,
maybe_width: None,
maybe_height: None,
maybe_h_align: None,
maybe_v_align: None,
cell_pad_w: 0.0,
cell_pad_h: 0.0,
}
}
pub fn cell_padding(mut self, w: Scalar, h: Scalar) -> Matrix {
self.cell_pad_w = w;
self.cell_pad_h = h;
self
}
pub fn each_widget<C, F>(self, ui: &mut Ui<C>, mut f: F) where
C: CharacterCache,
F: FnMut(&mut Ui<C>, WidgetNum, ColNum, RowNum, Point, Dimensions),
{
use utils::map_range;
let pos = self.get_position(&ui.theme);
let dim = self.get_dimensions(&ui.theme, &ui.glyph_cache);
let (h_align, v_align) = self.get_alignment(&ui.theme);
if let Some(id) = ui::parent_from_position(ui, pos) {
ui::set_current_parent_idx(ui, id);
}
let xy = ui.get_xy(None, pos, dim, h_align, v_align);
let (half_w, half_h) = (dim[0] / 2.0, dim[1] / 2.0);
let widget_w = dim[0] / self.cols as f64;
let widget_h = dim[1] / self.rows as f64;
let x_min = -half_w + widget_w / 2.0;
let x_max = half_w + widget_w / 2.0;
let y_min = -half_h - widget_h / 2.0;
let y_max = half_h - widget_h / 2.0;
let mut widget_num = 0;
for col in 0..self.cols {
for row in 0..self.rows {
let x = xy[0] + map_range(col as f64, 0.0, self.cols as f64, x_min, x_max);
let y = xy[1] + map_range(row as f64, 0.0, self.rows as f64, y_max, y_min);
let w = widget_w - self.cell_pad_w * 2.0;
let h = widget_h - self.cell_pad_h * 2.0;
f(ui, widget_num, col, row, [x, y], [w, h]);
widget_num += 1;
}
}
}
}
impl Positionable for Matrix {
#[inline]
fn position(mut self, pos: Position) -> Self {
self.maybe_position = Some(pos);
self
}
#[inline]
fn get_position(&self, theme: &Theme) -> Position {
self.maybe_position.unwrap_or(theme.position)
}
#[inline]
fn horizontal_align(mut self, h_align: HorizontalAlign) -> Self {
self.maybe_h_align = Some(h_align);
self
}
#[inline]
fn vertical_align(mut self, v_align: VerticalAlign) -> Self {
self.maybe_v_align = Some(v_align);
self
}
#[inline]
fn get_horizontal_align(&self, theme: &Theme) -> HorizontalAlign {
self.maybe_h_align.unwrap_or(theme.align.horizontal)
}
#[inline]
fn get_vertical_align(&self, theme: &Theme) -> VerticalAlign {
self.maybe_v_align.unwrap_or(theme.align.vertical)
}
#[inline]
fn depth(self, _: Depth) -> Self {
unimplemented!();
}
#[inline]
fn get_depth(&self) -> Depth {
unimplemented!();
}
}
impl Sizeable for Matrix {
#[inline]
fn width(mut self, w: f64) -> Self {
self.maybe_width = Some(w);
self
}
#[inline]
fn height(mut self, h: f64) -> Self {
self.maybe_height = Some(h);
self
}
#[inline]
fn get_width<C: CharacterCache>(&self, theme: &Theme, _: &GlyphCache<C>) -> f64 {
const DEFAULT_WIDTH: Scalar = 256.0;
self.maybe_width.or_else(|| {
theme.maybe_matrix.as_ref()
.map(|default| default.common.maybe_width.unwrap_or(DEFAULT_WIDTH))
}).unwrap_or(DEFAULT_WIDTH)
}
#[inline]
fn get_height(&self, theme: &Theme) -> f64 {
const DEFAULT_HEIGHT: Scalar = 256.0;
self.maybe_height.or_else(|| {
theme.maybe_matrix.as_ref()
.map(|default| default.common.maybe_height.unwrap_or(DEFAULT_HEIGHT))
}).unwrap_or(DEFAULT_HEIGHT)
}
}
}