mirror of
https://github.com/slint-ui/slint.git
synced 2025-10-02 06:41:14 +00:00
Add support for clip on Path elements
This allows clipping the viewbox conveniently.
This commit is contained in:
parent
7de783bbe1
commit
cc9d5e09f0
7 changed files with 131 additions and 11 deletions
|
@ -124,7 +124,7 @@ All notable changes to this project will be documented in this file.
|
||||||
- Signals can have return a value
|
- Signals can have return a value
|
||||||
- `has_hover` property in `TouchArea`
|
- `has_hover` property in `TouchArea`
|
||||||
- `font-weight` property on Text
|
- `font-weight` property on Text
|
||||||
- `viewbox-x/y/width/height` properties for `Path`
|
- `viewbox-x/y/width/height` and `clip` properties for `Path`
|
||||||
|
|
||||||
|
|
||||||
## [0.0.2] - 2020-10-22
|
## [0.0.2] - 2020-10-22
|
||||||
|
|
|
@ -231,6 +231,9 @@ accordingly.
|
||||||
defining the position and size of the viewport of the path in path coordinates. In the rendered output, the
|
defining the position and size of the viewport of the path in path coordinates. In the rendered output, the
|
||||||
If the `viewbox-width` or `viewbox-height` is less or equal than zero, the viewbox properties are ignored
|
If the `viewbox-width` or `viewbox-height` is less or equal than zero, the viewbox properties are ignored
|
||||||
and instead the bounding rectangle of all path elements are used to define the view port.
|
and instead the bounding rectangle of all path elements are used to define the view port.
|
||||||
|
* **`clip`** (*bool*): By default, when a path has a view box defined and the elements render outside of it, they are still
|
||||||
|
rendered. When this property is set to true, then rendering will be clipped at the boundaries of the view box.
|
||||||
|
This property must be a literal `true` or `false` (default: false)
|
||||||
|
|
||||||
#### Path Using SVG commands
|
#### Path Using SVG commands
|
||||||
|
|
||||||
|
|
|
@ -323,6 +323,7 @@ export Path := _ {
|
||||||
property <float> viewbox_y;
|
property <float> viewbox_y;
|
||||||
property <float> viewbox_width;
|
property <float> viewbox_width;
|
||||||
property <float> viewbox_height;
|
property <float> viewbox_height;
|
||||||
|
property <bool> clip;
|
||||||
|
|
||||||
//-disallow_global_types_as_child_elements
|
//-disallow_global_types_as_child_elements
|
||||||
MoveTo {}
|
MoveTo {}
|
||||||
|
|
|
@ -31,13 +31,22 @@ pub fn handle_clip(
|
||||||
&mut |elem_rc: &ElementRc, _| {
|
&mut |elem_rc: &ElementRc, _| {
|
||||||
let mut elem = elem_rc.borrow_mut();
|
let mut elem = elem_rc.borrow_mut();
|
||||||
if let Some(clip_prop) = elem.bindings.remove("clip") {
|
if let Some(clip_prop) = elem.bindings.remove("clip") {
|
||||||
if !elem.builtin_type().map_or(false, |bt| bt.name == "Rectangle") {
|
match elem.builtin_type().as_ref().map(|ty| ty.name.as_str()) {
|
||||||
diag.push_error(
|
Some("Rectangle") => {}
|
||||||
"The 'clip' property can only be applied to a Rectangle for now".into(),
|
Some("Path") => {
|
||||||
&clip_prop.span,
|
// it's an actual property, so keep the binding
|
||||||
);
|
elem.bindings.insert("clip".into(), clip_prop);
|
||||||
return;
|
return;
|
||||||
};
|
}
|
||||||
|
_ => {
|
||||||
|
diag.push_error(
|
||||||
|
"The 'clip' property can only be applied to a Rectangle or a Path for now"
|
||||||
|
.into(),
|
||||||
|
&clip_prop.span,
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
// Was added by the meterialier_fake_properties pass
|
// Was added by the meterialier_fake_properties pass
|
||||||
elem.property_declarations.remove("clip");
|
elem.property_declarations.remove("clip");
|
||||||
match &clip_prop.expression {
|
match &clip_prop.expression {
|
||||||
|
|
|
@ -17,7 +17,7 @@ SubElements := Rectangle {
|
||||||
}
|
}
|
||||||
Image {
|
Image {
|
||||||
clip: false;
|
clip: false;
|
||||||
// ^error{The 'clip' property can only be applied to a Rectangle for now}
|
// ^error{The 'clip' property can only be applied to a Rectangle or a Path for now}
|
||||||
}
|
}
|
||||||
for a in 12 : Rectangle {
|
for a in 12 : Rectangle {
|
||||||
clip: true || true;
|
clip: true || true;
|
||||||
|
|
|
@ -776,6 +776,7 @@ pub struct Path {
|
||||||
pub viewbox_y: Property<f32>,
|
pub viewbox_y: Property<f32>,
|
||||||
pub viewbox_width: Property<f32>,
|
pub viewbox_width: Property<f32>,
|
||||||
pub viewbox_height: Property<f32>,
|
pub viewbox_height: Property<f32>,
|
||||||
|
pub clip: Property<bool>,
|
||||||
pub cached_rendering_data: CachedRenderingData,
|
pub cached_rendering_data: CachedRenderingData,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -783,7 +784,7 @@ impl Item for Path {
|
||||||
fn init(self: Pin<&Self>, _window: &ComponentWindow) {}
|
fn init(self: Pin<&Self>, _window: &ComponentWindow) {}
|
||||||
|
|
||||||
fn geometry(self: Pin<&Self>) -> Rect {
|
fn geometry(self: Pin<&Self>) -> Rect {
|
||||||
euclid::rect(self.x(), self.y(), 0., 0.)
|
euclid::rect(self.x(), self.y(), self.width(), self.height())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn layouting_info(self: Pin<&Self>, _window: &ComponentWindow) -> LayoutInfo {
|
fn layouting_info(self: Pin<&Self>, _window: &ComponentWindow) -> LayoutInfo {
|
||||||
|
@ -815,7 +816,15 @@ impl Item for Path {
|
||||||
fn focus_event(self: Pin<&Self>, _: &FocusEvent, _window: &ComponentWindow) {}
|
fn focus_event(self: Pin<&Self>, _: &FocusEvent, _window: &ComponentWindow) {}
|
||||||
|
|
||||||
fn render(self: Pin<&Self>, backend: &mut ItemRendererRef) {
|
fn render(self: Pin<&Self>, backend: &mut ItemRendererRef) {
|
||||||
(*backend).draw_path(self)
|
let clip = self.clip();
|
||||||
|
if clip {
|
||||||
|
(*backend).save_state();
|
||||||
|
(*backend).combine_clip(self.geometry(), 0., 0.)
|
||||||
|
}
|
||||||
|
(*backend).draw_path(self);
|
||||||
|
if clip {
|
||||||
|
(*backend).restore_state();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
98
tests/cases/examples/path_viewbox.60
Normal file
98
tests/cases/examples/path_viewbox.60
Normal file
|
@ -0,0 +1,98 @@
|
||||||
|
/* LICENSE BEGIN
|
||||||
|
This file is part of the SixtyFPS Project -- https://sixtyfps.io
|
||||||
|
Copyright (c) 2020 Olivier Goffart <olivier.goffart@sixtyfps.io>
|
||||||
|
Copyright (c) 2020 Simon Hausmann <simon.hausmann@sixtyfps.io>
|
||||||
|
|
||||||
|
SPDX-License-Identifier: GPL-3.0-only
|
||||||
|
This file is also available under commercial licensing terms.
|
||||||
|
Please contact info@sixtyfps.io for more information.
|
||||||
|
LICENSE END */
|
||||||
|
|
||||||
|
RectPath := Path {
|
||||||
|
MoveTo {
|
||||||
|
x: 0;
|
||||||
|
y: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
LineTo {
|
||||||
|
x: 100;
|
||||||
|
y: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
LineTo {
|
||||||
|
x: 100;
|
||||||
|
y: 100;
|
||||||
|
}
|
||||||
|
|
||||||
|
LineTo {
|
||||||
|
x: 0;
|
||||||
|
y: 100;
|
||||||
|
}
|
||||||
|
|
||||||
|
Close {}
|
||||||
|
}
|
||||||
|
|
||||||
|
PathViewBox := Window {
|
||||||
|
preferred-width: 600px;
|
||||||
|
preferred-height: 600px;
|
||||||
|
|
||||||
|
// This is the reference path rectangle
|
||||||
|
RectPath {
|
||||||
|
x: 100px;
|
||||||
|
y: 100px;
|
||||||
|
width: 100px;
|
||||||
|
height: 100px;
|
||||||
|
|
||||||
|
stroke-width: 1px;
|
||||||
|
stroke: black;
|
||||||
|
}
|
||||||
|
|
||||||
|
// This path rectangle uses an unclipped viewbox and therefore
|
||||||
|
// draws outside the boundaries of the underlying green rectangle.
|
||||||
|
Rectangle {
|
||||||
|
background: #26e115da;
|
||||||
|
x: 300px;
|
||||||
|
y: 100px;
|
||||||
|
width: 100px;
|
||||||
|
height: 100px;
|
||||||
|
|
||||||
|
RectPath {
|
||||||
|
width: 100px;
|
||||||
|
height: 100px;
|
||||||
|
|
||||||
|
stroke-width: 1px;
|
||||||
|
stroke: black;
|
||||||
|
|
||||||
|
viewbox-x: 50;
|
||||||
|
viewbox-y: 0;
|
||||||
|
viewbox-width: 100;
|
||||||
|
viewbox-height: 100;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// This path rectangle uses an clipped viewbox and therefore
|
||||||
|
// draws only inside the boundaries of the underlying green rectangle.
|
||||||
|
Rectangle {
|
||||||
|
background: #26e115da;
|
||||||
|
x: 100px;
|
||||||
|
y: 300px;
|
||||||
|
width: 100px;
|
||||||
|
height: 100px;
|
||||||
|
|
||||||
|
RectPath {
|
||||||
|
width: 100px;
|
||||||
|
height: 100px;
|
||||||
|
|
||||||
|
stroke-width: 1px;
|
||||||
|
stroke: black;
|
||||||
|
|
||||||
|
clip: true;
|
||||||
|
|
||||||
|
viewbox-x: 50;
|
||||||
|
viewbox-y: 0;
|
||||||
|
viewbox-width: 100;
|
||||||
|
viewbox-height: 100;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue