Struct kas_core::layout::Margins

source ·
pub struct Margins {
    pub horiz: (u16, u16),
    pub vert: (u16, u16),
}
Expand description

Margin sizes

Used by the layout system for margins around child widgets. Margins may be drawn in and handle events like any other widget area.

Fields§

§horiz: (u16, u16)

Size of horizontal margins

§vert: (u16, u16)

Size of vertical margins

Implementations§

Zero-sized margins

Margins with equal size on each edge.

Examples found in repository?
src/layout/size_types.rs (line 125)
125
    pub const ZERO: Margins = Margins::splat(0);

Margins via horizontal and vertical sizes

Examples found in repository?
src/layout/sizer.rs (line 149)
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
    pub fn find_constraints(widget: &mut dyn Widget, size_mgr: SizeMgr) -> Self {
        let start = std::time::Instant::now();

        let w = widget.size_rules(size_mgr.re(), AxisInfo::new(false, None, None));
        let h = widget.size_rules(
            size_mgr.re(),
            AxisInfo::new(true, Some(w.ideal_size()), None),
        );

        let min = Size(w.min_size(), h.min_size());
        let ideal = Size(w.ideal_size(), h.ideal_size());
        let margins = Margins::hv(w.margins(), h.margins());

        log::trace!(
            target: "kas_perf::layout", "find_constraints: {}μs",
            start.elapsed().as_micros(),
        );
        log::debug!("find_constraints: min={min:?}, ideal={ideal:?}, margins={margins:?}");
        let refresh_rules = false;
        let last_width = ideal.0;
        SolveCache {
            min,
            ideal,
            margins,
            refresh_rules,
            last_width,
        }
    }

Margins via horizontal and vertical sizes

Examples found in repository?
src/layout/size_types.rs (line 130)
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
    pub const fn splat(size: u16) -> Self {
        Margins::hv_splat((size, size))
    }

    /// Margins via horizontal and vertical sizes
    #[inline]
    pub const fn hv(horiz: (u16, u16), vert: (u16, u16)) -> Self {
        Margins { horiz, vert }
    }

    /// Margins via horizontal and vertical sizes
    #[inline]
    pub const fn hv_splat((h, v): (u16, u16)) -> Self {
        Margins {
            horiz: (h, h),
            vert: (v, v),
        }
    }

    /// Sum of horizontal margins
    #[inline]
    pub fn sum_horiz(&self) -> i32 {
        i32::from(self.horiz.0) + i32::from(self.horiz.1)
    }

    /// Sum of vertical margins
    #[inline]
    pub fn sum_vert(&self) -> i32 {
        i32::from(self.vert.0) + i32::from(self.vert.1)
    }

    /// Pad a size with margins
    pub fn pad(self, size: Size) -> Size {
        Size::new(size.0 + self.sum_horiz(), size.1 + self.sum_vert())
    }

    /// Extract one component, based on a direction
    ///
    /// This merely extracts the horizontal or vertical component.
    /// It never negates it, even if the axis is reversed.
    #[inline]
    pub fn extract<D: Directional>(self, dir: D) -> (u16, u16) {
        match dir.is_vertical() {
            false => self.horiz,
            true => self.vert,
        }
    }
}

