Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add padding to View component #931

Merged
merged 2 commits into from
Jan 30, 2025
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions compositor_api/src/types/component.rs
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,18 @@ pub struct View {

/// List of box shadows.
pub box_shadow: Option<Vec<BoxShadow>>,

/// (**default=`0.0`**) Padding on top side in pixels.
pub padding_top: Option<f32>,
noituri marked this conversation as resolved.
Show resolved Hide resolved

/// (**default=`0.0`**) Padding on right side in pixels.
pub padding_right: Option<f32>,

/// (**default=`0.0`**) Padding on bottom side in pixels.
pub padding_bottom: Option<f32>,

/// (**default=`0.0`**) Padding on left side in pixels.
pub padding_left: Option<f32>,
}

#[derive(Debug, Serialize, Deserialize, Clone, JsonSchema)]
Expand Down
12 changes: 12 additions & 0 deletions compositor_api/src/types/from_component.rs
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,17 @@ impl TryFrom<View> for scene::ViewComponent {
Some(Overflow::Fit) => scene::Overflow::Fit,
None => scene::Overflow::Hidden,
};
let padding = scene::Padding {
top: view.padding_top.unwrap_or(0.0),
right: view.padding_right.unwrap_or(0.0),
bottom: view.padding_bottom.unwrap_or(0.0),
left: view.padding_left.unwrap_or(0.0),
};

if padding.top < 0.0 || padding.right < 0.0 || padding.bottom < 0.0 || padding.left < 0.0 {
return Err(TypeError::new("Padding values cannot be negative."));
}

Ok(Self {
id: view.id.map(Into::into),
children: view
Expand Down Expand Up @@ -114,6 +125,7 @@ impl TryFrom<View> for scene::ViewComponent {
.into_iter()
.map(TryInto::try_into)
.collect::<Result<_, _>>()?,
padding,
})
}
}
Expand Down
20 changes: 20 additions & 0 deletions compositor_render/src/scene/components.rs
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,8 @@ pub struct ViewComponent {
pub border_color: RGBAColor,

pub box_shadow: Vec<BoxShadow>,

pub padding: Padding,
}

#[derive(Debug, Clone, Copy)]
Expand Down Expand Up @@ -178,6 +180,24 @@ pub enum ViewChildrenDirection {
Column,
}

#[derive(Debug, Clone, Copy, Default)]
pub struct Padding {
pub top: f32,
pub right: f32,
pub bottom: f32,
pub left: f32,
}

impl Padding {
pub fn horizontal(&self) -> f32 {
self.left + self.right
}

pub fn vertical(&self) -> f32 {
self.top + self.bottom
}
}

#[derive(Debug, Clone)]
pub struct RescalerComponent {
pub id: Option<ComponentId>,
Expand Down
24 changes: 23 additions & 1 deletion compositor_render/src/scene/components/position.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use crate::scene::AbsolutePosition;

use super::Position;
use super::{Padding, Position};

impl Position {
pub(crate) fn with_border(self, border_width: f32) -> Self {
Expand All @@ -24,4 +24,26 @@ impl Position {
}),
}
}

