extern crate pushrod; extern crate sdl2; use pushrod::layouts::horizontal_layout::HorizontalLayout; use pushrod::layouts::vertical_layout::VerticalLayout; use pushrod::render::callbacks::widget_id_for_name; use pushrod::render::engine::Engine; use pushrod::render::layout::{Layout, LayoutPosition}; use pushrod::render::widget::{BaseWidget, Widget}; use pushrod::render::widget_cache::WidgetContainer; use pushrod::render::widget_config::{ PaddingConstraint, CONFIG_BORDER_WIDTH, CONFIG_COLOR_BORDER, CONFIG_COLOR_TEXT, }; use pushrod::render::{make_points, make_points_origin, make_size}; use pushrod::widgets::push_button_widget::PushButtonWidget; use pushrod::widgets::text_widget::{TextJustify, TextWidget}; use sdl2::pixels::Color; #[macro_export] macro_rules! cast { ($a:expr, $b:expr, $c:ident) => { $a[$b] .widget .borrow_mut() .as_any() .downcast_mut::<$c>() .unwrap() }; } pub const MAX_SPACING: i32 = 20; pub fn main() { let sdl_context = sdl2::init().unwrap(); let video_subsystem = sdl_context.video().unwrap(); let window = video_subsystem .window("pushrod-render horizontal layout demo", 400, 300) .position_centered() .opengl() .build() .unwrap(); let mut engine = Engine::new(400, 300, 60); let mut layout = HorizontalLayout::new(20, 20, 360, 80, PaddingConstraint::new(0, 0, 0, 0, 1)); let mut layout2 = VerticalLayout::new(250, 120, 130, 160, PaddingConstraint::new(0, 0, 0, 0, 1)); let mut widget1 = BaseWidget::new(make_points_origin(), make_size(0, 0)); widget1 .get_config() .set_color(CONFIG_COLOR_BORDER, Color::RGB(0, 0, 0)); widget1.get_config().set_numeric(CONFIG_BORDER_WIDTH, 2); let mut widget2 = BaseWidget::new(make_points_origin(), make_size(0, 0)); widget2 .get_config() .set_color(CONFIG_COLOR_BORDER, Color::RGB(0, 0, 0)); widget2.get_config().set_numeric(CONFIG_BORDER_WIDTH, 2); let mut widget3 = BaseWidget::new(make_points_origin(), make_size(0, 0)); widget3 .get_config() .set_color(CONFIG_COLOR_BORDER, Color::RGB(0, 0, 0)); widget3.get_config().set_numeric(CONFIG_BORDER_WIDTH, 2); let mut widget4 = BaseWidget::new(make_points_origin(), make_size(0, 0)); widget4 .get_config() .set_color(CONFIG_COLOR_BORDER, Color::RGB(0, 0, 0)); widget4.get_config().set_numeric(CONFIG_BORDER_WIDTH, 2); let widget1_id = engine.add_widget(Box::new(widget1), String::from("widget1")); let widget2_id = engine.add_widget(Box::new(widget2), String::from("widget2")); let widget3_id = engine.add_widget(Box::new(widget3), String::from("widget3")); let widget4_id = engine.add_widget(Box::new(widget4), String::from("widget4")); layout.append_widget(widget1_id); layout.append_widget(widget2_id); layout2.append_widget(widget3_id); layout2.append_widget(widget4_id); engine.add_layout(Box::new(layout)); engine.add_layout(Box::new(layout2)); let mut text_widget1 = TextWidget::new( String::from("assets/OpenSans-Regular.ttf"), sdl2::ttf::FontStyle::NORMAL, 16, TextJustify::Right, String::from("Spacing:"), make_points(20, 116), make_size(70, 22), ); text_widget1 .get_config() .set_color(CONFIG_COLOR_TEXT, Color::RGB(0, 0, 0)); let mut text_widget2 = TextWidget::new( String::from("assets/OpenSans-Regular.ttf"), sdl2::ttf::FontStyle::NORMAL, 16, TextJustify::Left, String::from("1"), make_points(100, 116), make_size(40, 22), ); text_widget2 .get_config() .set_color(CONFIG_COLOR_TEXT, Color::RGB(0, 0, 255)); let mut button1 = PushButtonWidget::new( make_points(130, 112), make_size(50, 30), String::from("<"), 20, ); button1.set_color(CONFIG_COLOR_BORDER, Color::RGB(0, 0, 0)); button1.set_numeric(CONFIG_BORDER_WIDTH, 2); button1.on_click(|_, _widgets, _layouts| { let mut spacing = _layouts[0].layout.borrow_mut().get_padding().spacing - 1; let top = _layouts[0].layout.borrow_mut().get_padding().top; let bottom = _layouts[0].layout.borrow_mut().get_padding().bottom; let left = _layouts[0].layout.borrow_mut().get_padding().left; let right = _layouts[0].layout.borrow_mut().get_padding().right; let text_widget2_id = widget_id_for_name(_widgets, String::from("text_widget2")); if spacing <= 0 { spacing = 0; } let spacing_new = PaddingConstraint::new(top, bottom, left, right, spacing); _layouts[0] .layout .borrow_mut() .set_padding(spacing_new.clone()); _layouts[1] .layout .borrow_mut() .set_padding(spacing_new.clone()); refresh_widgets(_widgets); cast!(_widgets, text_widget2_id, TextWidget).set_text(format!("{}", spacing)); }); let mut button2 = PushButtonWidget::new( make_points(180, 112), make_size(50, 30), String::from(">"), 20, ); button2.set_color(CONFIG_COLOR_BORDER, Color::RGB(0, 0, 0)); button2.set_numeric(CONFIG_BORDER_WIDTH, 2); button2.on_click(|_, _widgets, _layouts| { let mut spacing = _layouts[0].layout.borrow_mut().get_padding().spacing + 1; let top = _layouts[0].layout.borrow_mut().get_padding().top; let bottom = _layouts[0].layout.borrow_mut().get_padding().bottom; let left = _layouts[0].layout.borrow_mut().get_padding().left; let right = _layouts[0].layout.borrow_mut().get_padding().right; let text_widget2_id = widget_id_for_name(_widgets, String::from("text_widget2")); if spacing >= MAX_SPACING { spacing = MAX_SPACING; } let spacing_new = PaddingConstraint::new(top, bottom, left, right, spacing); _layouts[0] .layout .borrow_mut() .set_padding(spacing_new.clone()); _layouts[1] .layout .borrow_mut() .set_padding(spacing_new.clone()); refresh_widgets(_widgets); cast!(_widgets, text_widget2_id, TextWidget).set_text(format!("{}", spacing)); }); let mut text_widget3 = TextWidget::new( String::from("assets/OpenSans-Regular.ttf"), sdl2::ttf::FontStyle::NORMAL, 16, TextJustify::Right, String::from("Top:"), make_points(20, 146), make_size(70, 22), ); text_widget3 .get_config() .set_color(CONFIG_COLOR_TEXT, Color::RGB(0, 0, 0)); let mut text_widget4 = TextWidget::new( String::from("assets/OpenSans-Regular.ttf"), sdl2::ttf::FontStyle::NORMAL, 16, TextJustify::Left, String::from("0"), make_points(100, 146), make_size(40, 22), ); text_widget4 .get_config() .set_color(CONFIG_COLOR_TEXT, Color::RGB(0, 0, 255)); let mut button3 = PushButtonWidget::new( make_points(130, 142), make_size(50, 30), String::from("<"), 20, ); button3.set_color(CONFIG_COLOR_BORDER, Color::RGB(0, 0, 0)); button3.set_numeric(CONFIG_BORDER_WIDTH, 2); button3.on_click(|_, _widgets, _layouts| { let spacing = _layouts[0].layout.borrow_mut().get_padding().spacing; let mut top = _layouts[0].layout.borrow_mut().get_padding().top - 1; let bottom = _layouts[0].layout.borrow_mut().get_padding().bottom; let left = _layouts[0].layout.borrow_mut().get_padding().left; let right = _layouts[0].layout.borrow_mut().get_padding().right; let text_widget4_id = widget_id_for_name(_widgets, String::from("text_widget4")); if top <= 0 { top = 0; } let spacing_new = PaddingConstraint::new(top, bottom, left, right, spacing); _layouts[0] .layout .borrow_mut() .set_padding(spacing_new.clone()); _layouts[1] .layout .borrow_mut() .set_padding(spacing_new.clone()); refresh_widgets(_widgets); cast!(_widgets, text_widget4_id, TextWidget).set_text(format!("{}", top)); }); let mut button4 = PushButtonWidget::new( make_points(180, 142), make_size(50, 30), String::from(">"), 20, ); button4.set_color(CONFIG_COLOR_BORDER, Color::RGB(0, 0, 0)); button4.set_numeric(CONFIG_BORDER_WIDTH, 2); button4.on_click(|_, _widgets, _layouts| { let spacing = _layouts[0].layout.borrow_mut().get_padding().spacing; let mut top = _layouts[0].layout.borrow_mut().get_padding().top + 1; let bottom = _layouts[0].layout.borrow_mut().get_padding().bottom; let left = _layouts[0].layout.borrow_mut().get_padding().left; let right = _layouts[0].layout.borrow_mut().get_padding().right; let text_widget4_id = widget_id_for_name(_widgets, String::from("text_widget4")); if top >= MAX_SPACING { top = MAX_SPACING; } let spacing_new = PaddingConstraint::new(top, bottom, left, right, spacing); _layouts[0] .layout .borrow_mut() .set_padding(spacing_new.clone()); _layouts[1] .layout .borrow_mut() .set_padding(spacing_new.clone()); refresh_widgets(_widgets); cast!(_widgets, text_widget4_id, TextWidget).set_text(format!("{}", top)); }); let mut text_widget5 = TextWidget::new( String::from("assets/OpenSans-Regular.ttf"), sdl2::ttf::FontStyle::NORMAL, 16, TextJustify::Right, String::from("Bottom:"), make_points(20, 176), make_size(70, 22), ); text_widget5 .get_config() .set_color(CONFIG_COLOR_TEXT, Color::RGB(0, 0, 0)); let mut text_widget6 = TextWidget::new( String::from("assets/OpenSans-Regular.ttf"), sdl2::ttf::FontStyle::NORMAL, 16, TextJustify::Left, String::from("0"), make_points(100, 176), make_size(40, 22), ); text_widget6 .get_config() .set_color(CONFIG_COLOR_TEXT, Color::RGB(0, 0, 255)); let mut button5 = PushButtonWidget::new( make_points(130, 172), make_size(50, 30), String::from("<"), 20, ); button5.set_color(CONFIG_COLOR_BORDER, Color::RGB(0, 0, 0)); button5.set_numeric(CONFIG_BORDER_WIDTH, 2); button5.on_click(|_, _widgets, _layouts| { let spacing = _layouts[0].layout.borrow_mut().get_padding().spacing; let top = _layouts[0].layout.borrow_mut().get_padding().top; let mut bottom = _layouts[0].layout.borrow_mut().get_padding().bottom - 1; let left = _layouts[0].layout.borrow_mut().get_padding().left; let right = _layouts[0].layout.borrow_mut().get_padding().right; let text_widget6_id = widget_id_for_name(_widgets, String::from("text_widget6")); if bottom <= 0 { bottom = 0; } let spacing_new = PaddingConstraint::new(top, bottom, left, right, spacing); _layouts[0] .layout .borrow_mut() .set_padding(spacing_new.clone()); _layouts[1] .layout .borrow_mut() .set_padding(spacing_new.clone()); refresh_widgets(_widgets); cast!(_widgets, text_widget6_id, TextWidget).set_text(format!("{}", bottom)); }); let mut button6 = PushButtonWidget::new( make_points(180, 172), make_size(50, 30), String::from(">"), 20, ); button6.set_color(CONFIG_COLOR_BORDER, Color::RGB(0, 0, 0)); button6.set_numeric(CONFIG_BORDER_WIDTH, 2); button6.on_click(|_, _widgets, _layouts| { let spacing = _layouts[0].layout.borrow_mut().get_padding().spacing; let top = _layouts[0].layout.borrow_mut().get_padding().top; let mut bottom = _layouts[0].layout.borrow_mut().get_padding().bottom + 1; let left = _layouts[0].layout.borrow_mut().get_padding().left; let right = _layouts[0].layout.borrow_mut().get_padding().right; let text_widget6_id = widget_id_for_name(_widgets, String::from("text_widget6")); if bottom >= MAX_SPACING { bottom = MAX_SPACING; } let spacing_new = PaddingConstraint::new(top, bottom, left, right, spacing); _layouts[0] .layout .borrow_mut() .set_padding(spacing_new.clone()); _layouts[1] .layout .borrow_mut() .set_padding(spacing_new.clone()); refresh_widgets(_widgets); cast!(_widgets, text_widget6_id, TextWidget).set_text(format!("{}", bottom)); }); let mut text_widget7 = TextWidget::new( String::from("assets/OpenSans-Regular.ttf"), sdl2::ttf::FontStyle::NORMAL, 16, TextJustify::Right, String::from("Left:"), make_points(20, 206), make_size(70, 22), ); text_widget7 .get_config() .set_color(CONFIG_COLOR_TEXT, Color::RGB(0, 0, 0)); let mut text_widget8 = TextWidget::new( String::from("assets/OpenSans-Regular.ttf"), sdl2::ttf::FontStyle::NORMAL, 16, TextJustify::Left, String::from("0"), make_points(100, 206), make_size(40, 22), ); text_widget8 .get_config() .set_color(CONFIG_COLOR_TEXT, Color::RGB(0, 0, 255)); let mut button7 = PushButtonWidget::new( make_points(130, 202), make_size(50, 30), String::from("<"), 20, ); button7.set_color(CONFIG_COLOR_BORDER, Color::RGB(0, 0, 0)); button7.set_numeric(CONFIG_BORDER_WIDTH, 2); button7.on_click(|_, _widgets, _layouts| { let spacing = _layouts[0].layout.borrow_mut().get_padding().spacing; let top = _layouts[0].layout.borrow_mut().get_padding().top; let bottom = _layouts[0].layout.borrow_mut().get_padding().bottom; let mut left = _layouts[0].layout.borrow_mut().get_padding().left - 1; let right = _layouts[0].layout.borrow_mut().get_padding().right; let text_widget8_id = widget_id_for_name(_widgets, String::from("text_widget8")); if left <= 0 { left = 0; } let spacing_new = PaddingConstraint::new(top, bottom, left, right, spacing); _layouts[0] .layout .borrow_mut() .set_padding(spacing_new.clone()); _layouts[1] .layout .borrow_mut() .set_padding(spacing_new.clone()); refresh_widgets(_widgets); cast!(_widgets, text_widget8_id, TextWidget).set_text(format!("{}", left)); }); let mut button8 = PushButtonWidget::new( make_points(180, 202), make_size(50, 30), String::from(">"), 20, ); button8.set_color(CONFIG_COLOR_BORDER, Color::RGB(0, 0, 0)); button8.set_numeric(CONFIG_BORDER_WIDTH, 2); button8.on_click(|_, _widgets, _layouts| { let spacing = _layouts[0].layout.borrow_mut().get_padding().spacing; let top = _layouts[0].layout.borrow_mut().get_padding().top; let bottom = _layouts[0].layout.borrow_mut().get_padding().bottom; let mut left = _layouts[0].layout.borrow_mut().get_padding().left + 1; let right = _layouts[0].layout.borrow_mut().get_padding().right; let text_widget8_id = widget_id_for_name(_widgets, String::from("text_widget8")); if left >= MAX_SPACING { left = MAX_SPACING; } let spacing_new = PaddingConstraint::new(top, bottom, left, right, spacing); _layouts[0] .layout .borrow_mut() .set_padding(spacing_new.clone()); _layouts[1] .layout .borrow_mut() .set_padding(spacing_new.clone()); refresh_widgets(_widgets); cast!(_widgets, text_widget8_id, TextWidget).set_text(format!("{}", left)); }); let mut text_widget9 = TextWidget::new( String::from("assets/OpenSans-Regular.ttf"), sdl2::ttf::FontStyle::NORMAL, 16, TextJustify::Right, String::from("Right:"), make_points(20, 236), make_size(70, 22), ); text_widget9 .get_config() .set_color(CONFIG_COLOR_TEXT, Color::RGB(0, 0, 0)); let mut text_widget10 = TextWidget::new( String::from("assets/OpenSans-Regular.ttf"), sdl2::ttf::FontStyle::NORMAL, 16, TextJustify::Left, String::from("0"), make_points(100, 236), make_size(40, 22), ); text_widget10 .get_config() .set_color(CONFIG_COLOR_TEXT, Color::RGB(0, 0, 255)); let mut button9 = PushButtonWidget::new( make_points(130, 232), make_size(50, 30), String::from("<"), 20, ); button9.set_color(CONFIG_COLOR_BORDER, Color::RGB(0, 0, 0)); button9.set_numeric(CONFIG_BORDER_WIDTH, 2); button9.on_click(|_, _widgets, _layouts| { let spacing = _layouts[0].layout.borrow_mut().get_padding().spacing; let top = _layouts[0].layout.borrow_mut().get_padding().top; let bottom = _layouts[0].layout.borrow_mut().get_padding().bottom; let left = _layouts[0].layout.borrow_mut().get_padding().left; let mut right = _layouts[0].layout.borrow_mut().get_padding().right - 1; let text_widget10_id = widget_id_for_name(_widgets, String::from("text_widget10")); if right <= 0 { right = 0; } let spacing_new = PaddingConstraint::new(top, bottom, left, right, spacing); _layouts[0] .layout .borrow_mut() .set_padding(spacing_new.clone()); _layouts[1] .layout .borrow_mut() .set_padding(spacing_new.clone()); refresh_widgets(_widgets); cast!(_widgets, text_widget10_id, TextWidget).set_text(format!("{}", right)); }); let mut button10 = PushButtonWidget::new( make_points(180, 232), make_size(50, 30), String::from(">"), 20, ); button10.set_color(CONFIG_COLOR_BORDER, Color::RGB(0, 0, 0)); button10.set_numeric(CONFIG_BORDER_WIDTH, 2); button10.on_click(|_, _widgets, _layouts| { let spacing = _layouts[0].layout.borrow_mut().get_padding().spacing; let top = _layouts[0].layout.borrow_mut().get_padding().top; let bottom = _layouts[0].layout.borrow_mut().get_padding().bottom; let left = _layouts[0].layout.borrow_mut().get_padding().left; let mut right = _layouts[0].layout.borrow_mut().get_padding().right + 1; let text_widget10_id = widget_id_for_name(_widgets, String::from("text_widget10")); if right >= MAX_SPACING { right = MAX_SPACING; } let spacing_new = PaddingConstraint::new(top, bottom, left, right, spacing); _layouts[0] .layout .borrow_mut() .set_padding(spacing_new.clone()); _layouts[1] .layout .borrow_mut() .set_padding(spacing_new.clone()); refresh_widgets(_widgets); cast!(_widgets, text_widget10_id, TextWidget).set_text(format!("{}", right)); }); engine.add_widget(Box::new(text_widget1), String::from("text_widget1")); engine.add_widget(Box::new(text_widget2), String::from("text_widget2")); engine.add_widget(Box::new(button1), String::from("button1")); engine.add_widget(Box::new(button2), String::from("button2")); engine.add_widget(Box::new(text_widget3), String::from("text_widget3")); engine.add_widget(Box::new(text_widget4), String::from("text_widget4")); engine.add_widget(Box::new(button3), String::from("button3")); engine.add_widget(Box::new(button4), String::from("button4")); engine.add_widget(Box::new(text_widget5), String::from("text_widget5")); engine.add_widget(Box::new(text_widget6), String::from("text_widget6")); engine.add_widget(Box::new(button5), String::from("button5")); engine.add_widget(Box::new(button6), String::from("button6")); engine.add_widget(Box::new(text_widget7), String::from("text_widget7")); engine.add_widget(Box::new(text_widget8), String::from("text_widget8")); engine.add_widget(Box::new(button7), String::from("button7")); engine.add_widget(Box::new(button8), String::from("button8")); engine.add_widget(Box::new(text_widget9), String::from("text_widget9")); engine.add_widget(Box::new(text_widget10), String::from("text_widget10")); engine.add_widget(Box::new(button9), String::from("button9")); engine.add_widget(Box::new(button10), String::from("button10")); engine.run(sdl_context, window); } fn refresh_widgets(_widgets: &[WidgetContainer]) { _widgets[0] .widget .borrow_mut() .get_config() .set_invalidated(true); _widgets[5] .widget .borrow_mut() .get_config() .set_invalidated(true); _widgets[6] .widget .borrow_mut() .get_config() .set_invalidated(true); _widgets[9] .widget .borrow_mut() .get_config() .set_invalidated(true); _widgets[10] .widget .borrow_mut() .get_config() .set_invalidated(true); _widgets[13] .widget .borrow_mut() .get_config() .set_invalidated(true); _widgets[14] .widget .borrow_mut() .get_config() .set_invalidated(true); _widgets[17] .widget .borrow_mut() .get_config() .set_invalidated(true); _widgets[18] .widget .borrow_mut() .get_config() .set_invalidated(true); _widgets[21] .widget .borrow_mut() .get_config() .set_invalidated(true); _widgets[22] .widget .borrow_mut() .get_config() .set_invalidated(true); }