impl From<Size> for Margins {
    fn from(size: Size) -> Self {
        Margins::hv_splat(size.cast())
    }

Sum of horizontal margins

Examples found in repository?
src/layout/size_types.rs (line 162)
161
162
163
    pub fn pad(self, size: Size) -> Size {
        Size::new(size.0 + self.sum_horiz(), size.1 + self.sum_vert())
    }
More examples
Hide additional examples
src/layout/sizer.rs (line 198)
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
    pub fn apply_rect(
        &mut self,
        widget: &mut dyn Widget,
        mgr: &mut ConfigMgr,
        mut rect: Rect,
        inner_margin: bool,
        print_heirarchy: bool,
    ) {
        let start = std::time::Instant::now();

        let mut width = rect.size.0;
        if inner_margin {
            width -= self.margins.sum_horiz();
        }

        // We call size_rules not because we want the result, but to allow
        // internal layout solving.
        if self.refresh_rules || width != self.last_width {
            if self.refresh_rules {
                let w = widget.size_rules(mgr.size_mgr(), AxisInfo::new(false, None, None));
                self.min.0 = w.min_size();
                self.ideal.0 = w.ideal_size();
                self.margins.horiz = w.margins();
                width = rect.size.0 - self.margins.sum_horiz();
            }

            let h = widget.size_rules(mgr.size_mgr(), AxisInfo::new(true, Some(width), None));
            self.min.1 = h.min_size();
            self.ideal.1 = h.ideal_size();
            self.margins.vert = h.margins();
            self.last_width = width;
        }

        if inner_margin {
            rect.pos += Size::conv((self.margins.horiz.0, self.margins.vert.0));
            rect.size.0 = width;
            rect.size.1 -= self.margins.sum_vert();
        }
        widget.set_rect(mgr, rect);

        log::trace!(target: "kas_perf::layout", "apply_rect: {}μs", start.elapsed().as_micros());
        if print_heirarchy {
            log::trace!(
                target: "kas_core::layout::hierarchy",
                "apply_rect: rect={rect:?}:{}",
                WidgetHeirarchy(widget, 0),
            );
        }

        self.refresh_rules = false;
    }

Sum of vertical margins

Examples found in repository?
src/layout/size_types.rs (line 162)
161
162
163
    pub fn pad(self, size: Size) -> Size {
        Size::new(size.0 + self.sum_horiz(), size.1 + self.sum_vert())
    }
More examples
Hide additional examples
src/layout/sizer.rs (line 222)
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
    pub fn apply_rect(
        &mut self,
        widget: &mut dyn Widget,
        mgr: &mut ConfigMgr,
        mut rect: Rect,
        inner_margin: bool,
        print_heirarchy: bool,
    ) {
        let start = std::time::Instant::now();

        let mut width = rect.size.0;
        if inner_margin {
            width -= self.margins.sum_horiz();
        }

        // We call size_rules not because we want the result, but to allow
        // internal layout solving.
        if self.refresh_rules || width != self.last_width {
            if self.refresh_rules {
                let w = widget.size_rules(mgr.size_mgr(), AxisInfo::new(false, None, None));
                self.min.0 = w.min_size();
                self.ideal.0 = w.ideal_size();
                self.margins.horiz = w.margins();
                width = rect.size.0 - self.margins.sum_horiz();
            }

            let h = widget.size_rules(mgr.size_mgr(), AxisInfo::new(true, Some(width), None));
            self.min.1 = h.min_size();
            self.ideal.1 = h.ideal_size();
            self.margins.vert = h.margins();
            self.last_width = width;
        }

        if inner_margin {
            rect.pos += Size::conv((self.margins.horiz.0, self.margins.vert.0));
            rect.size.0 = width;
            rect.size.1 -= self.margins.sum_vert();
        }
        widget.set_rect(mgr, rect);

        log::trace!(target: "kas_perf::layout", "apply_rect: {}μs", start.elapsed().as_micros());
        if print_heirarchy {
            log::trace!(
                target: "kas_core::layout::hierarchy",
                "apply_rect: rect={rect:?}:{}",
                WidgetHeirarchy(widget, 0),
            );
        }

        self.refresh_rules = false;
    }

Pad a size with margins

Examples found in repository?
src/layout/sizer.rs (line 113)
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
    pub fn min(&self, inner_margin: bool) -> Size {
        if inner_margin {
            self.margins.pad(self.min)
        } else {
            self.min
        }
    }

