conrod 0.36.0

An easy-to-use, extensible 2D GUI library
Documentation
use {Backend, CharacterCache, Dimension, GlyphCache};
use graph::{self, NodeIndex};
use position::{Align, Depth, Dimensions, Padding, Position, Positionable, Rect, Sizeable};
use std;
use theme::{self, Theme};
use ui::{self, Ui, UiCell};

pub use self::id::Id;
pub use self::index::Index;

// Macro providing modules.
#[macro_use] mod builder;
#[macro_use] mod style;

// Widget functionality modules.
mod id;
mod index;
pub mod scroll;

// Primitive widget modules.
pub mod primitive;

// Widget modules.
pub mod button;
pub mod canvas;
pub mod drop_down_list;
pub mod envelope_editor;
pub mod matrix;
pub mod number_dialer;
pub mod scrollbar;
pub mod slider;
pub mod tabs;
pub mod text_box;
pub mod text_edit;
pub mod title_bar;
pub mod toggle;
pub mod xy_pad;


/// Arguments for the [**Widget::update**](./trait.Widget#method.update) method in a struct to
/// simplify the method signature.
pub struct UpdateArgs<'a, 'b: 'a, W, B: 'a>
    where W: Widget,
          B: Backend,
{
    /// The **Widget**'s unique index.
    pub idx: Index,
    /// The **Widget**'s parent unique index, if there is one.
    pub maybe_parent_idx: Option<Index>,
    /// The **Widget**'s previous state. Specifically, the state that is common between all widgets,
    /// such as positioning, floatability, draggability, etc.
    pub prev: &'a CommonState,
    /// A wrapper around the **Widget**'s unique state, providing methods for both immutably viewing
    /// and mutably updating the state.
    ///
    /// We wrap mutation in a method so that we can keep track of whether or not the unique state
    /// has been updated.
    ///
    /// If **State::update** is called, we assume that there has been some mutation and in turn
    /// will require re-drawing the **Widget**. Thus, it is recommended that you *only* call
    /// **State::update** if you need to update the unique state in some way.
    pub state: &'a mut State<'b, W::State>,
    /// The rectangle describing the **Widget**'s area.
    pub rect: Rect,
    /// The **Widget**'s current **Widget::Style**.
    pub style: &'a W::Style,
    /// Restricted access to the `Ui`.
    ///
    /// Provides methods for immutably accessing the `Ui`'s `Theme` and `GlyphCache`.  Also allows
    /// calling `Widget::set` within the `Widget::update` method.
    pub ui: UiCell<'a, B>,
}

/// A small cache for a single unique **NodeIndex**.
///
/// This should be used by **Widget**s within their unique **State** for instantiating their own
/// unique widgets.
///
/// This should reduce the need for users to directly call `UiCell::new_unique_node_index` and in
/// turn reduce related mistakes (i.e. accidentally calling it and growing the graph unnecessarily).
#[derive(Clone, Debug, PartialEq)]
pub struct IndexSlot {
    maybe_idx: std::cell::Cell<Option<NodeIndex>>,
}

/// Arguments to the [**Widget::kid_area**](./trait.Widget#method.kid_area) method in a struct to
/// simplify the method signature.
pub struct KidAreaArgs<'a, W, C: 'a>
    where W: Widget,
{
    /// The **Rect** describing the **Widget**'s position and dimensions.
    pub rect: Rect,
    /// Current **Widget::Style** of the **Widget**.
    pub style: &'a W::Style,
    /// The active **Theme** within the **Ui**.
    pub theme: &'a Theme,
    /// The **Ui**'s **GlyphCache** (for determining text width).
    pub glyph_cache: &'a GlyphCache<C>,
}

/// The area upon which a **Widget**'s child widgets will be placed.
#[derive(Copy, Clone, Debug, PartialEq)]
pub struct KidArea {
    /// The **Rect** bounds describing the position and area.
    pub rect: Rect,
    /// The distance between the edge of the area and where the widgets will be placed.
    pub pad: Padding,
}

/// The builder argument for the **Widget**'s parent.
#[derive(Copy, Clone, Debug, PartialEq)]
pub enum MaybeParent {
    /// The user specified the widget should not have any parents, so the Root will be used.
    None,
    /// The user gave a specific parent widget.
    Some(Index),
    /// No parent widget was specified, so we will assume they want the last parent.
    Unspecified,
}

impl MaybeParent {
    /// Convert the **MaybeParent** into an **Option<Index>**.
    ///
    /// If `Unspecified`, check the positioning to retrieve the **Index** from there.
    ///
    /// If `None`, the `Ui`'s `window` widget will be used.
    ///
    /// **Note:** This method does not check whether or not using the `window` widget as the parent
    /// would cause a cycle. If it is important that the inferred parent should not cause a cycle,
    /// use `get` instead.
    pub fn get_unchecked<B>(&self, ui: &Ui<B>, x_pos: Position, y_pos: Position) -> Index
        where B: Backend,
    {
        match *self {
            MaybeParent::Some(idx) => idx,
            MaybeParent::None => ui.window.into(),
            MaybeParent::Unspecified => ui::infer_parent_unchecked(ui, x_pos, y_pos),
        }
    }

    /// The same as `get_unchecked`, but checks whether or not the widget that we're inferring the
    /// parent for is the `Ui`'s window (which cannot have a parent, without creating a cycle).
    pub fn get<B>(&self, idx: Index, ui: &Ui<B>, x_pos: Position, y_pos: Position) -> Option<Index>
        where B: Backend,
    {
        if idx == ui.window.into() {
            None
        } else {
            Some(self.get_unchecked(ui, x_pos, y_pos))
        }
    }
}

/// State necessary for "floating" (pop-up style) widgets.
#[derive(Copy, Clone, Debug, PartialEq)]
pub struct Floating {
    /// The time the **Widget** was last clicked (used for depth sorting in the widget **Graph**).
    pub time_last_clicked: std::time::Instant,
}

