Skip to content

Commit

Permalink
Add Divider widget (SecondHalfGames#135)
Browse files Browse the repository at this point in the history
add Divider widget
  • Loading branch information
Uriopass authored Dec 24, 2023
1 parent 9f0a092 commit f61a137
Show file tree
Hide file tree
Showing 4 changed files with 114 additions and 7 deletions.
15 changes: 10 additions & 5 deletions crates/yakui-widgets/src/shorthand.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,11 @@ use yakui_core::{Alignment, ManagedTextureId, Response, TextureId};
use crate::widgets::{
Align, AlignResponse, Button, ButtonResponse, Canvas, CanvasResponse, Checkbox,
CheckboxResponse, Circle, CircleResponse, ColoredBox, ColoredBoxResponse, ConstrainedBox,
ConstrainedBoxResponse, CountGrid, Draggable, DraggableResponse, Flexible, FlexibleResponse,
Image, ImageResponse, List, ListResponse, MaxWidth, MaxWidthResponse, NineSlice, Offset,
OffsetResponse, Opaque, OpaqueResponse, Pad, PadResponse, Reflow, ReflowResponse, Scrollable,
ScrollableResponse, Slider, SliderResponse, State, StateResponse, Text, TextBox,
TextBoxResponse, TextResponse,
ConstrainedBoxResponse, CountGrid, Divider, DividerResponse, Draggable, DraggableResponse,
Flexible, FlexibleResponse, Image, ImageResponse, List, ListResponse, MaxWidth,
MaxWidthResponse, NineSlice, Offset, OffsetResponse, Opaque, OpaqueResponse, Pad, PadResponse,
Reflow, ReflowResponse, Scrollable, ScrollableResponse, Slider, SliderResponse, State,
StateResponse, Text, TextBox, TextBoxResponse, TextResponse,
};

/// See [List].
Expand Down Expand Up @@ -147,6 +147,11 @@ pub fn nineslice(
NineSlice::new(texture, margins, scale).show(children)
}

/// See [Divider].
pub fn divider(color: Color, height: f32, thickness: f32) -> Response<DividerResponse> {
Divider::new(color, height, thickness).show()
}

/// See [Scrollable].
pub fn scroll_vertical(children: impl FnOnce()) -> Response<ScrollableResponse> {
Scrollable::vertical().show(children)
Expand Down
95 changes: 95 additions & 0 deletions crates/yakui-widgets/src/widgets/divider.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
use yakui_core::geometry::{Color, Constraints, Rect, Vec2};
use yakui_core::paint::PaintRect;
use yakui_core::widget::{LayoutContext, PaintContext, Widget};
use yakui_core::Response;

/// A horizontal divider line. Will take up the whole width of the parent.
///
/// Responds with [DividerResponse].
#[derive(Debug)]
#[non_exhaustive]
pub struct Divider {
/// The color of the divider.
pub color: Color,
/// The thickness of the divider.
pub thickness: f32,
/// The height of the divider.
/// How much vertical space it takes up.
pub height: f32,
/// The indent of the divider from the left.
pub indent: f32,
/// The indent of the divider from the right.
pub end_indent: f32,
}

impl Divider {
pub fn new(color: Color, height: f32, thickness: f32) -> Self {
Self {
color,
thickness,
height,
indent: 0.0,
end_indent: 0.0,
}
}

pub fn show(self) -> Response<DividerResponse> {
crate::util::widget::<DividerWidget>(self)
}
}

#[derive(Debug)]
pub struct DividerWidget {
props: Divider,
}

pub type DividerResponse = ();

impl Widget for DividerWidget {
type Props<'a> = Divider;
type Response = DividerResponse;

fn new() -> Self {
Self {
props: Divider::new(Color::WHITE, 0.0, 0.0),
}
}

fn update(&mut self, props: Self::Props<'_>) -> Self::Response {
self.props = props;
}

fn layout(&self, _ctx: LayoutContext<'_>, input: Constraints) -> Vec2 {
Vec2::new(
input.min.x,
self.props.height.clamp(input.min.y, input.max.y),
)
}

fn paint(&self, ctx: PaintContext<'_>) {
// We get the parent's width during the paint phase because
// using constraints.max.x is often useless as it is often infinite.

let id = ctx.dom.current();
let Some(parent) = ctx.dom.get(id).unwrap().parent else {
return;
};
let line_width = ctx.layout.get(parent).unwrap().rect.size().x;

let outer_rect = ctx.layout.get(id).unwrap().rect;

let line_pos = outer_rect.pos()
+ Vec2::new(
self.props.indent,
(outer_rect.size().y - self.props.thickness) / 2.0,
);
let line_size = Vec2::new(
line_width - self.props.indent - self.props.end_indent,
self.props.thickness,
);

let mut line_rect = PaintRect::new(Rect::from_pos_size(line_pos, line_size));
line_rect.color = self.props.color;
line_rect.add(ctx.paint);
}
}
2 changes: 2 additions & 0 deletions crates/yakui-widgets/src/widgets/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ mod colored_box;
mod constrained_box;
mod count_grid;
mod cutout;
mod divider;
mod draggable;
mod flexible;
mod image;
Expand Down Expand Up @@ -39,6 +40,7 @@ pub use self::colored_box::*;
pub use self::constrained_box::*;
pub use self::count_grid::*;
pub use self::cutout::*;
pub use self::divider::*;
pub use self::draggable::*;
pub use self::flexible::*;
pub use self::image::*;
Expand Down
9 changes: 7 additions & 2 deletions crates/yakui/examples/leaderboard.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,20 +35,21 @@ pub fn run() {
stat_column(|| {
label("Name");
for datum in &data {
divider();
label(datum.name);
}
});

stat_column(|| {
label("Score");
for datum in &data {
divider();
label(format!("{}", datum.score));
}
});

stat_column(|| {
label("Money");
for datum in &data {
divider();
label(format!("{}", datum.currency));
}
});
Expand All @@ -58,6 +59,10 @@ pub fn run() {
});
}

fn divider() {
yakui_widgets::divider(Color::GRAY, 1.0, 1.0);
}

fn stat_column(children: impl FnOnce()) {
let mut col = List::column();
col.main_axis_size = MainAxisSize::Min;
Expand Down

0 comments on commit f61a137

Please sign in to comment.