i_slint_backend_qt/qt_widgets/
stylemetrics.rs1use i_slint_core::items::LayoutAlignment;
7
8use super::*;
9
10cpp! {{
11namespace {
12struct StyleChangeListener : QWidget {
13 const void *nativeStyleMetrics = nullptr;
14 StyleChangeListener(const void *nativeStyleMetrics) : nativeStyleMetrics(nativeStyleMetrics) {}
15 bool event(QEvent *event) override {
16 auto ty = event->type();
17 if (ty == QEvent::StyleChange || ty == QEvent::PaletteChange || ty == QEvent::FontChange) {
18 rust!(Slint_style_change_event [nativeStyleMetrics: Pin<&NativeStyleMetrics> as "const void*"] {
19 nativeStyleMetrics.init_impl();
20 });
21 }
22 return QWidget::event(event);
23 }
24};
25}
26}}
27
28#[repr(C)]
29#[derive(FieldOffsets, SlintElement)]
30#[pin]
31#[pin_drop]
32pub struct NativeStyleMetrics {
33 pub layout_spacing: Property<LogicalLength>,
34 pub layout_padding: Property<LogicalLength>,
35 pub text_cursor_width: Property<LogicalLength>,
36 pub window_background: Property<Color>,
37 pub default_text_color: Property<Color>,
38 pub textedit_background: Property<Color>,
39 pub textedit_text_color: Property<Color>,
40 pub textedit_background_disabled: Property<Color>,
41 pub textedit_text_color_disabled: Property<Color>,
42
43 pub placeholder_color: Property<Color>,
44 pub placeholder_color_disabled: Property<Color>,
45
46 pub dark_color_scheme: Property<bool>,
47
48 pub tab_bar_alignment: Property<LayoutAlignment>,
50
51 pub style_name: Property<SharedString>,
52
53 pub style_change_listener: core::cell::Cell<*const u8>,
54}
55
56impl const_field_offset::PinnedDrop for NativeStyleMetrics {
57 fn drop(self: Pin<&mut Self>) {
58 slint_native_style_metrics_deinit(self);
59 }
60}
61
62impl NativeStyleMetrics {
63 pub fn new() -> Pin<Rc<Self>> {
64 Rc::pin(NativeStyleMetrics {
65 layout_spacing: Default::default(),
66 layout_padding: Default::default(),
67 text_cursor_width: Default::default(),
68 window_background: Default::default(),
69 default_text_color: Default::default(),
70 textedit_background: Default::default(),
71 textedit_text_color: Default::default(),
72 textedit_background_disabled: Default::default(),
73 textedit_text_color_disabled: Default::default(),
74 placeholder_color: Default::default(),
75 placeholder_color_disabled: Default::default(),
76 dark_color_scheme: Default::default(),
77 tab_bar_alignment: Default::default(),
78 style_name: Default::default(),
79 style_change_listener: core::cell::Cell::new(core::ptr::null()),
80 })
81 }
82
83 pub fn init<T>(self: Pin<Rc<Self>>, _root: &T) {
84 self.as_ref().init_impl();
85 }
86
87 fn init_impl(self: Pin<&Self>) {
88 let wrong_thread = cpp!(unsafe [] -> bool as "bool" {
89 static QMutex mtx;
90 QMutexLocker locker(&mtx);
91 ensure_initialized();
92 return qApp->thread() != QThread::currentThread();
93 });
94 if wrong_thread {
95 return;
96 }
97
98 if self.style_change_listener.get().is_null() {
99 self.style_change_listener.set(cpp!(unsafe [self as "void*"] -> *const u8 as "void*"{
100 return new StyleChangeListener(self);
101 }));
102 }
103
104 let layout_spacing = cpp!(unsafe [] -> f32 as "float" {
105 int spacing = qApp->style()->pixelMetric(QStyle::PM_LayoutHorizontalSpacing);
106 if (spacing < 0)
107 spacing = qApp->style()->layoutSpacing(QSizePolicy::DefaultType, QSizePolicy::DefaultType, Qt::Horizontal);
108 return spacing;
109 });
110 self.layout_spacing.set(LogicalLength::new(layout_spacing.max(0.0)));
111 let layout_padding = cpp!(unsafe [] -> f32 as "float" {
112 return qApp->style()->pixelMetric(QStyle::PM_LayoutLeftMargin);
113 });
114 self.layout_padding.set(LogicalLength::new(layout_padding.max(0.0)));
115 let text_cursor_width = cpp!(unsafe [] -> f32 as "float" {
116 return qApp->style()->pixelMetric(QStyle::PM_TextCursorWidth);
117 });
118 self.text_cursor_width.set(LogicalLength::new(text_cursor_width.max(0.0)));
119 let window_background = cpp!(unsafe[] -> u32 as "QRgb" {
120 return qApp->palette().color(QPalette::Window).rgba();
121 });
122 let window_background = Color::from_argb_encoded(window_background);
123 self.window_background.set(window_background);
124 let default_text_color = cpp!(unsafe[] -> u32 as "QRgb" {
125 return qApp->palette().color(QPalette::WindowText).rgba();
126 });
127 self.default_text_color.set(Color::from_argb_encoded(default_text_color));
128 let textedit_text_color = cpp!(unsafe[] -> u32 as "QRgb" {
129 return qApp->palette().color(QPalette::Text).rgba();
130 });
131 self.textedit_text_color.set(Color::from_argb_encoded(textedit_text_color));
132 let textedit_text_color_disabled = cpp!(unsafe[] -> u32 as "QRgb" {
133 return qApp->palette().color(QPalette::Disabled, QPalette::Text).rgba();
134 });
135 self.textedit_text_color_disabled
136 .set(Color::from_argb_encoded(textedit_text_color_disabled));
137 let textedit_background = cpp!(unsafe[] -> u32 as "QRgb" {
138 return qApp->palette().color(QPalette::Base).rgba();
139 });
140 self.textedit_background.set(Color::from_argb_encoded(textedit_background));
141 let textedit_background_disabled = cpp!(unsafe[] -> u32 as "QRgb" {
142 return qApp->palette().color(QPalette::Disabled, QPalette::Base).rgba();
143 });
144 self.textedit_background_disabled
145 .set(Color::from_argb_encoded(textedit_background_disabled));
146 let placeholder_color = cpp!(unsafe[] -> u32 as "QRgb" {
147 return qApp->palette().color(QPalette::PlaceholderText).rgba();
148 });
149 self.placeholder_color.set(Color::from_argb_encoded(placeholder_color));
150 let placeholder_color_disabled = cpp!(unsafe[] -> u32 as "QRgb" {
151 return qApp->palette().color(QPalette::Disabled, QPalette::PlaceholderText).rgba();
152 });
153 self.placeholder_color_disabled.set(Color::from_argb_encoded(placeholder_color_disabled));
154
155 self.dark_color_scheme.set(
159 (window_background.red() as u32
160 + window_background.green() as u32
161 + window_background.blue() as u32)
162 / 3
163 < 128,
164 );
165
166 let tab_bar_alignment = cpp!(unsafe[] -> u32 as "uint32_t" {
167 switch (qApp->style()->styleHint(QStyle::SH_TabBar_Alignment)) {
168 case Qt::AlignLeft: return 1;
169 case Qt::AlignCenter: return 2;
170 case Qt::AlignRight: return 3;
171 default: return 0;
172 }
173 });
174 self.tab_bar_alignment.set(match tab_bar_alignment {
175 1 => LayoutAlignment::Start,
176 2 => LayoutAlignment::Center,
177 3 => LayoutAlignment::End,
178 _ => LayoutAlignment::SpaceBetween, });
180 }
181}
182
183#[cfg(feature = "rtti")]
184impl i_slint_core::rtti::BuiltinGlobal for NativeStyleMetrics {
185 fn new() -> Pin<Rc<Self>> {
186 let r = NativeStyleMetrics::new();
187 r.as_ref().init_impl();
188 r
189 }
190}
191
192#[unsafe(no_mangle)]
193pub extern "C" fn slint_native_style_metrics_init(self_: Pin<&NativeStyleMetrics>) {
194 self_.style_change_listener.set(core::ptr::null()); self_.init_impl();
196}
197
198#[unsafe(no_mangle)]
199pub extern "C" fn slint_native_style_metrics_deinit(self_: Pin<&mut NativeStyleMetrics>) {
200 let scl = self_.style_change_listener.get();
201 cpp!(unsafe [scl as "StyleChangeListener*"] { delete scl; });
202 self_.style_change_listener.set(core::ptr::null());
203}