/// A struct containing builder data common to all **Widget** types.
///
/// This type also allows us to do a blanket impl of **Positionable** and **Sizeable** for `T: Widget`.
///
/// When Rust gets some sort of field inheritance feature, this will most likely be refactored to
/// take advantage of that.
#[derive(Clone, Copy, Debug)]
pub struct CommonBuilder {
    /// Styling and positioning data that is common between all widget types.
    pub style: CommonStyle,
    /// The parent widget of the Widget.
    pub maybe_parent_idx: MaybeParent,
    /// Whether or not the Widget is a "floating" Widget.
    pub is_floating: bool,
    /// Whether or not the children of this **Widget** should be cropped to its `kid_area`.
    ///
    /// By default, the kid_area is the size of the entire widget, though it may be specified
    /// otherwise via the `Widget::kid_area` method.
    pub crop_kids: bool,
    /// Arguments to the scrolling of the widget's *x* axis.
    pub maybe_x_scroll: Option<scroll::Scroll>,
    /// Arguments to the scrolling of the widget's *y* axis.
    pub maybe_y_scroll: Option<scroll::Scroll>,
    /// Whether or not the **Widget** should be placed on the kid_area.
    ///
    /// If `true`, the **Widget** will be placed on the `kid_area` of the parent **Widget** if the
    /// **Widget** is given a **Place** variant for its **Position**.
    ///
    /// If `false`, the **Widget** will be placed on the parent **Widget**'s *total* area.
    pub place_on_kid_area: bool,
    /// Describes whether or not the **Widget** is instantiated as a graphical element for some
    /// other **Widget**.
    ///
    /// When adding an edge *a -> b* where *b* is considered to be a graphical element of *a*,
    /// several things are implied about *b*:
    ///
    /// - If *b* is picked within either **Graph::pick_widget** or
    /// **Graph::pick_top_scrollable_widget**, it will instead return the index for *a*.
    /// - When determining the **Graph::scroll_offset** for *b*, *a*'s scrolling (if it is
    /// scrollable, that is) will be skipped.
    /// - *b* will always be placed upon *a*'s total area, rather than its kid_area which is the
    /// default.
    /// - Any **Graphic** child of *b* will be considered as a **Graphic** child of *a*.
    pub maybe_graphics_for: Option<Index>,
}

/// Styling and positioning data that is common between all widget types.
#[derive(Clone, Copy, Debug)]
pub struct CommonStyle {
    /// The width of a Widget.
    pub maybe_x_dimension: Option<Dimension>,
    /// The height of a Widget.
    pub maybe_y_dimension: Option<Dimension>,
    /// The position of a Widget along the *x* axis.
    pub maybe_x_position: Option<Position>,
    /// The position of a Widget along the *y* axis.
    pub maybe_y_position: Option<Position>,
    /// The rendering Depth of the Widget.
    pub maybe_depth: Option<Depth>,
}

/// A wrapper around a **Widget**'s unique **Widget::State**.
///
/// This type is used to provide limited access to the **Widget::State** within the
/// [**Widget::update**](./trait.Widget#method.update) method (to which it is passed via the
/// [**UpdateArgs**](./struct.UpdateArgs)).
///
/// The type provides only two methods. One for viewing the state, the other for mutating it.
///
/// We do this so that we can keep track of whether or not the **Widget::State** has been mutated
/// (using an internal `has_updated` flag). This allows us to know whether or not we need to
/// re-draw the **Widget**, without having to compare the previous and new **Widget::State**s.
#[derive(Debug)]
pub struct State<'a, T: 'a> {
    state: &'a mut T,
    /// A flag indicating whether or not the widget's State has been updated.
    has_updated: bool,
}

/// A wrapper around state that is common to all **Widget** types.
#[derive(Copy, Clone, Debug, PartialEq)]
pub struct CommonState {
    /// The rectangle describing the `Widget`'s area.
    pub rect: Rect,
    /// The rendering depth for the Widget (the default is 0.0).
    pub depth: Depth,
    /// Floating state for the widget if it is floating.
    pub maybe_floating: Option<Floating>,
    /// The area of the widget upon which kid widgets are placed.
    pub kid_area: KidArea,
}

/// A **Widget**'s state in a form that is retrievable from the **Ui**'s widget cache.
pub struct Cached<W>
    where W: Widget,
{
    /// State that is unique to the Widget.
    pub state: W::State,
    /// Unique styling state for the Widget.
    pub style: W::Style,
    /// The rectangle representing the Widget's area.
    pub rect: Rect,
    /// Previous rendering depth of the Widget.
    pub depth: Depth,
    /// The area in which child widgets are placed.
    pub kid_area: KidArea,
    /// Whether or not the Widget is a "floating" Widget.
    pub maybe_floating: Option<Floating>,
    /// The state for a widget's scrollable *x* axis.
    pub maybe_x_scroll_state: Option<scroll::StateX>,
    /// The state for a widget's scrollable *y* axis.
    pub maybe_y_scroll_state: Option<scroll::StateY>,
}

/// A unique identifier for a **Widget** type.
///
/// Note: This might be replaced with **Any::get_type_id** when it stabilises.
pub type Kind = &'static str;

/// **Widget** data to be cached prior to the **Widget::update** call in the **set_widget**
/// function.
///
/// We do this so that if this **Widget** were to internally `set` some other **Widget**s, this
/// **Widget**'s positioning and dimension data already exists within the widget **Graph** for
/// reference.
#[allow(missing_copy_implementations)]
pub struct PreUpdateCache {
    /// The **Widget**'s unique kind.
    pub kind: Kind,
    /// The **Widget**'s unique Index.
    pub idx: Index,
    /// The **Widget**'s parent's unique index (if it has a parent).
    pub maybe_parent_idx: Option<Index>,
    /// If this **Widget** is relatively positioned to another **Widget**, this will be the index
    /// of the **Widget** to which this **Widget** is relatively positioned along the *x* axis.
    pub maybe_x_positioned_relatively_idx: Option<Index>,
    /// If this **Widget** is relatively positioned to another **Widget**, this will be the index
    /// of the **Widget** to which this **Widget** is relatively positioned along the *y* axis.
    pub maybe_y_positioned_relatively_idx: Option<Index>,
    /// The **Rect** describing the **Widget**'s position and dimensions.
    pub rect: Rect,
    /// The z-axis depth - affects the render order of sibling widgets.
    pub depth: Depth,
    /// The area upon which the **Widget**'s children widgets will be placed.
    pub kid_area: KidArea,
    /// Floating data for the **Widget** if there is some.
    pub maybe_floating: Option<Floating>,
    /// Whether or not the children of the **Widget** should be cropped to its `kid_area`.
    pub crop_kids: bool,
    /// Scrolling data for the **Widget**'s *x* axis if there is some.
    pub maybe_x_scroll_state: Option<scroll::StateX>,
    /// Scrolling data for the **Widget**'s *y* axis if there is some.
    pub maybe_y_scroll_state: Option<scroll::StateY>,
    /// Whether or not the **Widget** has been instantiated as a graphical element for some other
    /// widget.
    pub maybe_graphics_for: Option<Index>,
}

