use crate::style::Style;
use crate::tree::{NodeId, UiTree};
use crate::widget_id::{WidgetId, WidgetIdRegistry};
#[cfg(feature = "docking")]
use crate::widgets::ScrollbarTheme;
#[cfg(feature = "docking")]
use crate::widgets::docking::{
DockSplitter, DockTabs, PanelConstraints, TabScrollIndicator, TabScrollbarPosition,
};
use crate::widgets::scroll_container::{ScrollAxis, ScrollContainer, ScrollbarVisibility};
use crate::widgets::{
Button, Column, Container, Image, ImageFit, ImageTexture, ImageUV, Row, Text, TextInput,
Tooltip, Widget,
};
use astrelis_render::Color;
macro_rules! impl_node_style_methods {
() => {
pub fn width(mut self, width: impl Into<crate::constraint::Constraint>) -> Self {
self.widget.style_mut().set_width(width);
self
}
pub fn height(mut self, height: impl Into<crate::constraint::Constraint>) -> Self {
self.widget.style_mut().set_height(height);
self
}
pub fn padding(mut self, padding: impl Into<crate::constraint::Constraint> + Copy) -> Self {
self.widget.style_mut().set_padding(padding);
self
}
pub fn margin(mut self, margin: impl Into<crate::constraint::Constraint> + Copy) -> Self {
self.widget.style_mut().set_margin(margin);
self
}
pub fn padding_left(mut self, value: impl Into<crate::constraint::Constraint>) -> Self {
self.widget.style_mut().set_padding_left(value);
self
}
pub fn padding_right(mut self, value: impl Into<crate::constraint::Constraint>) -> Self {
self.widget.style_mut().set_padding_right(value);
self
}
pub fn padding_top(mut self, value: impl Into<crate::constraint::Constraint>) -> Self {
self.widget.style_mut().set_padding_top(value);
self
}
pub fn padding_bottom(mut self, value: impl Into<crate::constraint::Constraint>) -> Self {
self.widget.style_mut().set_padding_bottom(value);
self
}
pub fn padding_x(mut self, value: impl Into<crate::constraint::Constraint> + Copy) -> Self {
self.widget.style_mut().set_padding_x(value);
self
}
pub fn padding_y(mut self, value: impl Into<crate::constraint::Constraint> + Copy) -> Self {
self.widget.style_mut().set_padding_y(value);
self
}
pub fn margin_left(mut self, value: impl Into<crate::constraint::Constraint>) -> Self {
self.widget.style_mut().set_margin_left(value);
self
}
pub fn margin_right(mut self, value: impl Into<crate::constraint::Constraint>) -> Self {
self.widget.style_mut().set_margin_right(value);
self
}
pub fn margin_top(mut self, value: impl Into<crate::constraint::Constraint>) -> Self {
self.widget.style_mut().set_margin_top(value);
self
}
pub fn margin_bottom(mut self, value: impl Into<crate::constraint::Constraint>) -> Self {
self.widget.style_mut().set_margin_bottom(value);
self
}
pub fn margin_x(mut self, value: impl Into<crate::constraint::Constraint> + Copy) -> Self {
self.widget.style_mut().set_margin_x(value);
self
}
pub fn margin_y(mut self, value: impl Into<crate::constraint::Constraint> + Copy) -> Self {
self.widget.style_mut().set_margin_y(value);
self
}
pub fn min_width(mut self, width: impl Into<crate::constraint::Constraint>) -> Self {
self.widget.style_mut().set_min_width(width);
self
}
pub fn min_height(mut self, height: impl Into<crate::constraint::Constraint>) -> Self {
self.widget.style_mut().set_min_height(height);
self
}
pub fn max_width(mut self, width: impl Into<crate::constraint::Constraint>) -> Self {
self.widget.style_mut().set_max_width(width);
self
}
pub fn max_height(mut self, height: impl Into<crate::constraint::Constraint>) -> Self {
self.widget.style_mut().set_max_height(height);
self
}
pub fn flex_basis(mut self, basis: impl Into<crate::constraint::Constraint>) -> Self {
self.widget.style_mut().set_flex_basis(basis);
self
}
pub fn opacity(mut self, opacity: f32) -> Self {
self.widget.style_mut().set_opacity(opacity);
self
}
pub fn visible(mut self, visible: bool) -> Self {
self.widget.style_mut().set_visible(visible);
self
}
pub fn pointer_events(mut self, pointer_events: crate::style::PointerEvents) -> Self {
self.widget.style_mut().set_pointer_events(pointer_events);
self
}
pub fn translate(mut self, x: f32, y: f32) -> Self {
self.widget
.style_mut()
.set_translate(astrelis_core::math::Vec2::new(x, y));
self
}
pub fn translate_x(mut self, x: f32) -> Self {
self.widget.style_mut().set_translate_x(x);
self
}
pub fn translate_y(mut self, y: f32) -> Self {
self.widget.style_mut().set_translate_y(y);
self
}
pub fn scale(mut self, x: f32, y: f32) -> Self {
self.widget
.style_mut()
.set_scale(astrelis_core::math::Vec2::new(x, y));
self
}
pub fn uniform_scale(mut self, s: f32) -> Self {
self.widget.style_mut().set_uniform_scale(s);
self
}
};
}
macro_rules! impl_node_layout_methods {
() => {
pub fn background_color(mut self, color: astrelis_render::Color) -> Self {
self.widget.style_mut().set_background_color(color);
self
}
pub fn border_color(mut self, color: astrelis_render::Color) -> Self {
self.widget.style_mut().set_border_color(color);
self
}
pub fn border_width(mut self, width: f32) -> Self {
self.widget.style_mut().set_border_width(width);
self
}
pub fn border_radius(mut self, radius: f32) -> Self {
self.widget.style_mut().set_border_radius(radius);
self
}
pub fn overflow(mut self, overflow: crate::Overflow) -> Self {
self.widget.style_mut().set_overflow(overflow);
self
}
pub fn overflow_x(mut self, overflow: crate::Overflow) -> Self {
self.widget.style_mut().set_overflow_x(overflow);
self
}
pub fn overflow_y(mut self, overflow: crate::Overflow) -> Self {
self.widget.style_mut().set_overflow_y(overflow);
self
}
pub fn aspect_ratio(mut self, ratio: f32) -> Self {
self.widget.style_mut().set_aspect_ratio(ratio);
self
}
};
}
macro_rules! impl_node_flex_methods {
() => {
pub fn flex_direction(mut self, direction: taffy::FlexDirection) -> Self {
self.widget.style_mut().set_flex_direction(direction);
self
}
pub fn justify_content(mut self, justify: taffy::JustifyContent) -> Self {
self.widget.style_mut().set_justify_content(justify);
self
}
pub fn align_items(mut self, align: taffy::AlignItems) -> Self {
self.widget.style_mut().set_align_items(align);
self
}
pub fn gap(mut self, gap: impl Into<crate::constraint::Constraint> + Copy) -> Self {
self.widget.style_mut().set_gap(gap);
self
}
pub fn flex_wrap(mut self, wrap: taffy::FlexWrap) -> Self {
self.widget.style_mut().set_flex_wrap(wrap);
self
}
};
}
pub trait IntoNodeBuilder: Widget + Sized {
type Builder<'b, 'a: 'b>;
fn into_node_builder<'b, 'a: 'b>(self, builder: &'b mut UiBuilder<'a>)
-> Self::Builder<'b, 'a>;
}
pub struct LeafNodeBuilder<'b, 'a: 'b, W: Widget> {
builder: &'b mut UiBuilder<'a>,
widget: W,
widget_id: Option<WidgetId>,
}
impl<'b, 'a: 'b, W: Widget + 'static> LeafNodeBuilder<'b, 'a, W> {
pub fn new(builder: &'b mut UiBuilder<'a>, widget: W) -> Self {
Self {
builder,
widget,
widget_id: None,
}
}
pub fn id(mut self, id: WidgetId) -> Self {
self.widget_id = Some(id);
self
}
pub fn configure<F: FnOnce(&mut W)>(mut self, f: F) -> Self {
f(&mut self.widget);
self
}
pub fn style(mut self, style: Style) -> Self {
*self.widget.style_mut() = style;
self
}
pub fn build(self) -> NodeId {
let node_id = self.builder.add_widget(Box::new(self.widget));
if let Some(widget_id) = self.widget_id {
self.builder.widget_registry.register(widget_id, node_id);
}
self.builder.set_root(node_id);
node_id
}
impl_node_style_methods!();
}
pub struct ContainerNodeBuilder<'b, 'a: 'b, W: Widget> {
builder: &'b mut UiBuilder<'a>,
widget: W,
children: Vec<NodeId>,
widget_id: Option<WidgetId>,
}
impl<'b, 'a: 'b, W: Widget + 'static> ContainerNodeBuilder<'b, 'a, W> {
pub fn new(builder: &'b mut UiBuilder<'a>, widget: W) -> Self {
Self {
builder,
widget,
children: Vec::new(),
widget_id: None,
}
}
pub fn id(mut self, id: WidgetId) -> Self {
self.widget_id = Some(id);
self
}
pub fn configure<F: FnOnce(&mut W)>(mut self, f: F) -> Self {
f(&mut self.widget);
self
}
pub fn child<F>(mut self, build_child: F) -> Self
where
F: FnOnce(&mut UiBuilder) -> NodeId,
{
let mut child_builder = self.builder.child_builder();
let child_id = build_child(&mut child_builder);
self.children.push(child_id);
self
}
pub fn children<F>(mut self, build_children: F) -> Self
where
F: FnOnce(&mut UiBuilder) -> Vec<NodeId>,
{
let mut child_builder = self.builder.child_builder();
let mut child_ids = build_children(&mut child_builder);
self.children.append(&mut child_ids);
self
}
pub fn style(mut self, style: Style) -> Self {
*self.widget.style_mut() = style;
self
}
pub fn build(mut self) -> NodeId {
let children = std::mem::take(&mut self.children);
if let Some(widget_children) = self.widget.children_mut() {
*widget_children = children.clone();
}
let node_id = self.builder.add_widget(Box::new(self.widget));
self.builder.tree.set_children(node_id, &children);
if let Some(widget_id) = self.widget_id {
self.builder.widget_registry.register(widget_id, node_id);
}
self.builder.set_root(node_id);
node_id
}
impl_node_style_methods!();
impl_node_layout_methods!();
impl_node_flex_methods!();
}
impl<'b, 'a: 'b> LeafNodeBuilder<'b, 'a, Text> {
pub fn size(mut self, size: f32) -> Self {
self.widget = self.widget.size(size);
self
}
pub fn color(mut self, color: Color) -> Self {
self.widget = self.widget.color(color);
self
}
pub fn weight(mut self, weight: astrelis_text::FontWeight) -> Self {
self.widget = self.widget.weight(weight);
self
}
pub fn bold(self) -> Self {
self.weight(astrelis_text::FontWeight::Bold)
}
pub fn align(mut self, align: astrelis_text::TextAlign) -> Self {
self.widget = self.widget.align(align);
self
}
pub fn font_id(mut self, font_id: u32) -> Self {
self.widget = self.widget.font_id(font_id);
self
}
pub fn max_wrap_width(mut self, width: impl Into<crate::constraint::Constraint>) -> Self {
self.widget = self.widget.max_wrap_width(width);
self
}
}
impl<'b, 'a: 'b> LeafNodeBuilder<'b, 'a, Button> {
pub fn background_color(mut self, color: Color) -> Self {
self.widget = self.widget.background_color(color);
self
}
pub fn hover_color(mut self, color: Color) -> Self {
self.widget = self.widget.hover_color(color);
self
}
pub fn text_color(mut self, color: Color) -> Self {
self.widget = self.widget.text_color(color);
self
}
pub fn font_size(mut self, size: f32) -> Self {
self.widget = self.widget.font_size(size);
self
}
pub fn font_id(mut self, font_id: u32) -> Self {
self.widget = self.widget.font_id(font_id);
self
}
pub fn on_click<F>(mut self, callback: F) -> Self
where
F: Fn() + 'static,
{
self.widget = self.widget.on_click(callback);
self
}
}
impl<'b, 'a: 'b> LeafNodeBuilder<'b, 'a, Image> {
pub fn uv(mut self, uv: ImageUV) -> Self {
self.widget = self.widget.uv(uv);
self
}
pub fn tint(mut self, color: Color) -> Self {
self.widget = self.widget.tint(color);
self
}
pub fn fit(mut self, fit: ImageFit) -> Self {
self.widget = self.widget.fit(fit);
self
}
pub fn natural_size(mut self, width: f32, height: f32) -> Self {
self.widget = self.widget.natural_size(width, height);
self
}
pub fn border_radius(mut self, radius: f32) -> Self {
self.widget = self.widget.border_radius(radius);
self
}
pub fn sampling(mut self, sampling: astrelis_render::ImageSampling) -> Self {
self.widget = self.widget.sampling(sampling);
self
}
pub fn pixel_perfect(self) -> Self {
self.sampling(astrelis_render::ImageSampling::Nearest)
}
}
impl<'b, 'a: 'b> LeafNodeBuilder<'b, 'a, TextInput> {
pub fn content(mut self, content: impl Into<String>) -> Self {
self.widget = self.widget.content(content);
self
}
pub fn font_size(mut self, size: f32) -> Self {
self.widget = self.widget.font_size(size);
self
}
pub fn text_color(mut self, color: Color) -> Self {
self.widget = self.widget.text_color(color);
self
}
pub fn placeholder_color(mut self, color: Color) -> Self {
self.widget = self.widget.placeholder_color(color);
self
}
pub fn max_length(mut self, max: usize) -> Self {
self.widget = self.widget.max_length(max);
self
}
pub fn on_change<F>(mut self, callback: F) -> Self
where
F: Fn(String) + 'static,
{
self.widget = self.widget.on_change(callback);
self
}
}
impl<'b, 'a: 'b> LeafNodeBuilder<'b, 'a, Tooltip> {
pub fn font_size(mut self, size: f32) -> Self {
self.widget = self.widget.font_size(size);
self
}
pub fn text_color(mut self, color: Color) -> Self {
self.widget = self.widget.text_color(color);
self
}
pub fn background_color(mut self, color: Color) -> Self {
self.widget = self.widget.background_color(color);
self
}
}
impl<'b, 'a: 'b> ContainerNodeBuilder<'b, 'a, Row> {
}
impl<'b, 'a: 'b> ContainerNodeBuilder<'b, 'a, Column> {
}
impl<'b, 'a: 'b> ContainerNodeBuilder<'b, 'a, ScrollContainer> {
pub fn scroll_axis(mut self, axis: ScrollAxis) -> Self {
self.widget.scroll_axis = axis;
self
}
pub fn scrollbar_visibility(mut self, visibility: ScrollbarVisibility) -> Self {
self.widget.scrollbar_visibility = visibility;
self
}
pub fn scrollbar_theme(mut self, theme: crate::widgets::ScrollbarTheme) -> Self {
self.widget.scrollbar_theme = theme;
self
}
}
impl IntoNodeBuilder for Text {
type Builder<'b, 'a: 'b> = LeafNodeBuilder<'b, 'a, Text>;
fn into_node_builder<'b, 'a: 'b>(
self,
builder: &'b mut UiBuilder<'a>,
) -> Self::Builder<'b, 'a> {
LeafNodeBuilder::new(builder, self)
}
}
impl IntoNodeBuilder for Button {
type Builder<'b, 'a: 'b> = LeafNodeBuilder<'b, 'a, Button>;
fn into_node_builder<'b, 'a: 'b>(
self,
builder: &'b mut UiBuilder<'a>,
) -> Self::Builder<'b, 'a> {
LeafNodeBuilder::new(builder, self)
}
}
impl IntoNodeBuilder for Image {
type Builder<'b, 'a: 'b> = LeafNodeBuilder<'b, 'a, Image>;
fn into_node_builder<'b, 'a: 'b>(
self,
builder: &'b mut UiBuilder<'a>,
) -> Self::Builder<'b, 'a> {
LeafNodeBuilder::new(builder, self)
}
}
impl IntoNodeBuilder for TextInput {
type Builder<'b, 'a: 'b> = LeafNodeBuilder<'b, 'a, TextInput>;
fn into_node_builder<'b, 'a: 'b>(
self,
builder: &'b mut UiBuilder<'a>,
) -> Self::Builder<'b, 'a> {
LeafNodeBuilder::new(builder, self)
}
}
impl IntoNodeBuilder for Tooltip {
type Builder<'b, 'a: 'b> = LeafNodeBuilder<'b, 'a, Tooltip>;
fn into_node_builder<'b, 'a: 'b>(
self,
builder: &'b mut UiBuilder<'a>,
) -> Self::Builder<'b, 'a> {
LeafNodeBuilder::new(builder, self)
}
}
impl IntoNodeBuilder for Container {
type Builder<'b, 'a: 'b> = ContainerNodeBuilder<'b, 'a, Container>;
fn into_node_builder<'b, 'a: 'b>(
self,
builder: &'b mut UiBuilder<'a>,
) -> Self::Builder<'b, 'a> {
ContainerNodeBuilder::new(builder, self)
}
}
impl IntoNodeBuilder for Row {
type Builder<'b, 'a: 'b> = ContainerNodeBuilder<'b, 'a, Row>;
fn into_node_builder<'b, 'a: 'b>(
self,
builder: &'b mut UiBuilder<'a>,
) -> Self::Builder<'b, 'a> {
ContainerNodeBuilder::new(builder, self)
}
}
impl IntoNodeBuilder for Column {
type Builder<'b, 'a: 'b> = ContainerNodeBuilder<'b, 'a, Column>;
fn into_node_builder<'b, 'a: 'b>(
self,
builder: &'b mut UiBuilder<'a>,
) -> Self::Builder<'b, 'a> {
ContainerNodeBuilder::new(builder, self)
}
}
impl IntoNodeBuilder for ScrollContainer {
type Builder<'b, 'a: 'b> = ContainerNodeBuilder<'b, 'a, ScrollContainer>;
fn into_node_builder<'b, 'a: 'b>(
self,
builder: &'b mut UiBuilder<'a>,
) -> Self::Builder<'b, 'a> {
ContainerNodeBuilder::new(builder, self)
}
}
#[cfg(feature = "docking")]
pub struct DockSplitterNodeBuilder<'b, 'a: 'b> {
builder: &'b mut UiBuilder<'a>,
widget: DockSplitter,
first_child: Option<NodeId>,
second_child: Option<NodeId>,
}
#[cfg(feature = "docking")]
impl<'b, 'a: 'b> DockSplitterNodeBuilder<'b, 'a> {
pub fn split_ratio(mut self, ratio: f32) -> Self {
self.widget = self.widget.split_ratio(ratio);
self
}
pub fn separator_size(mut self, size: f32) -> Self {
self.widget = self.widget.separator_size(size);
self
}
pub fn separator_colors(mut self, normal: Color, hover: Color) -> Self {
self.widget = self.widget.separator_colors(normal, hover);
self
}
pub fn first_min_size(mut self, min_size: f32) -> Self {
self.widget.first_constraints = PanelConstraints::min(min_size);
self
}
pub fn second_min_size(mut self, min_size: f32) -> Self {
self.widget.second_constraints = PanelConstraints::min(min_size);
self
}
pub fn first_constraints(mut self, constraints: PanelConstraints) -> Self {
self.widget = self.widget.first_constraints(constraints);
self
}
pub fn second_constraints(mut self, constraints: PanelConstraints) -> Self {
self.widget = self.widget.second_constraints(constraints);
self
}
pub fn separator_tolerance(mut self, tolerance: f32) -> Self {
self.widget = self.widget.separator_tolerance(tolerance);
self
}
pub fn first<F>(mut self, build_child: F) -> Self
where
F: FnOnce(&mut UiBuilder) -> NodeId,
{
let mut child_builder = self.builder.child_builder();
let child_id = build_child(&mut child_builder);
self.first_child = Some(child_id);
self
}
pub fn second<F>(mut self, build_child: F) -> Self
where
F: FnOnce(&mut UiBuilder) -> NodeId,
{
let mut child_builder = self.builder.child_builder();
let child_id = build_child(&mut child_builder);
self.second_child = Some(child_id);
self
}
pub fn build(mut self) -> NodeId {
let mut children = Vec::new();
if let Some(first) = self.first_child {
children.push(first);
}
if let Some(second) = self.second_child {
children.push(second);
}
self.widget.children = children.clone();
let node_id = self.builder.add_widget(Box::new(self.widget));
self.builder.tree.set_children(node_id, &children);
self.builder.set_root(node_id);
node_id
}
impl_node_style_methods!();
impl_node_layout_methods!();
}
#[cfg(feature = "docking")]
impl IntoNodeBuilder for DockSplitter {
type Builder<'b, 'a: 'b> = DockSplitterNodeBuilder<'b, 'a>;
fn into_node_builder<'b, 'a: 'b>(
self,
builder: &'b mut UiBuilder<'a>,
) -> Self::Builder<'b, 'a> {
DockSplitterNodeBuilder {
builder,
widget: self,
first_child: None,
second_child: None,
}
}
}
#[cfg(feature = "docking")]
struct TabContentBuilder {
label: String,
content: Option<NodeId>,
}
#[cfg(feature = "docking")]
pub struct DockTabsNodeBuilder<'b, 'a: 'b> {
builder: &'b mut UiBuilder<'a>,
widget: DockTabs,
tab_builders: Vec<TabContentBuilder>,
}
#[cfg(feature = "docking")]
impl<'b, 'a: 'b> DockTabsNodeBuilder<'b, 'a> {
pub fn tab<F>(mut self, label: impl Into<String>, build_content: F) -> Self
where
F: FnOnce(&mut UiBuilder) -> NodeId,
{
let mut child_builder = self.builder.child_builder();
let content_id = build_content(&mut child_builder);
self.tab_builders.push(TabContentBuilder {
label: label.into(),
content: Some(content_id),
});
self
}
pub fn active_tab(mut self, index: usize) -> Self {
self.widget.active_tab = index;
self
}
pub fn tab_bar_height(mut self, height: f32) -> Self {
self.widget = self.widget.tab_bar_height(height);
self
}
pub fn tab_colors(mut self, bar: Color, active: Color, inactive: Color) -> Self {
self.widget = self.widget.tab_colors(bar, active, inactive);
self
}
pub fn text_color(mut self, color: Color) -> Self {
self.widget = self.widget.text_color(color);
self
}
pub fn closable(mut self, closable: bool) -> Self {
self.widget = self.widget.closable(closable);
self
}
pub fn tab_font_size(mut self, size: f32) -> Self {
self.widget = self.widget.tab_font_size(size);
self
}
pub fn scroll_indicator(mut self, mode: TabScrollIndicator) -> Self {
self.widget = self.widget.scroll_indicator(mode);
self
}
pub fn scrollbar_position(mut self, position: TabScrollbarPosition) -> Self {
self.widget = self.widget.scrollbar_position(position);
self
}
pub fn scrollbar_theme(mut self, theme: ScrollbarTheme) -> Self {
self.widget = self.widget.scrollbar_theme(theme);
self
}
pub fn content_padding(mut self, padding: f32) -> Self {
self.widget = self.widget.content_padding(padding);
self
}
pub fn build(mut self) -> NodeId {
for tab_builder in self.tab_builders {
if let Some(content) = tab_builder.content {
self.widget.add_tab(tab_builder.label, content);
}
}
let children = self.widget.children.clone();
let node_id = self.builder.add_widget(Box::new(self.widget));
self.builder.tree.set_children(node_id, &children);
self.builder.set_root(node_id);
node_id
}
impl_node_style_methods!();
impl_node_layout_methods!();
}
#[cfg(feature = "docking")]
impl IntoNodeBuilder for DockTabs {
type Builder<'b, 'a: 'b> = DockTabsNodeBuilder<'b, 'a>;
fn into_node_builder<'b, 'a: 'b>(
self,
builder: &'b mut UiBuilder<'a>,
) -> Self::Builder<'b, 'a> {
DockTabsNodeBuilder {
builder,
widget: self,
tab_builders: Vec::new(),
}
}
}
pub struct UiBuilder<'a> {
tree: &'a mut UiTree,
widget_registry: &'a mut WidgetIdRegistry,
root: Option<NodeId>,
is_root_builder: bool,
}
impl<'a> UiBuilder<'a> {
pub fn new(tree: &'a mut UiTree, widget_registry: &'a mut WidgetIdRegistry) -> Self {
tree.clear();
Self {
tree,
widget_registry,
root: None,
is_root_builder: true,
}
}
pub fn add<W: IntoNodeBuilder>(&mut self, widget: W) -> W::Builder<'_, 'a> {
widget.into_node_builder(self)
}
pub fn container(&mut self) -> ContainerNodeBuilder<'_, 'a, Container> {
self.add(Container::new())
}
pub fn text(&mut self, content: impl Into<String>) -> LeafNodeBuilder<'_, 'a, Text> {
self.add(Text::new(content))
}
pub fn button(&mut self, label: impl Into<String>) -> LeafNodeBuilder<'_, 'a, Button> {
self.add(Button::new(label))
}
pub fn row(&mut self) -> ContainerNodeBuilder<'_, 'a, Row> {
self.add(Row::new())
}
pub fn column(&mut self) -> ContainerNodeBuilder<'_, 'a, Column> {
self.add(Column::new())
}
pub fn text_input(
&mut self,
placeholder: impl Into<String>,
) -> LeafNodeBuilder<'_, 'a, TextInput> {
self.add(TextInput::new(placeholder))
}
pub fn tooltip(&mut self, text: impl Into<String>) -> LeafNodeBuilder<'_, 'a, Tooltip> {
self.add(Tooltip::new(text))
}
pub fn image(&mut self, texture: ImageTexture) -> LeafNodeBuilder<'_, 'a, Image> {
self.add(Image::new().texture(texture))
}
pub fn image_placeholder(&mut self) -> LeafNodeBuilder<'_, 'a, Image> {
self.add(Image::new())
}
pub fn scroll_container(&mut self) -> ContainerNodeBuilder<'_, 'a, ScrollContainer> {
self.add(ScrollContainer::new())
}
#[cfg(feature = "docking")]
pub fn hsplit(&mut self) -> DockSplitterNodeBuilder<'_, 'a> {
self.add(DockSplitter::horizontal())
}
#[cfg(feature = "docking")]
pub fn vsplit(&mut self) -> DockSplitterNodeBuilder<'_, 'a> {
self.add(DockSplitter::vertical())
}
#[cfg(feature = "docking")]
pub fn dock_tabs(&mut self) -> DockTabsNodeBuilder<'_, 'a> {
self.add(DockTabs::new())
}
fn add_widget(&mut self, widget: Box<dyn Widget>) -> NodeId {
self.tree.add_widget(widget)
}
fn set_root(&mut self, node_id: NodeId) {
if self.is_root_builder && self.root.is_none() {
self.root = Some(node_id);
self.tree.set_root(node_id);
}
}
fn child_builder(&mut self) -> UiBuilder<'_> {
UiBuilder {
tree: self.tree,
widget_registry: self.widget_registry,
root: None,
is_root_builder: false,
}
}
pub fn finish(self) {
}
}
pub type TextBuilder<'b, 'a> = LeafNodeBuilder<'b, 'a, Text>;
pub type ContainerBuilder<'b, 'a> = ContainerNodeBuilder<'b, 'a, Container>;
pub type ButtonBuilder<'b, 'a> = LeafNodeBuilder<'b, 'a, Button>;
pub type RowBuilder<'b, 'a> = ContainerNodeBuilder<'b, 'a, Row>;
pub type ColumnBuilder<'b, 'a> = ContainerNodeBuilder<'b, 'a, Column>;
pub type TextInputBuilder<'b, 'a> = LeafNodeBuilder<'b, 'a, TextInput>;
pub type TooltipBuilder<'b, 'a> = LeafNodeBuilder<'b, 'a, Tooltip>;
pub type ImageBuilder<'b, 'a> = LeafNodeBuilder<'b, 'a, Image>;
pub type ScrollContainerBuilder<'b, 'a> = ContainerNodeBuilder<'b, 'a, ScrollContainer>;
#[cfg(feature = "docking")]
pub type DockSplitterBuilder<'b, 'a> = DockSplitterNodeBuilder<'b, 'a>;
#[cfg(feature = "docking")]
pub type DockTabsBuilder<'b, 'a> = DockTabsNodeBuilder<'b, 'a>;
pub trait WidgetBuilder {
fn style(self, style: Style) -> Self;
fn width(self, width: impl Into<crate::constraint::Constraint>) -> Self;
fn height(self, height: impl Into<crate::constraint::Constraint>) -> Self;
fn padding(self, padding: impl Into<crate::constraint::Constraint> + Copy) -> Self;
fn margin(self, margin: impl Into<crate::constraint::Constraint> + Copy) -> Self;
}