use {Color, Colorable, FontSize, Borderable, Labelable, Positionable, Sizeable, Ui};
use position::{self, Align, Dimension, Scalar};
use text;
use widget::{self, Widget};
pub struct TitleBar<'a> {
pub common: widget::CommonBuilder,
pub style: Style,
pub label: &'a str,
}
pub struct State {
ids: Ids,
}
widget_ids! {
struct Ids {
rectangle,
label,
}
}
widget_style!{
style Style {
- color: Color { theme.background_color }
- border: Scalar { theme.border_width }
- border_color: Color { theme.border_color }
- text_color: Color { theme.label_color }
- font_size: FontSize { theme.font_size_medium }
- maybe_wrap: Option<widget::text::Wrap> { Some(widget::text::Wrap::Whitespace) }
- line_spacing: Scalar { 1.0 }
- justify: text::Justify { text::Justify::Center }
- label_x: position::Relative { position::Relative::Align(Align::Middle) }
- label_y: position::Relative { position::Relative::Align(Align::Middle) }
- font_id: Option<text::font::Id> { theme.font_id }
}
}
const LABEL_PADDING: f64 = 4.0;
impl<'a> TitleBar<'a> {
pub fn new(label: &'a str, id: widget::Id) -> Self {
TitleBar {
common: widget::CommonBuilder::new(),
style: Style::new(),
label: label,
}.w_of(id).mid_top_of(id)
}
pub fn left_justify_label(mut self) -> Self {
self.style.justify = Some(text::Justify::Left);
self
}
pub fn center_justify_label(mut self) -> Self {
self.style.justify = Some(text::Justify::Center);
self
}
pub fn right_justify_label(mut self) -> Self {
self.style.justify = Some(text::Justify::Right);
self
}
pub fn label_x(mut self, x: position::Relative) -> Self {
self.style.label_x = Some(x);
self
}
pub fn label_y(mut self, y: position::Relative) -> Self {
self.style.label_y = Some(y);
self
}
pub fn font_id(mut self, font_id: text::font::Id) -> Self {
self.style.font_id = Some(Some(font_id));
self
}
builder_methods!{
pub line_spacing { style.line_spacing = Some(Scalar) }
}
}
pub fn calc_height(font_size: FontSize) -> Scalar {
font_size as Scalar + LABEL_PADDING * 2.0
}
impl<'a> Widget for TitleBar<'a> {
type State = State;
type Style = Style;
type Event = ();
fn common(&self) -> &widget::CommonBuilder {
&self.common
}
fn common_mut(&mut self) -> &mut widget::CommonBuilder {
&mut self.common
}
fn init_state(&self, id_gen: widget::id::Generator) -> Self::State {
State {
ids: Ids::new(id_gen),
}
}
fn style(&self) -> Self::Style {
self.style.clone()
}
fn default_y_dimension(&self, ui: &Ui) -> Dimension {
let font_size = self.style.font_size(&ui.theme);
let h = calc_height(font_size);
Dimension::Absolute(h)
}
fn update(self, args: widget::UpdateArgs<Self>) {
let widget::UpdateArgs { id, state, rect, style, ui, .. } = args;
let TitleBar { label, .. } = self;
let dim = rect.dim();
let color = style.color(ui.theme());
let border = style.border(ui.theme());
let border_color = style.border_color(ui.theme());
widget::BorderedRectangle::new(dim)
.color(color)
.border(border)
.border_color(border_color)
.middle_of(id)
.graphics_for(id)
.set(state.ids.rectangle, ui);
let text_color = style.text_color(ui.theme());
let justify = style.justify(ui.theme());
let font_size = style.font_size(ui.theme());
let line_spacing = style.line_spacing(ui.theme());
let maybe_wrap = style.maybe_wrap(ui.theme());
let font_id = style.font_id(&ui.theme).or(ui.fonts.ids().next());
let label_x = style.label_x(&ui.theme);
let label_y = style.label_y(&ui.theme);
widget::Text::new(label)
.and_mut(|text| {
text.style.maybe_wrap = Some(maybe_wrap);
text.style.justify = Some(justify);
})
.and_then(font_id, widget::Text::font_id)
.padded_w_of(state.ids.rectangle, border)
.x_position_relative_to(state.ids.rectangle, label_x)
.y_position_relative_to(state.ids.rectangle, label_y)
.color(text_color)
.font_size(font_size)
.line_spacing(line_spacing)
.graphics_for(id)
.set(state.ids.label, ui);
}
}
impl<'a> Colorable for TitleBar<'a> {
builder_method!(color { style.color = Some(Color) });
}
impl<'a> Borderable for TitleBar<'a> {
builder_methods!{
border { style.border = Some(Scalar) }
border_color { style.border_color = Some(Color) }
}
}
impl<'a> Labelable<'a> for TitleBar<'a> {
builder_methods!{
label { label = &'a str }
label_color { style.text_color = Some(Color) }
label_font_size { style.font_size = Some(FontSize) }
}
}