/// **Widget** data to be cached after the **Widget::update** call in the **set_widget**
/// function.
///
/// We do this so that if this **Widget** were to internally **Widget::set** some other
/// **Widget**s, this **Widget**'s positioning and dimension data will already exist within the
/// widget **Graph** for reference.
pub struct PostUpdateCache<W>
    where W: Widget,
{
    /// The **Widget**'s unique **Index**.
    pub idx: Index,
    /// The **Widget**'s parent's unique **Index** (if it has a parent).
    pub maybe_parent_idx: Option<Index>,
    /// The newly produced unique **Widget::State** associated with the **Widget**.
    pub state: W::State,
    /// The newly produced unique **Widget::Style** associated with the **Widget**.
    pub style: W::Style,
}


/// The necessary bounds for a **Widget**'s associated **Style** type.
pub trait Style: std::any::Any + std::fmt::Debug + PartialEq + Sized {}

/// Auto-implement the **Style** trait for all applicable types.
impl<T> Style for T where T: std::any::Any + std::fmt::Debug + PartialEq + Sized {}


/// Determines the default **Dimension** for a **Widget**.
///
/// This function checks for a default dimension in the following order.
/// 1. Check for a default value within the **Ui**'s **Theme**.
/// 2. Otherwise attempts to copy the dimension of the previously set widget if there is one.
/// 3. Otherwise attempts to copy the dimension of our parent widget.
/// 4. If no parent widget can be inferred, the window dimensions are used.
fn default_dimension<W, B, F>(widget: &W, ui: &Ui<B>, f: F) -> Dimension
    where W: Widget,
          B: Backend,
          F: FnOnce(theme::UniqueDefault<W::Style>) -> Option<Dimension>,
{
    ui.theme.widget_style::<W::Style>(widget.unique_kind())
        .and_then(f)
        .or_else(|| ui.maybe_prev_widget().map(|idx| Dimension::Of(idx, None)))
        .unwrap_or_else(|| {
            let x_pos = widget.get_x_position(ui);
            let y_pos = widget.get_y_position(ui);
            let parent_idx = widget.common().maybe_parent_idx.get_unchecked(ui, x_pos, y_pos);
            Dimension::Of(parent_idx, None)
        })
}

/// Determines the default **Dimension** for a **Widget**.
///
/// This function checks for a default dimension in the following order.
/// 1. Check for a default value within the **Ui**'s **Theme**.
/// 2. Otherwise attempts to copy the dimension of the previously set widget if there is one.
/// 3. Otherwise attempts to copy the dimension of our parent widget.
/// 4. If no parent widget can be inferred, the window dimensions are used.
///
/// This is called by the default implementations of **Widget::default_x_dimension**.
///
/// If you wish to override **Widget::default_x_dimension**, feel free to call this function
/// internally if you partly require the bahaviour of the default implementations.
pub fn default_x_dimension<W, B>(widget: &W, ui: &Ui<B>) -> Dimension
    where W: Widget,
          B: Backend,
{
    default_dimension(widget, ui, |default| default.common.maybe_x_dimension)
}

/// Determines the default **Dimension** for a **Widget**.
///
/// This function checks for a default dimension in the following order.
/// 1. Check for a default value within the **Ui**'s **Theme**.
/// 2. Otherwise attempts to copy the dimension of the previously set widget if there is one.
/// 3. Otherwise attempts to copy the dimension of our parent widget.
/// 4. If no parent widget can be inferred, the window dimensions are used.
///
/// This is called by the default implementations of **Widget::default_y_dimension**.
///
/// If you wish to override **Widget::default_y_dimension**, feel free to call this function
/// internally if you partly require the bahaviour of the default implementations.
pub fn default_y_dimension<W, B>(widget: &W, ui: &Ui<B>) -> Dimension
    where W: Widget,
          B: Backend,
{
    default_dimension(widget, ui, |default| default.common.maybe_y_dimension)
}