    /// Get the ideal size
    ///
    /// If `inner_margin` is true, margins are included in the result.
    pub fn ideal(&self, inner_margin: bool) -> Size {
        if inner_margin {
            self.margins.pad(self.ideal)
        } else {
            self.ideal
        }
    }

Extract one component, based on a direction

This merely extracts the horizontal or vertical component. It never negates it, even if the axis is reversed.

Examples found in repository?
src/layout/size_rules.rs (line 145)
143
144
145
146
147
    pub fn extract<D: Directional>(dir: D, size: Size, margins: Margins, stretch: Stretch) -> Self {
        let size = size.extract(dir);
        let m = margins.extract(dir);
        SizeRules::new(size, size, m, stretch)
    }
More examples
Hide additional examples
src/layout/size_types.rs (line 254)
253
254
255
256
257
258
259
260
261
262
263
264
265
266
    pub fn size_rules(&mut self, mgr: SizeMgr, axis: AxisInfo) -> SizeRules {
        let margins = mgr.margins(self.margins).extract(axis);
        let scale_factor = mgr.scale_factor();
        let min = self
            .size
            .to_physical(scale_factor * self.min_factor)
            .extract(axis);
        let ideal = self
            .size
            .to_physical(scale_factor * self.ideal_factor)
            .extract(axis);
        self.align.set_component(axis, axis.align_or_center());
        SizeRules::new(min, ideal, margins, self.stretch)
    }
src/layout/visitor.rs (line 229)
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
    fn size_rules_(&mut self, mgr: SizeMgr, axis: AxisInfo) -> SizeRules {
        match &mut self.layout {
            LayoutType::None => SizeRules::EMPTY,
            LayoutType::Component(component) => component.size_rules(mgr, axis),
            LayoutType::BoxComponent(component) => component.size_rules(mgr, axis),
            LayoutType::Single(child) => child.size_rules(mgr, axis),
            LayoutType::AlignSingle(child, hints) => {
                child.size_rules(mgr, axis.with_align_hints(*hints))
            }
            LayoutType::Align(layout, hints) => {
                layout.size_rules_(mgr, axis.with_align_hints(*hints))
            }
            LayoutType::Pack(layout, stor, hints) => {
                let rules = layout.size_rules_(mgr, stor.apply_align(axis, *hints));
                stor.size.set_component(axis, rules.ideal_size());
                rules
            }
            LayoutType::Margins(child, dirs, margins) => {
                let mut child_rules = child.size_rules_(mgr.re(), axis);
                if dirs.intersects(Directions::from(axis)) {
                    let mut rule_margins = child_rules.margins();
                    let margins = mgr.margins(*margins).extract(axis);
                    if dirs.intersects(Directions::LEFT | Directions::UP) {
                        rule_margins.0 = margins.0;
                    }
                    if dirs.intersects(Directions::RIGHT | Directions::DOWN) {
                        rule_margins.1 = margins.1;
                    }
                    child_rules.set_margins(rule_margins);
                }
                child_rules
            }
            LayoutType::Frame(child, storage, style) => {
                let child_rules = child.size_rules_(mgr.re(), storage.child_axis(axis));
                storage.size_rules(mgr, axis, child_rules, *style)
            }
            LayoutType::Button(child, storage, _) => {
                let child_rules = child.size_rules_(mgr.re(), storage.child_axis_centered(axis));
                storage.size_rules(mgr, axis, child_rules, FrameStyle::Button)
            }
        }
    }

Trait Implementations§

Returns a copy of the value. Read more
Performs copy-assignment from source. Read more
Formats the value using the given formatter. Read more
Returns the “default value” for a type. Read more
Converts to this type from the input type.
This method tests for self and other values to be equal, and is used by ==.
This method tests for !=. The default implementation is almost always sufficient, and should not be overridden without very good reason.

Auto Trait Implementations§

Blanket Implementations§

Gets the TypeId of self. Read more
Immutably borrows from an owned value. Read more
Mutably borrows from an owned value. Read more
Cast from Self to T Read more
Try converting from Self to T Read more
Try approximate conversion from Self to T Read more
Cast approximately from Self to T Read more
Cast to integer, truncating Read more
Cast to the nearest integer Read more
Cast the floor to an integer Read more
Cast the ceiling to an integer Read more
Try converting to integer with truncation Read more
Try converting to the nearest integer Read more
Try converting the floor to an integer Read more
Try convert the ceiling to an integer Read more
Compare self to key and return true if they are equal.

Returns the argument unchanged.

Calls U::from(self).

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

The resulting type after obtaining ownership.
Creates owned data from borrowed data, usually by cloning. Read more
Uses borrowed data to replace owned data, usually by cloning. Read more
The type returned in the event of a conversion error.
Performs the conversion.
The type returned in the event of a conversion error.
Performs the conversion.