From adc5cb5f3bc8dd902f2b251aefcd03cf13644685 Mon Sep 17 00:00:00 2001 From: griffi-gh Date: Mon, 25 Mar 2024 12:57:45 +0100 Subject: [PATCH] more granular control over wrapping --- hui/src/element/builtin/container.rs | 19 ++++++------- hui/src/layout.rs | 40 ++++++++++++++++++++++++++++ 2 files changed, 48 insertions(+), 11 deletions(-) diff --git a/hui/src/element/builtin/container.rs b/hui/src/element/builtin/container.rs index 4a65b60..466bc93 100644 --- a/hui/src/element/builtin/container.rs +++ b/hui/src/element/builtin/container.rs @@ -4,10 +4,10 @@ use derive_setters::Setters; use glam::{Vec2, vec2}; use crate::{ element::{ElementList, MeasureContext, ProcessContext, UiElement}, - layout::{Alignment, Alignment2d, Direction, LayoutInfo, Size, Size2d}, frame::{Frame, FrameRect}, + layout::{Alignment, Alignment2d, Direction, LayoutInfo, Size, Size2d, WrapBehavior}, measure::{Hints, Response}, - rect::{Sides, FillColor}, + rect::Sides, }; //XXX: add Order/Direction::Forward/Reverse or sth? @@ -52,13 +52,9 @@ pub struct Container { #[setters(skip)] pub background_frame: Box, - /// Set this to `true` to allow the elements wrap automatically - /// - /// Disabling/enabling this does not affect explicit wrapping\ - /// (for example, `Br`, or any other element with `should_wrap` set to `true`) - /// - /// This is an experimental feature and may not work as expected - pub wrap: bool, + /// Controls if wrapping is enabled + #[setters(into)] + pub wrap: WrapBehavior, /// List of children elements #[setters(skip)] @@ -86,7 +82,7 @@ impl Default for Container { padding: Sides::all(0.), align: Alignment2d::default(), background_frame: Box::::default(), - wrap: false, + wrap: WrapBehavior::Allow, children: ElementList(Vec::new()), } } @@ -189,7 +185,8 @@ impl UiElement for Container { }; //Wrap the element if it exceeds container's size and is not the first element in the line - if ((self.wrap && (end_pos_pri > max_line_pri)) || measure.should_wrap) && (line_element_count > 0) { + let should_wrap_overflow = self.wrap.is_enabled() && (end_pos_pri > max_line_pri); + if self.wrap.is_allowed() && line_element_count > 0 && (measure.should_wrap || should_wrap_overflow) { // >>>>>>> WRAP THAT B*TCH! //Negate the leftover gap from the previous element diff --git a/hui/src/layout.rs b/hui/src/layout.rs index 064e3bc..12e8a13 100644 --- a/hui/src/layout.rs +++ b/hui/src/layout.rs @@ -2,6 +2,46 @@ use glam::{vec2, Vec2}; +/// Controls wrapping behavior of elements +#[derive(Clone, Copy, PartialEq, Eq, Debug, PartialOrd, Ord, Default)] +pub enum WrapBehavior { + /// No wrapping is allowed, even if explicit line breaks is requested by the element + Disable = 0, + + /// Allow wrapping if the element explicitly requests it (default behavior) + #[default] + Allow = 1, + + /// Elements will be wrapped automatically when they reach the maximum width/height of the container + Enable = 2, +} + +impl From for WrapBehavior { + #[inline] + fn from(value: bool) -> Self { + match value { + true => Self::Enable, + false => Self::Disable, + } + } +} + +impl WrapBehavior { + /// Check if wrapping is allowed for the element + #[inline] + pub fn is_allowed(&self) -> bool { + *self != Self::Disable + } + + /// Check if wrapping is enabled for the element + /// + /// (Wrapping will be done automatically when the element reaches the maximum width/height) + #[inline] + pub fn is_enabled(&self) -> bool { + *self == Self::Enable + } +} + /// Alignment along a single axis #[derive(Clone, Copy, PartialEq, Eq, Debug, Default, PartialOrd, Ord)] pub enum Alignment {