/// A trait to be implemented by all **Widget** types.
///
/// A type that implements **Widget** can be thought of as a collection of arguments to the
/// **Widget**'s **Widget::update** method. They type itself is not stored between updates, but
/// rather is used to update an instance of the **Widget**'s **Widget::State**, which *is* stored.
///
/// Methods that *must* be overridden:
///
/// - common
/// - common_mut
/// - unique_kind
/// - init_state
/// - style
/// - update
///
/// Methods that can be optionally overridden:
///
/// - default_x_position
/// - default_y_position
/// - default_width
/// - default_height
/// - drag_area
/// - kid_area
///
/// Methods that should not be overridden:
///
/// - floating
/// - scroll_kids
/// - scroll_kids_vertically
/// - scroll_kids_horizontally
/// - place_widget_on_kid_area
/// - parent
/// - no_parent
/// - set
pub trait Widget: Sized {
    /// State to be stored within the `Ui`s widget cache.
    ///
    /// Take advantage of this type for any large allocations that you would like to avoid
    /// repeating between updates, or any calculations that you'd like to avoid repeating between
    /// calls to `update`.
    ///
    /// Conrod will never clone the state, it will only ever be moved.
    type State: std::any::Any + PartialEq + std::fmt::Debug;
    /// Every widget is required to have its own associated `Style` type. This type is intended to
    /// contain high-level styling information for the widget that can be *optionally specified* by
    /// a user of the widget.
    ///
    /// All `Style` structs are typically `Copy` and contain simple, descriptive fields like
    /// `color`, `font_size`, `line_spacing`, `frame_width`, etc. These types are also required to
    /// be `PartialEq`. This is so that the `Ui` may automatically compare the previous style to
    /// the new style each time `.set` is called, allowing conrod to automatically determine
    /// whether or not something has changed and if a re-draw is required.
    ///
    /// Each field in a `Style` struct is typically an `Option<T>`. This is so that each field may
    /// be *optionally specified*, indicating to fall back to defaults if the fields are `None`
    /// upon style retrieval.
    ///
    /// The reason this data is required to be in its own `Style` type (rather than in the widget
    /// type itself) is so that conrod can distinguish between default style data that may be
    /// stored within the `Theme`'s `widget_styling`, and other data that is necessary for the
    /// widget's behaviour logic. Having `Style` be an associated type makes it trivial to retrieve
    /// unique, widget-specific styling data for each widget from a single method (see
    /// [`Theme::widget_style`](./theme/struct.Theme.html#method.widget_style)).
    ///
    /// These types are often quite similar and can involve a lot of boilerplate when written by
    /// hand due to rust's lack of field inheritance. To get around this, conrod provides
    /// [`widget_style!`][1] - a macro that vastly simplifies the definition and implementation of
    /// widget `Style` types.
    ///
    /// Conrod doesn't yet support serializing widget styling with the `Theme` type, but we hope to
    /// soon.
    ///
    /// # Examples
    ///
    /// ```
    /// # extern crate conrod;
    /// # use conrod::{Color, FontSize, Scalar};
    /// # fn main() {}
    /// /// Unique styling for a Button widget.
    /// pub struct Style {
    ///     /// Color of the Button's pressable area.
    ///     pub color: Option<Color>,
    ///     /// Width of the frame surrounding the button.
    ///     pub frame: Option<Scalar>,
    ///     /// The color of the Button's rectangular frame.
    ///     pub frame_color: Option<Color>,
    ///     /// The color of the Button's label.
    ///     pub label_color: Option<Color>,
    ///     /// The font size for the Button's label.
    ///     pub label_font_size: Option<FontSize>,
    /// }
    /// ```
    ///
    /// Note: It is recommended that you don't write these types yourself as it can get tedious.
    /// Instead, we suggest using the [`widget_style!`][1] macro which also provides all necessary
    /// style retrieval method implementations.
    ///
    /// [1]: ./macro.widget_style!.html
    type Style: Style;

    /// Return a reference to a **CommonBuilder** struct owned by the Widget.
    /// This method allows us to do a blanket impl of Positionable and Sizeable for T: Widget.
    ///
    /// Note: When rust introduces field inheritance, we will move the **CommonBuilder**
    /// accordingly (perhaps under a different name).
    fn common(&self) -> &CommonBuilder;

    /// Return a mutable reference to a CommonBuilder struct owned by the Widget.
    /// This method allows us to do a blanket impl of Positionable and Sizeable for T: Widget.
    ///
    /// Note: When rust introduces field inheritance, we will move the **CommonBuilder**
    /// accordingly (perhaps under a different name).
    fn common_mut(&mut self) -> &mut CommonBuilder;

    /// Return the kind of the widget as a &'static str.
    ///
    /// Note that this must be unique from all other widgets' "unique kinds".
    ///
    /// This is used by conrod to help avoid WidgetId errors and to provide better messages for
    /// those that do occur.
    fn unique_kind(&self) -> Kind;

    /// Return the initial **State** of the Widget.
    ///
    /// The `Ui` will only call this once, shortly prior to the first time that **Widget::update**
    /// is first called.
    fn init_state(&self) -> Self::State;

    /// Return the styling of the widget.
    ///
    /// The `Ui` will call this once prior to each `update`. It does this so that it can check for
    /// differences in `Style` in case we need to re-draw the widget.
    fn style(&self) -> Self::Style;

    /// Update our **Widget**'s unique **Widget::State** via the **State** wrapper type (the
    /// `state` field within the [**UpdateArgs**](./struct.UpdateArgs)).
    ///
    /// Whenever [**State::update**](./struct.State.html#method.update) is called, a `has_updated`
    /// flag is set within the **State**, indicating that there has been some change to the unique
    /// **Widget::State** and that we require re-drawing the **Widget**. As a result, widget
    /// designers should only call **State::update** when necessary, checking whether or not the
    /// state has changed before invoking the method. See the custom_widget.rs example for a
    /// demonstration of this.
    ///
    /// # Arguments
    /// * idx - The `Widget`'s unique index (whether `Public` or `Internal`).
    /// * prev - The previous common state of the Widget. If this is the first time **update** is
    /// called, `Widget::init_state` will be used to produce some intial state instead.
    /// * state - A wrapper around the `Widget::State`. See the [**State** docs](./struct.State)
    /// for more details.
    /// * rect - The position (centered) and dimensions of the widget.
    /// * style - The style produced by the `Widget::style` method.
    /// * ui - A wrapper around the `Ui`, offering restricted access to its functionality. See the
    /// docs for `UiCell` for more details.
    fn update<B: Backend>(self, args: UpdateArgs<Self, B>);

    /// The default **Position** for the widget along the *x* axis.
    ///
    /// This is used when no **Position** is explicitly given when instantiating the Widget.
    fn default_x_position<B: Backend>(&self, ui: &Ui<B>) -> Position {
        ui.theme.widget_style::<Self::Style>(self.unique_kind())
            .and_then(|style| style.common.maybe_x_position)
            .unwrap_or(ui.theme.x_position)
    }

    /// The default **Position** for the widget along the *y* axis.
    ///
    /// This is used when no **Position** is explicitly given when instantiating the Widget.
    fn default_y_position<B: Backend>(&self, ui: &Ui<B>) -> Position {
        ui.theme.widget_style::<Self::Style>(self.unique_kind())
            .and_then(|style| style.common.maybe_y_position)
            .unwrap_or(ui.theme.y_position)
    }

    /// The default width for the **Widget**.
    ///
    /// This method is only used if no height is explicitly given.
    ///
    /// By default, this simply calls [**default_dimension**](./fn.default_dimension) with a
    /// fallback absolute dimension of 0.0.
    fn default_x_dimension<B: Backend>(&self, ui: &Ui<B>) -> Dimension {
        default_x_dimension(self, ui)
    }

    /// The default height of the widget.
    ///
    /// By default, this simply calls [**default_dimension**](./fn.default_dimension) with a
    /// fallback absolute dimension of 0.0.
    fn default_y_dimension<B: Backend>(&self, ui: &Ui<B>) -> Dimension {
        default_y_dimension(self, ui)
    }

