Skip to content

Commit 33447db

Browse files
committed
Implemented Grid/Stack baseline
Also fixed indicator baseline calculations.
1 parent 9451994 commit 33447db

File tree

8 files changed

+260
-87
lines changed

8 files changed

+260
-87
lines changed

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ license = "MIT OR Apache-2.0"
1111
keywords = ["gui", "ui", "widgets", "reactive"]
1212
categories = ["gui"]
1313
readme = "./README.md"
14-
rust-version = "1.80.0"
14+
rust-version = "1.81.0"
1515

1616
[features]
1717
default = ["tracing-output", "roboto-flex", "native-dialogs", "localization"]

examples/baseline-align.rs

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
use cushy::reactive::value::Dynamic;
2+
use cushy::widget::MakeWidget;
3+
use cushy::widgets::checkbox::Checkable;
4+
use cushy::widgets::grid::{GridSection, GridWidgets};
5+
use cushy::widgets::Grid;
6+
use cushy::Run;
7+
8+
fn main() -> cushy::Result {
9+
"Label"
10+
.and("Button".into_button())
11+
.and(
12+
Dynamic::<bool>::default()
13+
.into_checkbox()
14+
.labelled_by("Checkbox"),
15+
)
16+
.into_columns()
17+
.contain()
18+
.and(
19+
Grid::from_rows(
20+
GridWidgets::from(GridSection::from(("Label", "Button".into_button()))).and((
21+
"Label",
22+
Dynamic::<bool>::default()
23+
.into_checkbox()
24+
.labelled_by("Checkbox"),
25+
)),
26+
)
27+
.contain(),
28+
)
29+
.into_rows()
30+
.centered()
31+
.run()
32+
}

src/styles.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2837,8 +2837,9 @@ impl RequireInvalidation for HorizontalAlign {
28372837
/// Alignment along the vertical axis.
28382838
#[derive(Default, Debug, Clone, Copy, Eq, PartialEq)]
28392839
pub enum VerticalAlign {
2840-
/// Align towards the top.
2840+
/// Align along the top.
28412841
Top,
2842+
/// Align along the baseline of the first line of text.
28422843
#[default]
28432844
Baseline,
28442845
/// Align towards the center/middle.

src/widget.rs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -513,12 +513,23 @@ where
513513
}
514514
// ANCHOR_END: run
515515

516+
/// The measurement from the top of the content to the bottom of the first line
517+
/// of text.
518+
///
519+
/// In typography, the baseline of text is where the font rendering begins
520+
/// drawing characters. Portions of characters may extend belown this
521+
/// measurement. For example, the letters `yjg` all have portions that extend
522+
/// below the baseline.
516523
#[derive(Default, Debug, Clone, Copy, Eq, PartialEq)]
517524
pub struct Baseline(pub Option<UPx>);
518525

519526
impl Baseline {
527+
/// No baseline measurement.
520528
pub const NONE: Self = Self(None);
521529

530+
/// Apply `map` to the baseline, if present, and return the result.
531+
///
532+
/// If this baseline is `None`, `map` will not be invoked.
522533
#[must_use]
523534
pub fn map(self, map: impl FnOnce(UPx) -> UPx) -> Self {
524535
Self(self.0.map(map))
@@ -594,9 +605,13 @@ impl PartialOrd for Baseline {
594605
}
595606
}
596607

608+
/// Information about a widget's desired layout.
597609
#[derive(Clone, Copy, Eq, PartialEq, Debug)]
598610
pub struct WidgetLayout {
611+
/// The size desired for this widget.
599612
pub size: Size<UPx>,
613+
/// The baseline of the first line of text within this widget, if text is
614+
/// present.
600615
pub baseline: Baseline,
601616
}
602617

src/widgets/checkbox.rs

Lines changed: 21 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -193,25 +193,29 @@ impl CheckboxColors {
193193
}
194194
}
195195

196+
fn indicator_layout(context: &mut GraphicsContext<'_, '_, '_, '_>) -> WidgetLayout {
197+
let size = Size::squared(
198+
context
199+
.get(&CheckboxSize)
200+
.into_upx(context.gfx.scale())
201+
.ceil(),
202+
);
203+
let icon_inset = Lp::points(3).into_upx(context.gfx.scale()).ceil();
204+
let icon_height = size.height - icon_inset * 2;
205+
206+
let checkmark_lowest_point = (icon_inset + icon_height * 3 / 4).round();
207+
208+
WidgetLayout {
209+
size,
210+
baseline: Baseline::from(checkmark_lowest_point),
211+
}
212+
}
213+
196214
impl IndicatorBehavior for CheckboxIndicator {
197215
type Colors = CheckboxColors;
198216

199217
fn size(&self, context: &mut GraphicsContext<'_, '_, '_, '_>) -> WidgetLayout {
200-
let size = Size::squared(
201-
context
202-
.get(&CheckboxSize)
203-
.into_upx(context.gfx.scale())
204-
.ceil(),
205-
);
206-
let icon_inset = Lp::points(3).into_upx(context.gfx.scale()).ceil();
207-
let icon_height = size.height - icon_inset * 2;
208-
209-
let checkmark_lowest_point = (icon_inset + icon_height * 3 / 4).round();
210-
211-
WidgetLayout {
212-
size,
213-
baseline: Baseline::from(checkmark_lowest_point),
214-
}
218+
indicator_layout(context)
215219
}
216220

217221
fn desired_colors(
@@ -378,7 +382,7 @@ fn draw_filled_checkbox(
378382
.line_to(
379383
Point::new(
380384
icon_area.origin.x + icon_area.size.width,
381-
icon_area.origin.y,
385+
icon_area.origin.y + icon_area.size.height / 4,
382386
)
383387
.round(),
384388
)
@@ -531,11 +535,7 @@ impl Widget for CheckboxOrnament {
531535
_available_space: Size<ConstraintLimit>,
532536
context: &mut LayoutContext<'_, '_, '_, '_>,
533537
) -> WidgetLayout {
534-
let checkbox_size = context
535-
.get(&CheckboxSize)
536-
.into_upx(context.gfx.scale())
537-
.ceil();
538-
Size::squared(checkbox_size).into()
538+
indicator_layout(context)
539539
}
540540
}
541541

0 commit comments

Comments
 (0)