pub(crate) fn with_padding(self, padding: Padding) -> Self {
match self {
Position::Static { width, height } => Self::Static {
width: width.map(|w| w + padding.horizontal()),
height: height.map(|h| h + padding.vertical()),
},
Position::Absolute(AbsolutePosition {
width,
height,
position_horizontal,
position_vertical,
rotation_degrees,
}) => Self::Absolute(AbsolutePosition {
width: width.map(|w| w + padding.horizontal()),
height: height.map(|h| h + padding.vertical()),
position_horizontal,
position_vertical,
rotation_degrees,
}),
}
}
}
24 changes: 17 additions & 7 deletions compositor_render/src/scene/layout.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use crate::{
use super::{
rescaler_component::StatefulRescalerComponent, tiles_component::StatefulTilesComponent,
view_component::StatefulViewComponent, AbsolutePosition, BorderRadius, ComponentId,
HorizontalPosition, Position, RGBAColor, Size, StatefulComponent, VerticalPosition,
HorizontalPosition, Padding, Position, RGBAColor, Size, StatefulComponent, VerticalPosition,
};

#[derive(Debug, Clone)]
Expand Down Expand Up @@ -161,18 +161,28 @@ impl StatefulLayoutComponent {
child: &mut StatefulComponent,
position: AbsolutePosition,
parent_size: Size,
child_padding: Padding,
parent_padding: Padding,
pts: Duration,
) -> NestedLayout {
let width = position.width.unwrap_or(parent_size.width);
let height = position.height.unwrap_or(parent_size.height);
let width = position
.width
.unwrap_or(parent_size.width + child_padding.horizontal());
noituri marked this conversation as resolved.
Show resolved Hide resolved
let height = position
.height
.unwrap_or(parent_size.height + child_padding.vertical());

let top = match position.position_vertical {
VerticalPosition::TopOffset(top) => top,
VerticalPosition::BottomOffset(bottom) => parent_size.height - bottom - height,
VerticalPosition::TopOffset(top) => top + parent_padding.top,
VerticalPosition::BottomOffset(bottom) => {
parent_size.height - bottom - height - parent_padding.bottom + parent_padding.top
}
};
let left = match position.position_horizontal {
HorizontalPosition::LeftOffset(left) => left,
HorizontalPosition::RightOffset(right) => parent_size.width - right - width,
HorizontalPosition::LeftOffset(left) => left + parent_padding.left,
HorizontalPosition::RightOffset(right) => {
parent_size.width - right - width - parent_padding.right + parent_padding.left
noituri marked this conversation as resolved.
Show resolved Hide resolved
}
};

let rotation_degrees = position.rotation_degrees;
Expand Down
13 changes: 13 additions & 0 deletions compositor_render/src/scene/types/interpolation.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
use crate::scene::Padding;

use super::{HorizontalPosition, VerticalPosition};

#[derive(Debug, Clone, Copy)]
Expand Down Expand Up @@ -77,3 +79,14 @@ impl ContinuousValue for HorizontalPosition {
}
}
}

impl ContinuousValue for Padding {
fn interpolate(start: &Self, end: &Self, state: InterpolationState) -> Self {
Self {
top: ContinuousValue::interpolate(&start.top, &end.top, state),
right: ContinuousValue::interpolate(&start.right, &end.right, state),
bottom: ContinuousValue::interpolate(&start.bottom, &end.bottom, state),
left: ContinuousValue::interpolate(&start.left, &end.left, state),
}
}
}
15 changes: 12 additions & 3 deletions compositor_render/src/scene/view_component.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use super::{
scene_state::BuildStateTreeCtx,
transition::{TransitionOptions, TransitionState},
types::interpolation::ContinuousValue,
BorderRadius, BoxShadow, Component, ComponentId, IntermediateNode, Overflow, Position,
BorderRadius, BoxShadow, Component, ComponentId, IntermediateNode, Overflow, Padding, Position,
RGBAColor, SceneError, Size, StatefulComponent,
};

Expand Down Expand Up @@ -37,6 +37,8 @@ struct ViewComponentParam {
border_color: RGBAColor,

box_shadow: Vec<BoxShadow>,

padding: Padding,
}

impl StatefulViewComponent {
Expand All @@ -56,10 +58,16 @@ impl StatefulViewComponent {
self.children.iter_mut().collect()
}

/// External position of a component (includes border)
/// External position of a component (includes border and padding)
pub(super) fn position(&self, pts: Duration) -> Position {
let view = self.view(pts);
view.position.with_border(view.border_width)
view.position
.with_border(view.border_width)
.with_padding(view.padding)
}

pub(super) fn padding(&self, pts: Duration) -> Padding {
self.view(pts).padding
}

pub(super) fn component_id(&self) -> Option<&ComponentId> {
Expand Down Expand Up @@ -130,6 +138,7 @@ impl ViewComponent {
border_width: self.border_width,
border_color: self.border_color,
box_shadow: self.box_shadow,
padding: self.padding,
},
transition,
children: self
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ impl ContinuousValue for ViewComponentParam {
),
border_color: end.border_color,
box_shadow: ContinuousValue::interpolate(&start.box_shadow, &end.box_shadow, state),
padding: ContinuousValue::interpolate(&start.padding, &end.padding, state),
}
}
}
55 changes: 38 additions & 17 deletions compositor_render/src/scene/view_component/layout.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ use std::time::Duration;

