[go: up one dir, main page]

BoxConstraints

Struct BoxConstraints 

Source
pub struct BoxConstraints { /* private fields */ }
Expand description

Constraints for layout.

The layout strategy for Druid is strongly inspired by Flutter, and this struct is similar to the Flutter BoxConstraints class.

At the moment, it represents simply a minimum and maximum size. A widget’s layout method should choose an appropriate size that meets these constraints.

Further, a container widget should compute appropriate constraints for each of its child widgets, and pass those down when recursing.

The constraints are always rounded away from zero to integers to enable pixel perfect layout.

Implementations§

Source§

impl BoxConstraints

Source

pub const UNBOUNDED: BoxConstraints

An unbounded box constraints object.

Can be satisfied by any nonnegative size.

Source

pub fn new(min: Size, max: Size) -> BoxConstraints

Create a new box constraints object.

Create constraints based on minimum and maximum size.

The given sizes are also rounded away from zero, so that the layout is aligned to integers.

Examples found in repository?
examples/input_region.rs (lines 128-131)
120    fn layout(
121        &mut self,
122        ctx: &mut druid::LayoutCtx,
123        bc: &druid::BoxConstraints,
124        data: &AppState,
125        env: &druid::Env,
126    ) -> druid::Size {
127        let mut interactable_area = Region::EMPTY;
128        let smaller_bc = BoxConstraints::new(
129            Size::new(0.0, 0.0),
130            Size::new(bc.max().width - 100.0, bc.max().height - 100.0),
131        );
132        let full_bc = BoxConstraints::new(Size::new(0.0, 0.0), bc.max());
133        let _label_size = self.info_label.layout(ctx, &smaller_bc, data, env);
134        let controls_size = self.controls.layout(ctx, &full_bc, data, env);
135
136        let text_origin_point = Point::new(50.0, 50.0 + controls_size.height);
137        self.info_label.set_origin(ctx, text_origin_point);
138        let controls_origin_point = Point::new(EXAMPLE_BORDER_SIZE, EXAMPLE_BORDER_SIZE);
139        self.controls.set_origin(ctx, controls_origin_point);
140
141        // Add side rects to clarify the dimensions of the window.
142        let left_rect = Rect::new(0.0, 0.0, EXAMPLE_BORDER_SIZE, bc.max().height);
143        let right_rect = Rect::new(
144            bc.max().width - EXAMPLE_BORDER_SIZE,
145            0.0,
146            bc.max().width,
147            bc.max().height,
148        );
149        let bottom_rect = Rect::new(
150            0.0,
151            bc.max().height - EXAMPLE_BORDER_SIZE,
152            bc.max().width,
153            bc.max().height,
154        );
155        interactable_area.add_rect(left_rect);
156        interactable_area.add_rect(right_rect);
157        interactable_area.add_rect(bottom_rect);
158        interactable_area.add_rect(self.info_label.layout_rect());
159        interactable_area.add_rect(self.controls.layout_rect());
160
161        if data.limit_input_region {
162            ctx.window().set_input_region(Some(interactable_area));
163        } else {
164            ctx.window().set_input_region(None);
165        }
166
167        bc.max()
168    }
Source

pub fn tight(size: Size) -> BoxConstraints

Create a “tight” box constraints object.

A “tight” constraint can only be satisfied by a single size.

The given size is also rounded away from zero, so that the layout is aligned to integers.

Source

pub fn loosen(&self) -> BoxConstraints

Create a “loose” version of the constraints.

Make a version with zero minimum size, but the same maximum size.

Examples found in repository?
examples/timer.rs (line 78)
77    fn layout(&mut self, ctx: &mut LayoutCtx, bc: &BoxConstraints, data: &u32, env: &Env) -> Size {
78        self.simple_box.layout(ctx, &bc.loosen(), data, env);
79        self.simple_box.set_origin(ctx, self.pos);
80        bc.constrain((500.0, 500.0))
81    }
Source

pub fn constrain(&self, size: impl Into<Size>) -> Size

Clamp a given size so that it fits within the constraints.

The given size is also rounded away from zero, so that the layout is aligned to integers.