    /// If the widget is draggable, implement this method and return the position and dimensions of
    /// the draggable space. The position should be relative to the center of the widget.
    fn drag_area(&self,
                 _dim: Dimensions,
                 _style: &Self::Style,
                 _theme: &Theme) -> Option<Rect>
    {
        None
    }

    /// The area on which child widgets will be placed when using the `Place` `Position` methods.
    fn kid_area<C: CharacterCache>(&self, args: KidAreaArgs<Self, C>) -> KidArea {
        KidArea {
            rect: args.rect,
            pad: Padding::none(),
        }
    }


    // None of the following methods should require overriding. Perhaps they should be split off
    // into a separate trait which is impl'ed for W: Widget to make this clearer?
    // Most of them would benefit by some sort of field inheritance as they are mainly just used to
    // set sommon data.


    /// Set the parent widget for this Widget by passing the WidgetId of the parent.
    ///
    /// This will attach this Widget to the parent widget.
    fn parent<I: Into<Index>>(mut self, parent_idx: I) -> Self {
        self.common_mut().maybe_parent_idx = MaybeParent::Some(parent_idx.into());
        self
    }

    /// Specify that this widget has no parent widgets.
    fn no_parent(mut self) -> Self {
        self.common_mut().maybe_parent_idx = MaybeParent::None;
        self
    }

    /// Set whether or not the **Widget** should be placed on the kid_area.
    ///
    /// If `true`, the **Widget** will be placed on the `kid_area` of the parent **Widget** if the
    /// **Widget** is given a **Place** variant for its **Position**.
    ///
    /// If `false`, the **Widget** will be placed on the parent **Widget**'s *total* area.
    ///
    /// By default, conrod will automatically determine this for you by checking whether or not the
    /// **Widget** that our **Widget** is being placed upon returns `Some` from its
    /// **Widget::kid_area** method.
    fn place_on_kid_area(mut self, b: bool) -> Self {
        self.common_mut().place_on_kid_area = b;
        self
    }

    /// Indicates that the **Widget** is used as a non-interactive graphical element for some other
    /// widget.
    ///
    /// This is useful for **Widget**s that are used to compose some other **Widget**.
    ///
    /// When adding an edge *a -> b* where *b* is considered to be a graphical element of *a*,
    /// several things are implied about *b*:
    ///
    /// - If *b* is picked within either **Graph::pick_widget** or
    /// **Graph::pick_top_scrollable_widget**, it will instead return the index for *a*.
    /// - When determining the **Graph::scroll_offset** for *b*, *a*'s scrolling (if it is
    /// scrollable, that is) will be skipped.
    /// - *b* will always be placed upon *a*'s total area, rather than its kid_area which is the
    /// default.
    /// - Any **Graphic** child of *b* will be considered as a **Graphic** child of *a*.
    fn graphics_for<I: Into<Index>>(mut self, idx: I) -> Self {
        self.common_mut().maybe_graphics_for = Some(idx.into());
        self
    }

    /// Set whether or not the widget is floating (the default is `false`).
    /// A typical example of a floating widget would be a pop-up or alert window.
    ///
    /// A "floating" widget will always be rendered *after* its parent tree and all widgets
    /// connected to its parent tree. If two sibling widgets are both floating, then the one that
    /// was last clicked will be rendered last. If neither are clicked, they will be rendered in
    /// the order in which they were cached into the `Ui`.
    fn floating(mut self, is_floating: bool) -> Self {
        self.common_mut().is_floating = is_floating;
        self
    }

    /// Indicates that all widgets who are children of this widget should be cropped to the
    /// `kid_area` of this widget.
    fn crop_kids(mut self) -> Self {
        self.common_mut().crop_kids = true;
        self
    }

    /// Makes the widget's `KidArea` scrollable.
    ///
    /// If a widget is scrollable and it has children widgets that fall outside of its `KidArea`,
    /// the `KidArea` will become scrollable.
    ///
    /// This method calls `Widget::crop_kids` internally.
    fn scroll_kids(self) -> Self {
        self.scroll_kids_vertically().scroll_kids_horizontally().crop_kids()
    }

    /// Makes the widget's `KidArea` scrollable.
    ///
    /// If a widget is scrollable and it has children widgets that fall outside of its `KidArea`,
    /// the `KidArea` will become scrollable.
    ///
    /// This method calls `Widget::crop_kids` internally.
    fn scroll_kids_vertically(mut self) -> Self {
        self.common_mut().maybe_y_scroll = Some(scroll::Scroll::new());
        self.crop_kids()
    }

    /// Set whether or not the widget's `KidArea` is scrollable (the default is false).
    ///
    /// If a widget is scrollable and it has children widgets that fall outside of its `KidArea`,
    /// the `KidArea` will become scrollable.
    ///
    /// This method calls `Widget::crop_kids` internally.
    fn scroll_kids_horizontally(mut self) -> Self {
        self.common_mut().maybe_x_scroll = Some(scroll::Scroll::new());
        self.crop_kids()
    }

    /// A builder method that "lifts" the **Widget** through the given `build` function.
    ///
    /// This method is solely for providing slight ergonomic improvement by helping to maintain
    /// the symmetry of the `builder` pattern in some cases.
    #[inline]
    fn and<F>(self, build: F) -> Self
        where F: FnOnce(Self) -> Self,
    {
        build(self)
    }

    /// A builder method that mutates the **Widget** with the given `mutate` function.
    ///
    /// This method is solely for providing slight ergonomic improvement by helping to maintain
    /// the symmetry of the `builder` pattern in some cases.
    #[inline]
    fn and_mut<F>(mut self, mutate: F) -> Self
        where F: FnOnce(&mut Self),
    {
        mutate(&mut self);
        self
    }

    /// A method that conditionally builds the **Widget** with the given `build` function.
    ///
    /// If `cond` is `true`, `build(self)` is evaluated and returned.
    ///
    /// If `false`, `self` is returned.
    #[inline]
    fn and_if<F>(self, cond: bool, build: F) -> Self
        where F: FnOnce(Self) -> Self,
    {
        if cond { build(self) } else { self }
    }

