i_slint_backend_qt/qt_widgets/
button.rs1use super::*;
7use i_slint_core::graphics::euclid;
8
9#[allow(nonstandard_style)]
10#[allow(unused)]
11mod standard_button {
12 pub const QStyle_StandardPixmap_SP_TitleBarMenuButton: QStyle_StandardPixmap = 0;
15 pub const QStyle_StandardPixmap_SP_TitleBarMinButton: QStyle_StandardPixmap = 1;
16 pub const QStyle_StandardPixmap_SP_TitleBarMaxButton: QStyle_StandardPixmap = 2;
17 pub const QStyle_StandardPixmap_SP_TitleBarCloseButton: QStyle_StandardPixmap = 3;
18 pub const QStyle_StandardPixmap_SP_TitleBarNormalButton: QStyle_StandardPixmap = 4;
19 pub const QStyle_StandardPixmap_SP_TitleBarShadeButton: QStyle_StandardPixmap = 5;
20 pub const QStyle_StandardPixmap_SP_TitleBarUnshadeButton: QStyle_StandardPixmap = 6;
21 pub const QStyle_StandardPixmap_SP_TitleBarContextHelpButton: QStyle_StandardPixmap = 7;
22 pub const QStyle_StandardPixmap_SP_DockWidgetCloseButton: QStyle_StandardPixmap = 8;
23 pub const QStyle_StandardPixmap_SP_MessageBoxInformation: QStyle_StandardPixmap = 9;
24 pub const QStyle_StandardPixmap_SP_MessageBoxWarning: QStyle_StandardPixmap = 10;
25 pub const QStyle_StandardPixmap_SP_MessageBoxCritical: QStyle_StandardPixmap = 11;
26 pub const QStyle_StandardPixmap_SP_MessageBoxQuestion: QStyle_StandardPixmap = 12;
27 pub const QStyle_StandardPixmap_SP_DesktopIcon: QStyle_StandardPixmap = 13;
28 pub const QStyle_StandardPixmap_SP_TrashIcon: QStyle_StandardPixmap = 14;
29 pub const QStyle_StandardPixmap_SP_ComputerIcon: QStyle_StandardPixmap = 15;
30 pub const QStyle_StandardPixmap_SP_DriveFDIcon: QStyle_StandardPixmap = 16;
31 pub const QStyle_StandardPixmap_SP_DriveHDIcon: QStyle_StandardPixmap = 17;
32 pub const QStyle_StandardPixmap_SP_DriveCDIcon: QStyle_StandardPixmap = 18;
33 pub const QStyle_StandardPixmap_SP_DriveDVDIcon: QStyle_StandardPixmap = 19;
34 pub const QStyle_StandardPixmap_SP_DriveNetIcon: QStyle_StandardPixmap = 20;
35 pub const QStyle_StandardPixmap_SP_DirOpenIcon: QStyle_StandardPixmap = 21;
36 pub const QStyle_StandardPixmap_SP_DirClosedIcon: QStyle_StandardPixmap = 22;
37 pub const QStyle_StandardPixmap_SP_DirLinkIcon: QStyle_StandardPixmap = 23;
38 pub const QStyle_StandardPixmap_SP_DirLinkOpenIcon: QStyle_StandardPixmap = 24;
39 pub const QStyle_StandardPixmap_SP_FileIcon: QStyle_StandardPixmap = 25;
40 pub const QStyle_StandardPixmap_SP_FileLinkIcon: QStyle_StandardPixmap = 26;
41 pub const QStyle_StandardPixmap_SP_ToolBarHorizontalExtensionButton: QStyle_StandardPixmap = 27;
42 pub const QStyle_StandardPixmap_SP_ToolBarVerticalExtensionButton: QStyle_StandardPixmap = 28;
43 pub const QStyle_StandardPixmap_SP_FileDialogStart: QStyle_StandardPixmap = 29;
44 pub const QStyle_StandardPixmap_SP_FileDialogEnd: QStyle_StandardPixmap = 30;
45 pub const QStyle_StandardPixmap_SP_FileDialogToParent: QStyle_StandardPixmap = 31;
46 pub const QStyle_StandardPixmap_SP_FileDialogNewFolder: QStyle_StandardPixmap = 32;
47 pub const QStyle_StandardPixmap_SP_FileDialogDetailedView: QStyle_StandardPixmap = 33;
48 pub const QStyle_StandardPixmap_SP_FileDialogInfoView: QStyle_StandardPixmap = 34;
49 pub const QStyle_StandardPixmap_SP_FileDialogContentsView: QStyle_StandardPixmap = 35;
50 pub const QStyle_StandardPixmap_SP_FileDialogListView: QStyle_StandardPixmap = 36;
51 pub const QStyle_StandardPixmap_SP_FileDialogBack: QStyle_StandardPixmap = 37;
52 pub const QStyle_StandardPixmap_SP_DirIcon: QStyle_StandardPixmap = 38;
53 pub const QStyle_StandardPixmap_SP_DialogOkButton: QStyle_StandardPixmap = 39;
54 pub const QStyle_StandardPixmap_SP_DialogCancelButton: QStyle_StandardPixmap = 40;
55 pub const QStyle_StandardPixmap_SP_DialogHelpButton: QStyle_StandardPixmap = 41;
56 pub const QStyle_StandardPixmap_SP_DialogOpenButton: QStyle_StandardPixmap = 42;
57 pub const QStyle_StandardPixmap_SP_DialogSaveButton: QStyle_StandardPixmap = 43;
58 pub const QStyle_StandardPixmap_SP_DialogCloseButton: QStyle_StandardPixmap = 44;
59 pub const QStyle_StandardPixmap_SP_DialogApplyButton: QStyle_StandardPixmap = 45;
60 pub const QStyle_StandardPixmap_SP_DialogResetButton: QStyle_StandardPixmap = 46;
61 pub const QStyle_StandardPixmap_SP_DialogDiscardButton: QStyle_StandardPixmap = 47;
62 pub const QStyle_StandardPixmap_SP_DialogYesButton: QStyle_StandardPixmap = 48;
63 pub const QStyle_StandardPixmap_SP_DialogNoButton: QStyle_StandardPixmap = 49;
64 pub const QStyle_StandardPixmap_SP_ArrowUp: QStyle_StandardPixmap = 50;
65 pub const QStyle_StandardPixmap_SP_ArrowDown: QStyle_StandardPixmap = 51;
66 pub const QStyle_StandardPixmap_SP_ArrowLeft: QStyle_StandardPixmap = 52;
67 pub const QStyle_StandardPixmap_SP_ArrowRight: QStyle_StandardPixmap = 53;
68 pub const QStyle_StandardPixmap_SP_ArrowBack: QStyle_StandardPixmap = 54;
69 pub const QStyle_StandardPixmap_SP_ArrowForward: QStyle_StandardPixmap = 55;
70 pub const QStyle_StandardPixmap_SP_DirHomeIcon: QStyle_StandardPixmap = 56;
71 pub const QStyle_StandardPixmap_SP_CommandLink: QStyle_StandardPixmap = 57;
72 pub const QStyle_StandardPixmap_SP_VistaShield: QStyle_StandardPixmap = 58;
73 pub const QStyle_StandardPixmap_SP_BrowserReload: QStyle_StandardPixmap = 59;
74 pub const QStyle_StandardPixmap_SP_BrowserStop: QStyle_StandardPixmap = 60;
75 pub const QStyle_StandardPixmap_SP_MediaPlay: QStyle_StandardPixmap = 61;
76 pub const QStyle_StandardPixmap_SP_MediaStop: QStyle_StandardPixmap = 62;
77 pub const QStyle_StandardPixmap_SP_MediaPause: QStyle_StandardPixmap = 63;
78 pub const QStyle_StandardPixmap_SP_MediaSkipForward: QStyle_StandardPixmap = 64;
79 pub const QStyle_StandardPixmap_SP_MediaSkipBackward: QStyle_StandardPixmap = 65;
80 pub const QStyle_StandardPixmap_SP_MediaSeekForward: QStyle_StandardPixmap = 66;
81 pub const QStyle_StandardPixmap_SP_MediaSeekBackward: QStyle_StandardPixmap = 67;
82 pub const QStyle_StandardPixmap_SP_MediaVolume: QStyle_StandardPixmap = 68;
83 pub const QStyle_StandardPixmap_SP_MediaVolumeMuted: QStyle_StandardPixmap = 69;
84 pub const QStyle_StandardPixmap_SP_LineEditClearButton: QStyle_StandardPixmap = 70;
85 pub const QStyle_StandardPixmap_SP_DialogYesToAllButton: QStyle_StandardPixmap = 71;
86 pub const QStyle_StandardPixmap_SP_DialogNoToAllButton: QStyle_StandardPixmap = 72;
87 pub const QStyle_StandardPixmap_SP_DialogSaveAllButton: QStyle_StandardPixmap = 73;
88 pub const QStyle_StandardPixmap_SP_DialogAbortButton: QStyle_StandardPixmap = 74;
89 pub const QStyle_StandardPixmap_SP_DialogRetryButton: QStyle_StandardPixmap = 75;
90 pub const QStyle_StandardPixmap_SP_DialogIgnoreButton: QStyle_StandardPixmap = 76;
91 pub const QStyle_StandardPixmap_SP_RestoreDefaultsButton: QStyle_StandardPixmap = 77;
92 pub const QStyle_StandardPixmap_SP_CustomBase: QStyle_StandardPixmap = 4026531840;
93 pub type QStyle_StandardPixmap = ::std::os::raw::c_uint;
94}
95
96use i_slint_core::{
97 input::{FocusEventResult, KeyEventType},
98 items::StandardButtonKind,
99 platform::PointerEventButton,
100};
101use standard_button::*;
102
103type ActualStandardButtonKind = Option<StandardButtonKind>;
104
105#[repr(C)]
106#[derive(FieldOffsets, Default, SlintElement)]
107#[pin]
108pub struct NativeButton {
109 pub text: Property<SharedString>,
110 pub icon: Property<i_slint_core::graphics::Image>,
111 pub icon_size: Property<LogicalLength>,
112 pub pressed: Property<bool>,
113 pub has_hover: Property<bool>,
114 pub checkable: Property<bool>,
115 pub checked: Property<bool>,
116 pub primary: Property<bool>,
117 pub has_focus: Property<bool>,
118 pub clicked: Callback<VoidArg>,
119 pub enabled: Property<bool>,
120 pub colorize_icon: Property<bool>,
121 pub standard_button_kind: Property<StandardButtonKind>,
122 pub is_standard_button: Property<bool>,
123 widget_ptr: std::cell::Cell<SlintTypeErasedWidgetPtr>,
124 animation_tracker: Property<i32>,
125 pub cached_rendering_data: CachedRenderingData,
126}
127
128impl NativeButton {
129 fn actual_standard_button_kind(self: Pin<&Self>) -> ActualStandardButtonKind {
130 self.is_standard_button().then(|| self.standard_button_kind())
131 }
132
133 fn actual_text(
134 self: Pin<&Self>,
135 standard_button_kind: ActualStandardButtonKind,
136 ) -> qttypes::QString {
137 match standard_button_kind {
139 Some(StandardButtonKind::Ok) => "OK".into(),
140 Some(StandardButtonKind::Cancel) => "Cancel".into(),
141 Some(StandardButtonKind::Apply) => "Apply".into(),
142 Some(StandardButtonKind::Close) => "Close".into(),
143 Some(StandardButtonKind::Reset) => "Reset".into(),
144 Some(StandardButtonKind::Help) => "Help".into(),
145 Some(StandardButtonKind::Yes) => "Yes".into(),
146 Some(StandardButtonKind::No) => "No".into(),
147 Some(StandardButtonKind::Abort) => "Abort".into(),
148 Some(StandardButtonKind::Retry) => "Retry".into(),
149 Some(StandardButtonKind::Ignore) => "Ignore".into(),
150 None => self.text().as_str().into(),
151 }
152 }
153
154 fn actual_icon(
155 self: Pin<&Self>,
156 standard_button_kind: ActualStandardButtonKind,
157 ) -> qttypes::QPixmap {
158 let style_icon = match standard_button_kind {
159 Some(StandardButtonKind::Ok) => QStyle_StandardPixmap_SP_DialogOkButton,
160 Some(StandardButtonKind::Cancel) => QStyle_StandardPixmap_SP_DialogCancelButton,
161 Some(StandardButtonKind::Apply) => QStyle_StandardPixmap_SP_DialogApplyButton,
162 Some(StandardButtonKind::Close) => QStyle_StandardPixmap_SP_DialogCloseButton,
163 Some(StandardButtonKind::Reset) => QStyle_StandardPixmap_SP_DialogResetButton,
164 Some(StandardButtonKind::Help) => QStyle_StandardPixmap_SP_DialogHelpButton,
165 Some(StandardButtonKind::Yes) => QStyle_StandardPixmap_SP_DialogYesButton,
166 Some(StandardButtonKind::No) => QStyle_StandardPixmap_SP_DialogNoButton,
167 Some(StandardButtonKind::Abort) => QStyle_StandardPixmap_SP_DialogAbortButton,
168 Some(StandardButtonKind::Retry) => QStyle_StandardPixmap_SP_DialogRetryButton,
169 Some(StandardButtonKind::Ignore) => QStyle_StandardPixmap_SP_DialogIgnoreButton,
170 None => {
171 let icon_size = self.icon_size().get().round() as u32;
172 let source_size = Some(euclid::Size2D::new(icon_size, icon_size));
173 return crate::qt_window::image_to_pixmap((&self.icon()).into(), source_size)
174 .unwrap_or_default();
175 }
176 };
177 let widget_ptr: NonNull<()> = SlintTypeErasedWidgetPtr::qwidget_ptr(&self.widget_ptr);
178 cpp!(unsafe [style_icon as "QStyle::StandardPixmap", widget_ptr as "QWidget*"] -> qttypes::QPixmap as "QPixmap" {
179 ensure_initialized();
180 auto style = qApp->style();
181 if (!style->styleHint(QStyle::SH_DialogButtonBox_ButtonsHaveIcons, nullptr, widget_ptr))
182 return QPixmap();
183 return style->standardPixmap(style_icon);
184 })
185 }
186
187 fn activate(self: Pin<&Self>) {
188 Self::FIELD_OFFSETS.pressed.apply_pin(self).set(false);
189 if self.checkable() {
190 let checked = Self::FIELD_OFFSETS.checked.apply_pin(self);
191 checked.set(!checked.get());
192 }
193 Self::FIELD_OFFSETS.clicked.apply_pin(self).call(&());
194 }
195}
196
197impl Item for NativeButton {
198 fn init(self: Pin<&Self>, _self_rc: &ItemRc) {
199 let animation_tracker_property_ptr = Self::FIELD_OFFSETS.animation_tracker.apply_pin(self);
200 self.widget_ptr.set(cpp! { unsafe [animation_tracker_property_ptr as "void*"] -> SlintTypeErasedWidgetPtr as "std::unique_ptr<SlintTypeErasedWidget>" {
201 return make_unique_animated_widget<QPushButton>(animation_tracker_property_ptr);
202 }});
203 let widget_ptr: NonNull<()> = SlintTypeErasedWidgetPtr::qwidget_ptr(&self.widget_ptr);
204 let icon_size = unsafe {
205 cpp!([widget_ptr as "QWidget*" ] -> i32 as "int"
206 {
207 ensure_initialized();
208 return qApp->style()->pixelMetric(QStyle::PM_ButtonIconSize, 0, widget_ptr);
209 })
210 };
211 Self::FIELD_OFFSETS
212 .icon_size
213 .apply_pin(self)
214 .set(LogicalLength::new(icon_size as i_slint_core::Coord));
215 }
216
217 fn layout_info(
218 self: Pin<&Self>,
219 orientation: Orientation,
220 _window_adapter: &Rc<dyn WindowAdapter>,
221 _self_rc: &ItemRc,
222 ) -> LayoutInfo {
223 let standard_button_kind = self.actual_standard_button_kind();
224 let mut text: qttypes::QString = self.actual_text(standard_button_kind);
225 let icon: qttypes::QPixmap = self.actual_icon(standard_button_kind);
226 let icon_size = self.icon_size().get() as i32;
227 let widget_ptr: NonNull<()> = SlintTypeErasedWidgetPtr::qwidget_ptr(&self.widget_ptr);
228 let size = cpp!(unsafe [
229 mut text as "QString",
230 icon as "QPixmap",
231 icon_size as "int",
232 widget_ptr as "QWidget*"
233 ] -> qttypes::QSize as "QSize" {
234 ensure_initialized();
235 QStyleOptionButton option;
236 if (text.isEmpty())
237 text = "**";
238 option.rect = option.fontMetrics.boundingRect(text);
239 option.text = std::move(text);
240 option.icon = icon;
241 option.iconSize = QSize(icon_size, icon_size);
242 if (!icon.isNull()) {
243 option.rect.setHeight(qMax(option.rect.height(), icon_size));
244 option.rect.setWidth(option.rect.width() + 4 + icon_size);
245 }
246 return qApp->style()->sizeFromContents(QStyle::CT_PushButton, &option, option.rect.size(), widget_ptr);
247 });
248 let min = match orientation {
249 Orientation::Horizontal => size.width as f32,
250 Orientation::Vertical => size.height as f32,
251 };
252 LayoutInfo { min, preferred: min, ..LayoutInfo::default() }
253 }
254
255 fn input_event_filter_before_children(
256 self: Pin<&Self>,
257 event: &MouseEvent,
258 _window_adapter: &Rc<dyn WindowAdapter>,
259 _self_rc: &ItemRc,
260 ) -> InputEventFilterResult {
261 Self::FIELD_OFFSETS.has_hover.apply_pin(self).set(!matches!(event, MouseEvent::Exit));
262 InputEventFilterResult::ForwardEvent
263 }
264
265 fn input_event(
266 self: Pin<&Self>,
267 event: &MouseEvent,
268 _window_adapter: &Rc<dyn WindowAdapter>,
269 self_rc: &i_slint_core::items::ItemRc,
270 ) -> InputEventResult {
271 if matches!(event, MouseEvent::Exit) {
272 Self::FIELD_OFFSETS.has_hover.apply_pin(self).set(false);
273 }
274 let enabled = self.enabled();
275 if !enabled {
276 return InputEventResult::EventIgnored;
277 }
278
279 let was_pressed = self.pressed();
280
281 Self::FIELD_OFFSETS.pressed.apply_pin(self).set(match event {
282 MouseEvent::Pressed { button, .. } => *button == PointerEventButton::Left,
283 MouseEvent::Exit | MouseEvent::Released { .. } => false,
284 MouseEvent::Moved { .. } => {
285 return if was_pressed {
286 InputEventResult::GrabMouse
287 } else {
288 InputEventResult::EventAccepted
289 }
290 }
291 MouseEvent::Wheel { .. } => return InputEventResult::EventIgnored,
292 MouseEvent::DragMove(..) | MouseEvent::Drop(..) => {
293 return InputEventResult::EventIgnored
294 }
295 });
296 if let MouseEvent::Released { position, .. } = event {
297 let geo = self_rc.geometry();
298 if LogicalRect::new(LogicalPoint::default(), geo.size).contains(*position)
299 && was_pressed
300 {
301 self.activate();
302 }
303 InputEventResult::EventAccepted
304 } else {
305 InputEventResult::GrabMouse
306 }
307 }
308
309 fn capture_key_event(
310 self: Pin<&Self>,
311 _event: &KeyEvent,
312 _window_adapter: &Rc<dyn WindowAdapter>,
313 _self_rc: &ItemRc,
314 ) -> KeyEventResult {
315 KeyEventResult::EventIgnored
316 }
317
318 fn key_event(
319 self: Pin<&Self>,
320 event: &KeyEvent,
321 _window_adapter: &Rc<dyn WindowAdapter>,
322 _self_rc: &ItemRc,
323 ) -> KeyEventResult {
324 match event.event_type {
325 KeyEventType::KeyPressed if event.text == " " || event.text == "\n" => {
326 Self::FIELD_OFFSETS.pressed.apply_pin(self).set(true);
327 KeyEventResult::EventAccepted
328 }
329 KeyEventType::KeyPressed => KeyEventResult::EventIgnored,
330 KeyEventType::KeyReleased if event.text == " " || event.text == "\n" => {
331 self.activate();
332 KeyEventResult::EventAccepted
333 }
334 KeyEventType::KeyReleased => KeyEventResult::EventIgnored,
335 KeyEventType::UpdateComposition | KeyEventType::CommitComposition => {
336 KeyEventResult::EventIgnored
337 }
338 }
339 }
340
341 fn focus_event(
342 self: Pin<&Self>,
343 event: &FocusEvent,
344 _window_adapter: &Rc<dyn WindowAdapter>,
345 _self_rc: &ItemRc,
346 ) -> FocusEventResult {
347 if self.enabled() {
348 Self::FIELD_OFFSETS
349 .has_focus
350 .apply_pin(self)
351 .set(matches!(event, FocusEvent::FocusIn(_)));
352 FocusEventResult::FocusAccepted
353 } else {
354 FocusEventResult::FocusIgnored
355 }
356 }
357
358 fn_render! { this dpr size painter widget initial_state =>
359 let down: bool = this.pressed();
360 let checked: bool = this.checked();
361 let standard_button_kind = this.actual_standard_button_kind();
362 let text: qttypes::QString = this.actual_text(standard_button_kind);
363 let icon: qttypes::QPixmap = this.actual_icon(standard_button_kind);
364 let enabled = this.enabled();
365 let has_focus = this.has_focus();
366 let has_hover = this.has_hover();
367 let primary = this.primary();
368 let icon_size = this.icon_size().get().round() as i32;
369 let colorize_icon = this.colorize_icon();
370
371 cpp!(unsafe [
372 painter as "QPainterPtr*",
373 widget as "QWidget*",
374 text as "QString",
375 icon as "QPixmap",
376 enabled as "bool",
377 size as "QSize",
378 down as "bool",
379 checked as "bool",
380 has_focus as "bool",
381 has_hover as "bool",
382 primary as "bool",
383 icon_size as "int",
384 colorize_icon as "bool",
385 dpr as "float",
386 initial_state as "int"
387 ] {
388 class ColorizedIconEngine : public QIconEngine
389 {
390 public:
391 ColorizedIconEngine(const QIcon &icon, const QColor &color) : m_icon(icon), m_color(color) { }
392
393 QPixmap pixmap(const QSize &size, QIcon::Mode mode, QIcon::State state) override
394 {
395 QPixmap iconPixmap = m_icon.pixmap(size, mode, state);
396 if (!iconPixmap.isNull()) {
397 QPainter colorizePainter(&iconPixmap);
398 colorizePainter.setCompositionMode(QPainter::CompositionMode_SourceIn);
399 colorizePainter.fillRect(iconPixmap.rect(), m_color);
400 }
401 return iconPixmap;
402 }
403
404 void paint(QPainter *painter, const QRect &rect, QIcon::Mode mode, QIcon::State state) override
405 {
406 painter->drawPixmap(rect, this->pixmap(rect.size(), mode, state));
407 }
408
409 QIconEngine *clone() const override { return new ColorizedIconEngine(m_icon, m_color); }
410
411 private:
412 QIcon m_icon;
413 QColor m_color;
414 };
415
416 QStyleOptionButton option;
417 option.styleObject = widget;
418 option.state |= QStyle::State(initial_state);
419 option.text = std::move(text);
420
421 QColor iconColor = qApp->palette().color(QPalette::ButtonText).rgba();
422
423 if (down) {
424 option.state |= QStyle::State_Sunken;
425 } else {
426 option.state |= QStyle::State_Raised;
427 }
428 if (checked) {
429 option.state |= QStyle::State_On;
430 }
431 if (enabled) {
432 option.state |= QStyle::State_Enabled;
433 } else {
434 option.palette.setCurrentColorGroup(QPalette::Disabled);
435 iconColor = qApp->palette().color(QPalette::Disabled, QPalette::ButtonText).rgba();
436 }
437 if (has_focus) {
438 option.state |= QStyle::State_HasFocus | QStyle::State_KeyboardFocusChange | QStyle::State_Item;
439 }
440 if (has_hover) {
441 option.state |= QStyle::State_MouseOver;
442 }
443 if (primary) {
444 option.features |= QStyleOptionButton::DefaultButton;
445 }
446 if (colorize_icon) {
447 option.icon = QIcon(new ColorizedIconEngine(icon, iconColor));
448 } else {
449 option.icon = icon;
450 }
451 option.iconSize = QSize(icon_size, icon_size);
452 option.rect = QRect(QPoint(), size / dpr);
453
454 qApp->style()->drawControl(QStyle::CE_PushButton, &option, painter->get(), widget);
455 });
456 }
457
458 fn bounding_rect(
459 self: core::pin::Pin<&Self>,
460 _window_adapter: &Rc<dyn WindowAdapter>,
461 _self_rc: &ItemRc,
462 geometry: LogicalRect,
463 ) -> LogicalRect {
464 geometry
465 }
466
467 fn clips_children(self: core::pin::Pin<&Self>) -> bool {
468 false
469 }
470}
471
472impl ItemConsts for NativeButton {
473 const cached_rendering_data_offset: const_field_offset::FieldOffset<Self, CachedRenderingData> =
474 Self::FIELD_OFFSETS.cached_rendering_data.as_unpinned_projection();
475}
476
477declare_item_vtable! {
478 fn slint_get_NativeButtonVTable() -> NativeButtonVTable for NativeButton
479}