add should_wrap flag

This commit is contained in:
griffi-gh 2024-03-06 17:19:35 +01:00
parent ef0d610764
commit 4c26a1297f
8 changed files with 45 additions and 12 deletions

View file

@ -33,7 +33,7 @@ pub struct ProcessContext<'a> {
pub trait UiElement { pub trait UiElement {
/// Get the name of the element, for example "Button" or "ProgressBar" /// Get the name of the element, for example "Button" or "ProgressBar"
fn name(&self) -> &'static str { "UiElement" } fn name(&self) -> &'static str;
/// Get the unique id used for internal state management\ /// Get the unique id used for internal state management\
/// This value must be unique for each instance of the element /// This value must be unique for each instance of the element
@ -41,11 +41,13 @@ pub trait UiElement {
/// If the element is stateless, this function should return `None` /// If the element is stateless, this function should return `None`
fn state_id(&self) -> Option<u64> { None } fn state_id(&self) -> Option<u64> { None }
/// Check if the element has state /// Check if the element has state.\
/// Should not be overridden
fn is_stateful(&self) -> bool { self.state_id().is_some() } fn is_stateful(&self) -> bool { self.state_id().is_some() }
/// Check if the element has no state /// Check if the element has no state\
fn is_stateless(&self) -> bool { self.state_id().is_none() } /// Should not be overridden
fn is_stateless(&self) -> bool { !self.is_stateful() }
/// Initialize the state of the element\ /// Initialize the state of the element\
/// This function should be called exactly once during the lifetime of the element, /// This function should be called exactly once during the lifetime of the element,

View file

@ -103,6 +103,10 @@ impl Container {
} }
impl UiElement for Container { impl UiElement for Container {
fn name(&self) -> &'static str {
"Container"
}
fn measure(&self, ctx: MeasureContext) -> Response { fn measure(&self, ctx: MeasureContext) -> Response {
let mut size = Vec2::ZERO; let mut size = Vec2::ZERO;
let mut leftover_gap = Vec2::ZERO; let mut leftover_gap = Vec2::ZERO;
@ -156,7 +160,7 @@ impl UiElement for Container {
inner_content_size, inner_content_size,
..Default::default() ..Default::default()
}, },
user_data: None ..Default::default()
} }
} }

View file

@ -40,6 +40,10 @@ impl Default for FillRect {
} }
impl UiElement for FillRect { impl UiElement for FillRect {
fn name(&self) -> &'static str {
"FillRect"
}
fn measure(&self, ctx: MeasureContext) -> Response { fn measure(&self, ctx: MeasureContext) -> Response {
Response { Response {
size: vec2( size: vec2(
@ -54,8 +58,7 @@ impl UiElement for FillRect {
Size::Static(pixels) => pixels, Size::Static(pixels) => pixels,
}, },
), ),
hints: Default::default(), ..Default::default()
user_data: None
} }
} }

View file

@ -49,7 +49,9 @@ impl Default for ProgressBar {
} }
impl UiElement for ProgressBar { impl UiElement for ProgressBar {
fn name(&self) -> &'static str { "Progress bar" } fn name(&self) -> &'static str {
"ProgressBar"
}
fn measure(&self, ctx: MeasureContext) -> Response { fn measure(&self, ctx: MeasureContext) -> Response {
Response { Response {
@ -67,6 +69,7 @@ impl UiElement for ProgressBar {
), ),
hints: Default::default(), hints: Default::default(),
user_data: None, user_data: None,
..Default::default()
} }
} }

View file

@ -18,14 +18,17 @@ impl Default for Spacer {
} }
impl UiElement for Spacer { impl UiElement for Spacer {
fn name(&self) -> &'static str {
"Spacer"
}
fn measure(&self, ctx: MeasureContext) -> Response { fn measure(&self, ctx: MeasureContext) -> Response {
Response { Response {
size: match ctx.layout.direction { size: match ctx.layout.direction {
UiDirection::Horizontal => vec2(self.0, 0.), UiDirection::Horizontal => vec2(self.0, 0.),
UiDirection::Vertical => vec2(0., self.0), UiDirection::Vertical => vec2(0., self.0),
}, },
hints: Default::default(), ..Default::default()
user_data: None
} }
} }

View file

@ -63,6 +63,10 @@ impl Text {
} }
impl UiElement for Text { impl UiElement for Text {
fn name(&self) -> &'static str {
"Text"
}
fn measure(&self, ctx: MeasureContext) -> Response { fn measure(&self, ctx: MeasureContext) -> Response {
let mut size = (0., 0.); let mut size = (0., 0.);
if matches!(self.size.width, Size::Auto) || matches!(self.size.height, Size::Auto) { if matches!(self.size.width, Size::Auto) || matches!(self.size.height, Size::Auto) {
@ -84,8 +88,7 @@ impl UiElement for Text {
Size::Static(pixels) => pixels, Size::Static(pixels) => pixels,
}, },
), ),
hints: Default::default(), ..Default::default()
user_data: None
} }
} }

View file

@ -37,6 +37,10 @@ impl Transformer {
} }
impl UiElement for Transformer { impl UiElement for Transformer {
fn name(&self) -> &'static str {
"Transformer"
}
fn measure(&self, ctx: MeasureContext) -> Response { fn measure(&self, ctx: MeasureContext) -> Response {
self.element.measure(ctx) self.element.measure(ctx)
} }

View file

@ -11,7 +11,18 @@ pub struct Hints {
#[derive(Default)] #[derive(Default)]
pub struct Response { pub struct Response {
/// Computed size of the element
pub size: Vec2, pub size: Vec2,
/// Hints for the layout system, can be used to optimize the layout engine.\
/// These will never cause the UI to be rendered differently (assuming the values are correct)
pub hints: Hints, pub hints: Hints,
/// Arbitrary user data, can be used to pass data (for example, cache) between measure and process stages
pub user_data: Option<Box<dyn std::any::Any>>, pub user_data: Option<Box<dyn std::any::Any>>,
/// If true, the element should always cause the content to wrap to the next line\
/// (the element itself gets wrapped to the next line too)
/// You should almost never set this
pub should_wrap: bool,
} }