    /// A method that optionally builds the the **Widget** with the given `build` function.
    ///
    /// If `maybe` is `Some(t)`, `build(self, t)` is evaluated and returned.
    ///
    /// If `None`, `self` is returned.
    #[inline]
    fn and_then<T, F>(self, maybe: Option<T>, build: F) -> Self
        where F: FnOnce(Self, T) -> Self,
    {
        if let Some(t) = maybe { build(self, t) } else { self }
    }

    /// Note: There should be no need to override this method.
    ///
    /// After building the widget, you call this method to set its current state into the given
    /// `Ui`. More precisely, the following will occur when calling this method:
    /// - The widget's previous state and style will be retrieved.
    /// - The widget's current `Style` will be retrieved (from the `Widget::style` method).
    /// - The widget's state will be updated (using the `Widget::udpate` method).
    /// - If the widget's state or style has changed, the **Ui** will be notified that the widget
    /// needs to be re-drawn.
    /// - The new State and Style will be cached within the `Ui`.
    fn set<'a, 'b, I, B>(self, idx: I, ui_cell: &'a mut UiCell<'b, B>)
        where I: Into<Index>,
              B: Backend,
    {
        let idx: Index = idx.into();
        let ui: &'a mut Ui<B> = ui::ref_mut_from_ui_cell(ui_cell);
        set_widget(self, idx, ui);
    }

}



