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 1e9848e
Show file tree
Hide file tree
Showing 21 changed files with 511 additions and 30 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,
}),
}
}
}
20 changes: 13 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,24 @@ 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());
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
}
};

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)) => {
(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

0 comments on commit 1e9848e

Please sign in to comment.