Add a Clip

This commit is contained in:
Olivier Goffart 2020-11-20 15:43:52 +01:00
parent 89e0b57627
commit 08fe5f6c72
8 changed files with 103 additions and 11 deletions

View file

@ -41,6 +41,7 @@ extern const cbindgen_private::ItemVTable PathVTable;
extern const cbindgen_private::ItemVTable FlickableVTable; extern const cbindgen_private::ItemVTable FlickableVTable;
extern const cbindgen_private::ItemVTable WindowVTable; extern const cbindgen_private::ItemVTable WindowVTable;
extern const cbindgen_private::ItemVTable TextInputVTable; extern const cbindgen_private::ItemVTable TextInputVTable;
extern const cbindgen_private::ItemVTable ClipVTable;
extern const cbindgen_private::ItemVTable NativeButtonVTable; extern const cbindgen_private::ItemVTable NativeButtonVTable;
extern const cbindgen_private::ItemVTable NativeCheckBoxVTable; extern const cbindgen_private::ItemVTable NativeCheckBoxVTable;
@ -124,6 +125,7 @@ private:
} }
using cbindgen_private::BorderRectangle; using cbindgen_private::BorderRectangle;
using cbindgen_private::Clip;
using cbindgen_private::Flickable; using cbindgen_private::Flickable;
using cbindgen_private::Image; using cbindgen_private::Image;
using cbindgen_private::Path; using cbindgen_private::Path;

View file

@ -114,7 +114,6 @@ A text simply show the text on the screen
within the item within the item
### Example ### Example
```60 ```60
@ -303,4 +302,8 @@ Example := Window {
} }
``` ```
## `Clip`
By default, when an item is bigger or outside another item, it is still shown.
But the `Clip` element make sure to clip any children outside of the rectangle bounds

View file

@ -12,7 +12,6 @@ Remaining feature to implement to have parity:
* bold text when the tile is in the correct position in classic style * bold text when the tile is in the correct position in classic style
Note that this feature is kind of broken in the flutter example as it is only applied Note that this feature is kind of broken in the flutter example as it is only applied
when changing themes when changing themes
* Clip the Expanding cirle animation when pressing a tile.
* Hover effect on tiles * Hover effect on tiles
* Animation of the auto-play checkbox. * Animation of the auto-play checkbox.
* When the puzzle is finished, the last tile is added, and the tiles are growing in the Seatle theme. * When the puzzle is finished, the last tile is added, and the tiles are growing in the Seatle theme.

View file