/// Updates the given widget and caches it within the given `Ui`'s `widget_graph`.
///
/// If it is the first time a widget has been set, it will be cached into the `Ui`'s widget_graph.
/// For all following occasions, the pre-existing cached state will be compared and updated.
///
/// Note that this is a very imperative, mutation oriented segment of code. We try to move as much
/// imperativeness and mutation out of the users hands and into this function as possible, so that
/// users have a clear, consise, purely functional `Widget` API. As a result, we try to keep this
/// as verbosely annotated as possible. If anything is unclear, feel free to post an issue or PR
/// with concerns/improvements to the github repo.
fn set_widget<B, W>(widget: W, idx: Index, ui: &mut Ui<B>)
    where B: Backend,
          W: Widget,
{
    let kind = widget.unique_kind();

    // Take the previous state of the widget from the cache if there is some to collect.
    let maybe_widget_state: Option<Cached<W>> = {

        // If the cache is already initialised for a widget of a different kind, warn the user.
        let check_container_kind = |container: &mut graph::Container| {
            use std::io::Write;
            if container.kind != kind {
                writeln!(std::io::stderr(),
                         "A widget of a different kind already exists at the given WidgetId \
                         ({:?}). You tried to insert a {:?}, however the existing widget is a \
                         {:?}. Check your widgets' `WidgetId`s for errors.",
                          idx, kind, container.kind).unwrap();
                return None;
            } else {
                container.take_widget_state()
            }
        };

        ui::widget_graph_mut(ui).widget_mut(idx).and_then(check_container_kind)
    };

    // Seperate the Widget's previous state into it's unique state, style and scrolling.
    let (maybe_prev_unique_state,
         maybe_prev_common,
         maybe_prev_style,
         maybe_prev_x_scroll_state,
         maybe_prev_y_scroll_state) =
        maybe_widget_state.map(|prev| {

            // Destructure the cached state.
            let Cached {
                state,
                style,
                rect,
                depth,
                maybe_floating,
                maybe_x_scroll_state,
                maybe_y_scroll_state,
                kid_area,
                ..
            } = prev;

            // Use the cached state to construct the prev_state (to be fed to Widget::update).
            let prev_common = CommonState {
                rect: rect,
                depth: depth,
                maybe_floating: maybe_floating,
                kid_area: kid_area,
            };

            (Some(state),
             Some(prev_common),
             Some(style),
             maybe_x_scroll_state,
             maybe_y_scroll_state)
        }).unwrap_or_else(|| (None, None, None, None, None));

    // We need to hold onto the current "previously set widget", as this may change during our
    // `Widget`'s update method (i.e. if it sets any of its own widgets, they will become the last
    // previous widget).
    let maybe_prev_widget_idx = ui.maybe_prev_widget();

    let new_style = widget.style();
    let depth = widget.get_depth();
    let dim = widget.get_wh(&ui).unwrap_or([0.0, 0.0]);
    let x_pos = widget.get_x_position(ui);
    let y_pos = widget.get_y_position(ui);
    let place_on_kid_area = widget.common().place_on_kid_area;

    // Determine the id of the canvas that the widget is attached to. If not given explicitly,
    // check the positioning to retrieve the Id from there.
    let maybe_parent_idx = widget.common().maybe_parent_idx.get(idx, ui, x_pos, y_pos);

    // Calculate the `xy` location of the widget, considering drag.
    let xy = maybe_prev_common
        .as_ref()
        .and_then(|prev| {
            let maybe_drag_area = widget.drag_area(dim, &new_style, &ui.theme);
            maybe_drag_area.map(|drag_area| {
                let mut left_mouse_drags = ui.widget_input(idx).drags().left();
                let maybe_first_drag = left_mouse_drags.next();
                let prev_xy = prev.rect.xy();
                maybe_first_drag
                    .and_then(|first_drag| {
                        if drag_area.is_over(first_drag.from) {
                            let total_drag_xy = left_mouse_drags
                                .fold(first_drag.delta_xy, |total, drag| {
                                    [total[0] + drag.delta_xy[0], total[1] + drag.delta_xy[1]]
                                });
                            Some([prev_xy[0] + total_drag_xy[0], prev_xy[1] + total_drag_xy[1]])
                        } else {
                            None
                        }
                    })
                    .unwrap_or(prev_xy)
            })
        })
        // If there is no previous state to compare for dragging, return an initial state.
        //
        // A function for generating the xy coords from the given alignment and Position.
        .unwrap_or_else(|| ui.calc_xy(Some(idx), x_pos, y_pos, dim, place_on_kid_area));

    // Construct the rectangle describing our Widget's area.
    let rect = Rect::from_xy_dim(xy, dim);

    // Check whether or not the widget is a "floating" (hovering / pop-up style) widget.
    let maybe_floating = if widget.common().is_floating {

        fn new_floating() -> Floating {
            Floating { time_last_clicked: std::time::Instant::now() }
        }

        // If it is floating, check to see if we need to update the last time it was clicked.
        match maybe_prev_common.as_ref() {
            Some(prev) => {
                let maybe_mouse = ui.widget_input(idx).mouse();
                match (prev.maybe_floating, maybe_mouse) {
                    (Some(prev_floating), Some(mouse)) => {
                        if mouse.buttons.left().is_down() {
                            Some(new_floating())
                        } else {
                            Some(prev_floating)
                        }
                    },
                    (Some(prev_floating), None) => Some(prev_floating),
                    _ => Some(new_floating()),
                }
            },
            None => Some(new_floating()),
        }
    } else {
        None
    };

    // Retrieve the area upon which kid widgets will be placed.
    let kid_area = {
        let args: KidAreaArgs<W, B::CharacterCache> = KidAreaArgs {
            rect: rect,
            style: &new_style,
            theme: &ui.theme,
            glyph_cache: &ui.glyph_cache,
        };
        widget.kid_area(args)
    };

    // If either axis is scrollable, retrieve the up-to-date `scroll::State` for that axis.
    //
    // We must step the scrolling using the previous `kid_area` state so that the bounding box
    // around our kid widgets is in sync with the position of the `kid_area`.
    let prev_kid_area = maybe_prev_common.map(|common| common.kid_area)
        .unwrap_or_else(|| kid_area);

    // If the widget is scrollable, check for given `Scroll` events.
    //
    // TODO: On the first time the widget is set (i.e. if `maybe_prev_*_scroll_state` is `None` and
    // `maybe_*_scroll` is `Some`) we should consider and handle the `scroll_args`'
    // `maybe_initial_alignment` field.
    let mut maybe_x_scroll_state = widget.common().maybe_x_scroll.map(|_scroll_args| {
        scroll::State::update(ui, idx, &prev_kid_area, maybe_prev_x_scroll_state, 0.0)
    });
    let mut maybe_y_scroll_state = widget.common().maybe_y_scroll.map(|_scroll_args| {
        scroll::State::update(ui, idx, &prev_kid_area, maybe_prev_y_scroll_state, 0.0)
    });

    for scroll in ui.widget_input(idx).scrolls() {

        if widget.common().maybe_x_scroll.is_some() {
            maybe_x_scroll_state =
                Some(scroll::State::update(ui, idx, &prev_kid_area, maybe_x_scroll_state, scroll.x))
        }

        if widget.common().maybe_y_scroll.is_some() {
            maybe_y_scroll_state =
                Some(scroll::State::update(ui, idx, &prev_kid_area, maybe_y_scroll_state, scroll.y))
        }
    }

    // Determine whether or not this is the first time set has been called.
    // We'll use this to determine whether or not we need to draw for the first time.
    let is_first_set = maybe_prev_common.is_none();

    // Update all positioning and dimension related data prior to calling `Widget::update`.
    // We do this so that if this widget were to internally `set` some other `Widget`s, this
    // `Widget`s positioning and dimension data already exists within the `Graph`.
    {
        use Position::{Place, Relative, Direction, Align, Absolute};

        // Some widget to which this widget is relatively positioned (if there is one).
        let maybe_positioned_relatively_idx = |pos: Position| match pos {
            Place(_, maybe_idx) | Relative(_, maybe_idx) |
            Direction(_, _, maybe_idx) | Align(_, maybe_idx) =>
                maybe_idx.or(maybe_prev_widget_idx),
            Absolute(_) => None,
        };

        let maybe_x_positioned_relatively_idx = maybe_positioned_relatively_idx(x_pos);
        let maybe_y_positioned_relatively_idx = maybe_positioned_relatively_idx(y_pos);

        // Retrieve whether or not the widget's children should be cropped to it.
        let crop_kids = widget.common().crop_kids;

        // This will cache the given data into the `ui`'s `widget_graph`.
        ui::pre_update_cache(ui, PreUpdateCache {
            kind: kind,
            idx: idx,
            maybe_parent_idx: maybe_parent_idx,
            maybe_x_positioned_relatively_idx: maybe_x_positioned_relatively_idx,
            maybe_y_positioned_relatively_idx: maybe_y_positioned_relatively_idx,
            rect: rect,
            depth: depth,
            kid_area: kid_area,
            maybe_floating: maybe_floating,
            crop_kids: crop_kids,
            maybe_y_scroll_state: maybe_y_scroll_state,
            maybe_x_scroll_state: maybe_x_scroll_state,
            maybe_graphics_for: widget.common().maybe_graphics_for,
        });
    }

    // Unwrap the widget's previous common state. If there is no previous common state, we'll
    // use the new state in it's place.
    let prev_common = maybe_prev_common.unwrap_or_else(|| CommonState {
        rect: rect,
        depth: depth,
        maybe_floating: maybe_floating,
        kid_area: kid_area,
    });

    // Retrieve the widget's unique state and update it via `Widget::update`.
    let (unique_state, has_state_updated) = {

        // Unwrap our unique widget state. If there is no previous state to unwrap, call the
        // `init_state` method to construct some initial state.
        let mut unique_state = maybe_prev_unique_state.unwrap_or_else(|| widget.init_state());
        let has_updated = {

            // A wrapper around the widget's unique state in order to keep track of whether or not it
            // has been updated during the `Widget::update` method.
            let mut state = State {
                state: &mut unique_state,
                has_updated: false,
            };

            widget.update(UpdateArgs {
                idx: idx,
                maybe_parent_idx: maybe_parent_idx,
                state: &mut state,
                prev: &prev_common,
                rect: rect,
                style: &new_style,
                ui: ui::new_ui_cell(ui),
            });

            state.has_updated
        };

        (unique_state, has_updated)
    };

    // Determine whether or not the `State` has changed.
    let state_has_changed = has_state_updated
        || rect != prev_common.rect
        || depth != prev_common.depth
        || is_first_set;

    // Determine whether or not the widget's `Style` has changed.
    let style_has_changed = maybe_prev_style.map(|style| style != new_style).unwrap_or(false);

    // We need to know if the scroll state has changed to see if we need to redraw.
    let scroll_has_changed = maybe_x_scroll_state != maybe_prev_x_scroll_state
        || maybe_y_scroll_state != maybe_prev_y_scroll_state;

    // We only need to redraw if some visible part of our widget has changed.
    let requires_redraw = style_has_changed || state_has_changed || scroll_has_changed;

    // If we require a redraw, we should notify the `Ui`.
    if requires_redraw {
        ui.needs_redraw();
    }

    // Finally, cache the `Widget`'s newly updated `State` and `Style` within the `ui`'s
    // `widget_graph`.
    ui::post_update_cache::<B, W>(ui, PostUpdateCache {
        idx: idx,
        maybe_parent_idx: maybe_parent_idx,
        state: unique_state,
        style: new_style,
    });
}




