i_slint_backend_qt/qt_widgets/
listviewitem.rs1use i_slint_core::input::FocusEventResult;
5
6use super::*;
7
8#[repr(C)]
9#[derive(FieldOffsets, Default, SlintElement)]
10#[pin]
11pub struct NativeStandardListViewItem {
12 pub item: Property<i_slint_core::model::StandardListViewItem>,
13 pub index: Property<i32>,
14 pub is_selected: Property<bool>,
15 pub cached_rendering_data: CachedRenderingData,
16 pub has_hover: Property<bool>,
17 pub has_focus: Property<bool>,
18 pub pressed: Property<bool>,
19 pub pressed_x: Property<LogicalLength>,
20 pub pressed_y: Property<LogicalLength>,
21
22 pub combobox: Property<bool>,
24 widget_ptr: std::cell::Cell<SlintTypeErasedWidgetPtr>,
25 animation_tracker: Property<i32>,
26}
27
28impl Item for NativeStandardListViewItem {
29 fn init(self: Pin<&Self>, _self_rc: &ItemRc) {
30 let animation_tracker_property_ptr = Self::FIELD_OFFSETS.animation_tracker.apply_pin(self);
31 self.widget_ptr.set(cpp! { unsafe [animation_tracker_property_ptr as "void*"] -> SlintTypeErasedWidgetPtr as "std::unique_ptr<SlintTypeErasedWidget>" {
32 return make_unique_animated_widget<QWidget>(animation_tracker_property_ptr);
33 }})
34 }
35
36 fn layout_info(
37 self: Pin<&Self>,
38 orientation: Orientation,
39 _window_adapter: &Rc<dyn WindowAdapter>,
40 _self_rc: &ItemRc,
41 ) -> LayoutInfo {
42 let index: i32 = self.index();
43 let item = self.item();
44 let text: qttypes::QString = item.text.as_str().into();
45 let combobox: bool = self.combobox();
46
47 let s = cpp!(unsafe [
48 index as "int",
49 text as "QString",
50 combobox as "bool"
51 ] -> qttypes::QSize as "QSize" {
52 ensure_initialized();
53
54 QStyleOptionComboBox cb_opt;
55 if (combobox && qApp->style()->styleHint(QStyle::SH_ComboBox_Popup, &cb_opt, nullptr)) {
56 QStyleOptionMenuItem option;
57 option.text = text;
58 option.text.replace(QChar('&'), QLatin1String("&&"));
59 return qApp->style()->sizeFromContents(QStyle::CT_MenuItem, &option, QSize{}, nullptr);
60 } else {
61 QStyleOptionViewItem option;
62 option.decorationPosition = QStyleOptionViewItem::Left;
63 option.decorationAlignment = Qt::AlignCenter;
64 option.displayAlignment = Qt::AlignLeft|Qt::AlignVCenter;
65 option.showDecorationSelected = qApp->style()->styleHint(QStyle::SH_ItemView_ShowDecorationSelected, nullptr, nullptr);
66 if (index % 2) {
67 option.features |= QStyleOptionViewItem::Alternate;
68 }
69 option.features |= QStyleOptionViewItem::HasDisplay;
70 option.text = text;
71 return qApp->style()->sizeFromContents(QStyle::CT_ItemViewItem, &option, QSize{}, nullptr);
72 }
73 });
74 let min = match orientation {
75 Orientation::Horizontal => s.width,
76 Orientation::Vertical => s.height,
77 } as f32;
78 LayoutInfo { min, preferred: min, ..LayoutInfo::default() }
79 }
80
81 fn input_event_filter_before_children(
82 self: Pin<&Self>,
83 _: &MouseEvent,
84 _window_adapter: &Rc<dyn WindowAdapter>,
85 _self_rc: &ItemRc,
86 ) -> InputEventFilterResult {
87 InputEventFilterResult::ForwardAndIgnore
88 }
89
90 fn input_event(
91 self: Pin<&Self>,
92 _: &MouseEvent,
93 _window_adapter: &Rc<dyn WindowAdapter>,
94 _self_rc: &i_slint_core::items::ItemRc,
95 ) -> InputEventResult {
96 InputEventResult::EventIgnored
97 }
98
99 fn capture_key_event(
100 self: Pin<&Self>,
101 _event: &KeyEvent,
102 _window_adapter: &Rc<dyn WindowAdapter>,
103 _self_rc: &ItemRc,
104 ) -> KeyEventResult {
105 KeyEventResult::EventIgnored
106 }
107
108 fn key_event(
109 self: Pin<&Self>,
110 _: &KeyEvent,
111 _window_adapter: &Rc<dyn WindowAdapter>,
112 _self_rc: &ItemRc,
113 ) -> KeyEventResult {
114 KeyEventResult::EventIgnored
115 }
116
117 fn focus_event(
118 self: Pin<&Self>,
119 _: &FocusEvent,
120 _window_adapter: &Rc<dyn WindowAdapter>,
121 _self_rc: &ItemRc,
122 ) -> FocusEventResult {
123 FocusEventResult::FocusIgnored
124 }
125
126 fn_render! { this dpr size painter widget initial_state =>
127 let index: i32 = this.index();
128 let is_selected: bool = this.is_selected();
129 let combobox: bool = this.combobox();
130 let has_hover: bool = this.has_hover();
131 let has_focus: bool = this.has_focus();
132 let item = this.item();
133 let text: qttypes::QString = item.text.as_str().into();
134 cpp!(unsafe [
135 painter as "QPainterPtr*",
136 widget as "QWidget*",
137 size as "QSize",
138 dpr as "float",
139 index as "int",
140 is_selected as "bool",
141 has_hover as "bool",
142 has_focus as "bool",
143 text as "QString",
144 initial_state as "int",
145 combobox as "bool"
146 ] {
147 QStyleOptionComboBox cb_opt;
148 if (combobox && qApp->style()->styleHint(QStyle::SH_ComboBox_Popup, &cb_opt, widget)) {
149 widget->setProperty("_q_isComboBoxPopupItem", true);
150 QStyleOptionMenuItem option;
151 option.styleObject = widget;
152 option.state |= QStyle::State(initial_state);
153 option.rect = QRect(QPoint(), size / dpr);
154 option.menuRect = QRect(QPoint(), size / dpr);
155 option.state = QStyle::State_Enabled;
156 if (has_hover) {
157 option.state |= QStyle::State_MouseOver;
158 option.state |= QStyle::State_Selected;
159 }
160
161 if (has_focus) {
162 option.state |= QStyle::State_HasFocus;
163 option.state |= QStyle::State_Selected;
164 }
165 option.text = text;
166 option.text.replace(QChar('&'), QLatin1String("&&"));
167 option.checked = is_selected;
168 option.menuItemType = QStyleOptionMenuItem::Normal;
169 qApp->style()->drawControl(QStyle::CE_MenuItem, &option, painter->get(), widget);
173 widget->setProperty("_q_isComboBoxPopupItem", {});
174 } else {
175 QStyleOptionViewItem option;
176 option.styleObject = widget;
177 option.state |= QStyle::State(initial_state);
178 option.rect = QRect(QPoint(), size / dpr);
179 option.state |= QStyle::State_Enabled;
180 if (is_selected) {
181 option.state |= QStyle::State_Selected;
182 }
183 if (has_hover) {
184 option.state |= QStyle::State_MouseOver;
185 }
186 if (has_focus) {
187 option.state |= QStyle::State_HasFocus;
188 }
189 option.decorationPosition = QStyleOptionViewItem::Left;
190 option.decorationAlignment = Qt::AlignCenter;
191 option.displayAlignment = Qt::AlignLeft|Qt::AlignVCenter;
192 option.showDecorationSelected = qApp->style()->styleHint(QStyle::SH_ItemView_ShowDecorationSelected, nullptr, nullptr);
193
194 if (index % 2) {
195 option.features |= QStyleOptionViewItem::Alternate;
196 }
197 option.features |= QStyleOptionViewItem::HasDisplay;
198
199 option.text = text;
200
201 qApp->style()->drawPrimitive(QStyle::PE_PanelItemViewRow, &option, painter->get(), widget);
202 qApp->style()->drawControl(QStyle::CE_ItemViewItem, &option, painter->get(), widget);
203 }
204 });
205 }
206
207 fn bounding_rect(
208 self: core::pin::Pin<&Self>,
209 _window_adapter: &Rc<dyn WindowAdapter>,
210 _self_rc: &ItemRc,
211 geometry: LogicalRect,
212 ) -> LogicalRect {
213 geometry
214 }
215
216 fn clips_children(self: core::pin::Pin<&Self>) -> bool {
217 false
218 }
219}
220
221impl ItemConsts for NativeStandardListViewItem {
222 const cached_rendering_data_offset: const_field_offset::FieldOffset<Self, CachedRenderingData> =
223 Self::FIELD_OFFSETS.cached_rendering_data.as_unpinned_projection();
224}
225
226declare_item_vtable! {
227fn slint_get_NativeStandardListViewItemVTable() -> NativeStandardListViewItemVTable for NativeStandardListViewItem
228}