1#![allow(
33 clippy::cast_possible_truncation,
34 clippy::cast_sign_loss,
35 clippy::as_conversions
36)]
37use crate::Context;
38use crate::internal::RawWrapper;
39use crate::sys;
40use crate::utils::HoveredFlags;
41use crate::widget::TreeNodeFlags;
42use crate::widget::{TableFlags, TableRowFlags};
43use crate::window::WindowFlags;
44#[cfg(feature = "serde")]
45use serde::{Deserialize, Serialize};
46use std::cell::UnsafeCell;
47
48#[repr(transparent)]
53#[derive(Debug)]
54pub struct Style(pub(crate) UnsafeCell<sys::ImGuiStyle>);
55
56const _: [(); std::mem::size_of::<sys::ImGuiStyle>()] = [(); std::mem::size_of::<Style>()];
58const _: [(); std::mem::align_of::<sys::ImGuiStyle>()] = [(); std::mem::align_of::<Style>()];
59
60impl Style {
61 #[inline]
62 fn inner(&self) -> &sys::ImGuiStyle {
63 unsafe { &*self.0.get() }
67 }
68
69 #[inline]
70 fn inner_mut(&mut self) -> &mut sys::ImGuiStyle {
71 unsafe { &mut *self.0.get() }
73 }
74
75 pub fn color(&self, color: StyleColor) -> [f32; 4] {
77 let c = self.inner().Colors[color as usize];
78 [c.x, c.y, c.z, c.w]
79 }
80
81 pub fn set_color(&mut self, color: StyleColor, value: [f32; 4]) {
83 self.inner_mut().Colors[color as usize] = sys::ImVec4 {
84 x: value[0],
85 y: value[1],
86 z: value[2],
87 w: value[3],
88 };
89 }
90
91 pub fn font_scale_main(&self) -> f32 {
93 self.inner().FontScaleMain
94 }
95
96 pub fn set_font_scale_main(&mut self, scale: f32) {
98 self.inner_mut().FontScaleMain = scale;
99 }
100
101 pub fn font_scale_dpi(&self) -> f32 {
103 self.inner().FontScaleDpi
104 }
105
106 pub fn set_font_scale_dpi(&mut self, scale: f32) {
108 self.inner_mut().FontScaleDpi = scale;
109 }
110
111 pub fn font_size_base(&self) -> f32 {
113 self.inner().FontSizeBase
114 }
115
116 pub fn set_font_size_base(&mut self, sz: f32) {
117 self.inner_mut().FontSizeBase = sz;
118 }
119
120 pub fn alpha(&self) -> f32 {
123 self.inner().Alpha
124 }
125 pub fn set_alpha(&mut self, v: f32) {
126 self.inner_mut().Alpha = v;
127 }
128
129 pub fn disabled_alpha(&self) -> f32 {
130 self.inner().DisabledAlpha
131 }
132 pub fn set_disabled_alpha(&mut self, v: f32) {
133 self.inner_mut().DisabledAlpha = v;
134 }
135
136 pub fn window_padding(&self) -> [f32; 2] {
137 [self.inner().WindowPadding.x, self.inner().WindowPadding.y]
138 }
139 pub fn set_window_padding(&mut self, v: [f32; 2]) {
140 self.inner_mut().WindowPadding = sys::ImVec2 { x: v[0], y: v[1] };
141 }
142
143 pub fn window_rounding(&self) -> f32 {
144 self.inner().WindowRounding
145 }
146 pub fn set_window_rounding(&mut self, v: f32) {
147 self.inner_mut().WindowRounding = v;
148 }
149
150 pub fn window_border_size(&self) -> f32 {
151 self.inner().WindowBorderSize
152 }
153 pub fn set_window_border_size(&mut self, v: f32) {
154 self.inner_mut().WindowBorderSize = v;
155 }
156
157 pub fn window_min_size(&self) -> [f32; 2] {
158 [self.inner().WindowMinSize.x, self.inner().WindowMinSize.y]
159 }
160 pub fn set_window_min_size(&mut self, v: [f32; 2]) {
161 self.inner_mut().WindowMinSize = sys::ImVec2 { x: v[0], y: v[1] };
162 }
163
164 pub fn window_title_align(&self) -> [f32; 2] {
165 [
166 self.inner().WindowTitleAlign.x,
167 self.inner().WindowTitleAlign.y,
168 ]
169 }
170 pub fn set_window_title_align(&mut self, v: [f32; 2]) {
171 self.inner_mut().WindowTitleAlign = sys::ImVec2 { x: v[0], y: v[1] };
172 }
173
174 pub fn window_menu_button_position(&self) -> Direction {
175 Direction::from(self.inner().WindowMenuButtonPosition)
176 }
177 pub fn set_window_menu_button_position(&mut self, d: Direction) {
178 self.inner_mut().WindowMenuButtonPosition = d.into();
179 }
180
181 pub fn child_rounding(&self) -> f32 {
182 self.inner().ChildRounding
183 }
184 pub fn set_child_rounding(&mut self, v: f32) {
185 self.inner_mut().ChildRounding = v;
186 }
187
188 pub fn child_border_size(&self) -> f32 {
189 self.inner().ChildBorderSize
190 }
191 pub fn set_child_border_size(&mut self, v: f32) {
192 self.inner_mut().ChildBorderSize = v;
193 }
194
195 pub fn popup_rounding(&self) -> f32 {
196 self.inner().PopupRounding
197 }
198 pub fn set_popup_rounding(&mut self, v: f32) {
199 self.inner_mut().PopupRounding = v;
200 }
201
202 pub fn popup_border_size(&self) -> f32 {
203 self.inner().PopupBorderSize
204 }
205 pub fn set_popup_border_size(&mut self, v: f32) {
206 self.inner_mut().PopupBorderSize = v;
207 }
208
209 pub fn frame_padding(&self) -> [f32; 2] {
210 [self.inner().FramePadding.x, self.inner().FramePadding.y]
211 }
212 pub fn set_frame_padding(&mut self, v: [f32; 2]) {
213 self.inner_mut().FramePadding = sys::ImVec2 { x: v[0], y: v[1] };
214 }
215
216 pub fn frame_rounding(&self) -> f32 {
217 self.inner().FrameRounding
218 }
219 pub fn set_frame_rounding(&mut self, v: f32) {
220 self.inner_mut().FrameRounding = v;
221 }
222
223 pub fn frame_border_size(&self) -> f32 {
224 self.inner().FrameBorderSize
225 }
226 pub fn set_frame_border_size(&mut self, v: f32) {
227 self.inner_mut().FrameBorderSize = v;
228 }
229
230 pub fn item_spacing(&self) -> [f32; 2] {
231 [self.inner().ItemSpacing.x, self.inner().ItemSpacing.y]
232 }
233 pub fn set_item_spacing(&mut self, v: [f32; 2]) {
234 self.inner_mut().ItemSpacing = sys::ImVec2 { x: v[0], y: v[1] };
235 }
236
237 pub fn item_inner_spacing(&self) -> [f32; 2] {
238 [
239 self.inner().ItemInnerSpacing.x,
240 self.inner().ItemInnerSpacing.y,
241 ]
242 }
243 pub fn set_item_inner_spacing(&mut self, v: [f32; 2]) {
244 self.inner_mut().ItemInnerSpacing = sys::ImVec2 { x: v[0], y: v[1] };
245 }
246
247 pub fn cell_padding(&self) -> [f32; 2] {
248 [self.inner().CellPadding.x, self.inner().CellPadding.y]
249 }
250 pub fn set_cell_padding(&mut self, v: [f32; 2]) {
251 self.inner_mut().CellPadding = sys::ImVec2 { x: v[0], y: v[1] };
252 }
253
254 pub fn touch_extra_padding(&self) -> [f32; 2] {
255 [
256 self.inner().TouchExtraPadding.x,
257 self.inner().TouchExtraPadding.y,
258 ]
259 }
260 pub fn set_touch_extra_padding(&mut self, v: [f32; 2]) {
261 self.inner_mut().TouchExtraPadding = sys::ImVec2 { x: v[0], y: v[1] };
262 }
263
264 pub fn indent_spacing(&self) -> f32 {
265 self.inner().IndentSpacing
266 }
267 pub fn set_indent_spacing(&mut self, v: f32) {
268 self.inner_mut().IndentSpacing = v;
269 }
270
271 pub fn columns_min_spacing(&self) -> f32 {
272 self.inner().ColumnsMinSpacing
273 }
274 pub fn set_columns_min_spacing(&mut self, v: f32) {
275 self.inner_mut().ColumnsMinSpacing = v;
276 }
277
278 pub fn scrollbar_size(&self) -> f32 {
279 self.inner().ScrollbarSize
280 }
281 pub fn set_scrollbar_size(&mut self, v: f32) {
282 self.inner_mut().ScrollbarSize = v;
283 }
284
285 pub fn scrollbar_rounding(&self) -> f32 {
286 self.inner().ScrollbarRounding
287 }
288 pub fn set_scrollbar_rounding(&mut self, v: f32) {
289 self.inner_mut().ScrollbarRounding = v;
290 }
291
292 pub fn grab_min_size(&self) -> f32 {
293 self.inner().GrabMinSize
294 }
295 pub fn set_grab_min_size(&mut self, v: f32) {
296 self.inner_mut().GrabMinSize = v;
297 }
298
299 pub fn grab_rounding(&self) -> f32 {
300 self.inner().GrabRounding
301 }
302 pub fn set_grab_rounding(&mut self, v: f32) {
303 self.inner_mut().GrabRounding = v;
304 }
305
306 pub fn log_slider_deadzone(&self) -> f32 {
307 self.inner().LogSliderDeadzone
308 }
309 pub fn set_log_slider_deadzone(&mut self, v: f32) {
310 self.inner_mut().LogSliderDeadzone = v;
311 }
312
313 pub fn tab_rounding(&self) -> f32 {
314 self.inner().TabRounding
315 }
316 pub fn set_tab_rounding(&mut self, v: f32) {
317 self.inner_mut().TabRounding = v;
318 }
319
320 pub fn tab_border_size(&self) -> f32 {
321 self.inner().TabBorderSize
322 }
323 pub fn set_tab_border_size(&mut self, v: f32) {
324 self.inner_mut().TabBorderSize = v;
325 }
326
327 pub fn color_button_position(&self) -> Direction {
328 Direction::from(self.inner().ColorButtonPosition)
329 }
330 pub fn set_color_button_position(&mut self, d: Direction) {
331 self.inner_mut().ColorButtonPosition = d.into();
332 }
333
334 pub fn button_text_align(&self) -> [f32; 2] {
335 [
336 self.inner().ButtonTextAlign.x,
337 self.inner().ButtonTextAlign.y,
338 ]
339 }
340 pub fn set_button_text_align(&mut self, v: [f32; 2]) {
341 self.inner_mut().ButtonTextAlign = sys::ImVec2 { x: v[0], y: v[1] };
342 }
343
344 pub fn selectable_text_align(&self) -> [f32; 2] {
345 [
346 self.inner().SelectableTextAlign.x,
347 self.inner().SelectableTextAlign.y,
348 ]
349 }
350 pub fn set_selectable_text_align(&mut self, v: [f32; 2]) {
351 self.inner_mut().SelectableTextAlign = sys::ImVec2 { x: v[0], y: v[1] };
352 }
353
354 pub fn display_window_padding(&self) -> [f32; 2] {
355 [
356 self.inner().DisplayWindowPadding.x,
357 self.inner().DisplayWindowPadding.y,
358 ]
359 }
360 pub fn set_display_window_padding(&mut self, v: [f32; 2]) {
361 self.inner_mut().DisplayWindowPadding = sys::ImVec2 { x: v[0], y: v[1] };
362 }
363
364 pub fn display_safe_area_padding(&self) -> [f32; 2] {
365 [
366 self.inner().DisplaySafeAreaPadding.x,
367 self.inner().DisplaySafeAreaPadding.y,
368 ]
369 }
370 pub fn set_display_safe_area_padding(&mut self, v: [f32; 2]) {
371 self.inner_mut().DisplaySafeAreaPadding = sys::ImVec2 { x: v[0], y: v[1] };
372 }
373
374 pub fn mouse_cursor_scale(&self) -> f32 {
375 self.inner().MouseCursorScale
376 }
377 pub fn set_mouse_cursor_scale(&mut self, v: f32) {
378 self.inner_mut().MouseCursorScale = v;
379 }
380
381 pub fn anti_aliased_lines(&self) -> bool {
382 self.inner().AntiAliasedLines
383 }
384 pub fn set_anti_aliased_lines(&mut self, v: bool) {
385 self.inner_mut().AntiAliasedLines = v;
386 }
387
388 pub fn anti_aliased_lines_use_tex(&self) -> bool {
389 self.inner().AntiAliasedLinesUseTex
390 }
391 pub fn set_anti_aliased_lines_use_tex(&mut self, v: bool) {
392 self.inner_mut().AntiAliasedLinesUseTex = v;
393 }
394
395 pub fn anti_aliased_fill(&self) -> bool {
396 self.inner().AntiAliasedFill
397 }
398 pub fn set_anti_aliased_fill(&mut self, v: bool) {
399 self.inner_mut().AntiAliasedFill = v;
400 }
401
402 pub fn curve_tessellation_tol(&self) -> f32 {
403 self.inner().CurveTessellationTol
404 }
405 pub fn set_curve_tessellation_tol(&mut self, v: f32) {
406 self.inner_mut().CurveTessellationTol = v;
407 }
408
409 pub fn circle_tessellation_max_error(&self) -> f32 {
410 self.inner().CircleTessellationMaxError
411 }
412 pub fn set_circle_tessellation_max_error(&mut self, v: f32) {
413 self.inner_mut().CircleTessellationMaxError = v;
414 }
415
416 pub fn window_border_hover_padding(&self) -> f32 {
419 self.inner().WindowBorderHoverPadding
420 }
421 pub fn set_window_border_hover_padding(&mut self, v: f32) {
422 self.inner_mut().WindowBorderHoverPadding = v;
423 }
424
425 pub fn scrollbar_padding(&self) -> f32 {
426 self.inner().ScrollbarPadding
427 }
428 pub fn set_scrollbar_padding(&mut self, v: f32) {
429 self.inner_mut().ScrollbarPadding = v;
430 }
431
432 pub fn image_border_size(&self) -> f32 {
433 self.inner().ImageBorderSize
434 }
435 pub fn set_image_border_size(&mut self, v: f32) {
436 self.inner_mut().ImageBorderSize = v;
437 }
438
439 pub fn tab_min_width_base(&self) -> f32 {
440 self.inner().TabMinWidthBase
441 }
442 pub fn set_tab_min_width_base(&mut self, v: f32) {
443 self.inner_mut().TabMinWidthBase = v;
444 }
445
446 pub fn tab_min_width_shrink(&self) -> f32 {
447 self.inner().TabMinWidthShrink
448 }
449 pub fn set_tab_min_width_shrink(&mut self, v: f32) {
450 self.inner_mut().TabMinWidthShrink = v;
451 }
452
453 pub fn tab_close_button_min_width_selected(&self) -> f32 {
454 self.inner().TabCloseButtonMinWidthSelected
455 }
456 pub fn set_tab_close_button_min_width_selected(&mut self, v: f32) {
457 self.inner_mut().TabCloseButtonMinWidthSelected = v;
458 }
459
460 pub fn tab_close_button_min_width_unselected(&self) -> f32 {
461 self.inner().TabCloseButtonMinWidthUnselected
462 }
463 pub fn set_tab_close_button_min_width_unselected(&mut self, v: f32) {
464 self.inner_mut().TabCloseButtonMinWidthUnselected = v;
465 }
466
467 pub fn tab_bar_border_size(&self) -> f32 {
468 self.inner().TabBarBorderSize
469 }
470 pub fn set_tab_bar_border_size(&mut self, v: f32) {
471 self.inner_mut().TabBarBorderSize = v;
472 }
473
474 pub fn tab_bar_overline_size(&self) -> f32 {
475 self.inner().TabBarOverlineSize
476 }
477 pub fn set_tab_bar_overline_size(&mut self, v: f32) {
478 self.inner_mut().TabBarOverlineSize = v;
479 }
480
481 pub fn table_angled_headers_angle(&self) -> f32 {
482 self.inner().TableAngledHeadersAngle
483 }
484 pub fn set_table_angled_headers_angle(&mut self, v: f32) {
485 self.inner_mut().TableAngledHeadersAngle = v;
486 }
487
488 pub fn table_angled_headers_text_align(&self) -> [f32; 2] {
489 [
490 self.inner().TableAngledHeadersTextAlign.x,
491 self.inner().TableAngledHeadersTextAlign.y,
492 ]
493 }
494 pub fn set_table_angled_headers_text_align(&mut self, v: [f32; 2]) {
495 self.inner_mut().TableAngledHeadersTextAlign = sys::ImVec2 { x: v[0], y: v[1] };
496 }
497
498 pub fn tree_lines_flags(&self) -> TreeNodeFlags {
499 TreeNodeFlags::from_bits_truncate(self.inner().TreeLinesFlags as i32)
500 }
501 pub fn set_tree_lines_flags(&mut self, flags: TreeNodeFlags) {
502 self.inner_mut().TreeLinesFlags = flags.bits() as sys::ImGuiTreeNodeFlags;
503 }
504
505 pub fn tree_lines_size(&self) -> f32 {
506 self.inner().TreeLinesSize
507 }
508 pub fn set_tree_lines_size(&mut self, v: f32) {
509 self.inner_mut().TreeLinesSize = v;
510 }
511
512 pub fn tree_lines_rounding(&self) -> f32 {
513 self.inner().TreeLinesRounding
514 }
515 pub fn set_tree_lines_rounding(&mut self, v: f32) {
516 self.inner_mut().TreeLinesRounding = v;
517 }
518
519 pub fn separator_text_border_size(&self) -> f32 {
520 self.inner().SeparatorTextBorderSize
521 }
522 pub fn set_separator_text_border_size(&mut self, v: f32) {
523 self.inner_mut().SeparatorTextBorderSize = v;
524 }
525
526 pub fn separator_text_align(&self) -> [f32; 2] {
527 [
528 self.inner().SeparatorTextAlign.x,
529 self.inner().SeparatorTextAlign.y,
530 ]
531 }
532 pub fn set_separator_text_align(&mut self, v: [f32; 2]) {
533 self.inner_mut().SeparatorTextAlign = sys::ImVec2 { x: v[0], y: v[1] };
534 }
535
536 pub fn separator_text_padding(&self) -> [f32; 2] {
537 [
538 self.inner().SeparatorTextPadding.x,
539 self.inner().SeparatorTextPadding.y,
540 ]
541 }
542 pub fn set_separator_text_padding(&mut self, v: [f32; 2]) {
543 self.inner_mut().SeparatorTextPadding = sys::ImVec2 { x: v[0], y: v[1] };
544 }
545
546 pub fn docking_node_has_close_button(&self) -> bool {
547 self.inner().DockingNodeHasCloseButton
548 }
549 pub fn set_docking_node_has_close_button(&mut self, v: bool) {
550 self.inner_mut().DockingNodeHasCloseButton = v;
551 }
552
553 pub fn docking_separator_size(&self) -> f32 {
554 self.inner().DockingSeparatorSize
555 }
556 pub fn set_docking_separator_size(&mut self, v: f32) {
557 self.inner_mut().DockingSeparatorSize = v;
558 }
559
560 pub fn hover_stationary_delay(&self) -> f32 {
561 self.inner().HoverStationaryDelay
562 }
563 pub fn set_hover_stationary_delay(&mut self, v: f32) {
564 self.inner_mut().HoverStationaryDelay = v;
565 }
566
567 pub fn hover_delay_short(&self) -> f32 {
568 self.inner().HoverDelayShort
569 }
570 pub fn set_hover_delay_short(&mut self, v: f32) {
571 self.inner_mut().HoverDelayShort = v;
572 }
573
574 pub fn hover_delay_normal(&self) -> f32 {
575 self.inner().HoverDelayNormal
576 }
577 pub fn set_hover_delay_normal(&mut self, v: f32) {
578 self.inner_mut().HoverDelayNormal = v;
579 }
580
581 pub fn hover_flags_for_tooltip_mouse(&self) -> HoveredFlags {
582 HoveredFlags::from_bits_truncate(self.inner().HoverFlagsForTooltipMouse as i32)
583 }
584 pub fn set_hover_flags_for_tooltip_mouse(&mut self, flags: HoveredFlags) {
585 self.inner_mut().HoverFlagsForTooltipMouse = flags.bits() as sys::ImGuiHoveredFlags;
586 }
587
588 pub fn hover_flags_for_tooltip_nav(&self) -> HoveredFlags {
589 HoveredFlags::from_bits_truncate(self.inner().HoverFlagsForTooltipNav as i32)
590 }
591 pub fn set_hover_flags_for_tooltip_nav(&mut self, flags: HoveredFlags) {
592 self.inner_mut().HoverFlagsForTooltipNav = flags.bits() as sys::ImGuiHoveredFlags;
593 }
594}
595
596#[repr(i32)]
600#[derive(Copy, Clone, Debug, Hash, Eq, PartialEq)]
601pub enum Direction {
602 None = sys::ImGuiDir_None as i32,
603 Left = sys::ImGuiDir_Left as i32,
604 Right = sys::ImGuiDir_Right as i32,
605 Up = sys::ImGuiDir_Up as i32,
606 Down = sys::ImGuiDir_Down as i32,
607}
608
609impl From<sys::ImGuiDir> for Direction {
610 fn from(d: sys::ImGuiDir) -> Self {
611 match d as i32 {
612 x if x == sys::ImGuiDir_Left as i32 => Direction::Left,
613 x if x == sys::ImGuiDir_Right as i32 => Direction::Right,
614 x if x == sys::ImGuiDir_Up as i32 => Direction::Up,
615 x if x == sys::ImGuiDir_Down as i32 => Direction::Down,
616 _ => Direction::None,
617 }
618 }
619}
620
621impl From<Direction> for sys::ImGuiDir {
622 fn from(d: Direction) -> Self {
623 match d {
624 Direction::None => sys::ImGuiDir_None,
625 Direction::Left => sys::ImGuiDir_Left,
626 Direction::Right => sys::ImGuiDir_Right,
627 Direction::Up => sys::ImGuiDir_Up,
628 Direction::Down => sys::ImGuiDir_Down,
629 }
630 }
631}
632
633#[repr(i32)]
635#[derive(Copy, Clone, Debug, Hash, Eq, PartialEq)]
636#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
637pub enum StyleColor {
638 Text = sys::ImGuiCol_Text as i32,
639 TextDisabled = sys::ImGuiCol_TextDisabled as i32,
640 WindowBg = sys::ImGuiCol_WindowBg as i32,
641 ChildBg = sys::ImGuiCol_ChildBg as i32,
642 PopupBg = sys::ImGuiCol_PopupBg as i32,
643 Border = sys::ImGuiCol_Border as i32,
644 BorderShadow = sys::ImGuiCol_BorderShadow as i32,
645 FrameBg = sys::ImGuiCol_FrameBg as i32,
646 FrameBgHovered = sys::ImGuiCol_FrameBgHovered as i32,
647 FrameBgActive = sys::ImGuiCol_FrameBgActive as i32,
648 TitleBg = sys::ImGuiCol_TitleBg as i32,
649 TitleBgActive = sys::ImGuiCol_TitleBgActive as i32,
650 TitleBgCollapsed = sys::ImGuiCol_TitleBgCollapsed as i32,
651 MenuBarBg = sys::ImGuiCol_MenuBarBg as i32,
652 ScrollbarBg = sys::ImGuiCol_ScrollbarBg as i32,
653 ScrollbarGrab = sys::ImGuiCol_ScrollbarGrab as i32,
654 ScrollbarGrabHovered = sys::ImGuiCol_ScrollbarGrabHovered as i32,
655 ScrollbarGrabActive = sys::ImGuiCol_ScrollbarGrabActive as i32,
656 CheckMark = sys::ImGuiCol_CheckMark as i32,
657 SliderGrab = sys::ImGuiCol_SliderGrab as i32,
658 SliderGrabActive = sys::ImGuiCol_SliderGrabActive as i32,
659 Button = sys::ImGuiCol_Button as i32,
660 ButtonHovered = sys::ImGuiCol_ButtonHovered as i32,
661 ButtonActive = sys::ImGuiCol_ButtonActive as i32,
662 Header = sys::ImGuiCol_Header as i32,
663 HeaderHovered = sys::ImGuiCol_HeaderHovered as i32,
664 HeaderActive = sys::ImGuiCol_HeaderActive as i32,
665 Separator = sys::ImGuiCol_Separator as i32,
666 SeparatorHovered = sys::ImGuiCol_SeparatorHovered as i32,
667 SeparatorActive = sys::ImGuiCol_SeparatorActive as i32,
668 ResizeGrip = sys::ImGuiCol_ResizeGrip as i32,
669 ResizeGripHovered = sys::ImGuiCol_ResizeGripHovered as i32,
670 ResizeGripActive = sys::ImGuiCol_ResizeGripActive as i32,
671 Tab = sys::ImGuiCol_Tab as i32,
672 TabHovered = sys::ImGuiCol_TabHovered as i32,
673 TabSelected = sys::ImGuiCol_TabSelected as i32,
675 TabSelectedOverline = sys::ImGuiCol_TabSelectedOverline as i32,
676 TabDimmed = sys::ImGuiCol_TabDimmed as i32,
677 TabDimmedSelected = sys::ImGuiCol_TabDimmedSelected as i32,
678 TabDimmedSelectedOverline = sys::ImGuiCol_TabDimmedSelectedOverline as i32,
679 DockingPreview = sys::ImGuiCol_DockingPreview as i32,
680 DockingEmptyBg = sys::ImGuiCol_DockingEmptyBg as i32,
681 PlotLines = sys::ImGuiCol_PlotLines as i32,
682 PlotLinesHovered = sys::ImGuiCol_PlotLinesHovered as i32,
683 PlotHistogram = sys::ImGuiCol_PlotHistogram as i32,
684 PlotHistogramHovered = sys::ImGuiCol_PlotHistogramHovered as i32,
685 TableHeaderBg = sys::ImGuiCol_TableHeaderBg as i32,
686 TableBorderStrong = sys::ImGuiCol_TableBorderStrong as i32,
687 TableBorderLight = sys::ImGuiCol_TableBorderLight as i32,
688 TableRowBg = sys::ImGuiCol_TableRowBg as i32,
689 TableRowBgAlt = sys::ImGuiCol_TableRowBgAlt as i32,
690 TextSelectedBg = sys::ImGuiCol_TextSelectedBg as i32,
691 TextLink = sys::ImGuiCol_TextLink as i32,
692 TreeLines = sys::ImGuiCol_TreeLines as i32,
693 InputTextCursor = sys::ImGuiCol_InputTextCursor as i32,
694 DragDropTarget = sys::ImGuiCol_DragDropTarget as i32,
695 DragDropTargetBg = sys::ImGuiCol_DragDropTargetBg as i32,
696 UnsavedMarker = sys::ImGuiCol_UnsavedMarker as i32,
697 NavCursor = sys::ImGuiCol_NavCursor as i32,
698 NavWindowingHighlight = sys::ImGuiCol_NavWindowingHighlight as i32,
699 NavWindowingDimBg = sys::ImGuiCol_NavWindowingDimBg as i32,
700 ModalWindowDimBg = sys::ImGuiCol_ModalWindowDimBg as i32,
701}
702
703impl StyleColor {
704 pub const COUNT: usize = sys::ImGuiCol_COUNT as usize;
705}
706
707impl Clone for Style {
708 fn clone(&self) -> Self {
709 Self(UnsafeCell::new(*self.inner()))
710 }
711}
712
713impl PartialEq for Style {
714 fn eq(&self, other: &Self) -> bool {
715 *self.inner() == *other.inner()
716 }
717}
718
719impl RawWrapper for Style {
720 type Raw = sys::ImGuiStyle;
721
722 unsafe fn raw(&self) -> &Self::Raw {
723 self.inner()
724 }
725
726 unsafe fn raw_mut(&mut self) -> &mut Self::Raw {
727 self.inner_mut()
728 }
729}
730
731#[derive(Copy, Clone, Debug, PartialEq)]
733#[non_exhaustive]
734pub enum StyleVar {
735 Alpha(f32),
737 DisabledAlpha(f32),
739 WindowPadding([f32; 2]),
741 WindowRounding(f32),
743 WindowBorderSize(f32),
745 WindowMinSize([f32; 2]),
747 WindowTitleAlign([f32; 2]),
749 ChildRounding(f32),
751 ChildBorderSize(f32),
753 PopupRounding(f32),
755 PopupBorderSize(f32),
757 FramePadding([f32; 2]),
759 FrameRounding(f32),
761 FrameBorderSize(f32),
763 ItemSpacing([f32; 2]),
765 ItemInnerSpacing([f32; 2]),
767 IndentSpacing(f32),
769 CellPadding([f32; 2]),
771 ScrollbarSize(f32),
773 ScrollbarRounding(f32),
775 GrabMinSize(f32),
777 GrabRounding(f32),
779 TabRounding(f32),
781 ButtonTextAlign([f32; 2]),
783 SelectableTextAlign([f32; 2]),
785}
786
787#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
792#[derive(Copy, Clone, Debug, PartialEq, Eq)]
793pub enum ThemePreset {
794 None,
796 Dark,
798 Light,
800 Classic,
802}
803
804impl Default for ThemePreset {
805 fn default() -> Self {
806 ThemePreset::None
807 }
808}
809
810#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
812#[derive(Clone, Debug, PartialEq)]
813pub struct ColorOverride {
814 pub id: StyleColor,
816 pub rgba: [f32; 4],
818}
819
820#[derive(Clone, Debug)]
825#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
826#[cfg_attr(feature = "serde", serde(default))]
827pub struct StyleTweaks {
828 pub window_rounding: Option<f32>,
829 pub frame_rounding: Option<f32>,
830 pub tab_rounding: Option<f32>,
831
832 pub window_padding: Option<[f32; 2]>,
833 pub frame_padding: Option<[f32; 2]>,
834 pub cell_padding: Option<[f32; 2]>,
835 pub item_spacing: Option<[f32; 2]>,
836 pub item_inner_spacing: Option<[f32; 2]>,
837
838 pub scrollbar_size: Option<f32>,
839 pub grab_min_size: Option<f32>,
840
841 pub indent_spacing: Option<f32>,
842 pub scrollbar_rounding: Option<f32>,
843 pub grab_rounding: Option<f32>,
844 pub window_border_size: Option<f32>,
845 pub child_border_size: Option<f32>,
846 pub popup_border_size: Option<f32>,
847 pub frame_border_size: Option<f32>,
848 pub tab_border_size: Option<f32>,
849 pub child_rounding: Option<f32>,
850 pub popup_rounding: Option<f32>,
851
852 pub anti_aliased_lines: Option<bool>,
853 pub anti_aliased_fill: Option<bool>,
854}
855
856impl Default for StyleTweaks {
857 fn default() -> Self {
858 Self {
859 window_rounding: None,
860 frame_rounding: None,
861 tab_rounding: None,
862 window_padding: None,
863 frame_padding: None,
864 cell_padding: None,
865 item_spacing: None,
866 item_inner_spacing: None,
867 scrollbar_size: None,
868 grab_min_size: None,
869 indent_spacing: None,
870 scrollbar_rounding: None,
871 grab_rounding: None,
872 window_border_size: None,
873 child_border_size: None,
874 popup_border_size: None,
875 frame_border_size: None,
876 tab_border_size: None,
877 child_rounding: None,
878 popup_rounding: None,
879 anti_aliased_lines: None,
880 anti_aliased_fill: None,
881 }
882 }
883}
884
885impl StyleTweaks {
886 pub fn apply(&self, style: &mut Style) {
888 if let Some(v) = self.window_rounding {
889 style.set_window_rounding(v);
890 }
891 if let Some(v) = self.frame_rounding {
892 style.set_frame_rounding(v);
893 }
894 if let Some(v) = self.tab_rounding {
895 style.set_tab_rounding(v);
896 }
897
898 if let Some(v) = self.window_padding {
899 style.set_window_padding(v);
900 }
901 if let Some(v) = self.frame_padding {
902 style.set_frame_padding(v);
903 }
904 if let Some(v) = self.cell_padding {
905 style.set_cell_padding(v);
906 }
907 if let Some(v) = self.item_spacing {
908 style.set_item_spacing(v);
909 }
910 if let Some(v) = self.item_inner_spacing {
911 style.set_item_inner_spacing(v);
912 }
913
914 if let Some(v) = self.scrollbar_size {
915 style.set_scrollbar_size(v);
916 }
917 if let Some(v) = self.grab_min_size {
918 style.set_grab_min_size(v);
919 }
920
921 if let Some(v) = self.indent_spacing {
922 style.set_indent_spacing(v);
923 }
924 if let Some(v) = self.scrollbar_rounding {
925 style.set_scrollbar_rounding(v);
926 }
927 if let Some(v) = self.grab_rounding {
928 style.set_grab_rounding(v);
929 }
930 if let Some(v) = self.window_border_size {
931 style.set_window_border_size(v);
932 }
933 if let Some(v) = self.child_border_size {
934 style.set_child_border_size(v);
935 }
936 if let Some(v) = self.popup_border_size {
937 style.set_popup_border_size(v);
938 }
939 if let Some(v) = self.frame_border_size {
940 style.set_frame_border_size(v);
941 }
942 if let Some(v) = self.tab_border_size {
943 style.set_tab_border_size(v);
944 }
945 if let Some(v) = self.child_rounding {
946 style.set_child_rounding(v);
947 }
948 if let Some(v) = self.popup_rounding {
949 style.set_popup_rounding(v);
950 }
951
952 if let Some(v) = self.anti_aliased_lines {
953 style.set_anti_aliased_lines(v);
954 }
955 if let Some(v) = self.anti_aliased_fill {
956 style.set_anti_aliased_fill(v);
957 }
958 }
959}
960
961#[derive(Clone, Debug, Default)]
963#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
964pub struct WindowTheme {
965 pub default_window_flags: Option<WindowFlags>,
967 pub popup_window_flags: Option<WindowFlags>,
969}
970
971#[derive(Clone, Debug, Default)]
973#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
974pub struct TableTheme {
975 pub default_table_flags: Option<TableFlags>,
977 pub default_row_flags: Option<TableRowFlags>,
979}
980
981#[derive(Clone, Debug, Default)]
991#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
992pub struct Theme {
993 #[cfg_attr(feature = "serde", serde(default))]
995 pub preset: ThemePreset,
996
997 #[cfg_attr(feature = "serde", serde(default))]
999 pub colors: Vec<ColorOverride>,
1000
1001 #[cfg_attr(feature = "serde", serde(default))]
1003 pub style: StyleTweaks,
1004
1005 #[cfg_attr(feature = "serde", serde(default))]
1007 pub windows: WindowTheme,
1008
1009 #[cfg_attr(feature = "serde", serde(default))]
1011 pub tables: TableTheme,
1012}
1013
1014impl Theme {
1015 pub fn apply_to_style(&self, style: &mut Style) {
1019 match self.preset {
1021 ThemePreset::None => {}
1022 ThemePreset::Dark => unsafe {
1023 sys::igStyleColorsDark(style.raw_mut());
1024 },
1025 ThemePreset::Light => unsafe {
1026 sys::igStyleColorsLight(style.raw_mut());
1027 },
1028 ThemePreset::Classic => unsafe {
1029 sys::igStyleColorsClassic(style.raw_mut());
1030 },
1031 }
1032
1033 for c in &self.colors {
1035 style.set_color(c.id, c.rgba);
1036 }
1037
1038 self.style.apply(style);
1040 }
1041
1042 pub fn apply_to_context(&self, ctx: &mut Context) {
1044 let style = ctx.style_mut();
1045 self.apply_to_style(style);
1046 }
1047}