Skip to content

Commit

Permalink
Add cross-axis extent, stub implementations for ColoredBox and List
Browse files Browse the repository at this point in the history
  • Loading branch information
LPGhatguy committed Oct 21, 2024
1 parent d5b92aa commit 5c21a4d
Show file tree
Hide file tree
Showing 5 changed files with 76 additions and 17 deletions.
4 changes: 2 additions & 2 deletions crates/yakui-core/src/layout/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -201,12 +201,12 @@ impl LayoutDom {
}

/// Calculates the intrinsic size of the given widget along the given axis.
pub fn intrinsic_size(&self, dom: &Dom, id: WidgetId, axis: Axis) -> f32 {
pub fn intrinsic_size(&self, dom: &Dom, id: WidgetId, axis: Axis, extent: f32) -> f32 {
dom.enter(id);
let dom_node = dom.get(id).unwrap();

let context = IntrinsicSizeContext { dom, layout: self };
let size = dom_node.widget.intrinsic_size(context, axis);
let size = dom_node.widget.intrinsic_size(context, axis, extent);

dom.exit(id);
size
Expand Down
11 changes: 11 additions & 0 deletions crates/yakui-core/src/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -273,4 +273,15 @@ impl Axis {
Axis::Y => v.y,
}
}

/// Tells whether this axis indicates the same axis as a given [`Direction`].
pub fn is_direction(self, dir: Direction) -> bool {
match (self, dir) {
(Axis::X, Direction::Right) => true,
(Axis::Y, Direction::Down) => true,

(Axis::X, Direction::Down) => false,
(Axis::Y, Direction::Right) => false,
}
}
}
22 changes: 11 additions & 11 deletions crates/yakui-core/src/widget.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,8 @@ impl<'dom> LayoutContext<'dom> {
}

/// Calculates the intrinsic size for the given widget on the given axis.
pub fn intrinsic_size(&self, widget: WidgetId, axis: Axis) -> f32 {
self.layout.intrinsic_size(self.dom, widget, axis)
pub fn intrinsic_size(&self, widget: WidgetId, axis: Axis, extent: f32) -> f32 {
self.layout.intrinsic_size(self.dom, widget, axis, extent)
}
}

Expand All @@ -56,8 +56,8 @@ pub struct IntrinsicSizeContext<'dom> {

impl<'dom> IntrinsicSizeContext<'dom> {
/// Calculates the intrinsic size for the given widget on the given axis.
pub fn intrinsic_size(&self, widget: WidgetId, axis: Axis) -> f32 {
self.layout.intrinsic_size(self.dom, widget, axis)
pub fn intrinsic_size(&self, widget: WidgetId, axis: Axis, extent: f32) -> f32 {
self.layout.intrinsic_size(self.dom, widget, axis, extent)
}
}

Expand Down Expand Up @@ -156,14 +156,14 @@ pub trait Widget: 'static + fmt::Debug {
}

/// Tells the intrinsic size on one axis of the object, which is its size
/// along that axis if the widget were given unbounded constraints on the
/// other axis.
fn intrinsic_size(&self, ctx: IntrinsicSizeContext<'_>, axis: Axis) -> f32 {
/// along that axis if the widget is provided the given `extent` as the max
/// size along the other axis.
fn intrinsic_size(&self, ctx: IntrinsicSizeContext<'_>, axis: Axis, extent: f32) -> f32 {
let node = ctx.dom.get_current();
let mut size: f32 = 0.0;

for &child in &node.children {
let child_size = ctx.intrinsic_size(child, axis);
let child_size = ctx.intrinsic_size(child, axis, extent);
size = size.max(child_size);
}

Expand Down Expand Up @@ -217,7 +217,7 @@ pub trait ErasedWidget: Any + fmt::Debug {
fn layout(&self, ctx: LayoutContext<'_>, constraints: Constraints) -> Vec2;

/// See [`Widget::intrinsic_size`].
fn intrinsic_size(&self, ctx: IntrinsicSizeContext<'_>, axis: Axis) -> f32;
fn intrinsic_size(&self, ctx: IntrinsicSizeContext<'_>, axis: Axis, extent: f32) -> f32;

/// See [`Widget::flex`].
fn flex(&self) -> (u32, FlexFit);
Expand Down Expand Up @@ -246,8 +246,8 @@ where
<T as Widget>::layout(self, ctx, constraints)
}

fn intrinsic_size(&self, ctx: IntrinsicSizeContext<'_>, axis: Axis) -> f32 {
<T as Widget>::intrinsic_size(self, ctx, axis)
fn intrinsic_size(&self, ctx: IntrinsicSizeContext<'_>, axis: Axis, extent: f32) -> f32 {
<T as Widget>::intrinsic_size(self, ctx, axis, extent)
}

fn flex(&self) -> (u32, FlexFit) {
Expand Down
15 changes: 13 additions & 2 deletions crates/yakui-widgets/src/widgets/colored_box.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use yakui_core::geometry::{Color, Constraints, Vec2};
use yakui_core::paint::PaintRect;
use yakui_core::widget::{LayoutContext, PaintContext, Widget};
use yakui_core::Response;
use yakui_core::widget::{IntrinsicSizeContext, LayoutContext, PaintContext, Widget};
use yakui_core::{Axis, Response};

use crate::util::{widget, widget_children};

Expand Down Expand Up @@ -82,6 +82,17 @@ impl Widget for ColoredBoxWidget {
input.constrain_min(size)
}

fn intrinsic_size(&self, ctx: IntrinsicSizeContext<'_>, axis: Axis, extent: f32) -> f32 {
let node = ctx.dom.get_current();
let mut size = axis.select(self.props.min_size);

for &child in &node.children {
size = size.max(ctx.intrinsic_size(child, axis, extent));
}

size
}

fn paint(&self, mut ctx: PaintContext<'_>) {
let node = ctx.dom.get_current();
let layout_node = ctx.layout.get(ctx.dom.current()).unwrap();
Expand Down
41 changes: 39 additions & 2 deletions crates/yakui-widgets/src/widgets/list.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
use yakui_core::geometry::{Constraints, FlexFit, Vec2};
use yakui_core::widget::{LayoutContext, Widget};
use yakui_core::{CrossAxisAlignment, Direction, Flow, MainAxisAlignment, MainAxisSize, Response};
use yakui_core::widget::{IntrinsicSizeContext, LayoutContext, Widget};
use yakui_core::{
Axis, CrossAxisAlignment, Direction, Flow, MainAxisAlignment, MainAxisSize, Response,
};

use crate::util::widget_children;

Expand Down Expand Up @@ -285,4 +287,39 @@ impl Widget for ListWidget {

container_size
}

fn intrinsic_size(&self, ctx: IntrinsicSizeContext<'_>, axis: Axis, extent: f32) -> f32 {
let node = ctx.dom.get_current();

if axis.is_direction(self.props.direction) {
// main axis layout
let mut total_flex = 0.0;
let mut inflexible_space = 0.0;

for &child_id in &node.children {
let child_size = ctx.intrinsic_size(child_id, axis, extent);
let child = ctx.dom.get(child_id).unwrap();

let (flex, _) = child.widget.flex();

if flex > 0 {
// TODO
} else {
inflexible_space += child_size;
}
}

inflexible_space
} else {
// cross axis layout
let mut max_size: f32 = 0.0;

for &child_id in &node.children {
let child_size = ctx.intrinsic_size(child_id, axis, extent);
max_size = max_size.max(child_size);
}

max_size
}
}
}

0 comments on commit 5c21a4d

Please sign in to comment.