conrod_core/position/
mod.rs

1//! Items related to 2D positioning, used throughout conrod.
2
3use widget;
4use Ui;
5
6pub use self::range::{Edge, Range};
7pub use self::rect::{Corner, Rect};
8//pub use self::matrix::Matrix;
9
10//pub mod matrix;
11pub mod range;
12pub mod rect;
13
14/// An alias over the Scalar type used throughout Conrod.
15///
16/// This type is primarily used for spatial dimensions and positioning.
17pub type Scalar = f64;
18
19/// The depth at which the widget will be rendered.
20///
21/// This determines the order of rendering where widgets with a greater depth will be rendered
22/// first.
23///
24/// 0.0 is the default depth.
25pub type Depth = f32;
26
27/// General use 2D spatial dimensions.
28pub type Dimensions = [Scalar; 2];
29
30/// General use 2D spatial point.
31pub type Point = [Scalar; 2];
32
33/// The margin for some `Place`ment on either end of an axis.
34pub type Margin = Scalar;
35
36/// Represents either **Axis** in the 2-dimensional plane.
37#[derive(Copy, Clone, Debug, PartialEq, Eq)]
38pub enum Axis {
39    /// The horizontal plane's Axis.
40    X,
41    /// The vertical plane's Axis.
42    Y,
43}
44
45/// Some **Position** of some **Widget** along a single axis.
46///
47/// **Position**s for both the *x* and *y* axes are stored internally within the
48/// **widget::CommonBuilder** type, allowing all widgets to be positioned in a variety of different
49/// ways.
50///
51/// See the [**Positionable**](./trait.Positionable) trait for methods that allow for setting the
52/// **Position**s in various ways.
53///
54/// Note that **Positionable** is implemented for *all* types that implement **Widget**.
55#[derive(Copy, Clone, Debug, PartialEq)]
56pub enum Position {
57    /// A specific position.
58    Absolute(Scalar),
59    /// A position relative to some other Widget.
60    Relative(Relative, Option<widget::Id>),
61}
62
63/// Positions that are described as **Relative** to some other **Widget**.
64///
65/// **Relative** describes a relative position along a single axis.
66#[derive(Copy, Clone, Debug, PartialEq)]
67pub enum Relative {
68    /// A relative scalar distance.
69    Scalar(Scalar),
70    /// Aligned to either the `Start`, `Middle` or `End`.
71    Align(Align),
72    /// A distance as a `Scalar` value over the given `Direction`.
73    Direction(Direction, Scalar),
74    /// Some place on top of another widget.
75    ///
76    /// Similar to `Align`, but represents the `Start`/`End` of the other widget's `kid_area`.
77    ///
78    /// Also allows for specifying a `Margin` from either end.
79    ///
80    /// Using `Place` allows the `Ui` to infer the widget's parent as the widget upon which it is
81    /// `Placed`, though this inferrence only occurs if the `parent` was not specifically set.
82    Place(Place),
83}
84
85/// Directionally positioned, normally relative to some other widget.
86#[derive(Copy, Clone, Debug, PartialEq, Eq)]
87pub enum Direction {
88    /// Positioned forwards (*positive* **Scalar**) along some **Axis**.
89    Forwards,
90    /// Positioned backwards (*negative* **Scalar**) along some **Axis**.
91    Backwards,
92}
93
94/// The orientation of **Align**ment along some **Axis**.
95#[derive(Copy, Clone, Debug, PartialEq, Eq)]
96pub enum Align {
97    /// **Align** our **Start** with the **Start** of some other widget along the **Axis**.
98    Start,
99    /// **Align** our **Middle** with the **Middle** of some other widget along the **Axis**.
100    Middle,
101    /// **Align** our **End** with the **End** of some other widget along the **Axis**.
102    End,
103}
104
105/// Place the widget at a position on some other widget.
106#[derive(Copy, Clone, Debug, PartialEq)]
107pub enum Place {
108    /// Place upon the **Start** of the Widget's `kid_area`.
109    Start(Option<Margin>),
110    /// Place upon the **Middle** of the Widget's `kid_area`.
111    Middle,
112    /// Place upon the **End** of the Widget's `kid_area`.
113    End(Option<Margin>),
114}
115
116/// The length of a **Widget** over either the *x* or *y* axes.
117///
118/// This type is used to represent the different ways in which a dimension may be sized.
119///
120/// See the [**Sizeable**](./trait.Sizeable) trait for methods that allow for setting the
121/// `x` and `y` **Dimension**s in various ways.
122///
123/// Note that **Sizeable** is implemented for *all* types that implement **Widget**.
124#[derive(Copy, Clone, Debug, PartialEq)]
125pub enum Dimension {
126    /// Some specific length has been given.
127    Absolute(Scalar),
128    /// The dimension should match that of the widget at the given index.
129    ///
130    /// The `Option<Scalar>` is an optional padding argument which when `Some`, will subtract the
131    /// scalar from both ends of the other widget's dimension.
132    Of(widget::Id, Option<Scalar>),
133    /// The dimension should match that of the `kid_area` of the widget at the given index.
134    ///
135    /// The `Option<Scalar>` is an optional padding argument which when `Some`, will subtract the
136    /// scalar from both ends of the other widget's dimension.
137    KidAreaOf(widget::Id, Option<Scalar>),
138}
139
140/// Widgets that are positionable.
141///
142/// A **Position** is stored internally within the **widget::CommonBuilder** type, allowing all
143/// widgets to be positioned in a variety of different ways.
144///
145/// Thus, **Positionable** can be implemented for *all* types that implement **Widget**.
146pub trait Positionable: Sized {
147    /// Build with the given **Position** along the *x* axis.
148    fn x_position(self, x: Position) -> Self;
149
150    /// Build with the given **Position** along the *y* axis.
151    fn y_position(self, y: Position) -> Self;
152
153    /// Get the **Position** along the *x* axis.
154    fn get_x_position(&self, ui: &Ui) -> Position;
155
156    /// Get the **Position** along the *y* axis.
157    fn get_y_position(&self, ui: &Ui) -> Position;
158
159    // Absolute positioning.
160
161    /// Build with the given **Absolute** **Position** along the *x* axis.
162    fn x(self, x: Scalar) -> Self {
163        self.x_position(Position::Absolute(x))
164    }
165
166    /// Build with the given **Absolute** **Position** along the *y* axis.
167    fn y(self, y: Scalar) -> Self {
168        self.y_position(Position::Absolute(y))
169    }
170
171    /// Set the **Position** with some Point.
172    fn xy(self, point: Point) -> Self {
173        self.x(point[0]).y(point[1])
174    }
175
176    /// Set the **Position** with *x* *y* coordinates.
177    fn x_y(self, x: Scalar, y: Scalar) -> Self {
178        self.xy([x, y])
179    }
180
181    // Relative positioning.
182
183    /// Set the *x* **Position** **Relative** to the previous widget.
184    fn x_position_relative(self, x: Relative) -> Self {
185        self.x_position(Position::Relative(x, None))
186    }
187
188    /// Set the *y* **Position** **Relative** to the previous widget.
189    fn y_position_relative(self, y: Relative) -> Self {
190        self.y_position(Position::Relative(y, None))
191    }
192
193    /// Set the *x* and *y* **Position**s **Relative** to the previous widget.
194    fn x_y_position_relative(self, x: Relative, y: Relative) -> Self {
195        self.x_position_relative(x).y_position_relative(y)
196    }
197
198    /// Set the *x* **Position** **Relative** to the given widget.
199    fn x_position_relative_to(self, other: widget::Id, x: Relative) -> Self {
200        self.x_position(Position::Relative(x, Some(other)))
201    }
202
203    /// Set the *y* **Position** **Relative** to the given widget.
204    fn y_position_relative_to(self, other: widget::Id, y: Relative) -> Self {
205        self.y_position(Position::Relative(y, Some(other)))
206    }
207
208    /// Set the *x* and *y* **Position**s **Relative** to the given widget.
209    fn x_y_position_relative_to(self, other: widget::Id, x: Relative, y: Relative) -> Self {
210        self.x_position_relative_to(other, x)
211            .y_position_relative_to(other, y)
212    }
213
214    // Relative `Scalar` positioning.
215
216    /// Set the **Position** as a **Scalar** along the *x* axis **Relative** to the middle of
217    /// previous widget.
218    fn x_relative(self, x: Scalar) -> Self {
219        self.x_position_relative(Relative::Scalar(x))
220    }
221
222    /// Set the **Position** as a **Scalar** along the *y* axis **Relative** to the middle of
223    /// previous widget.
224    fn y_relative(self, y: Scalar) -> Self {
225        self.y_position_relative(Relative::Scalar(y))
226    }
227
228    /// Set the **Position** as a **Point** **Relative** to the middle of the previous widget.
229    fn xy_relative(self, point: Point) -> Self {
230        self.x_relative(point[0]).y_relative(point[1])
231    }
232
233    /// Set the **Position** as **Scalar**s along the *x* and *y* axes **Relative** to the middle
234    /// of the previous widget.
235    fn x_y_relative(self, x: Scalar, y: Scalar) -> Self {
236        self.xy_relative([x, y])
237    }
238
239    /// Set the position relative to the widget with the given widget::Id.
240    fn x_relative_to(self, other: widget::Id, x: Scalar) -> Self {
241        self.x_position_relative_to(other, Relative::Scalar(x))
242    }
243
244    /// Set the position relative to the widget with the given widget::Id.
245    fn y_relative_to(self, other: widget::Id, y: Scalar) -> Self {
246        self.y_position_relative_to(other, Relative::Scalar(y))
247    }
248
249    /// Set the position relative to the widget with the given widget::Id.
250    fn xy_relative_to(self, other: widget::Id, xy: Point) -> Self {
251        self.x_relative_to(other, xy[0]).y_relative_to(other, xy[1])
252    }
253
254    /// Set the position relative to the widget with the given widget::Id.
255    fn x_y_relative_to(self, other: widget::Id, x: Scalar, y: Scalar) -> Self {
256        self.xy_relative_to(other, [x, y])
257    }
258
259    // Directional positioning.
260
261    /// Build with the **Position** along the *x* axis as some distance from another widget.
262    fn x_direction(self, direction: Direction, x: Scalar) -> Self {
263        self.x_position_relative(Relative::Direction(direction, x))
264    }
265
266    /// Build with the **Position** along the *y* axis as some distance from another widget.
267    fn y_direction(self, direction: Direction, y: Scalar) -> Self {
268        self.y_position_relative(Relative::Direction(direction, y))
269    }
270
271    /// Build with the **Position** as some distance below another widget.
272    fn down(self, y: Scalar) -> Self {
273        self.y_direction(Direction::Backwards, y)
274    }
275
276    /// Build with the **Position** as some distance above another widget.
277    fn up(self, y: Scalar) -> Self {
278        self.y_direction(Direction::Forwards, y)
279    }
280
281    /// Build with the **Position** as some distance to the left of another widget.
282    fn left(self, x: Scalar) -> Self {
283        self.x_direction(Direction::Backwards, x)
284    }
285
286    /// Build with the **Position** as some distance to the right of another widget.
287    fn right(self, x: Scalar) -> Self {
288        self.x_direction(Direction::Forwards, x)
289    }
290
291    /// Build with the **Position** along the *x* axis as some distance from the given widget.
292    fn x_direction_from(self, other: widget::Id, direction: Direction, x: Scalar) -> Self {
293        self.x_position_relative_to(other, Relative::Direction(direction, x))
294    }
295
296    /// Build with the **Position** along the *y* axis as some distance from the given widget.
297    fn y_direction_from(self, other: widget::Id, direction: Direction, y: Scalar) -> Self {
298        self.y_position_relative_to(other, Relative::Direction(direction, y))
299    }
300
301    /// Build with the **Position** as some distance below the given widget.
302    fn down_from(self, other: widget::Id, y: Scalar) -> Self {
303        self.y_direction_from(other, Direction::Backwards, y)
304    }
305
306    /// Build with the **Position** as some distance above the given widget.
307    fn up_from(self, other: widget::Id, y: Scalar) -> Self {
308        self.y_direction_from(other, Direction::Forwards, y)
309    }
310
311    /// Build with the **Position** as some distance to the left of the given widget.
312    fn left_from(self, other: widget::Id, x: Scalar) -> Self {
313        self.x_direction_from(other, Direction::Backwards, x)
314    }
315
316    /// Build with the **Position** as some distance to the right of the given widget.
317    fn right_from(self, other: widget::Id, x: Scalar) -> Self {
318        self.x_direction_from(other, Direction::Forwards, x)
319    }
320
321    // Alignment positioning.
322
323    /// Align the **Position** of the widget along the *x* axis.
324    fn x_align(self, align: Align) -> Self {
325        self.x_position_relative(Relative::Align(align))
326    }
327
328    /// Align the **Position** of the widget along the *y* axis.
329    fn y_align(self, align: Align) -> Self {
330        self.y_position_relative(Relative::Align(align))
331    }
332
333    /// Align the position to the left (only effective for Up or Down `Direction`s).
334    fn align_left(self) -> Self {
335        self.x_align(Align::Start)
336    }
337
338    /// Align the position to the middle (only effective for Up or Down `Direction`s).
339    fn align_middle_x(self) -> Self {
340        self.x_align(Align::Middle)
341    }
342
343    /// Align the position to the right (only effective for Up or Down `Direction`s).
344    fn align_right(self) -> Self {
345        self.x_align(Align::End)
346    }
347
348    /// Align the position to the top (only effective for Left or Right `Direction`s).
349    fn align_top(self) -> Self {
350        self.y_align(Align::End)
351    }
352
353    /// Align the position to the middle (only effective for Left or Right `Direction`s).
354    fn align_middle_y(self) -> Self {
355        self.y_align(Align::Middle)
356    }
357
358    /// Align the position to the bottom (only effective for Left or Right `Direction`s).
359    fn align_bottom(self) -> Self {
360        self.y_align(Align::Start)
361    }
362
363    /// Align the **Position** of the widget with the given widget along the *x* axis.
364    fn x_align_to(self, other: widget::Id, align: Align) -> Self {
365        self.x_position_relative_to(other, Relative::Align(align))
366    }
367
368    /// Align the **Position** of the widget with the given widget along the *y* axis.
369    fn y_align_to(self, other: widget::Id, align: Align) -> Self {
370        self.y_position_relative_to(other, Relative::Align(align))
371    }
372
373    /// Align the position to the left (only effective for Up or Down `Direction`s).
374    fn align_left_of(self, other: widget::Id) -> Self {
375        self.x_align_to(other, Align::Start)
376    }
377
378    /// Align the position to the middle (only effective for Up or Down `Direction`s).
379    fn align_middle_x_of(self, other: widget::Id) -> Self {
380        self.x_align_to(other, Align::Middle)
381    }
382
383    /// Align the position to the right (only effective for Up or Down `Direction`s).
384    fn align_right_of(self, other: widget::Id) -> Self {
385        self.x_align_to(other, Align::End)
386    }
387
388    /// Align the position to the top (only effective for Left or Right `Direction`s).
389    fn align_top_of(self, other: widget::Id) -> Self {
390        self.y_align_to(other, Align::End)
391    }
392
393    /// Align the position to the middle (only effective for Left or Right `Direction`s).
394    fn align_middle_y_of(self, other: widget::Id) -> Self {
395        self.y_align_to(other, Align::Middle)
396    }
397
398    /// Align the position to the bottom (only effective for Left or Right `Direction`s).
399    fn align_bottom_of(self, other: widget::Id) -> Self {
400        self.y_align_to(other, Align::Start)
401    }
402
403    ///// `Place` methods. /////
404
405    /// Place the widget at some position on the `other` Widget along the *x* axis.
406    fn x_place_on(self, other: widget::Id, place: Place) -> Self {
407        self.x_position_relative_to(other, Relative::Place(place))
408    }
409
410    /// Place the widget at some position on the `other` Widget along the *y* axis.
411    fn y_place_on(self, other: widget::Id, place: Place) -> Self {
412        self.y_position_relative_to(other, Relative::Place(place))
413    }
414
415    /// Place the widget in the middle of the given Widget.
416    fn middle_of(self, other: widget::Id) -> Self {
417        self.x_place_on(other, Place::Middle)
418            .y_place_on(other, Place::Middle)
419    }
420
421    /// Place the widget in the top left corner of the given Widget.
422    fn top_left_of(self, other: widget::Id) -> Self {
423        self.x_place_on(other, Place::Start(None))
424            .y_place_on(other, Place::End(None))
425    }
426
427    /// Place the widget in the top left corner of the given Widget with the given margin between
428    /// both edges.
429    fn top_left_with_margin_on(self, other: widget::Id, mgn: Scalar) -> Self {
430        self.x_place_on(other, Place::Start(Some(mgn)))
431            .y_place_on(other, Place::End(Some(mgn)))
432    }
433
434    /// Place the widget in the top left corner of the given Widget with the given margins between
435    /// each respective edge.
436    fn top_left_with_margins_on(self, other: widget::Id, top: Scalar, left: Scalar) -> Self {
437        self.x_place_on(other, Place::Start(Some(left)))
438            .y_place_on(other, Place::End(Some(top)))
439    }
440
441    /// Place the widget in the top right corner of the given Widget.
442    fn top_right_of(self, other: widget::Id) -> Self {
443        self.x_place_on(other, Place::End(None))
444            .y_place_on(other, Place::End(None))
445    }
446
447    /// Place the widget in the top right corner of the given Widget with the given margin
448    /// between both edges.
449    fn top_right_with_margin_on(self, other: widget::Id, mgn: Scalar) -> Self {
450        self.x_place_on(other, Place::End(Some(mgn)))
451            .y_place_on(other, Place::End(Some(mgn)))
452    }
453
454    /// Place the widget in the top right corner of the given Widget with the given margins between
455    /// each respective edge.
456    fn top_right_with_margins_on(self, other: widget::Id, top: Scalar, right: Scalar) -> Self {
457        self.x_place_on(other, Place::End(Some(right)))
458            .y_place_on(other, Place::End(Some(top)))
459    }
460
461    /// Place the widget in the bottom left corner of the given Widget.
462    fn bottom_left_of(self, other: widget::Id) -> Self {
463        self.x_place_on(other, Place::Start(None))
464            .y_place_on(other, Place::Start(None))
465    }
466
467    /// Place the widget in the bottom left corner of the given Widget with the given margin
468    /// between both edges.
469    fn bottom_left_with_margin_on(self, other: widget::Id, mgn: Scalar) -> Self {
470        self.x_place_on(other, Place::Start(Some(mgn)))
471            .y_place_on(other, Place::Start(Some(mgn)))
472    }
473
474    /// Place the widget in the bottom left corner of the given Widget with the given margins
475    /// between each respective edge.
476    fn bottom_left_with_margins_on(self, other: widget::Id, bottom: Scalar, left: Scalar) -> Self {
477        self.x_place_on(other, Place::Start(Some(left)))
478            .y_place_on(other, Place::Start(Some(bottom)))
479    }
480
481    /// Place the widget in the bottom right corner of the given Widget.
482    fn bottom_right_of(self, other: widget::Id) -> Self {
483        self.x_place_on(other, Place::End(None))
484            .y_place_on(other, Place::Start(None))
485    }
486
487    /// Place the widget in the bottom right corner of the given Widget with the given margin
488    /// between both edges.
489    fn bottom_right_with_margin_on(self, other: widget::Id, mgn: Scalar) -> Self {
490        self.x_place_on(other, Place::End(Some(mgn)))
491            .y_place_on(other, Place::Start(Some(mgn)))
492    }
493
494    /// Place the widget in the bottom right corner of the given Widget with the given margins
495    /// between each respective edge.
496    fn bottom_right_with_margins_on(
497        self,
498        other: widget::Id,
499        bottom: Scalar,
500        right: Scalar,
501    ) -> Self {
502        self.x_place_on(other, Place::End(Some(right)))
503            .y_place_on(other, Place::Start(Some(bottom)))
504    }
505
506    /// Place the widget in the middle of the top edge of the given Widget.
507    fn mid_top_of(self, other: widget::Id) -> Self {
508        self.x_place_on(other, Place::Middle)
509            .y_place_on(other, Place::End(None))
510    }
511
512    /// Place the widget in the middle of the top edge of the given Widget with the given margin
513    /// between the edges.
514    fn mid_top_with_margin_on(self, other: widget::Id, mgn: Scalar) -> Self {
515        self.x_place_on(other, Place::Middle)
516            .y_place_on(other, Place::End(Some(mgn)))
517    }
518
519    /// Place the widget in the middle of the bottom edge of the given Widget.
520    fn mid_bottom_of(self, other: widget::Id) -> Self {
521        self.x_place_on(other, Place::Middle)
522            .y_place_on(other, Place::Start(None))
523    }
524
525    /// Place the widget in the middle of the bottom edge of the given Widget with the given margin
526    /// between the edges.
527    fn mid_bottom_with_margin_on(self, other: widget::Id, mgn: Scalar) -> Self {
528        self.x_place_on(other, Place::Middle)
529            .y_place_on(other, Place::Start(Some(mgn)))
530    }
531
532    /// Place the widget in the middle of the left edge of the given Widget.
533    fn mid_left_of(self, other: widget::Id) -> Self {
534        self.x_place_on(other, Place::Start(None))
535            .y_place_on(other, Place::Middle)
536    }
537
538    /// Place the widget in the middle of the left edge of the given Widget with the given margin
539    /// between the edges.
540    fn mid_left_with_margin_on(self, other: widget::Id, mgn: Scalar) -> Self {
541        self.x_place_on(other, Place::Start(Some(mgn)))
542            .y_place_on(other, Place::Middle)
543    }
544
545    /// Place the widget in the middle of the right edge of the given Widget.
546    fn mid_right_of(self, other: widget::Id) -> Self {
547        self.x_place_on(other, Place::End(None))
548            .y_place_on(other, Place::Middle)
549    }
550
551    /// Place the widget in the middle of the right edge of the given Widget with the given margin
552    /// between the edges.
553    fn mid_right_with_margin_on(self, other: widget::Id, mgn: Scalar) -> Self {
554        self.x_place_on(other, Place::End(Some(mgn)))
555            .y_place_on(other, Place::Middle)
556    }
557
558    /// Place the widget at some position on the Widget along the *x* axis.
559    fn x_place(self, place: Place) -> Self {
560        self.x_position_relative(Relative::Place(place))
561    }
562
563    /// Place the widget at some position on the Widget along the *y* axis.
564    fn y_place(self, place: Place) -> Self {
565        self.y_position_relative(Relative::Place(place))
566    }
567
568    /// Place the widget in the middle of the current parent Widget.
569    fn middle(self) -> Self {
570        self.x_place(Place::Middle).y_place(Place::Middle)
571    }
572
573    /// Place the widget in the top left corner of the current parent Widget.
574    fn top_left(self) -> Self {
575        self.x_place(Place::Start(None)).y_place(Place::End(None))
576    }
577
578    /// Place the widget in the top left corner of the current parent Widget with the given margin
579    /// between both edges.
580    fn top_left_with_margin(self, mgn: Scalar) -> Self {
581        self.x_place(Place::Start(Some(mgn)))
582            .y_place(Place::End(Some(mgn)))
583    }
584
585    /// Place the widget in the top left corner of the current parent Widget with the given margins
586    /// between each respective edge.
587    fn top_left_with_margins(self, top: Scalar, left: Scalar) -> Self {
588        self.x_place(Place::Start(Some(left)))
589            .y_place(Place::End(Some(top)))
590    }
591
592    /// Place the widget in the top right corner of the current parent Widget.
593    fn top_right(self) -> Self {
594        self.x_place(Place::End(None)).y_place(Place::End(None))
595    }
596
597    /// Place the widget in the top right corner of the current parent Widget with the given margin
598    /// between both edges.
599    fn top_right_with_margin(self, mgn: Scalar) -> Self {
600        self.x_place(Place::End(Some(mgn)))
601            .y_place(Place::End(Some(mgn)))
602    }
603
604    /// Place the widget in the top right corner of the current parent Widget with the given margins
605    /// between each respective edge.
606    fn top_right_with_margins(self, top: Scalar, right: Scalar) -> Self {
607        self.x_place(Place::End(Some(right)))
608            .y_place(Place::End(Some(top)))
609    }
610
611    /// Place the widget in the bottom left corner of the current parent Widget.
612    fn bottom_left(self) -> Self {
613        self.x_place(Place::Start(None)).y_place(Place::Start(None))
614    }
615
616    /// Place the widget in the bottom left corner of the current parent Widget with the given
617    /// margin between both edges.
618    fn bottom_left_with_margin(self, mgn: Scalar) -> Self {
619        self.x_place(Place::Start(Some(mgn)))
620            .y_place(Place::Start(Some(mgn)))
621    }
622
623    /// Place the widget in the bottom left corner of the current parent Widget with the given
624    /// margins between each respective edge.
625    fn bottom_left_with_margins(self, bottom: Scalar, left: Scalar) -> Self {
626        self.x_place(Place::Start(Some(left)))
627            .y_place(Place::Start(Some(bottom)))
628    }
629
630    /// Place the widget in the bottom right corner of the current parent Widget.
631    fn bottom_right(self) -> Self {
632        self.x_place(Place::End(None)).y_place(Place::Start(None))
633    }
634
635    /// Place the widget in the bottom right corner of the current parent Widget with the given
636    /// margin between both edges.
637    fn bottom_right_with_margin(self, mgn: Scalar) -> Self {
638        self.x_place(Place::End(Some(mgn)))
639            .y_place(Place::Start(Some(mgn)))
640    }
641
642    /// Place the widget in the bottom right corner of the current parent Widget with the given
643    /// margins between each respective edge.
644    fn bottom_right_with_margins(self, bottom: Scalar, right: Scalar) -> Self {
645        self.x_place(Place::End(Some(right)))
646            .y_place(Place::Start(Some(bottom)))
647    }
648
649    /// Place the widget in the middle of the top edge of the current parent Widget.
650    fn mid_top(self) -> Self {
651        self.x_place(Place::Middle).y_place(Place::End(None))
652    }
653
654    /// Place the widget in the middle of the top edge of the current parent Widget with the given
655    /// margin from the edge.
656    fn mid_top_with_margin(self, mgn: Scalar) -> Self {
657        self.x_place(Place::Middle).y_place(Place::End(Some(mgn)))
658    }
659
660    /// Place the widget in the middle of the bottom edge of the current parent Widget.
661    fn mid_bottom(self) -> Self {
662        self.x_place(Place::Middle).y_place(Place::Start(None))
663    }
664
665    /// Place the widget in the middle of the bottom edge of the current parent Widget with the
666    /// given margin from the edge.
667    fn mid_bottom_with_margin(self, mgn: Scalar) -> Self {
668        self.x_place(Place::Middle).y_place(Place::Start(Some(mgn)))
669    }
670
671    /// Place the widget in the middle of the left edge of the current parent Widget.
672    fn mid_left(self) -> Self {
673        self.x_place(Place::Start(None)).y_place(Place::Middle)
674    }
675
676    /// Place the widget in the middle of the left edge of the current parent Widget with the
677    /// given margin from the edge.
678    fn mid_left_with_margin(self, mgn: Scalar) -> Self {
679        self.x_place(Place::Start(Some(mgn))).y_place(Place::Middle)
680    }
681
682    /// Place the widget in the middle of the right edge of the current parent Widget.
683    fn mid_right(self) -> Self {
684        self.x_place(Place::End(None)).y_place(Place::Middle)
685    }
686
687    /// Place the widget in the middle of the right edge of the current parent Widget with the
688    /// given margin from the edge.
689    fn mid_right_with_margin(self, mgn: Scalar) -> Self {
690        self.x_place(Place::End(Some(mgn))).y_place(Place::Middle)
691    }
692
693    ///// Rendering Depth (aka Z axis) /////
694
695    /// The depth at which the widget should be rendered relatively to its sibling widgets.
696    fn depth(self, depth: Depth) -> Self;
697
698    /// Return the depth.
699    fn get_depth(&self) -> Depth;
700}
701
702/// Widgets that support different dimensions.
703pub trait Sizeable: Sized {
704    // Required implementations.
705
706    /// Set the length along the x axis.
707    fn x_dimension(self, x: Dimension) -> Self;
708
709    /// Set the length along the y axis.
710    fn y_dimension(self, x: Dimension) -> Self;
711
712    /// The widget's length along the x axis as a Dimension.
713    fn get_x_dimension(&self, ui: &Ui) -> Dimension;
714
715    /// The widget's length along the y axis as a Dimension.
716    fn get_y_dimension(&self, ui: &Ui) -> Dimension;
717
718    // Provided defaults.
719
720    /// Set the absolute width for the widget.
721    fn w(self, w: Scalar) -> Self {
722        self.x_dimension(Dimension::Absolute(w))
723    }
724
725    /// Set the absolute height for the widget.
726    fn h(self, h: Scalar) -> Self {
727        self.y_dimension(Dimension::Absolute(h))
728    }
729
730    /// Set the dimensions for the widget.
731    fn wh(self, wh: Dimensions) -> Self {
732        self.w(wh[0]).h(wh[1])
733    }
734
735    /// Set the width and height for the widget.
736    fn w_h(self, width: Scalar, height: Scalar) -> Self {
737        self.wh([width, height])
738    }
739
740    /// Set the width as the width of the widget at the given index.
741    fn w_of(self, idx: widget::Id) -> Self {
742        self.x_dimension(Dimension::Of(idx.into(), None))
743    }
744
745    /// Set the width as the width of the widget at the given index padded at both ends by the
746    /// given Scalar.
747    fn padded_w_of(self, idx: widget::Id, pad: Scalar) -> Self {
748        self.x_dimension(Dimension::Of(idx.into(), Some(pad)))
749    }
750
751    /// Set the height as the height of the widget at the given index.
752    fn h_of(self, idx: widget::Id) -> Self {
753        self.y_dimension(Dimension::Of(idx.into(), None))
754    }
755
756    /// Set the height as the height of the widget at the given index padded at both ends by the
757    /// given Scalar.
758    fn padded_h_of(self, idx: widget::Id, pad: Scalar) -> Self {
759        self.y_dimension(Dimension::Of(idx.into(), Some(pad)))
760    }
761
762    /// Set the dimensions as the dimensions of the widget at the given index.
763    fn wh_of(self, idx: widget::Id) -> Self {
764        self.w_of(idx).h_of(idx)
765    }
766
767    /// Set the dimensions as the dimensions of the widget at the given index with all four edges
768    /// padded by the given scalar.
769    fn padded_wh_of(self, idx: widget::Id, pad: Scalar) -> Self {
770        self.padded_w_of(idx, pad).padded_h_of(idx, pad)
771    }
772
773    /// Set the width as the width of the padded area of the widget at the given index.
774    fn kid_area_w_of(self, idx: widget::Id) -> Self {
775        self.x_dimension(Dimension::KidAreaOf(idx.into(), None))
776    }
777
778    /// Set the width as the `KidArea` width for the widget at the given index, padded at both ends
779    /// by the given scalar.
780    fn padded_kid_area_w_of(self, idx: widget::Id, pad: Scalar) -> Self {
781        self.x_dimension(Dimension::KidAreaOf(idx.into(), Some(pad)))
782    }
783
784    /// Set the height as the `KidArea` height of the widget at the given index.
785    fn kid_area_h_of(self, idx: widget::Id) -> Self {
786        self.y_dimension(Dimension::KidAreaOf(idx.into(), None))
787    }
788
789    /// Set the height as the `KidArea` height of the widget at the given index, padded at both
790    /// ends by the given scalar.
791    fn padded_kid_area_h_of(self, idx: widget::Id, pad: Scalar) -> Self {
792        self.y_dimension(Dimension::KidAreaOf(idx.into(), Some(pad)))
793    }
794
795    /// Set the dimensions as the `KidArea` dimensions of the widget at the given index.
796    fn kid_area_wh_of(self, idx: widget::Id) -> Self {
797        self.kid_area_w_of(idx).kid_area_h_of(idx)
798    }
799
800    /// Set the dimensions as the `KidArea` dimensions of the widget at the given index, padded at
801    /// all four edges by the given scalar.
802    fn padded_kid_area_wh_of(self, idx: widget::Id, pad: Scalar) -> Self {
803        self.padded_kid_area_w_of(idx, pad)
804            .padded_kid_area_h_of(idx, pad)
805    }
806
807    /// Get the absolute width of the widget as a Scalar value.
808    fn get_w(&self, ui: &Ui) -> Option<Scalar> {
809        match self.get_x_dimension(ui) {
810            Dimension::Absolute(width) => Some(width),
811            Dimension::Of(idx, None) => ui.w_of(idx),
812            Dimension::Of(idx, Some(pad)) => ui.w_of(idx).map(|w| w - pad * 2.0),
813            Dimension::KidAreaOf(idx, None) => ui.kid_area_of(idx).map(|r| r.w()),
814            Dimension::KidAreaOf(idx, Some(pad)) => ui.kid_area_of(idx).map(|r| r.w() - pad * 2.0),
815        }
816    }
817
818    /// Get the height of the widget.
819    fn get_h(&self, ui: &Ui) -> Option<Scalar> {
820        match self.get_y_dimension(ui) {
821            Dimension::Absolute(height) => Some(height),
822            Dimension::Of(idx, None) => ui.h_of(idx),
823            Dimension::Of(idx, Some(pad)) => ui.h_of(idx).map(|w| w - pad * 2.0),
824            Dimension::KidAreaOf(idx, None) => ui.kid_area_of(idx).map(|r| r.h()),
825            Dimension::KidAreaOf(idx, Some(pad)) => ui.kid_area_of(idx).map(|r| r.h() - pad * 2.0),
826        }
827    }
828
829    /// The dimensions for the widget.
830    fn get_wh(&self, ui: &Ui) -> Option<Dimensions> {
831        self.get_w(ui).and_then(|w| self.get_h(ui).map(|h| [w, h]))
832    }
833}
834
835/// The distance between the inner edge of a border and the outer edge of the inner content.
836#[derive(Copy, Clone, Debug, PartialEq)]
837pub struct Padding {
838    /// Padding on the start and end of the *x* axis.
839    pub x: Range,
840    /// Padding on the start and end of the *y* axis.
841    pub y: Range,
842}
843
844impl Padding {
845    /// No padding.
846    pub fn none() -> Padding {
847        Padding {
848            x: Range::new(0.0, 0.0),
849            y: Range::new(0.0, 0.0),
850        }
851    }
852}