@ -194,12 +194,8 @@ export MainWindow := Window {
} }
for p[i] in pieces : Rectangle { for p[i] in pieces : Clip {
property <bool> is_correct: i == p.pos_x * 4 + p.pos_y; property <bool> is_correct: i == p.pos_x * 4 + p.pos_y;
color: i >= 8 ? current-theme.piece-backround-2 : current-theme.piece-backround-1;
border-color: i >= 8 ? current-theme.piece-border-color-2 : current-theme.piece-border-color-1;
border-width: current-theme.piece-border;
border-radius: current-theme.piece-radius;
width: pieces_size; width: pieces_size;
height: pieces_size; height: pieces_size;
property<float> px: p.pos_x; property<float> px: p.pos_x;
@ -209,7 +205,16 @@ export MainWindow := Window {
y: px * (pieces_size + pieces_spacing) y: px * (pieces_size + pieces_spacing)
+ (parent.height - (4*pieces_size + 3*pieces_spacing))/2; + (parent.height - (4*pieces_size + 3*pieces_spacing))/2;
animate px , py { duration: 170ms; easing: cubic-bezier(0.17,0.76,0.4,1.75); } animate px , py { duration: 170ms; easing: cubic-bezier(0.17,0.76,0.4,1.75); }
animate border-width, border-radius { duration: 500ms; easing: ease-out; }
Rectangle {
width: 100%;
height: 100%;
color: i >= 8 ? current-theme.piece-backround-2 : current-theme.piece-backround-1;
border-color: i >= 8 ? current-theme.piece-border-color-2 : current-theme.piece-border-color-1;
border-width: current-theme.piece-border;
border-radius: current-theme.piece-radius;
animate border-width, border-radius { duration: 500ms; easing: ease-out; }
}
if (current-theme-index == 1) : Rectangle { if (current-theme-index == 1) : Rectangle {
width: 60%; width: 60%;

View file

@ -111,6 +111,13 @@ export TextInput := _ {
//focus() is hardcoded in typeregister.rs //focus() is hardcoded in typeregister.rs
} }
export Clip := _ {
property <length> x;
property <length> y;
property <length> width;
property <length> height;
}
Row := _ { Row := _ {
//-is_non_item_type //-is_non_item_type
} }

View file

@ -14,10 +14,9 @@ When adding an item or a property, it needs to be kept in sync with different pl
(This is less than ideal and maybe we can have some automation later) (This is less than ideal and maybe we can have some automation later)
- It needs to be changed in this module - It needs to be changed in this module
- The ItemVTable_static at the end of datastructures.rs (new items only)
- In the compiler: builtins.60 - In the compiler: builtins.60
- In the vewer: main.rs - In the interpreter: dynamic_component.rs
- For the C++ code (new item only): the build.rs to export the new item, and the `using` declaration in sixtyfps.h - For the C++ code (new item only): the cbindgen.rs to export the new item, and the `using` declaration in sixtyfps.h
- Don't forget to update the documentation - Don't forget to update the documentation
*/ */
@ -623,6 +622,81 @@ ItemVTable_static! {
pub static TouchAreaVTable for TouchArea pub static TouchAreaVTable for TouchArea
} }
#[repr(C)]
#[derive(FieldOffsets, Default, BuiltinItem)]
#[pin]
/// The implementation of the `Rectangle` element
pub struct Clip {
pub color: Property<Color>,
pub x: Property<f32>,
pub y: Property<f32>,
pub width: Property<f32>,
pub height: Property<f32>,
pub cached_rendering_data: CachedRenderingData,
}
impl Item for Clip {
fn init(self: Pin<&Self>, _window: &ComponentWindow) {}
fn geometry(self: Pin<&Self>) -> Rect {
euclid::rect(
Self::FIELD_OFFSETS.x.apply_pin(self).get(),
Self::FIELD_OFFSETS.y.apply_pin(self).get(),
Self::FIELD_OFFSETS.width.apply_pin(self).get(),
Self::FIELD_OFFSETS.height.apply_pin(self).get(),
)
}
fn rendering_primitive(
self: Pin<&Self>,
_window: &ComponentWindow,
) -> HighLevelRenderingPrimitive {
let width = Self::FIELD_OFFSETS.width.apply_pin(self).get();
let height = Self::FIELD_OFFSETS.height.apply_pin(self).get();
if width > 0. && height > 0. {
HighLevelRenderingPrimitive::ClipRect { width, height }
} else {
HighLevelRenderingPrimitive::NoContents
}
}
fn rendering_variables(
self: Pin<&Self>,
_window: &ComponentWindow,
) -> SharedArray<RenderingVariable> {
Default::default()
}
fn layouting_info(self: Pin<&Self>, _window: &crate::eventloop::ComponentWindow) -> LayoutInfo {
LayoutInfo { horizontal_stretch: 1., vertical_stretch: 1., ..LayoutInfo::default() }
}
fn input_event(
self: Pin<&Self>,
_: MouseEvent,
_window: &ComponentWindow,
_app_component: ComponentRefPin,
) -> InputEventResult {
InputEventResult::EventIgnored
}
fn key_event(self: Pin<&Self>, _: &KeyEvent, _window: &ComponentWindow) -> KeyEventResult {
KeyEventResult::EventIgnored
}
fn focus_event(self: Pin<&Self>, _: &FocusEvent, _window: &ComponentWindow) {}
}
impl ItemConsts for Clip {
const cached_rendering_data_offset: const_field_offset::FieldOffset<Clip, CachedRenderingData> =
Clip::FIELD_OFFSETS.cached_rendering_data.as_unpinned_projection();
}
ItemVTable_static! {
/// The VTable for `Clip`
#[no_mangle]
pub static ClipVTable for Clip
}
/// The implementation of the `Path` element /// The implementation of the `Path` element
#[repr(C)] #[repr(C)]
#[derive(FieldOffsets, Default, BuiltinItem)] #[derive(FieldOffsets, Default, BuiltinItem)]

View file

@ -497,6 +497,7 @@ fn generate_component<'id>(
rtti_for_flickable(), rtti_for_flickable(),
rtti_for::<Window>(), rtti_for::<Window>(),
rtti_for::<TextInput>(), rtti_for::<TextInput>(),
rtti_for::<Clip>(),
] ]
.iter() .iter()
.cloned(), .cloned(),

View file

@ -58,6 +58,7 @@ fn gen_corelib(include_dir: &Path) -> anyhow::Result<()> {
"TextVerticalAlignment", "TextVerticalAlignment",
"Window", "Window",
"TextInput", "TextInput",
"Clip",
] ]
.iter() .iter()
.map(|x| x.to_string()) .map(|x| x.to_string())