Examples found in repository?
examples/scroll.rs (line 58)
56    fn layout(&mut self, ctx: &mut LayoutCtx, bc: &BoxConstraints, _: &T, _: &Env) -> Size {
57        ctx.set_paint_insets(INSETS);
58        bc.constrain(Size::new(100., 100.))
59    }
More examples
Hide additional examples
examples/anim.rs (line 71)
64    fn layout(
65        &mut self,
66        _layout_ctx: &mut LayoutCtx,
67        bc: &BoxConstraints,
68        _data: &(),
69        _env: &Env,
70    ) -> Size {
71        bc.constrain((100.0, 100.0))
72    }
examples/sub_window.rs (line 271)
264    fn layout(
265        &mut self,
266        _ctx: &mut LayoutCtx,
267        bc: &BoxConstraints,
268        _data: &(),
269        _env: &Env,
270    ) -> Size {
271        bc.constrain(Size::new(800.0, 600.0))
272    }
examples/timer.rs (line 80)
77    fn layout(&mut self, ctx: &mut LayoutCtx, bc: &BoxConstraints, data: &u32, env: &Env) -> Size {
78        self.simple_box.layout(ctx, &bc.loosen(), data, env);
79        self.simple_box.set_origin(ctx, self.pos);
80        bc.constrain((500.0, 500.0))
81    }
82
83    fn paint(&mut self, ctx: &mut PaintCtx, data: &u32, env: &Env) {
84        self.simple_box.paint(ctx, data, env);
85    }
86}
87
88struct SimpleBox;
89
90impl Widget<u32> for SimpleBox {
91    fn event(&mut self, _ctx: &mut EventCtx, _event: &Event, _data: &mut u32, _env: &Env) {}
92
93    fn lifecycle(&mut self, ctx: &mut LifeCycleCtx, event: &LifeCycle, _data: &u32, _env: &Env) {
94        if let LifeCycle::HotChanged(_) = event {
95            ctx.request_paint();
96        }
97    }
98
99    fn update(&mut self, _ctx: &mut UpdateCtx, _old_data: &u32, _data: &u32, _env: &Env) {}
100
101    fn layout(
102        &mut self,
103        _ctx: &mut LayoutCtx,
104        bc: &BoxConstraints,
105        _data: &u32,
106        _env: &Env,
107    ) -> Size {
108        bc.constrain((50.0, 50.0))
109    }
examples/custom_widget.rs (line 70)
48    fn layout(
49        &mut self,
50        _layout_ctx: &mut LayoutCtx,
51        bc: &BoxConstraints,
52        _data: &String,
53        _env: &Env,
54    ) -> Size {
55        // BoxConstraints are passed by the parent widget.
56        // This method can return any Size within those constraints:
57        // bc.constrain(my_size)
58        //
59        // To check if a dimension is infinite or not (e.g. scrolling):
60        // bc.is_width_bounded() / bc.is_height_bounded()
61        //
62        // bx.max() returns the maximum size of the widget. Be careful
63        // using this, since always make sure the widget is bounded.
64        // If bx.max() is used in a scrolling widget things will probably
65        // not work correctly.
66        if bc.is_width_bounded() && bc.is_height_bounded() {
67            bc.max()
68        } else {
69            let size = Size::new(100.0, 100.0);
70            bc.constrain(size)
71        }
72    }
Source

pub fn max(&self) -> Size

Returns the max size of these constraints.

Examples found in repository?
examples/invalidation.rs (line 134)
127    fn layout(
128        &mut self,
129        _ctx: &mut LayoutCtx,
130        bc: &BoxConstraints,
131        _data: &Vector<Circle>,
132        _env: &Env,
133    ) -> Size {
134        bc.max()
135    }
More examples
Hide additional examples
examples/game_of_life.rs (line 289)
282    fn layout(
283        &mut self,
284        _layout_ctx: &mut LayoutCtx,
285        bc: &BoxConstraints,
286        _data: &AppData,
287        _env: &Env,
288    ) -> Size {
289        let max_size = bc.max();
290        let min_side = max_size.height.min(max_size.width);
291        Size {
292            width: min_side,
293            height: min_side,
294        }
295    }
examples/custom_widget.rs (line 67)
48    fn layout(
49        &mut self,
50        _layout_ctx: &mut LayoutCtx,
51        bc: &BoxConstraints,
52        _data: &String,
53        _env: &Env,
54    ) -> Size {
55        // BoxConstraints are passed by the parent widget.
56        // This method can return any Size within those constraints:
57        // bc.constrain(my_size)
58        //
59        // To check if a dimension is infinite or not (e.g. scrolling):
60        // bc.is_width_bounded() / bc.is_height_bounded()
61        //
62        // bx.max() returns the maximum size of the widget. Be careful
63        // using this, since always make sure the widget is bounded.
64        // If bx.max() is used in a scrolling widget things will probably
65        // not work correctly.
66        if bc.is_width_bounded() && bc.is_height_bounded() {
67            bc.max()
68        } else {
69            let size = Size::new(100.0, 100.0);
70            bc.constrain(size)
71        }
72    }
examples/input_region.rs (line 130)
120    fn layout(
121        &mut self,
122        ctx: &mut druid::LayoutCtx,
123        bc: &druid::BoxConstraints,
124        data: &AppState,
125        env: &druid::Env,
126    ) -> druid::Size {
127        let mut interactable_area = Region::EMPTY;
128        let smaller_bc = BoxConstraints::new(
129            Size::new(0.0, 0.0),
130            Size::new(bc.max().width - 100.0, bc.max().height - 100.0),
131        );
132        let full_bc = BoxConstraints::new(Size::new(0.0, 0.0), bc.max());
133        let _label_size = self.info_label.layout(ctx, &smaller_bc, data, env);
134        let controls_size = self.controls.layout(ctx, &full_bc, data, env);
135
136        let text_origin_point = Point::new(50.0, 50.0 + controls_size.height);
137        self.info_label.set_origin(ctx, text_origin_point);
138        let controls_origin_point = Point::new(EXAMPLE_BORDER_SIZE, EXAMPLE_BORDER_SIZE);
139        self.controls.set_origin(ctx, controls_origin_point);
140
141        // Add side rects to clarify the dimensions of the window.
142        let left_rect = Rect::new(0.0, 0.0, EXAMPLE_BORDER_SIZE, bc.max().height);
143        let right_rect = Rect::new(
144            bc.max().width - EXAMPLE_BORDER_SIZE,
145            0.0,
146            bc.max().width,
147            bc.max().height,
148        );
149        let bottom_rect = Rect::new(
150            0.0,
151            bc.max().height - EXAMPLE_BORDER_SIZE,
152            bc.max().width,
153            bc.max().height,
154        );
155        interactable_area.add_rect(left_rect);
156        interactable_area.add_rect(right_rect);
157        interactable_area.add_rect(bottom_rect);
158        interactable_area.add_rect(self.info_label.layout_rect());
159        interactable_area.add_rect(self.controls.layout_rect());
160
161        if data.limit_input_region {
162            ctx.window().set_input_region(Some(interactable_area));
163        } else {
164            ctx.window().set_input_region(None);
165        }
166
167        bc.max()
168    }
Source

pub fn min(&self) -> Size

Returns the min size of these constraints.

Source

pub fn is_width_bounded(&self) -> bool

Whether there is an upper bound on the width.

Examples found in repository?
examples/custom_widget.rs (line 66)
48    fn layout(
49        &mut self,
50        _layout_ctx: &mut LayoutCtx,
51        bc: &BoxConstraints,
52        _data: &String,
53        _env: &Env,
54    ) -> Size {
55        // BoxConstraints are passed by the parent widget.
56        // This method can return any Size within those constraints:
57        // bc.constrain(my_size)
58        //
59        // To check if a dimension is infinite or not (e.g. scrolling):
60        // bc.is_width_bounded() / bc.is_height_bounded()
61        //
62        // bx.max() returns the maximum size of the widget. Be careful
63        // using this, since always make sure the widget is bounded.
64        // If bx.max() is used in a scrolling widget things will probably
65        // not work correctly.
66        if bc.is_width_bounded() && bc.is_height_bounded() {
67            bc.max()
68        } else {
69            let size = Size::new(100.0, 100.0);
70            bc.constrain(size)
71        }
72    }
Source

pub fn is_height_bounded(&self) -> bool

Whether there is an upper bound on the height.

Examples found in repository?
examples/custom_widget.rs (line 66)
48    fn layout(
49        &mut self,
50        _layout_ctx: &mut LayoutCtx,
51        bc: &BoxConstraints,
52        _data: &String,
53        _env: &Env,
54    ) -> Size {
55        // BoxConstraints are passed by the parent widget.
56        // This method can return any Size within those constraints:
57        // bc.constrain(my_size)
58        //
59        // To check if a dimension is infinite or not (e.g. scrolling):
60        // bc.is_width_bounded() / bc.is_height_bounded()
61        //
62        // bx.max() returns the maximum size of the widget. Be careful
63        // using this, since always make sure the widget is bounded.
64        // If bx.max() is used in a scrolling widget things will probably
65        // not work correctly.
66        if bc.is_width_bounded() && bc.is_height_bounded() {
67            bc.max()
68        } else {
69            let size = Size::new(100.0, 100.0);
70            bc.constrain(size)
71        }
72    }
Source

pub fn debug_check(&self, name: &str)

Check to see if these constraints are legit.

Logs a warning if BoxConstraints are invalid.

Source

pub fn shrink(&self, diff: impl Into<Size>) -> BoxConstraints

Shrink min and max constraints by size

The given size is also rounded away from zero, so that the layout is aligned to integers.

Source

pub fn contains(&self, size: impl Into<Size>) -> bool

Test whether these constraints contain the given Size.

Source

pub fn constrain_aspect_ratio(&self, aspect_ratio: f64, width: f64) -> Size

Find the Size within these BoxConstraints that minimises the difference between the returned Size’s aspect ratio and aspect_ratio, where aspect ratio is defined as height / width.

If multiple Sizes give the optimal aspect_ratio, then the one with the width nearest the supplied width will be used. Specifically, if width == 0.0 then the smallest possible Size will be chosen, and likewise if width == f64::INFINITY, then the largest Size will be chosen.

Use this function when maintaining an aspect ratio is more important than minimizing the distance between input and output size width and height.

Source

pub fn unbound_max(&self, axis: Axis) -> Self

Sets the max on a given axis to infinity.

Source

pub fn unbound_max_width(&self) -> Self

Sets max width to infinity.

Source

pub fn unbound_max_height(&self) -> Self

Sets max height to infinity.

Source

pub fn shrink_max_to(&self, axis: Axis, dim: f64) -> Self

Shrinks the max dimension on the given axis. Does NOT shrink beyond min.

Source

pub fn shrink_max_width_to(&self, dim: f64) -> Self

Shrinks the max width to dim. Does NOT shrink beyond min width.

Source

pub fn shrink_max_height_to(&self, dim: f64) -> Self

Shrinks the max height to dim. Does NOT shrink beyond min height.

Trait Implementations§

Source§

impl Clone for BoxConstraints

Source§

fn clone(&self) -> BoxConstraints

Returns a duplicate of the value. Read more
1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for BoxConstraints

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl PartialEq for BoxConstraints

Source§

fn eq(&self, other: &BoxConstraints) -> bool

Tests for self and other values to be equal, and is used by ==.
1.0.0 · Source§

fn ne(&self, other: &Rhs) -> bool

Tests for !=. The default implementation is almost always sufficient, and should not be overridden without very good reason.
Source§

impl Copy for BoxConstraints

Source§

impl StructuralPartialEq for BoxConstraints

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> AnyEq for T
where T: Any + PartialEq,

Source§

fn equals(&self, other: &(dyn Any + 'static)) -> bool

Source§

fn as_any(&self) -> &(dyn Any + 'static)

Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> RoundFrom<T> for T

Source§

fn round_from(x: T) -> T

Performs the conversion.
Source§

impl<T, U> RoundInto<U> for T
where U: RoundFrom<T>,

Source§

fn round_into(self) -> U

Performs the conversion.
Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more