Add support for source clipping to the Image element

This allows rendering only a sub-rectangle of the original image, which
we can use right away in the sliding puzzle demo.
This commit is contained in:
Simon Hausmann 2020-11-20 17:29:59 +01:00
parent 7583394751
commit 3d85e45ec3
13 changed files with 219 additions and 25 deletions

View file

@ -8,6 +8,7 @@ All notable changes to this project will be documented in this file.
- VerticalLayout / HorizontalLayout - VerticalLayout / HorizontalLayout
- Placeholder text in line edit - Placeholder text in line edit
- global components (#96) - global components (#96)
- `Image` element: New source-clip-{x, y, width, height} properties
## [0.0.2] - 2020-12-22 ## [0.0.2] - 2020-12-22

View file

@ -37,6 +37,7 @@ extern const cbindgen_private::ItemVTable BorderRectangleVTable;
extern const cbindgen_private::ItemVTable TextVTable; extern const cbindgen_private::ItemVTable TextVTable;
extern const cbindgen_private::ItemVTable TouchAreaVTable; extern const cbindgen_private::ItemVTable TouchAreaVTable;
extern const cbindgen_private::ItemVTable ImageVTable; extern const cbindgen_private::ItemVTable ImageVTable;
extern const cbindgen_private::ItemVTable ClippedImageVTable;
extern const cbindgen_private::ItemVTable PathVTable; 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;
@ -126,6 +127,7 @@ private:
using cbindgen_private::BorderRectangle; using cbindgen_private::BorderRectangle;
using cbindgen_private::Clip; using cbindgen_private::Clip;
using cbindgen_private::ClippedImage;
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

@ -88,6 +88,8 @@ An Image can be used to represent an image loaded from an image file
* **`source`** (*image*): The image to load. In order to reference image, one uses the `img!"..."` macro * **`source`** (*image*): The image to load. In order to reference image, one uses the `img!"..."` macro
which loads the file relative to the directory containing the .60 file. which loads the file relative to the directory containing the .60 file.
* **`source-clip-x`**, **`source-clip-y`**, **`source-clip-width`**, **`source-clip-height`** (*int*): properties in source
image coordinates that, when specified, can be used to render only a portion of the specified image.
### Example ### Example

View file

@ -5,7 +5,6 @@ https://flutter.github.io/samples/slide_puzzle
This will allow to compare SixtyFPS and Flutter. This will allow to compare SixtyFPS and Flutter.
Remaining feature to implement to have parity: Remaining feature to implement to have parity:
* Images on the tiles in the "Berlin" theme.
* Fonts. * Fonts.
* "Spring" animation instead of a bezier curve. * "Spring" animation instead of a bezier curve.
* Animation when clicking on a tile that cannot be moved. * Animation when clicking on a tile that cannot be moved.

View file

@ -21,6 +21,7 @@ struct Theme := {
name: string, name: string,
window-background-color: color, window-background-color: color,
game-background-color: color, game-background-color: color,
game-use-background-image: bool,
game-border: length, game-border: length,
game-radius: length, game-radius: length,
game-text-color: color, game-text-color: color,
@ -133,6 +134,7 @@ export MainWindow := Window {
name: "SIMPLE", name: "SIMPLE",
window-background-color: #ffffff, window-background-color: #ffffff,
game-background-color: #ffffff, game-background-color: #ffffff,
game-use-background-image: false,
game-border: 1px, game-border: 1px,
game-radius: 2px, game-radius: 2px,
game-text-color: #858585, game-text-color: #858585,
@ -152,6 +154,7 @@ export MainWindow := Window {
name: "BERLIN", name: "BERLIN",
window-background-color: #ffffff88, window-background-color: #ffffff88,
game-background-color: #ffffffcc, game-background-color: #ffffffcc,
game-use-background-image: true,
game-border: 0px, game-border: 0px,
game-radius: 2px, game-radius: 2px,
game-text-color: #858585, game-text-color: #858585,
@ -171,6 +174,7 @@ export MainWindow := Window {
name: "PLASTER", name: "PLASTER",
window-background-color: #424244, window-background-color: #424244,
game-background-color: #f8f4e9, game-background-color: #f8f4e9,
game-use-background-image: false,
game-border: 5px, game-border: 5px,
game-radius: 20px, game-radius: 20px,
game-text-color: #858585, game-text-color: #858585,
@ -279,7 +283,17 @@ export MainWindow := Window {
+ (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); }
Rectangle { if (current-theme.game-use-background-image) : Image {
height: 100%; width: 100%;
// https://commons.wikimedia.org/wiki/File:Berlin_potsdamer_platz.jpg Belappetit, CC BY-SA 3.0
source: img!"berlin.jpg";
source-clip-x: mod(i, 4) * 1024 / 4;
source-clip-y: floor(i / 4) * 683 / 4;
source-clip-width: 1024 / 4;
source-clip-height: 683 / 4;
}
if (!current-theme.game-use-background-image) : Rectangle {
width: 100%; width: 100%;
height: 100%; height: 100%;
color: i >= 8 ? current-theme.piece-background-2 : current-theme.piece-background-1; color: i >= 8 ? current-theme.piece-background-2 : current-theme.piece-background-1;

View file

@ -34,7 +34,7 @@ BorderRectangle := Rectangle {
export { BorderRectangle as Rectangle } export { BorderRectangle as Rectangle }
export Image := _ { Image := _ {
property <resource> source; property <resource> source;
property <length> x; property <length> x;
property <length> y; property <length> y;
@ -42,6 +42,15 @@ export Image := _ {
property <length> height; property <length> height;
} }
export ClippedImage := Image {
property <int> source-clip-x;
property <int> source-clip-y;
property <int> source-clip-width;
property <int> source-clip-height;
}
export { ClippedImage as Image }
export Text := _ { export Text := _ {
property <string> text; property <string> text;
property <string> font_family; property <string> font_family;

View file

@ -43,6 +43,8 @@ use std::rc::Rc;
/// 2D Rectangle /// 2D Rectangle
pub type Rect = euclid::default::Rect<f32>; pub type Rect = euclid::default::Rect<f32>;
/// 2D Rectangle with integer coordinates
pub type IntRect = euclid::default::Rect<i32>;
/// 2D Point /// 2D Point
pub type Point = euclid::default::Point2D<f32>; pub type Point = euclid::default::Point2D<f32>;
/// 2D Size /// 2D Size
@ -276,7 +278,7 @@ pub enum HighLevelRenderingPrimitive {
/// Optional rendering variables: /// Optional rendering variables:
/// * [`RenderingVariable::ScaledWidth`]: The image will be scaled to the specified width. /// * [`RenderingVariable::ScaledWidth`]: The image will be scaled to the specified width.
/// * [`RenderingVariable::ScaledHeight`]: The image will be scaled to the specified height. /// * [`RenderingVariable::ScaledHeight`]: The image will be scaled to the specified height.
Image { source: crate::Resource }, Image { source: crate::Resource, source_clip_rect: IntRect },
/// Renders the specified `text` with a font that matches the specified family (`font_family`) and the given /// Renders the specified `text` with a font that matches the specified family (`font_family`) and the given
/// pixel size (`font_size`). /// pixel size (`font_size`).
/// ///
@ -1213,6 +1215,16 @@ pub(crate) mod ffi {
height: f32, height: f32,
} }
/// Expand IntRect so that cbindgen can see it. ( is in fact euclid::default::Rect<i32>)
#[cfg(cbindgen)]
#[repr(C)]
struct IntRect {
x: i32,
y: i32,
width: i32,
height: i32,
}
/// Expand Point so that cbindgen can see it. ( is in fact euclid::default::PointD2<f32>) /// Expand Point so that cbindgen can see it. ( is in fact euclid::default::PointD2<f32>)
#[cfg(cbindgen)] #[cfg(cbindgen)]
#[repr(C)] #[repr(C)]

View file

@ -26,7 +26,7 @@ When adding an item or a property, it needs to be kept in sync with different pl
use super::component::ComponentVTable; use super::component::ComponentVTable;
use super::eventloop::ComponentWindow; use super::eventloop::ComponentWindow;
use super::graphics::{Color, HighLevelRenderingPrimitive, PathData, Rect, Resource}; use super::graphics::{Color, HighLevelRenderingPrimitive, IntRect, PathData, Rect, Resource};
use super::input::{ use super::input::{
FocusEvent, InputEventResult, KeyEvent, KeyEventResult, KeyboardModifiers, MouseEvent, FocusEvent, InputEventResult, KeyEvent, KeyEventResult, KeyboardModifiers, MouseEvent,
MouseEventType, MouseEventType,
@ -305,6 +305,7 @@ impl Item for Image {
) -> HighLevelRenderingPrimitive { ) -> HighLevelRenderingPrimitive {
HighLevelRenderingPrimitive::Image { HighLevelRenderingPrimitive::Image {
source: Self::FIELD_OFFSETS.source.apply_pin(self).get(), source: Self::FIELD_OFFSETS.source.apply_pin(self).get(),
source_clip_rect: IntRect::default(),
} }
} }
@ -362,6 +363,103 @@ ItemVTable_static! {
pub static ImageVTable for Image pub static ImageVTable for Image
} }
#[repr(C)]
#[derive(FieldOffsets, Default, BuiltinItem)]
#[pin]
/// The implementation of the `ClippedImage` element
pub struct ClippedImage {
pub source: Property<Resource>,
pub x: Property<f32>,
pub y: Property<f32>,
pub width: Property<f32>,
pub height: Property<f32>,
pub source_clip_x: Property<i32>,
pub source_clip_y: Property<i32>,
pub source_clip_width: Property<i32>,
pub source_clip_height: Property<i32>,
pub cached_rendering_data: CachedRenderingData,
}
impl Item for ClippedImage {
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 {
HighLevelRenderingPrimitive::Image {
source: Self::FIELD_OFFSETS.source.apply_pin(self).get(),
source_clip_rect: euclid::rect(
Self::FIELD_OFFSETS.source_clip_x.apply_pin(self).get(),
Self::FIELD_OFFSETS.source_clip_y.apply_pin(self).get(),
Self::FIELD_OFFSETS.source_clip_width.apply_pin(self).get(),
Self::FIELD_OFFSETS.source_clip_height.apply_pin(self).get(),
),
}
}
fn rendering_variables(
self: Pin<&Self>,
_window: &ComponentWindow,
) -> SharedArray<RenderingVariable> {
let mut vars = SharedArray::default();
let width = Self::FIELD_OFFSETS.width.apply_pin(self).get();
let height = Self::FIELD_OFFSETS.height.apply_pin(self).get();
if width > 0. {
vars.push(RenderingVariable::ScaledWidth(width));
}
if height > 0. {
vars.push(RenderingVariable::ScaledHeight(height));
}
vars
}
fn layouting_info(self: Pin<&Self>, _window: &crate::eventloop::ComponentWindow) -> LayoutInfo {
// FIXME: should we use the image size here
Default::default()
}
fn input_event(
self: Pin<&Self>,
_: MouseEvent,
_window: &ComponentWindow,
_self_component: &VRc<ComponentVTable, vtable::Dyn>,
_self_index: usize,
) -> 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 ClippedImage {
const cached_rendering_data_offset: const_field_offset::FieldOffset<
ClippedImage,
CachedRenderingData,
> = ClippedImage::FIELD_OFFSETS.cached_rendering_data.as_unpinned_projection();
}
ItemVTable_static! {
/// The VTable for `ClippedImage`
#[no_mangle]
pub static ClippedImageVTable for ClippedImage
}
#[derive(Copy, Clone, Debug, PartialEq, strum_macros::EnumString, strum_macros::Display)] #[derive(Copy, Clone, Debug, PartialEq, strum_macros::EnumString, strum_macros::Display)]
#[repr(C)] #[repr(C)]
#[allow(non_camel_case_types)] #[allow(non_camel_case_types)]

View file

@ -489,6 +489,7 @@ fn generate_component<'id>(
rtti.extend( rtti.extend(
[ [
rtti_for::<Image>(), rtti_for::<Image>(),
rtti_for::<ClippedImage>(),
rtti_for::<Text>(), rtti_for::<Text>(),
rtti_for::<Rectangle>(), rtti_for::<Rectangle>(),
rtti_for::<BorderRectangle>(), rtti_for::<BorderRectangle>(),

View file

@ -18,8 +18,8 @@ use sixtyfps_corelib::eventloop::ComponentWindow;
use sixtyfps_corelib::{ use sixtyfps_corelib::{
graphics::{ graphics::{
Color, Frame as GraphicsFrame, GraphicsBackend, GraphicsWindow, Color, Frame as GraphicsFrame, GraphicsBackend, GraphicsWindow,
HighLevelRenderingPrimitive, Point, Rect, RenderingPrimitivesBuilder, RenderingVariable, HighLevelRenderingPrimitive, IntRect, Point, Rect, RenderingPrimitivesBuilder,
Resource, RgbaColor, Size, RenderingVariable, Resource, RgbaColor, Size,
}, },
SharedArray, SharedArray,
}; };
@ -413,7 +413,7 @@ impl RenderingPrimitivesBuilder for GLRenderingPrimitivesBuilder {
let rect = Rect::new(Point::default(), Size::new(*width, *height)); let rect = Rect::new(Point::default(), Size::new(*width, *height));
smallvec![self.fill_rectangle(&rect, *border_radius, *border_width)] smallvec![self.fill_rectangle(&rect, *border_radius, *border_width)]
} }
HighLevelRenderingPrimitive::Image { source } => { HighLevelRenderingPrimitive::Image { source, source_clip_rect } => {
match source { match source {
#[cfg(not(target_arch = "wasm32"))] #[cfg(not(target_arch = "wasm32"))]
Resource::AbsoluteFilePath(path) => { Resource::AbsoluteFilePath(path) => {
@ -430,7 +430,8 @@ impl RenderingPrimitivesBuilder for GLRenderingPrimitivesBuilder {
smallvec![GLRenderingPrimitivesBuilder::create_image( smallvec![GLRenderingPrimitivesBuilder::create_image(
&self.context, &self.context,
&mut *self.texture_atlas.borrow_mut(), &mut *self.texture_atlas.borrow_mut(),
image image,
source_clip_rect
)] )]
} }
#[cfg(target_arch = "wasm32")] #[cfg(target_arch = "wasm32")]
@ -447,12 +448,14 @@ impl RenderingPrimitivesBuilder for GLRenderingPrimitivesBuilder {
let shared_primitive = shared_primitive.clone(); let shared_primitive = shared_primitive.clone();
let window = self.window.clone(); let window = self.window.clone();
let event_loop_proxy = self.event_loop_proxy.clone(); let event_loop_proxy = self.event_loop_proxy.clone();
let source_clip_rect = *source_clip_rect;
move || { move || {
let texture_primitive = let texture_primitive =
GLRenderingPrimitivesBuilder::create_image( GLRenderingPrimitivesBuilder::create_image(
&context, &context,
&mut *atlas.borrow_mut(), &mut *atlas.borrow_mut(),
&html_image, &html_image,
&source_clip_rect,
); );
*shared_primitive.borrow_mut() = Some(texture_primitive); *shared_primitive.borrow_mut() = Some(texture_primitive);
@ -485,7 +488,8 @@ impl RenderingPrimitivesBuilder for GLRenderingPrimitivesBuilder {
smallvec![GLRenderingPrimitivesBuilder::create_image( smallvec![GLRenderingPrimitivesBuilder::create_image(
&self.context, &self.context,
&mut *self.texture_atlas.borrow_mut(), &mut *self.texture_atlas.borrow_mut(),
image image,
&source_clip_rect
)] )]
} }
Resource::EmbeddedRgbaImage { width, height, data } => { Resource::EmbeddedRgbaImage { width, height, data } => {
@ -498,7 +502,8 @@ impl RenderingPrimitivesBuilder for GLRenderingPrimitivesBuilder {
smallvec![GLRenderingPrimitivesBuilder::create_image( smallvec![GLRenderingPrimitivesBuilder::create_image(
&self.context, &self.context,
&mut *self.texture_atlas.borrow_mut(), &mut *self.texture_atlas.borrow_mut(),
image image,
&source_clip_rect
)] )]
} }
Resource::None => SmallVec::new(), Resource::None => SmallVec::new(),
@ -627,6 +632,7 @@ impl GLRenderingPrimitivesBuilder {
context: &Rc<glow::Context>, context: &Rc<glow::Context>,
atlas: &mut TextureAtlas, atlas: &mut TextureAtlas,
image: impl texture::UploadableAtlasImage, image: impl texture::UploadableAtlasImage,
source_rect: &IntRect,
) -> GLRenderingPrimitive { ) -> GLRenderingPrimitive {
let rect = let rect =
Rect::new(Point::new(0.0, 0.0), Size::new(image.width() as f32, image.height() as f32)); Rect::new(Point::new(0.0, 0.0), Size::new(image.width() as f32, image.height() as f32));
@ -642,8 +648,10 @@ impl GLRenderingPrimitivesBuilder {
&context, &context,
&vec![vertex1, vertex2, vertex3, vertex1, vertex3, vertex4], &vec![vertex1, vertex2, vertex3, vertex1, vertex3, vertex4],
); );
let texture_vertices = let texture_vertices = GLArrayBuffer::new(
GLArrayBuffer::new(&context, &atlas_allocation.normalized_texture_coordinates()); &context,
&atlas_allocation.normalized_texture_coordinates_with_source_rect(source_rect),
);
GLRenderingPrimitive::Texture { vertices, texture_vertices, texture: atlas_allocation } GLRenderingPrimitive::Texture { vertices, texture_vertices, texture: atlas_allocation }
} }

View file

@ -9,7 +9,11 @@
LICENSE END */ LICENSE END */
use super::{GLContext, Vertex}; use super::{GLContext, Vertex};
use glow::HasContext; use glow::HasContext;
use pathfinder_geometry::{rect::RectI, vector::Vector2I}; use pathfinder_geometry::{
rect::{RectF, RectI},
vector::{Vector2F, Vector2I},
};
use sixtyfps_corelib::graphics::IntRect;
use std::{cell::RefCell, rc::Rc}; use std::{cell::RefCell, rc::Rc};
pub struct GLTexture { pub struct GLTexture {
@ -202,12 +206,25 @@ impl Drop for AtlasAllocation {
} }
impl AtlasAllocation { impl AtlasAllocation {
pub(crate) fn normalized_texture_coordinates(&self) -> [Vertex; 6] { pub(crate) fn normalized_texture_coordinates_with_source_rect(
&self,
source_rect: &IntRect,
) -> [Vertex; 6] {
let atlas_width = self.atlas.texture.width as f32; let atlas_width = self.atlas.texture.width as f32;
let atlas_height = self.atlas.texture.height as f32; let atlas_height = self.atlas.texture.height as f32;
let origin = self.texture_coordinates.origin(); let origin = self.texture_coordinates.origin();
let size = self.texture_coordinates.size(); let size = self.texture_coordinates.size();
let texture_coordinates = RectI::new(origin, size); let texture_coordinates = RectF::new(
Vector2F::new(
(origin.x() + source_rect.min_x()) as f32,
(origin.y() + source_rect.min_y()) as f32,
),
if source_rect.is_empty() {
Vector2F::new(size.x() as f32, size.y() as f32)
} else {
Vector2F::new(source_rect.width() as f32, source_rect.height() as f32)
},
);
let tex_left = ((texture_coordinates.min_x() as f32) + 0.5) / atlas_width; let tex_left = ((texture_coordinates.min_x() as f32) + 0.5) / atlas_width;
let tex_top = ((texture_coordinates.min_y() as f32) + 0.5) / atlas_height; let tex_top = ((texture_coordinates.min_y() as f32) + 0.5) / atlas_height;
@ -221,6 +238,9 @@ impl AtlasAllocation {
[tex_vertex1, tex_vertex2, tex_vertex3, tex_vertex1, tex_vertex3, tex_vertex4] [tex_vertex1, tex_vertex2, tex_vertex3, tex_vertex1, tex_vertex3, tex_vertex4]
} }
pub(crate) fn normalized_texture_coordinates(&self) -> [Vertex; 6] {
self.normalized_texture_coordinates_with_source_rect(&IntRect::default())
}
} }
impl GLAtlasTexture { impl GLAtlasTexture {

View file

@ -163,7 +163,10 @@ impl Item for NativeButton {
option.state |= QStyle::State_Enabled; option.state |= QStyle::State_Enabled;
qApp->style()->drawControl(QStyle::CE_PushButton, &option, &p, nullptr); qApp->style()->drawControl(QStyle::CE_PushButton, &option, &p, nullptr);
}); });
return HighLevelRenderingPrimitive::Image { source: imgarray.to_resource() }; return HighLevelRenderingPrimitive::Image {
source: imgarray.to_resource(),
source_clip_rect: Default::default(),
};
} }
fn rendering_variables( fn rendering_variables(
@ -294,7 +297,10 @@ impl Item for NativeCheckBox {
option.state |= QStyle::State_Enabled; option.state |= QStyle::State_Enabled;
qApp->style()->drawControl(QStyle::CE_CheckBox, &option, &p, nullptr); qApp->style()->drawControl(QStyle::CE_CheckBox, &option, &p, nullptr);
}); });
return HighLevelRenderingPrimitive::Image { source: imgarray.to_resource() }; return HighLevelRenderingPrimitive::Image {
source: imgarray.to_resource(),
source_clip_rect: Default::default(),
};
} }
fn rendering_variables( fn rendering_variables(
@ -444,7 +450,10 @@ impl Item for NativeSpinBox {
auto text_rect = style->subControlRect(QStyle::CC_SpinBox, &option, QStyle::SC_SpinBoxEditField, nullptr); auto text_rect = style->subControlRect(QStyle::CC_SpinBox, &option, QStyle::SC_SpinBoxEditField, nullptr);
p.drawText(text_rect, QString::number(value)); p.drawText(text_rect, QString::number(value));
}); });
return HighLevelRenderingPrimitive::Image { source: imgarray.to_resource() }; return HighLevelRenderingPrimitive::Image {
source: imgarray.to_resource(),
source_clip_rect: Default::default(),
};
} }
fn rendering_variables( fn rendering_variables(
@ -651,7 +660,10 @@ impl Item for NativeSlider {
auto style = qApp->style(); auto style = qApp->style();
style->drawComplexControl(QStyle::CC_Slider, &option, &p, nullptr); style->drawComplexControl(QStyle::CC_Slider, &option, &p, nullptr);
}); });
return HighLevelRenderingPrimitive::Image { source: imgarray.to_resource() }; return HighLevelRenderingPrimitive::Image {
source: imgarray.to_resource(),
source_clip_rect: Default::default(),
};
} }
fn rendering_variables( fn rendering_variables(
@ -931,7 +943,10 @@ impl Item for NativeGroupBox {
QStyle::SH_GroupBox_TextLabelColor, &option)); QStyle::SH_GroupBox_TextLabelColor, &option));
qApp->style()->drawComplexControl(QStyle::CC_GroupBox, &option, &p, nullptr); qApp->style()->drawComplexControl(QStyle::CC_GroupBox, &option, &p, nullptr);
}); });
return HighLevelRenderingPrimitive::Image { source: imgarray.to_resource() }; return HighLevelRenderingPrimitive::Image {
source: imgarray.to_resource(),
source_clip_rect: Default::default(),
};
} }
fn rendering_variables( fn rendering_variables(
@ -1085,7 +1100,10 @@ impl Item for NativeLineEdit {
option.state |= QStyle::State_Enabled; option.state |= QStyle::State_Enabled;
qApp->style()->drawPrimitive(QStyle::PE_PanelLineEdit, &option, &p, nullptr); qApp->style()->drawPrimitive(QStyle::PE_PanelLineEdit, &option, &p, nullptr);
}); });
return HighLevelRenderingPrimitive::Image { source: imgarray.to_resource() }; return HighLevelRenderingPrimitive::Image {
source: imgarray.to_resource(),
source_clip_rect: Default::default(),
};
} }
fn rendering_variables( fn rendering_variables(
@ -1336,7 +1354,10 @@ impl Item for NativeScrollView {
data.pressed == 1, data.pressed == 1,
); );
return HighLevelRenderingPrimitive::Image { source: imgarray.to_resource() }; return HighLevelRenderingPrimitive::Image {
source: imgarray.to_resource(),
source_clip_rect: Default::default(),
};
} }
fn rendering_variables( fn rendering_variables(
@ -1584,7 +1605,10 @@ impl Item for NativeStandardListViewItem {
qApp->style()->drawPrimitive(QStyle::PE_PanelItemViewRow, &option, &p, nullptr); qApp->style()->drawPrimitive(QStyle::PE_PanelItemViewRow, &option, &p, nullptr);
qApp->style()->drawControl(QStyle::CE_ItemViewItem, &option, &p, nullptr); qApp->style()->drawControl(QStyle::CE_ItemViewItem, &option, &p, nullptr);
}); });
return HighLevelRenderingPrimitive::Image { source: imgarray.to_resource() }; return HighLevelRenderingPrimitive::Image {
source: imgarray.to_resource(),
source_clip_rect: Default::default(),
};
} }
fn rendering_variables( fn rendering_variables(
@ -1716,7 +1740,10 @@ impl Item for NativeComboBox {
qApp->style()->drawComplexControl(QStyle::CC_ComboBox, &option, &p, nullptr); qApp->style()->drawComplexControl(QStyle::CC_ComboBox, &option, &p, nullptr);
qApp->style()->drawControl(QStyle::CE_ComboBoxLabel, &option, &p, nullptr); qApp->style()->drawControl(QStyle::CE_ComboBoxLabel, &option, &p, nullptr);
}); });
return HighLevelRenderingPrimitive::Image { source: imgarray.to_resource() }; return HighLevelRenderingPrimitive::Image {
source: imgarray.to_resource(),
source_clip_rect: Default::default(),
};
} }
fn rendering_variables( fn rendering_variables(

View file

@ -45,6 +45,7 @@ fn gen_corelib(include_dir: &Path) -> anyhow::Result<()> {
"Rectangle", "Rectangle",
"BorderRectangle", "BorderRectangle",
"Image", "Image",
"ClippedImage",
"TouchArea", "TouchArea",
"Flickable", "Flickable",
"Text", "Text",