use crate::{
scene::{
layout::StatefulLayoutComponent, BorderRadius, Overflow, Position, RGBAColor, Size,
StatefulComponent, ViewChildrenDirection,
layout::StatefulLayoutComponent, BorderRadius, Overflow, Padding, Position, RGBAColor,
Size, StatefulComponent, ViewChildrenDirection,
},
transformations::layout::{LayoutContent, Mask, NestedLayout},
};
Expand Down Expand Up @@ -72,12 +72,18 @@ impl ViewComponentParam {
let children: Vec<_> = children
.iter_mut()
.map(|child| {
let position = match child {
StatefulComponent::Layout(layout) => layout.position(pts),
ref non_layout_component => Position::Static {
width: non_layout_component.width(pts),
height: non_layout_component.height(pts),
},
let (position, padding) = match child {
StatefulComponent::Layout(StatefulLayoutComponent::View(view)) => {
noituri marked this conversation as resolved.
Show resolved Hide resolved
(view.position(pts), view.padding(pts))
}
StatefulComponent::Layout(layout) => (layout.position(pts), Padding::default()),
ref non_layout_component => (
Position::Static {
width: non_layout_component.width(pts),
height: non_layout_component.height(pts),
},
Padding::default(),
),
};
match position {
Position::Static { width, height } => {
Expand All @@ -99,7 +105,12 @@ impl ViewComponentParam {
}
Position::Absolute(position) => {
StatefulLayoutComponent::layout_absolute_position_child(
child, position, size, pts,
child,
position,
size,
padding,
self.padding,
pts,
)
}
}
Expand Down Expand Up @@ -132,24 +143,34 @@ impl ViewComponentParam {
pts: Duration,
) -> (NestedLayout, f32) {
let mut static_offset = opts.static_offset;

let (static_width, static_height) = match self.direction {
ViewChildrenDirection::Row => (opts.static_child_size, opts.parent_size.height),
ViewChildrenDirection::Column => (opts.parent_size.width, opts.static_child_size),
};

// Parent padding can shrink the child if it doesn't have width/height provided
let static_width = static_width - self.padding.horizontal();
let static_height = static_height - self.padding.vertical();

let width = opts.width.unwrap_or(static_width);
let height = opts.height.unwrap_or(static_height);

let (top, left, width, height) = match self.direction {
ViewChildrenDirection::Row => {
let width = opts.width.unwrap_or(opts.static_child_size);
let height = opts.height.unwrap_or(opts.parent_size.height);
let top = opts.parent_border_width;
let left = static_offset;
let top = opts.parent_border_width + self.padding.top;
let left = static_offset + self.padding.left;
static_offset += width;
(top, left, width, height)
}
ViewChildrenDirection::Column => {
let height = opts.height.unwrap_or(opts.static_child_size);
let width = opts.width.unwrap_or(opts.parent_size.width);
let top = static_offset;
let left = opts.parent_border_width;
let top = static_offset + self.padding.top;
let left = opts.parent_border_width + self.padding.left;
static_offset += height;
(top, left, width, height)
}
};

let layout = match child {
StatefulComponent::Layout(layout_component) => {
let children_layouts = layout_component.layout(Size { width, height }, pts);
Expand Down
2 changes: 1 addition & 1 deletion integration_tests/examples/tiles.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ fn client_code() -> Result<()> {
.map(|_| {
json!({
"type": "input_stream",
"input_id": "input_1",
"input_id": "input_1"
})
})
.collect();
Expand Down
32 changes: 32 additions & 0 deletions schemas/scene.schema.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading
Loading