mirror of
https://github.com/danbulant/cushy
synced 2026-06-18 22:11:34 +00:00
Fixed odd padding rounding issues
The Container code was causing small rounding errors when laying out that would cause the layout to sometimes me larger by a pixel. I searched for all locations we are applying padding and added rounding calls. Refs #92
This commit is contained in:
parent
c117b1527e
commit
27d5594776
6 changed files with 65 additions and 38 deletions
|
|
@ -5,7 +5,7 @@ use std::time::Duration;
|
|||
use kludgine::app::winit::event::{DeviceId, ElementState, KeyEvent, MouseButton};
|
||||
use kludgine::app::winit::window::CursorIcon;
|
||||
use kludgine::figures::units::{Lp, Px, UPx};
|
||||
use kludgine::figures::{IntoSigned, Point, Rect, ScreenScale, Size};
|
||||
use kludgine::figures::{IntoSigned, Point, Rect, Round, ScreenScale, Size};
|
||||
use kludgine::shapes::{Shape, StrokeOptions};
|
||||
use kludgine::Color;
|
||||
|
||||
|
|
@ -467,7 +467,10 @@ impl Widget for Button {
|
|||
available_space: Size<crate::ConstraintLimit>,
|
||||
context: &mut LayoutContext<'_, '_, '_, '_, '_>,
|
||||
) -> Size<UPx> {
|
||||
let padding = context.get(&IntrinsicPadding).into_upx(context.gfx.scale());
|
||||
let padding = context
|
||||
.get(&IntrinsicPadding)
|
||||
.into_upx(context.gfx.scale())
|
||||
.round();
|
||||
let double_padding = padding * 2;
|
||||
let mounted = self.content.mounted(&mut context.as_event_context());
|
||||
let available_space = available_space.map(|space| space - double_padding);
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ use std::ops::Div;
|
|||
|
||||
use kludgine::figures::units::{Lp, Px, UPx};
|
||||
use kludgine::figures::{
|
||||
Abs, Angle, IntoSigned, IntoUnsigned, Point, Rect, ScreenScale, Size, Zero,
|
||||
Abs, Angle, IntoSigned, IntoUnsigned, Point, Rect, Round, ScreenScale, Size, Zero,
|
||||
};
|
||||
use kludgine::shapes::{CornerRadii, PathBuilder, Shape};
|
||||
use kludgine::Color;
|
||||
|
|
@ -165,7 +165,7 @@ impl Container {
|
|||
Some(padding) => padding.get(),
|
||||
None => Edges::from(context.get(&IntrinsicPadding)),
|
||||
}
|
||||
.map(|dim| dim.into_px(context.gfx.scale()))
|
||||
.map(|dim| dim.into_px(context.gfx.scale()).round())
|
||||
}
|
||||
|
||||
fn effective_background_color(&mut self, context: &WidgetContext<'_, '_>) -> kludgine::Color {
|
||||
|
|
|
|||
|
|
@ -155,7 +155,10 @@ impl<const COLUMNS: usize> Widget for Grid<COLUMNS> {
|
|||
|
||||
let content_size = self.layout.update(
|
||||
available_space,
|
||||
context.get(&IntrinsicPadding).into_upx(context.gfx.scale()),
|
||||
context
|
||||
.get(&IntrinsicPadding)
|
||||
.into_upx(context.gfx.scale())
|
||||
.round(),
|
||||
context.gfx.scale(),
|
||||
|row, column, constraints, persist| {
|
||||
let mut context = context.for_other(&self.live_rows[column][row]);
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ use kludgine::app::winit::keyboard::{Key, NamedKey};
|
|||
use kludgine::app::winit::window::{CursorIcon, ImePurpose};
|
||||
use kludgine::figures::units::{Lp, Px, UPx};
|
||||
use kludgine::figures::{
|
||||
Abs, FloatConversion, IntoSigned, IntoUnsigned, Point, Rect, ScreenScale, Size,
|
||||
Abs, FloatConversion, IntoSigned, IntoUnsigned, Point, Rect, Round, ScreenScale, Size,
|
||||
};
|
||||
use kludgine::shapes::{Shape, StrokeOptions};
|
||||
use kludgine::text::{MeasuredText, Text, TextOrigin};
|
||||
|
|
@ -340,7 +340,8 @@ where
|
|||
Self::point_from_cursor(&cache.measured, self.selection.cursor, cache.bytes);
|
||||
position.y += context
|
||||
.get(&IntrinsicPadding)
|
||||
.into_px(context.kludgine.scale());
|
||||
.into_px(context.kludgine.scale())
|
||||
.round();
|
||||
match affinity {
|
||||
Affinity::Before => position.x = Px::ZERO,
|
||||
Affinity::After => {
|
||||
|
|
@ -361,7 +362,8 @@ where
|
|||
position += Point::squared(
|
||||
context
|
||||
.get(&IntrinsicPadding)
|
||||
.into_px(context.kludgine.scale()),
|
||||
.into_px(context.kludgine.scale())
|
||||
.round(),
|
||||
);
|
||||
if let Some(target_x) = self.line_navigation_x_target {
|
||||
position.x = target_x;
|
||||
|
|
@ -819,7 +821,8 @@ where
|
|||
|
||||
let padding = context
|
||||
.get(&IntrinsicPadding)
|
||||
.into_px(context.kludgine.scale());
|
||||
.into_px(context.kludgine.scale())
|
||||
.round();
|
||||
let mut location = location - padding;
|
||||
if location.y < 0 {
|
||||
location.y = Px::ZERO;
|
||||
|
|
@ -1029,8 +1032,11 @@ where
|
|||
|
||||
let cursor_state = self.blink_state;
|
||||
let size = context.gfx.size();
|
||||
let padding = context.get(&IntrinsicPadding).into_px(context.gfx.scale());
|
||||
let padding = Point::<Px>::new(padding, padding);
|
||||
let padding = context
|
||||
.get(&IntrinsicPadding)
|
||||
.into_px(context.gfx.scale())
|
||||
.round();
|
||||
let padding = Point::squared(padding);
|
||||
|
||||
let cache = self.layout_text(Some(size.width.into_signed()), context);
|
||||
|
||||
|
|
@ -1147,7 +1153,10 @@ where
|
|||
available_space: Size<ConstraintLimit>,
|
||||
context: &mut LayoutContext<'_, '_, '_, '_, '_>,
|
||||
) -> Size<UPx> {
|
||||
let padding = context.get(&IntrinsicPadding).into_upx(context.gfx.scale());
|
||||
let padding = context
|
||||
.get(&IntrinsicPadding)
|
||||
.into_upx(context.gfx.scale())
|
||||
.round();
|
||||
|
||||
let width = available_space.width.max().saturating_sub(padding * 2);
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
//! A widget that combines a collection of [`Children`] widgets into one.
|
||||
|
||||
use kludgine::figures::units::UPx;
|
||||
use kludgine::figures::{IntoSigned, Rect, ScreenScale, Size};
|
||||
use kludgine::figures::{IntoSigned, Rect, Round, ScreenScale, Size};
|
||||
|
||||
use crate::context::{AsEventContext, EventContext, GraphicsContext, LayoutContext};
|
||||
use crate::styles::components::IntrinsicPadding;
|
||||
|
|
@ -142,7 +142,8 @@ impl Widget for Stack {
|
|||
FlexibleDimension::Auto => context.get(&IntrinsicPadding),
|
||||
FlexibleDimension::Dimension(dimension) => dimension,
|
||||
}
|
||||
.into_upx(context.gfx.scale());
|
||||
.into_upx(context.gfx.scale())
|
||||
.round();
|
||||
|
||||
let content_size = self.layout.update(
|
||||
available_space,
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
|
||||
use intentional::Cast;
|
||||
use kludgine::figures::units::{Px, UPx};
|
||||
use kludgine::figures::{IntoSigned, IntoUnsigned, Point, Rect, ScreenScale, Size, Zero};
|
||||
use kludgine::figures::{IntoSigned, IntoUnsigned, Point, Rect, Round, ScreenScale, Size, Zero};
|
||||
|
||||
use crate::context::{AsEventContext, GraphicsContext, LayoutContext};
|
||||
use crate::styles::components::{IntrinsicPadding, LayoutOrder};
|
||||
|
|
@ -64,6 +64,36 @@ impl Wrap {
|
|||
self.vertical_align = align.into_value();
|
||||
self
|
||||
}
|
||||
|
||||
fn horizontal_alignment(
|
||||
align: WrapAlign,
|
||||
order: HorizontalOrder,
|
||||
remaining: Px,
|
||||
row_children_len: usize,
|
||||
) -> (Px, Px) {
|
||||
match (align, order) {
|
||||
(WrapAlign::Start, HorizontalOrder::LeftToRight)
|
||||
| (WrapAlign::End, HorizontalOrder::RightToLeft) => (Px::ZERO, Px::ZERO),
|
||||
(WrapAlign::End, HorizontalOrder::LeftToRight)
|
||||
| (WrapAlign::Start, HorizontalOrder::RightToLeft) => (remaining, Px::ZERO),
|
||||
(WrapAlign::Center, _) => (remaining / 2, Px::ZERO),
|
||||
(WrapAlign::SpaceBetween, _) => {
|
||||
if row_children_len > 1 {
|
||||
(Px::ZERO, remaining / (row_children_len - 1).cast::<i32>())
|
||||
} else {
|
||||
(Px::ZERO, Px::ZERO)
|
||||
}
|
||||
}
|
||||
(WrapAlign::SpaceEvenly, _) => {
|
||||
let spacing = remaining / row_children_len.cast::<i32>();
|
||||
(spacing / 2, spacing)
|
||||
}
|
||||
(WrapAlign::SpaceAround, _) => {
|
||||
let spacing = remaining / (row_children_len + 1).cast::<i32>();
|
||||
(spacing, spacing)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Widget for Wrap {
|
||||
|
|
@ -73,6 +103,7 @@ impl Widget for Wrap {
|
|||
}
|
||||
}
|
||||
|
||||
#[allow(clippy::too_many_lines)]
|
||||
fn layout(
|
||||
&mut self,
|
||||
available_space: Size<ConstraintLimit>,
|
||||
|
|
@ -96,7 +127,8 @@ impl Widget for Wrap {
|
|||
FlexibleDimension::Auto => context.get(&IntrinsicPadding),
|
||||
FlexibleDimension::Dimension(dimension) => dimension,
|
||||
})
|
||||
.into_px(context.gfx.scale());
|
||||
.into_px(context.gfx.scale())
|
||||
.round();
|
||||
self.mounted
|
||||
.synchronize_with(&self.children, &mut context.as_event_context());
|
||||
|
||||
|
|
@ -144,28 +176,7 @@ impl Widget for Wrap {
|
|||
// Calculate the horizontal alignment.
|
||||
let remaining = (width - x).max(Px::ZERO);
|
||||
let (x, space_between) = if remaining > 0 {
|
||||
match (align, order) {
|
||||
(WrapAlign::Start, HorizontalOrder::LeftToRight)
|
||||
| (WrapAlign::End, HorizontalOrder::RightToLeft) => (Px::ZERO, Px::ZERO),
|
||||
(WrapAlign::End, HorizontalOrder::LeftToRight)
|
||||
| (WrapAlign::Start, HorizontalOrder::RightToLeft) => (remaining, Px::ZERO),
|
||||
(WrapAlign::Center, _) => (remaining / 2, Px::ZERO),
|
||||
(WrapAlign::SpaceBetween, _) => {
|
||||
if row_children.len() > 1 {
|
||||
(Px::ZERO, remaining / (row_children.len() - 1).cast::<i32>())
|
||||
} else {
|
||||
(Px::ZERO, Px::ZERO)
|
||||
}
|
||||
}
|
||||
(WrapAlign::SpaceEvenly, _) => {
|
||||
let spacing = remaining / row_children.len().cast::<i32>();
|
||||
(spacing / 2, spacing)
|
||||
}
|
||||
(WrapAlign::SpaceAround, _) => {
|
||||
let spacing = remaining / (row_children.len() + 1).cast::<i32>();
|
||||
(spacing, spacing)
|
||||
}
|
||||
}
|
||||
Self::horizontal_alignment(align, order, remaining, row_children.len())
|
||||
} else {
|
||||
(Px::ZERO, Px::ZERO)
|
||||
};
|
||||
|
|
|
|||
Loading…
Reference in a new issue