i_slint_backend_qt/qt_widgets/
tableheadersection.rs1use i_slint_core::{input::FocusEventResult, items::SortOrder};
5
6use super::*;
7
8#[repr(C)]
9#[derive(FieldOffsets, Default, SlintElement)]
10#[pin]
11pub struct NativeTableHeaderSection {
12 pub item: Property<i_slint_core::model::TableColumn>,
13 pub index: Property<i32>,
14 pub cached_rendering_data: CachedRenderingData,
15 pub has_hover: Property<bool>,
16 widget_ptr: std::cell::Cell<SlintTypeErasedWidgetPtr>,
17 animation_tracker: Property<i32>,
18}
19
20impl Item for NativeTableHeaderSection {
21 fn init(self: Pin<&Self>, _self_rc: &ItemRc) {
22 let animation_tracker_property_ptr = Self::FIELD_OFFSETS.animation_tracker.apply_pin(self);
23 self.widget_ptr.set(cpp! { unsafe [animation_tracker_property_ptr as "void*"] -> SlintTypeErasedWidgetPtr as "std::unique_ptr<SlintTypeErasedWidget>" {
24 return make_unique_animated_widget<QWidget>(animation_tracker_property_ptr);
25 }});
26 }
27
28 fn layout_info(
29 self: Pin<&Self>,
30 orientation: Orientation,
31 _window_adapter: &Rc<dyn WindowAdapter>,
32 _self_rc: &ItemRc,
33 ) -> LayoutInfo {
34 let index: i32 = self.index();
35 let item = self.item();
36 let text: qttypes::QString = item.title.as_str().into();
37 let widget: NonNull<()> = SlintTypeErasedWidgetPtr::qwidget_ptr(&self.widget_ptr);
38
39 let s = cpp!(unsafe [
40 index as "int",
41 text as "QString",
42 widget as "QWidget*"
43 ] -> qttypes::QSize as "QSize" {
44 ensure_initialized();
45
46 QStyleOptionHeader option;
47 option.state |= QStyle::State_Horizontal;
48 option.section = index;
49
50 option.text = text;
51
52 option.textAlignment = Qt::AlignCenter | Qt::AlignVCenter;
53 return qApp->style()->sizeFromContents(QStyle::CT_HeaderSection, &option, QSize{}, widget);
54 });
55 let min = match orientation {
56 Orientation::Horizontal => s.width,
57 Orientation::Vertical => s.height,
58 } as f32;
59 LayoutInfo { min, preferred: min, ..LayoutInfo::default() }
60 }
61
62 fn input_event_filter_before_children(
63 self: Pin<&Self>,
64 _: &MouseEvent,
65 _window_adapter: &Rc<dyn WindowAdapter>,
66 _self_rc: &ItemRc,
67 ) -> InputEventFilterResult {
68 InputEventFilterResult::ForwardAndIgnore
69 }
70
71 fn input_event(
72 self: Pin<&Self>,
73 _event: &MouseEvent,
74 _window_adapter: &Rc<dyn WindowAdapter>,
75 _self_rc: &i_slint_core::items::ItemRc,
76 ) -> InputEventResult {
77 InputEventResult::EventIgnored
78 }
79
80 fn capture_key_event(
81 self: Pin<&Self>,
82 _event: &KeyEvent,
83 _window_adapter: &Rc<dyn WindowAdapter>,
84 _self_rc: &ItemRc,
85 ) -> KeyEventResult {
86 KeyEventResult::EventIgnored
87 }
88
89 fn key_event(
90 self: Pin<&Self>,
91 _: &KeyEvent,
92 _window_adapter: &Rc<dyn WindowAdapter>,
93 _self_rc: &ItemRc,
94 ) -> KeyEventResult {
95 KeyEventResult::EventIgnored
96 }
97
98 fn focus_event(
99 self: Pin<&Self>,
100 _: &FocusEvent,
101 _window_adapter: &Rc<dyn WindowAdapter>,
102 _self_rc: &ItemRc,
103 ) -> FocusEventResult {
104 FocusEventResult::FocusIgnored
105 }
106
107 fn_render! { this dpr size painter widget initial_state =>
108 let index: i32 = this.index();
109 let has_hover: bool = this.has_hover();
110 let item = this.item();
111 let text: qttypes::QString = item.title.as_str().into();
112 let ascending: bool = item.sort_order == SortOrder::Ascending;
113 let descending: bool = item.sort_order == SortOrder::Descending;
114
115 cpp!(unsafe [
116 painter as "QPainterPtr*",
117 widget as "QWidget*",
118 size as "QSize",
119 dpr as "float",
120 index as "int",
121 has_hover as "bool",
122 text as "QString",
123 initial_state as "int",
124 ascending as "bool",
125 descending as "bool"
126 ] {
127 QPainter *painter_ = painter->get();
128
129 #if defined(Q_OS_MAC)
130 QImage header_image(size, QImage::Format_ARGB32_Premultiplied);
131 header_image.fill(Qt::transparent);
132 {QPainter p(&header_image); QPainter *painter_ = &p;
133 #endif
134
135 QStyleOptionHeader option;
136 option.styleObject = widget;
137 option.state |= QStyle::State(initial_state);
138 option.state |= QStyle::State_Horizontal | QStyle::State_Enabled;
139 option.rect = QRect(QPoint(), size / dpr);
140
141 option.section = index;
142
143 option.textAlignment = Qt::AlignLeft | Qt::AlignVCenter;
144
145 if (ascending) {
146 option.sortIndicator = QStyleOptionHeader::SortDown;
147 } else if (descending) {
148 option.sortIndicator = QStyleOptionHeader::SortUp;
149 } else {
150 option.sortIndicator = QStyleOptionHeader::None;
151 }
152
153 if (has_hover) {
154 option.state |= QStyle::State_MouseOver;
155 }
156
157 option.text = text;
158
159 qApp->style()->drawControl(QStyle::CE_Header, &option, painter_, widget);
160
161 #if defined(Q_OS_MAC)
162 }
163 (painter_)->drawImage(QPoint(), header_image);
164 #endif
165 });
166 }
167
168 fn bounding_rect(
169 self: core::pin::Pin<&Self>,
170 _window_adapter: &Rc<dyn WindowAdapter>,
171 _self_rc: &ItemRc,
172 geometry: LogicalRect,
173 ) -> LogicalRect {
174 geometry
175 }
176
177 fn clips_children(self: core::pin::Pin<&Self>) -> bool {
178 false
179 }
180}
181
182impl ItemConsts for NativeTableHeaderSection {
183 const cached_rendering_data_offset: const_field_offset::FieldOffset<Self, CachedRenderingData> =
184 Self::FIELD_OFFSETS.cached_rendering_data.as_unpinned_projection();
185}
186
187declare_item_vtable! {
188fn slint_get_NativeTableHeaderSectionVTable() -> NativeTableHeaderSectionVTable for NativeTableHeaderSection
189}