Skip to content

Commit

Permalink
Add padding to View component
Browse files Browse the repository at this point in the history
  • Loading branch information
noituri committed Jan 27, 2025
1 parent c65572e commit a4f2181
Show file tree
Hide file tree
Showing 21 changed files with 490 additions and 20 deletions.
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>,

/// (**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,
}),
}
}
}
15 changes: 10 additions & 5 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,23 @@ impl StatefulLayoutComponent {
child: &mut StatefulComponent,
position: AbsolutePosition,
parent_size: Size,
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 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
}
};

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),
}
}
}
11 changes: 8 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,12 @@ 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 component_id(&self) -> Option<&ComponentId> {
Expand Down Expand Up @@ -130,6 +134,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),
}
}
}
33 changes: 24 additions & 9 deletions compositor_render/src/scene/view_component/layout.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ impl ViewComponentParam {
width: f32::max(size.width - 2.0 * self.border_width, 0.0),
height: f32::max(size.height - 2.0 * self.border_width, 0.0),
};

let static_child_size = self.static_child_size(content_size, children, pts);
let (scale, crop, mask) = match self.overflow {
Overflow::Visible => (1.0, None, None),
Expand Down Expand Up @@ -99,7 +100,11 @@ impl ViewComponentParam {
}
Position::Absolute(position) => {
StatefulLayoutComponent::layout_absolute_position_child(
child, position, size, pts,
child,
position,
size,
self.padding,
pts,
)
}
}
Expand Down Expand Up @@ -132,24 +137,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.

49 changes: 49 additions & 0 deletions snapshot_tests/view/column_view_padding_static_children.scene.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
{
"video": {
"root": {
"type": "view",
"background_color": "#000000FF",
"children": [
{
"type": "view",
"background_color": "#FF0000FF",
"direction": "column",
"width": 300,
"height": 300,
"children": [
{
"type": "view",
"padding_top": 10,
"padding_left": 20,
"border_width": 4,
"border_color": "#FF00FFFF",
"background_color": "#0000FFFF",
"children": []
},
{
"type": "view",
"padding_top": 10,
"padding_bottom": 30,
"padding_right": 10,
"padding_left": 20,
"border_width": 4,
"border_color": "#0F0FF0FF",
"background_color": "#00FF00FF",
"children": [
{
"type": "view",
"width": 250,
"height": 250,
"border_width": 4,
"border_color": "#FF00FFFF",
"background_color": "#00FFFFFF",
"children": []
}
]
}
]
}
]
}
}
}
Loading

0 comments on commit a4f2181

Please sign in to comment.