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
|
||||
- `has_hover` property in `TouchArea`
|
||||
- `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
|
||||
|
|
|
@ -231,6 +231,9 @@ accordingly.
|
|||
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
|
||||
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
|
||||
|
||||
|
|
|
@ -323,6 +323,7 @@ export Path := _ {
|
|||
property <float> viewbox_y;
|
||||
property <float> viewbox_width;
|
||||
property <float> viewbox_height;
|
||||
property <bool> clip;
|
||||
|
||||
//-disallow_global_types_as_child_elements
|
||||
MoveTo {}
|
||||
|
|
|
@ -31,13 +31,22 @@ pub fn handle_clip(
|
|||
&mut |elem_rc: &ElementRc, _| {
|
||||
let mut elem = elem_rc.borrow_mut();
|
||||
if let Some(clip_prop) = elem.bindings.remove("clip") {
|
||||
if !elem.builtin_type().map_or(false, |bt| bt.name == "Rectangle") {
|
||||
diag.push_error(
|
||||
"The 'clip' property can only be applied to a Rectangle for now".into(),
|
||||
&clip_prop.span,
|
||||
);
|
||||
return;
|
||||
};
|
||||
match elem.builtin_type().as_ref().map(|ty| ty.name.as_str()) {
|
||||
Some("Rectangle") => {}
|
||||
Some("Path") => {
|
||||
// it's an actual property, so keep the binding
|
||||
elem.bindings.insert("clip".into(), clip_prop);
|
||||
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
|
||||
elem.property_declarations.remove("clip");
|
||||
match &clip_prop.expression {
|
||||
|
|
|
@ -17,7 +17,7 @@ SubElements := Rectangle {
|
|||
}
|
||||
Image {
|
||||
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 {
|
||||
clip: true || true;
|
||||
|
|
|
@ -776,6 +776,7 @@ pub struct Path {
|
|||
pub viewbox_y: Property<f32>,
|
||||
pub viewbox_width: Property<f32>,
|
||||
pub viewbox_height: Property<f32>,
|
||||
pub clip: Property<bool>,
|
||||
pub cached_rendering_data: CachedRenderingData,
|
||||
}
|
||||
|
||||
|
@ -783,7 +784,7 @@ impl Item for Path {
|
|||
fn init(self: Pin<&Self>, _window: &ComponentWindow) {}
|
||||
|
||||
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 {
|
||||
|
@ -815,7 +816,15 @@ impl Item for Path {
|
|||
fn focus_event(self: Pin<&Self>, _: &FocusEvent, _window: &ComponentWindow) {}
|
||||
|
||||
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