impl IndexSlot {

    /// Construct a new empty **IndexSlot**.
    pub fn new() -> Self {
        IndexSlot {
            maybe_idx: ::std::cell::Cell::new(None),
        }
    }

    /// Returns the **NodeIndex** held by the **IndexSlot**.
    ///
    /// If the **IndexSlot** does not yet hold a **NodeIndex**, the **UiCell** will be used to
    /// produce a `new_unique_node_index`.
    pub fn get<B>(&self, ui: &mut UiCell<B>) -> NodeIndex
        where B: Backend,
    {
        if self.maybe_idx.get().is_none() {
            let new_idx = ui.new_unique_node_index();
            self.maybe_idx.set(Some(new_idx));
        }
        self.maybe_idx.get().unwrap()
    }

}


impl<'a, T> State<'a, T> {

    /// Mutate the internal widget state and set a flag notifying us that there has been a mutation.
    ///
    /// If this method is *not* called, we assume that there has been no mutation and in turn we do
    /// not need to re-draw the Widget.
    ///
    /// If this method *is* called, we assume that there has been some mutation and in turn will
    /// need to re-draw the Widget. Thus, it is recommended that you *only* call this method if you
    /// need to update the unique state in some way.
    pub fn update<F>(&mut self, f: F) where F: FnOnce(&mut T) {
        self.has_updated = true;
        f(self.state);
    }

}

impl<'a, T> std::ops::Deref for State<'a, T> {
    type Target = T;
    fn deref(&self) -> &T {
        &self.state
    }
}


impl CommonBuilder {
    /// Construct an empty, initialised CommonBuilder.
    pub fn new() -> CommonBuilder {
        CommonBuilder {
            style: CommonStyle::new(),
            maybe_parent_idx: MaybeParent::Unspecified,
            place_on_kid_area: true,
            maybe_graphics_for: None,
            is_floating: false,
            maybe_x_scroll: None,
            maybe_y_scroll: None,
            crop_kids: false,
        }
    }
}

impl CommonStyle {
    /// A new default CommonStyle.
    pub fn new() -> Self {
        CommonStyle {
            maybe_x_dimension: None,
            maybe_y_dimension: None,
            maybe_x_position: None,
            maybe_y_position: None,
            maybe_depth: None,
        }
    }
}


impl<W> Positionable for W
    where W: Widget,
{
    #[inline]
    fn x_position(mut self, x: Position) -> Self {
        self.common_mut().style.maybe_x_position = Some(x);
        self
    }
    #[inline]
    fn y_position(mut self, y: Position) -> Self {
        self.common_mut().style.maybe_y_position = Some(y);
        self
    }
    #[inline]
    fn get_x_position<B: Backend>(&self, ui: &Ui<B>) -> Position {
        let from_y_position = || self.common().style.maybe_y_position
            .and_then(|y_pos| infer_position_from_other_position(y_pos, Align::Start));
        self.common().style.maybe_x_position
            .or_else(from_y_position)
            .unwrap_or(self.default_x_position(ui))
    }
    #[inline]
    fn get_y_position<B: Backend>(&self, ui: &Ui<B>) -> Position {
        let from_x_position = || self.common().style.maybe_x_position
            .and_then(|x_pos| infer_position_from_other_position(x_pos, Align::End));
        self.common().style.maybe_y_position
            .or_else(from_x_position)
            .unwrap_or(self.default_y_position(ui))
    }
    #[inline]
    fn depth(mut self, depth: Depth) -> Self {
        self.common_mut().style.maybe_depth = Some(depth);
        self
    }
    #[inline]
    fn get_depth(&self) -> Depth {
        const DEFAULT_DEPTH: Depth = 0.0;
        self.common().style.maybe_depth.unwrap_or(DEFAULT_DEPTH)
    }
}


/// In the case that a position hasn't been given for one of the axes, we must first check to see
/// if we can infer the missing axis position from the other axis.
///
/// This is used within the impl of **Positionable** for **Widget**.
fn infer_position_from_other_position(other_pos: Position, dir_align: Align) -> Option<Position> {
    match other_pos {
        Position::Direction(_, _, maybe_idx) => Some(Position::Align(dir_align, maybe_idx)),
        Position::Place(_, maybe_idx) => Some(Position::Align(Align::Middle, maybe_idx)),
        Position::Relative(_, maybe_idx) => Some(Position::Relative(0.0, maybe_idx)),
        Position::Align(_, _) | Position::Absolute(_) => None,
    }
}


impl<W> Sizeable for W
    where W: Widget,
{
    #[inline]
    fn x_dimension(mut self, w: Dimension) -> Self {
        self.common_mut().style.maybe_x_dimension = Some(w);
        self
    }
    #[inline]
    fn y_dimension(mut self, h: Dimension) -> Self {
        self.common_mut().style.maybe_y_dimension = Some(h);
        self
    }
    #[inline]
    /// We attempt to retrieve the `x` **Dimension** for the widget via the following:
    /// - Check for specified value at `maybe_x_dimension`
    /// - Otherwise, use the default returned by **Widget::default_x_dimension**.
    fn get_x_dimension<B: Backend>(&self, ui: &Ui<B>) -> Dimension {
        self.common().style.maybe_x_dimension.unwrap_or_else(|| self.default_x_dimension(ui))
    }
    #[inline]
    /// We attempt to retrieve the `y` **Dimension** for the widget via the following:
    /// - Check for specified value at `maybe_y_dimension`
    /// - Otherwise, use the default returned by **Widget::default_y_dimension**.
    fn get_y_dimension<B: Backend>(&self, ui: &Ui<B>) -> Dimension {
        self.common().style.maybe_y_dimension.unwrap_or_else(|| self.default_y_dimension(ui))
    }
}