1#![cfg(feature = "parser")]
26
27use alloc::{
28 boxed::Box,
29 string::{String, ToString},
30 vec::Vec,
31};
32use crate::{
33 corety::{AzString, OptionF32, OptionString, OptionU16},
34 css::Css,
35 parser2::{new_from_str, CssParseWarnMsg},
36 props::{
37 basic::{
38 color::{parse_css_color, ColorU, OptionColorU},
39 pixel::{PixelValue, OptionPixelValue},
40 },
41 style::scrollbar::{ComputedScrollbarStyle, OverscrollBehavior, ScrollBehavior, ScrollPhysics},
42 },
43};
44
45use crate::dynamic_selector::{BoolCondition, OsVersion};
46use core::fmt::Write;
47
48#[derive(Debug, Clone, Copy, PartialEq, Eq)]
54#[derive(Default)]
55pub enum RicingMode {
56 Off,
59 #[default]
62 Default,
63 Force,
67}
68
69
70#[must_use] pub fn ricing_mode() -> RicingMode {
74 let Ok(raw) = std::env::var("AZ_RICING") else {
75 return RicingMode::Default;
76 };
77 match raw.trim().to_ascii_lowercase().as_str() {
78 "off" | "disabled" | "none" | "0" | "false" => RicingMode::Off,
79 "force" | "prefer" | "aggressive" | "1" | "true" => RicingMode::Force,
80 _ => RicingMode::Default,
81 }
82}
83
84#[must_use] pub fn ricing_enabled() -> bool {
87 !matches!(ricing_mode(), RicingMode::Off)
88}
89
90#[allow(variant_size_differences)] #[derive(Debug, Default, Clone, PartialEq, Eq)]
94#[repr(C, u8)]
95pub enum Platform {
96 Windows,
97 MacOs,
98 Linux(DesktopEnvironment),
99 Android,
100 Ios,
101 #[default]
102 Unknown,
103}
104
105impl Platform {
106 #[inline]
108 #[must_use] pub const fn current() -> Self {
109 #[cfg(target_os = "macos")]
110 { Self::MacOs }
111 #[cfg(target_os = "windows")]
112 { Self::Windows }
113 #[cfg(target_os = "linux")]
114 { Self::Linux(DesktopEnvironment::Other(AzString::from_const_str("unknown"))) }
115 #[cfg(target_os = "android")]
116 { Self::Android }
117 #[cfg(target_os = "ios")]
118 { Self::Ios }
119 #[cfg(not(any(target_os = "macos", target_os = "windows", target_os = "linux", target_os = "android", target_os = "ios")))]
120 { Self::Unknown }
121 }
122}
123#[allow(variant_size_differences)] #[derive(Debug, Clone, PartialEq, Eq)]
126#[repr(C, u8)]
127pub enum DesktopEnvironment {
128 Gnome,
129 Kde,
130 Other(AzString),
131}
132
133#[derive(Debug, Default, Clone, Copy, PartialEq, Eq)]
135#[repr(C)]
136pub enum Theme {
137 #[default]
138 Light,
139 Dark,
140}
141
142#[derive(Debug, Clone, PartialEq)]
144#[repr(C)]
145pub struct SystemStyle {
146 pub fonts: SystemFonts,
147 pub metrics: SystemMetrics,
148 pub linux: LinuxCustomization,
150 pub platform: Platform,
151 pub focus_visuals: FocusVisuals,
153 pub language: AzString,
156 pub app_specific_stylesheet: Option<Box<Css>>,
161 pub scrollbar: Option<Box<ComputedScrollbarStyle>>,
163 pub scroll_physics: ScrollPhysics,
167 pub theme: Theme,
168 pub os_version: OsVersion,
170 pub prefers_reduced_motion: BoolCondition,
172 pub prefers_high_contrast: BoolCondition,
174 pub accessibility: AccessibilitySettings,
176 pub input: InputMetrics,
178 pub text_rendering: TextRenderingHints,
180 pub scrollbar_preferences: ScrollbarPreferences,
182 pub visual_hints: VisualHints,
184 pub animation: AnimationMetrics,
186 pub colors: SystemColors,
187 pub icon_style: IconStyleOptions,
189 pub audio: AudioMetrics,
191 pub run_destructor: bool,
203}
204
205impl Default for SystemStyle {
206 fn default() -> Self {
207 Self {
208 fonts: SystemFonts::default(),
209 metrics: SystemMetrics::default(),
210 linux: LinuxCustomization::default(),
211 platform: Platform::default(),
212 focus_visuals: FocusVisuals::default(),
213 language: AzString::default(),
214 app_specific_stylesheet: None,
215 scrollbar: None,
216 scroll_physics: ScrollPhysics::default(),
217 theme: Theme::default(),
218 os_version: OsVersion::default(),
219 prefers_reduced_motion: BoolCondition::default(),
220 prefers_high_contrast: BoolCondition::default(),
221 accessibility: AccessibilitySettings::default(),
222 input: InputMetrics::default(),
223 text_rendering: TextRenderingHints::default(),
224 scrollbar_preferences: ScrollbarPreferences::default(),
225 visual_hints: VisualHints::default(),
226 animation: AnimationMetrics::default(),
227 colors: SystemColors::default(),
228 icon_style: IconStyleOptions::default(),
229 audio: AudioMetrics::default(),
230 run_destructor: true,
231 }
232 }
233}
234
235impl Drop for SystemStyle {
236 fn drop(&mut self) {
237 if self.run_destructor {
247 self.run_destructor = false;
248 } else {
249 core::mem::forget(self.app_specific_stylesheet.take());
250 core::mem::forget(self.scrollbar.take());
251 }
252 }
253}
254
255#[derive(Debug, Default, Clone, Copy, PartialEq, Eq)]
260#[repr(C)]
261pub struct IconStyleOptions {
262 pub prefer_grayscale: bool,
265 pub tint_color: OptionColorU,
268 pub inherit_text_color: bool,
271}
272
273#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
284#[repr(C)]
285#[derive(Default)]
286pub enum SystemFontType {
287 #[default]
289 Ui,
290 UiBold,
292 Monospace,
294 MonospaceBold,
296 MonospaceItalic,
298 Title,
300 TitleBold,
302 Menu,
304 Small,
306 Serif,
308 SerifBold,
310}
311
312
313impl SystemFontType {
314 #[must_use] pub fn from_css_str(s: &str) -> Option<Self> {
324 let s = s.trim();
325 if !s.starts_with("system:") {
326 return None;
327 }
328 let rest = &s[7..]; match rest {
330 "ui" => Some(Self::Ui),
331 "ui:bold" => Some(Self::UiBold),
332 "monospace" => Some(Self::Monospace),
333 "monospace:bold" => Some(Self::MonospaceBold),
334 "monospace:italic" => Some(Self::MonospaceItalic),
335 "title" => Some(Self::Title),
336 "title:bold" => Some(Self::TitleBold),
337 "menu" => Some(Self::Menu),
338 "small" => Some(Self::Small),
339 "serif" => Some(Self::Serif),
340 "serif:bold" => Some(Self::SerifBold),
341 _ => None,
342 }
343 }
344
345 #[must_use] pub const fn as_css_str(&self) -> &'static str {
347 match self {
348 Self::Ui => "system:ui",
349 Self::UiBold => "system:ui:bold",
350 Self::Monospace => "system:monospace",
351 Self::MonospaceBold => "system:monospace:bold",
352 Self::MonospaceItalic => "system:monospace:italic",
353 Self::Title => "system:title",
354 Self::TitleBold => "system:title:bold",
355 Self::Menu => "system:menu",
356 Self::Small => "system:small",
357 Self::Serif => "system:serif",
358 Self::SerifBold => "system:serif:bold",
359 }
360 }
361
362 #[must_use] pub const fn is_bold(&self) -> bool {
365 matches!(
366 self,
367 Self::UiBold
368 | Self::MonospaceBold
369 | Self::TitleBold
370 | Self::SerifBold
371 )
372 }
373
374 #[must_use] pub const fn is_italic(&self) -> bool {
376 matches!(self, Self::MonospaceItalic)
377 }
378}
379
380#[derive(Debug, Default, Clone, Copy, PartialEq)]
388#[repr(C)]
389pub struct AccessibilitySettings {
390 pub text_scale_factor: f32,
392 pub prefers_bold_text: bool,
397 pub prefers_larger_text: bool,
402 pub prefers_high_contrast: bool,
407 pub prefers_reduced_motion: bool,
412 pub prefers_reduced_transparency: bool,
417 pub screen_reader_active: bool,
419 pub differentiate_without_color: bool,
422}
423
424#[derive(Debug, Default, Clone, Copy, PartialEq, Eq)]
433#[repr(C)]
434pub struct SystemColors {
435 pub text: OptionColorU,
438 pub secondary_text: OptionColorU,
440 pub tertiary_text: OptionColorU,
442 pub background: OptionColorU,
444
445 pub accent: OptionColorU,
448 pub accent_text: OptionColorU,
450
451 pub button_face: OptionColorU,
454 pub button_text: OptionColorU,
456 pub disabled_text: OptionColorU,
458
459 pub window_background: OptionColorU,
462 pub under_page_background: OptionColorU,
464
465 pub selection_background: OptionColorU,
468 pub selection_text: OptionColorU,
470 pub selection_background_inactive: OptionColorU,
473 pub selection_text_inactive: OptionColorU,
475
476 pub link: OptionColorU,
479 pub separator: OptionColorU,
481 pub grid: OptionColorU,
483 pub find_highlight: OptionColorU,
485
486 pub sidebar_background: OptionColorU,
489 pub sidebar_selection: OptionColorU,
491}
492
493#[derive(Debug, Default, Clone, PartialEq, Eq)]
499#[repr(C)]
500pub struct SystemFonts {
501 pub ui_font: OptionString,
506 pub ui_font_size: OptionF32,
508 pub monospace_font: OptionString,
513 pub monospace_font_size: OptionF32,
515 pub ui_font_bold: OptionString,
517 pub title_font: OptionString,
519 pub title_font_size: OptionF32,
521 pub menu_font: OptionString,
523 pub menu_font_size: OptionF32,
525 pub small_font: OptionString,
527 pub small_font_size: OptionF32,
529}
530
531#[derive(Debug, Default, Clone, PartialEq, Eq)]
533#[repr(C)]
534pub struct SystemMetrics {
535 pub corner_radius: OptionPixelValue,
537 pub border_width: OptionPixelValue,
539 pub button_padding_horizontal: OptionPixelValue,
541 pub button_padding_vertical: OptionPixelValue,
543 pub titlebar: TitlebarMetrics,
545}
546
547#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Default)]
549#[repr(C)]
550pub enum TitlebarButtonSide {
551 Left,
553 #[default]
555 Right,
556}
557
558#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
560#[repr(C)]
561pub struct TitlebarButtons {
562 pub has_close: bool,
564 pub has_minimize: bool,
566 pub has_maximize: bool,
568 pub has_fullscreen: bool,
570}
571
572impl Default for TitlebarButtons {
573 fn default() -> Self {
574 Self {
575 has_close: true,
576 has_minimize: true,
577 has_maximize: true,
578 has_fullscreen: false,
579 }
580 }
581}
582
583#[derive(Debug, Default, Clone, Copy, PartialEq, Eq)]
589#[repr(C)]
590pub struct SafeAreaInsets {
591 pub top: OptionPixelValue,
593 pub bottom: OptionPixelValue,
595 pub left: OptionPixelValue,
597 pub right: OptionPixelValue,
599}
600
601#[derive(Debug, Clone, PartialEq, Eq)]
606#[repr(C)]
607pub struct TitlebarMetrics {
608 pub button_side: TitlebarButtonSide,
610 pub buttons: TitlebarButtons,
612 pub height: OptionPixelValue,
614 pub button_area_width: OptionPixelValue,
617 pub padding_horizontal: OptionPixelValue,
619 pub safe_area: SafeAreaInsets,
621 pub title_font: OptionString,
623 pub title_font_size: OptionF32,
625 pub title_font_weight: OptionU16,
627}
628
629impl Default for TitlebarMetrics {
630 fn default() -> Self {
631 Self {
632 button_side: TitlebarButtonSide::Right,
633 buttons: TitlebarButtons::default(),
634 height: OptionPixelValue::Some(PixelValue::px(32.0)),
635 button_area_width: OptionPixelValue::Some(PixelValue::px(100.0)),
636 padding_horizontal: OptionPixelValue::Some(PixelValue::px(8.0)),
637 safe_area: SafeAreaInsets::default(),
638 title_font: OptionString::None,
639 title_font_size: OptionF32::Some(13.0),
640 title_font_weight: OptionU16::Some(600), }
642 }
643}
644
645impl TitlebarMetrics {
646 #[must_use] pub fn windows() -> Self {
648 Self {
649 button_side: TitlebarButtonSide::Right,
650 buttons: TitlebarButtons {
651 has_close: true,
652 has_minimize: true,
653 has_maximize: true,
654 has_fullscreen: false,
655 },
656 height: OptionPixelValue::Some(PixelValue::px(32.0)),
657 button_area_width: OptionPixelValue::Some(PixelValue::px(138.0)), padding_horizontal: OptionPixelValue::Some(PixelValue::px(8.0)),
659 safe_area: SafeAreaInsets::default(),
660 title_font: OptionString::Some("Segoe UI Variable Text".into()),
661 title_font_size: OptionF32::Some(12.0),
662 title_font_weight: OptionU16::Some(400), }
664 }
665
666 #[must_use] pub fn macos() -> Self {
668 Self {
669 button_side: TitlebarButtonSide::Left,
670 buttons: TitlebarButtons {
671 has_close: true,
672 has_minimize: true,
673 has_maximize: false, has_fullscreen: true,
675 },
676 height: OptionPixelValue::Some(PixelValue::px(28.0)),
677 button_area_width: OptionPixelValue::Some(PixelValue::px(78.0)), padding_horizontal: OptionPixelValue::Some(PixelValue::px(8.0)),
679 safe_area: SafeAreaInsets::default(),
680 title_font: OptionString::Some(".SF NS".into()),
681 title_font_size: OptionF32::Some(13.0),
682 title_font_weight: OptionU16::Some(600), }
684 }
685
686 #[must_use] pub fn linux_gnome() -> Self {
688 Self {
689 button_side: TitlebarButtonSide::Right, buttons: TitlebarButtons {
691 has_close: true,
692 has_minimize: true,
693 has_maximize: true,
694 has_fullscreen: false,
695 },
696 height: OptionPixelValue::Some(PixelValue::px(35.0)),
697 button_area_width: OptionPixelValue::Some(PixelValue::px(100.0)),
698 padding_horizontal: OptionPixelValue::Some(PixelValue::px(12.0)),
699 safe_area: SafeAreaInsets::default(),
700 title_font: OptionString::Some("Cantarell".into()),
701 title_font_size: OptionF32::Some(11.0),
702 title_font_weight: OptionU16::Some(700), }
704 }
705
706 #[must_use] pub fn ios() -> Self {
708 Self {
709 button_side: TitlebarButtonSide::Left,
710 buttons: TitlebarButtons {
711 has_close: false, has_minimize: false,
713 has_maximize: false,
714 has_fullscreen: false,
715 },
716 height: OptionPixelValue::Some(PixelValue::px(44.0)),
717 button_area_width: OptionPixelValue::Some(PixelValue::px(0.0)),
718 padding_horizontal: OptionPixelValue::Some(PixelValue::px(16.0)),
719 safe_area: SafeAreaInsets {
720 top: OptionPixelValue::Some(PixelValue::px(47.0)),
722 bottom: OptionPixelValue::Some(PixelValue::px(34.0)),
723 left: OptionPixelValue::None,
724 right: OptionPixelValue::None,
725 },
726 title_font: OptionString::Some(".SFUI-Semibold".into()),
727 title_font_size: OptionF32::Some(17.0),
728 title_font_weight: OptionU16::Some(600),
729 }
730 }
731
732 #[must_use] pub fn android() -> Self {
734 Self {
735 button_side: TitlebarButtonSide::Left, buttons: TitlebarButtons {
737 has_close: false,
738 has_minimize: false,
739 has_maximize: false,
740 has_fullscreen: false,
741 },
742 height: OptionPixelValue::Some(PixelValue::px(56.0)),
743 button_area_width: OptionPixelValue::Some(PixelValue::px(48.0)), padding_horizontal: OptionPixelValue::Some(PixelValue::px(16.0)),
745 safe_area: SafeAreaInsets::default(),
746 title_font: OptionString::Some("Roboto Medium".into()),
747 title_font_size: OptionF32::Some(20.0),
748 title_font_weight: OptionU16::Some(500),
749 }
750 }
751}
752
753#[derive(Debug, Clone, Copy, PartialEq)]
766#[repr(C)]
767pub struct InputMetrics {
768 pub double_click_time_ms: u32,
770 pub double_click_distance_px: f32,
772 pub drag_threshold_px: f32,
774 pub caret_blink_rate_ms: u32,
776 pub caret_width_px: f32,
778 pub wheel_scroll_lines: u32,
780 pub hover_time_ms: u32,
783}
784
785impl Default for InputMetrics {
786 fn default() -> Self {
787 Self {
788 double_click_time_ms: 500,
789 double_click_distance_px: 4.0,
790 drag_threshold_px: 5.0,
791 caret_blink_rate_ms: 530,
792 caret_width_px: 1.0,
793 wheel_scroll_lines: 3,
794 hover_time_ms: 400,
795 }
796 }
797}
798
799#[derive(Debug, Default, Clone, Copy, PartialEq, Eq)]
803#[repr(C)]
804pub enum SubpixelType {
805 #[default]
807 None,
808 Rgb,
810 Bgr,
812 VRgb,
814 VBgr,
816}
817
818#[derive(Debug, Clone, Copy, PartialEq, Eq)]
823#[repr(C)]
824pub struct TextRenderingHints {
825 pub subpixel_type: SubpixelType,
827 pub font_smoothing_gamma: u32,
829 pub font_smoothing_enabled: bool,
831 pub increased_contrast: bool,
833}
834
835impl Default for TextRenderingHints {
836 fn default() -> Self {
837 Self {
838 subpixel_type: SubpixelType::None,
839 font_smoothing_gamma: 1000,
840 font_smoothing_enabled: true,
841 increased_contrast: false,
842 }
843 }
844}
845
846#[derive(Debug, Default, Clone, Copy, PartialEq, Eq)]
853#[repr(C)]
854pub struct FocusVisuals {
855 pub focus_ring_color: OptionColorU,
858 pub focus_border_width: OptionPixelValue,
861 pub focus_border_height: OptionPixelValue,
863}
864
865#[derive(Debug, Default, Clone, Copy, PartialEq, Eq)]
869#[repr(C)]
870pub enum ScrollbarVisibility {
871 Always,
873 #[default]
875 WhenScrolling,
876 Automatic,
878}
879
880#[derive(Debug, Default, Clone, Copy, PartialEq, Eq)]
882#[repr(C)]
883pub enum ScrollbarTrackClick {
884 JumpToPosition,
886 #[default]
888 PageUpDown,
889}
890
891#[derive(Debug, Clone, Copy, PartialEq, Eq)]
896#[repr(C)]
897pub struct ScrollbarPreferences {
898 pub visibility: ScrollbarVisibility,
901 pub track_click: ScrollbarTrackClick,
903}
904
905impl Default for ScrollbarPreferences {
906 fn default() -> Self {
907 Self {
908 visibility: ScrollbarVisibility::WhenScrolling,
909 track_click: ScrollbarTrackClick::PageUpDown,
910 }
911 }
912}
913
914#[derive(Debug, Default, Clone, PartialEq, Eq)]
921#[repr(C)]
922pub struct LinuxCustomization {
923 pub gtk_theme: OptionString,
925 pub icon_theme: OptionString,
927 pub cursor_theme: OptionString,
929 pub cursor_size: u32,
931 pub titlebar_button_layout: OptionString,
934}
935
936#[derive(Debug, Default, Clone, Copy, PartialEq, Eq)]
940#[repr(C)]
941pub enum ToolbarStyle {
942 #[default]
944 IconsOnly,
945 TextOnly,
947 TextBesideIcon,
949 TextBelowIcon,
951}
952
953#[derive(Debug, Clone, Copy, PartialEq, Eq)]
958#[repr(C)]
959pub struct VisualHints {
960 pub toolbar_style: ToolbarStyle,
963 pub show_button_images: bool,
966 pub show_menu_images: bool,
969 pub show_tooltips: bool,
971 pub flash_on_alert: bool,
973}
974
975impl Default for VisualHints {
976 fn default() -> Self {
977 Self {
978 toolbar_style: ToolbarStyle::IconsOnly,
979 show_button_images: false,
980 show_menu_images: true,
981 show_tooltips: true,
982 flash_on_alert: true,
983 }
984 }
985}
986
987#[derive(Debug, Default, Clone, Copy, PartialEq, Eq)]
991#[repr(C)]
992pub enum FocusBehavior {
993 #[default]
995 AlwaysVisible,
996 KeyboardOnly,
999}
1000
1001#[derive(Debug, Clone, Copy, PartialEq)]
1013#[repr(C)]
1014pub struct AnimationMetrics {
1015 pub animations_enabled: bool,
1017 pub animation_duration_factor: f32,
1020 pub focus_indicator_behavior: FocusBehavior,
1022}
1023
1024impl Default for AnimationMetrics {
1025 fn default() -> Self {
1026 Self {
1027 animations_enabled: true,
1028 animation_duration_factor: 1.0,
1029 focus_indicator_behavior: FocusBehavior::AlwaysVisible,
1030 }
1031 }
1032}
1033
1034#[derive(Debug, Clone, Copy, PartialEq, Eq)]
1047#[repr(C)]
1048pub struct AudioMetrics {
1049 pub event_sounds_enabled: bool,
1051 pub input_feedback_sounds_enabled: bool,
1053}
1054
1055impl Default for AudioMetrics {
1056 fn default() -> Self {
1057 Self {
1058 event_sounds_enabled: true,
1059 input_feedback_sounds_enabled: false,
1060 }
1061 }
1062}
1063
1064pub mod apple_fonts {
1070 pub const SYSTEM_FONT: &str = "System Font";
1073
1074 pub const SF_NS_ROUNDED: &str = "SF NS Rounded";
1076
1077 pub const SF_COMPACT: &str = "SF Compact";
1080
1081 pub const SF_MONO: &str = "SF NS Mono Light";
1084
1085 pub const NEW_YORK: &str = "New York";
1088
1089 pub const SF_ARABIC: &str = "SF Arabic";
1091
1092 pub const SF_ARMENIAN: &str = "SF Armenian";
1094
1095 pub const SF_GEORGIAN: &str = "SF Georgian";
1097
1098 pub const SF_HEBREW: &str = "SF Hebrew";
1100
1101 pub const MENLO: &str = "Menlo";
1103 pub const MENLO_REGULAR: &str = "Menlo Regular";
1104 pub const MENLO_BOLD: &str = "Menlo Bold";
1105 pub const MONACO: &str = "Monaco";
1106 pub const LUCIDA_GRANDE: &str = "Lucida Grande";
1107 pub const LUCIDA_GRANDE_BOLD: &str = "Lucida Grande Bold";
1108 pub const HELVETICA_NEUE: &str = "Helvetica Neue";
1109 pub const HELVETICA_NEUE_BOLD: &str = "Helvetica Neue Bold";
1110}
1111
1112pub mod windows_fonts {
1114 pub const SEGOE_UI_VARIABLE: &str = "Segoe UI Variable";
1116 pub const SEGOE_UI_VARIABLE_TEXT: &str = "Segoe UI Variable Text";
1117 pub const SEGOE_UI_VARIABLE_DISPLAY: &str = "Segoe UI Variable Display";
1118
1119 pub const SEGOE_UI: &str = "Segoe UI";
1121 pub const CONSOLAS: &str = "Consolas";
1122 pub const CASCADIA_CODE: &str = "Cascadia Code";
1123 pub const CASCADIA_MONO: &str = "Cascadia Mono";
1124
1125 pub const TAHOMA: &str = "Tahoma";
1127 pub const MS_SANS_SERIF: &str = "MS Sans Serif";
1128 pub const LUCIDA_CONSOLE: &str = "Lucida Console";
1129 pub const COURIER_NEW: &str = "Courier New";
1130}
1131
1132pub mod linux_fonts {
1134 pub const CANTARELL: &str = "Cantarell";
1136 pub const ADWAITA: &str = "Adwaita";
1137
1138 pub const UBUNTU: &str = "Ubuntu";
1140 pub const UBUNTU_MONO: &str = "Ubuntu Mono";
1141
1142 pub const DEJAVU_SANS: &str = "DejaVu Sans";
1144 pub const DEJAVU_SANS_MONO: &str = "DejaVu Sans Mono";
1145 pub const DEJAVU_SERIF: &str = "DejaVu Serif";
1146
1147 pub const LIBERATION_SANS: &str = "Liberation Sans";
1149 pub const LIBERATION_MONO: &str = "Liberation Mono";
1150 pub const LIBERATION_SERIF: &str = "Liberation Serif";
1151
1152 pub const NOTO_SANS: &str = "Noto Sans";
1154 pub const NOTO_MONO: &str = "Noto Sans Mono";
1155 pub const NOTO_SERIF: &str = "Noto Serif";
1156
1157 pub const HACK: &str = "Hack";
1159
1160 pub const MONOSPACE: &str = "Monospace";
1162 pub const SANS_SERIF: &str = "Sans";
1163 pub const SERIF: &str = "Serif";
1164}
1165
1166impl SystemFontType {
1167 #[must_use] pub fn get_fallback_chain(&self, platform: &Platform) -> Vec<&'static str> {
1172 match platform {
1173 Platform::MacOs | Platform::Ios => self.macos_fallback_chain(),
1174 Platform::Windows => self.windows_fallback_chain(),
1175 Platform::Linux(_) => self.linux_fallback_chain(),
1176 Platform::Android => self.android_fallback_chain(),
1177 Platform::Unknown => self.generic_fallback_chain(),
1178 }
1179 }
1180
1181 fn macos_fallback_chain(self) -> Vec<&'static str> {
1182 match self {
1183 Self::Ui => vec![
1185 apple_fonts::SYSTEM_FONT,
1186 apple_fonts::HELVETICA_NEUE,
1187 apple_fonts::LUCIDA_GRANDE,
1188 ],
1189 Self::UiBold | Self::TitleBold => vec![
1191 apple_fonts::HELVETICA_NEUE,
1192 apple_fonts::LUCIDA_GRANDE,
1193 ],
1194 Self::Monospace | Self::MonospaceBold | Self::MonospaceItalic => vec![
1196 apple_fonts::MENLO,
1197 apple_fonts::MONACO,
1198 ],
1199 Self::Title | Self::Menu | Self::Small => vec![
1201 apple_fonts::SYSTEM_FONT,
1202 apple_fonts::HELVETICA_NEUE,
1203 ],
1204 Self::Serif => vec![
1206 apple_fonts::NEW_YORK,
1207 "Georgia",
1208 "Times New Roman",
1209 ],
1210 Self::SerifBold => vec![
1211 "Georgia", "Times New Roman",
1213 ],
1214 }
1215 }
1216
1217 fn windows_fallback_chain(self) -> Vec<&'static str> {
1218 match self {
1219 Self::Ui | Self::UiBold => vec![
1220 windows_fonts::SEGOE_UI_VARIABLE_TEXT,
1221 windows_fonts::SEGOE_UI,
1222 windows_fonts::TAHOMA,
1223 ],
1224 Self::Monospace | Self::MonospaceBold | Self::MonospaceItalic => vec![
1225 windows_fonts::CASCADIA_MONO,
1226 windows_fonts::CASCADIA_CODE,
1227 windows_fonts::CONSOLAS,
1228 windows_fonts::LUCIDA_CONSOLE,
1229 windows_fonts::COURIER_NEW,
1230 ],
1231 Self::Title | Self::TitleBold => vec![
1232 windows_fonts::SEGOE_UI_VARIABLE_DISPLAY,
1233 windows_fonts::SEGOE_UI,
1234 ],
1235 Self::Menu => vec![
1236 windows_fonts::SEGOE_UI,
1237 windows_fonts::TAHOMA,
1238 ],
1239 Self::Small => vec![
1240 windows_fonts::SEGOE_UI,
1241 ],
1242 Self::Serif | Self::SerifBold => vec![
1243 "Cambria",
1244 "Georgia",
1245 "Times New Roman",
1246 ],
1247 }
1248 }
1249
1250 fn linux_fallback_chain(self) -> Vec<&'static str> {
1251 match self {
1252 Self::Ui | Self::UiBold => vec![
1253 linux_fonts::CANTARELL,
1254 linux_fonts::UBUNTU,
1255 linux_fonts::NOTO_SANS,
1256 linux_fonts::DEJAVU_SANS,
1257 linux_fonts::LIBERATION_SANS,
1258 linux_fonts::SANS_SERIF,
1259 ],
1260 Self::Monospace | Self::MonospaceBold | Self::MonospaceItalic => vec![
1261 linux_fonts::UBUNTU_MONO,
1262 linux_fonts::HACK,
1263 linux_fonts::NOTO_MONO,
1264 linux_fonts::DEJAVU_SANS_MONO,
1265 linux_fonts::LIBERATION_MONO,
1266 linux_fonts::MONOSPACE,
1267 ],
1268 Self::Title | Self::TitleBold | Self::Menu | Self::Small => vec![
1269 linux_fonts::CANTARELL,
1270 linux_fonts::UBUNTU,
1271 linux_fonts::NOTO_SANS,
1272 ],
1273 Self::Serif | Self::SerifBold => vec![
1274 linux_fonts::NOTO_SERIF,
1275 linux_fonts::DEJAVU_SERIF,
1276 linux_fonts::LIBERATION_SERIF,
1277 linux_fonts::SERIF,
1278 ],
1279 }
1280 }
1281
1282 fn android_fallback_chain(self) -> Vec<&'static str> {
1283 match self {
1284 Self::Ui | Self::UiBold | Self::Title | Self::TitleBold => vec!["Roboto", "Noto Sans"],
1285 Self::Monospace | Self::MonospaceBold | Self::MonospaceItalic => {
1286 vec!["Roboto Mono", "Droid Sans Mono", "monospace"]
1287 }
1288 Self::Menu | Self::Small => vec!["Roboto"],
1289 Self::Serif | Self::SerifBold => vec!["Noto Serif", "Droid Serif", "serif"],
1290 }
1291 }
1292
1293 fn generic_fallback_chain(self) -> Vec<&'static str> {
1294 match self {
1295 Self::Ui | Self::UiBold | Self::Title | Self::TitleBold | Self::Menu | Self::Small => {
1296 vec!["sans-serif"]
1297 }
1298 Self::Monospace | Self::MonospaceBold | Self::MonospaceItalic => {
1299 vec!["monospace"]
1300 }
1301 Self::Serif | Self::SerifBold => vec!["serif"],
1302 }
1303 }
1304}
1305
1306impl SystemStyle {
1307
1308 #[allow(clippy::too_many_lines)] #[must_use] pub fn to_json_string(&self) -> AzString {
1314 use alloc::format;
1315
1316 fn opt_color(c: OptionColorU) -> alloc::string::String {
1317 c.as_ref().map_or_else(
1318 || "null".into(),
1319 |c| format!("\"#{:02x}{:02x}{:02x}{:02x}\"", c.r, c.g, c.b, c.a),
1320 )
1321 }
1322 fn opt_str(s: &OptionString) -> alloc::string::String {
1323 s.as_ref()
1324 .map_or_else(|| "null".into(), |s| format!("\"{}\"", s.as_str()))
1325 }
1326 fn opt_f32(v: OptionF32) -> alloc::string::String {
1327 v.into_option()
1328 .map_or_else(|| "null".into(), |v| format!("{v:.2}"))
1329 }
1330 fn opt_u16(v: OptionU16) -> alloc::string::String {
1331 v.into_option()
1332 .map_or_else(|| "null".into(), |v| format!("{v}"))
1333 }
1334 fn opt_px(v: &OptionPixelValue) -> alloc::string::String {
1335 v.as_ref().map_or_else(
1336 || "null".into(),
1337 |v| format!("{:.1}", v.to_pixels_internal(0.0, 0.0, 0.0)),
1338 )
1339 }
1340
1341 let tm = &self.metrics.titlebar;
1342 let inp = &self.input;
1343 let tr = &self.text_rendering;
1344 let acc = &self.accessibility;
1345 let sp = &self.scrollbar_preferences;
1346 let lnx = &self.linux;
1347 let vh = &self.visual_hints;
1348 let anim = &self.animation;
1349 let audio = &self.audio;
1350
1351 let json = format!(
1352r#"{{
1353 "theme": "{:?}",
1354 "platform": "{:?}",
1355 "os_version": "{:?}:{}",
1356 "language": "{}",
1357 "prefers_reduced_motion": {:?},
1358 "prefers_high_contrast": {:?},
1359 "colors": {{
1360 "text": {},
1361 "secondary_text": {},
1362 "tertiary_text": {},
1363 "background": {},
1364 "accent": {},
1365 "accent_text": {},
1366 "button_face": {},
1367 "button_text": {},
1368 "disabled_text": {},
1369 "window_background": {},
1370 "under_page_background": {},
1371 "selection_background": {},
1372 "selection_text": {},
1373 "selection_background_inactive": {},
1374 "selection_text_inactive": {},
1375 "link": {},
1376 "separator": {},
1377 "grid": {},
1378 "find_highlight": {},
1379 "sidebar_background": {},
1380 "sidebar_selection": {}
1381 }},
1382 "fonts": {{
1383 "ui_font": {},
1384 "ui_font_size": {},
1385 "monospace_font": {},
1386 "title_font": {},
1387 "menu_font": {},
1388 "small_font": {}
1389 }},
1390 "titlebar": {{
1391 "button_side": "{:?}",
1392 "height": {},
1393 "button_area_width": {},
1394 "padding_horizontal": {},
1395 "title_font": {},
1396 "title_font_size": {},
1397 "title_font_weight": {},
1398 "has_close": {},
1399 "has_minimize": {},
1400 "has_maximize": {},
1401 "has_fullscreen": {}
1402 }},
1403 "input": {{
1404 "double_click_time_ms": {},
1405 "double_click_distance_px": {:.1},
1406 "drag_threshold_px": {:.1},
1407 "caret_blink_rate_ms": {},
1408 "caret_width_px": {:.1},
1409 "wheel_scroll_lines": {},
1410 "hover_time_ms": {}
1411 }},
1412 "text_rendering": {{
1413 "font_smoothing_enabled": {},
1414 "subpixel_type": "{:?}",
1415 "font_smoothing_gamma": {},
1416 "increased_contrast": {}
1417 }},
1418 "accessibility": {{
1419 "prefers_bold_text": {},
1420 "prefers_larger_text": {},
1421 "text_scale_factor": {:.2},
1422 "prefers_high_contrast": {},
1423 "prefers_reduced_motion": {},
1424 "prefers_reduced_transparency": {},
1425 "screen_reader_active": {},
1426 "differentiate_without_color": {}
1427 }},
1428 "scrollbar_preferences": {{
1429 "visibility": "{:?}",
1430 "track_click": "{:?}"
1431 }},
1432 "linux": {{
1433 "gtk_theme": {},
1434 "icon_theme": {},
1435 "cursor_theme": {},
1436 "cursor_size": {},
1437 "titlebar_button_layout": {}
1438 }},
1439 "visual_hints": {{
1440 "show_button_images": {},
1441 "show_menu_images": {},
1442 "toolbar_style": "{:?}",
1443 "show_tooltips": {}
1444 }},
1445 "animation": {{
1446 "animations_enabled": {},
1447 "animation_duration_factor": {:.2},
1448 "focus_indicator_behavior": "{:?}"
1449 }},
1450 "audio": {{
1451 "event_sounds_enabled": {},
1452 "input_feedback_sounds_enabled": {}
1453 }}
1454}}"#,
1455 self.theme,
1457 self.platform,
1458 self.os_version.os, self.os_version.version_id,
1459 self.language.as_str(),
1460 self.prefers_reduced_motion,
1461 self.prefers_high_contrast,
1462 opt_color(self.colors.text),
1464 opt_color(self.colors.secondary_text),
1465 opt_color(self.colors.tertiary_text),
1466 opt_color(self.colors.background),
1467 opt_color(self.colors.accent),
1468 opt_color(self.colors.accent_text),
1469 opt_color(self.colors.button_face),
1470 opt_color(self.colors.button_text),
1471 opt_color(self.colors.disabled_text),
1472 opt_color(self.colors.window_background),
1473 opt_color(self.colors.under_page_background),
1474 opt_color(self.colors.selection_background),
1475 opt_color(self.colors.selection_text),
1476 opt_color(self.colors.selection_background_inactive),
1477 opt_color(self.colors.selection_text_inactive),
1478 opt_color(self.colors.link),
1479 opt_color(self.colors.separator),
1480 opt_color(self.colors.grid),
1481 opt_color(self.colors.find_highlight),
1482 opt_color(self.colors.sidebar_background),
1483 opt_color(self.colors.sidebar_selection),
1484 opt_str(&self.fonts.ui_font),
1486 opt_f32(self.fonts.ui_font_size),
1487 opt_str(&self.fonts.monospace_font),
1488 opt_str(&self.fonts.title_font),
1489 opt_str(&self.fonts.menu_font),
1490 opt_str(&self.fonts.small_font),
1491 tm.button_side,
1493 opt_px(&tm.height),
1494 opt_px(&tm.button_area_width),
1495 opt_px(&tm.padding_horizontal),
1496 opt_str(&tm.title_font),
1497 opt_f32(tm.title_font_size),
1498 opt_u16(tm.title_font_weight),
1499 tm.buttons.has_close,
1500 tm.buttons.has_minimize,
1501 tm.buttons.has_maximize,
1502 tm.buttons.has_fullscreen,
1503 inp.double_click_time_ms,
1505 inp.double_click_distance_px,
1506 inp.drag_threshold_px,
1507 inp.caret_blink_rate_ms,
1508 inp.caret_width_px,
1509 inp.wheel_scroll_lines,
1510 inp.hover_time_ms,
1511 tr.font_smoothing_enabled,
1513 tr.subpixel_type,
1514 tr.font_smoothing_gamma,
1515 tr.increased_contrast,
1516 acc.prefers_bold_text,
1518 acc.prefers_larger_text,
1519 acc.text_scale_factor,
1520 acc.prefers_high_contrast,
1521 acc.prefers_reduced_motion,
1522 acc.prefers_reduced_transparency,
1523 acc.screen_reader_active,
1524 acc.differentiate_without_color,
1525 sp.visibility,
1527 sp.track_click,
1528 opt_str(&lnx.gtk_theme),
1530 opt_str(&lnx.icon_theme),
1531 opt_str(&lnx.cursor_theme),
1532 lnx.cursor_size,
1533 opt_str(&lnx.titlebar_button_layout),
1534 vh.show_button_images,
1536 vh.show_menu_images,
1537 vh.toolbar_style,
1538 vh.show_tooltips,
1539 anim.animations_enabled,
1541 anim.animation_duration_factor,
1542 anim.focus_indicator_behavior,
1543 audio.event_sounds_enabled,
1545 audio.input_feedback_sounds_enabled,
1546 );
1547
1548 AzString::from(json)
1549 }
1550
1551 #[must_use] pub fn detect() -> Self {
1557 Self::default_for_platform()
1558 }
1559
1560 #[must_use] pub fn default_for_platform() -> Self {
1562 #[cfg(target_os = "windows")]
1563 { defaults::windows_11_light() }
1564 #[cfg(target_os = "macos")]
1565 { defaults::macos_modern_light() }
1566 #[cfg(target_os = "linux")]
1567 { defaults::gnome_adwaita_light() }
1568 #[cfg(target_os = "android")]
1569 { defaults::android_material_light() }
1570 #[cfg(target_os = "ios")]
1571 { defaults::ios_light() }
1572 #[cfg(not(any(
1573 target_os = "linux",
1574 target_os = "windows",
1575 target_os = "macos",
1576 target_os = "android",
1577 target_os = "ios"
1578 )))]
1579 { Self::default() }
1580 }
1581
1582 #[inline]
1584 #[must_use] pub fn new() -> Self {
1585 Self::detect()
1586 }
1587
1588 #[must_use] pub fn create_csd_stylesheet(&self) -> Css {
1594 use alloc::format;
1595
1596 use crate::parser2::new_from_str;
1597
1598 let mut css = String::new();
1600
1601 let bg_color = self
1603 .colors
1604 .window_background
1605 .as_option()
1606 .copied()
1607 .unwrap_or(ColorU::new_rgb(240, 240, 240));
1608 let text_color = self
1609 .colors
1610 .text
1611 .as_option()
1612 .copied()
1613 .unwrap_or(ColorU::new_rgb(0, 0, 0));
1614 let accent_color = self
1615 .colors
1616 .accent
1617 .as_option()
1618 .copied()
1619 .unwrap_or(ColorU::new_rgb(0, 120, 215));
1620 let border_color = match self.theme {
1621 Theme::Dark => ColorU::new_rgb(60, 60, 60),
1622 Theme::Light => ColorU::new_rgb(200, 200, 200),
1623 };
1624
1625 let corner_radius = self
1627 .metrics
1628 .corner_radius
1629 .map(|px| {
1630 use crate::props::basic::pixel::DEFAULT_FONT_SIZE;
1631 format!("{}px", px.to_pixels_internal(1.0, DEFAULT_FONT_SIZE, DEFAULT_FONT_SIZE))
1632 })
1633 .unwrap_or_else(|| "4px".to_string());
1634
1635 let _ = write!(css,
1637 ".csd-titlebar {{ width: 100%; height: 32px; background: rgb({}, {}, {}); \
1638 border-bottom: 1px solid rgb({}, {}, {}); display: flex; flex-direction: row; \
1639 align-items: center; justify-content: space-between; padding: 0 8px; \
1640 cursor: grab; user-select: none; }} ",
1641 bg_color.r, bg_color.g, bg_color.b, border_color.r, border_color.g, border_color.b,
1642 );
1643
1644 let _ = write!(css,
1646 ".csd-title {{ color: rgb({}, {}, {}); font-size: 13px; flex-grow: 1; text-align: \
1647 center; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; \
1648 user-select: none; }} ",
1649 text_color.r, text_color.g, text_color.b,
1650 );
1651
1652 css.push_str(".csd-buttons { display: flex; flex-direction: row; gap: 4px; } ");
1654
1655 let _ = write!(css,
1657 ".csd-button {{ width: 32px; height: 24px; border-radius: {}; background: \
1658 transparent; color: rgb({}, {}, {}); font-size: 16px; line-height: 24px; text-align: \
1659 center; cursor: pointer; user-select: none; }} ",
1660 corner_radius, text_color.r, text_color.g, text_color.b,
1661 );
1662
1663 let hover_color = match self.theme {
1665 Theme::Dark => ColorU::new_rgb(60, 60, 60),
1666 Theme::Light => ColorU::new_rgb(220, 220, 220),
1667 };
1668 let _ = write!(css,
1669 ".csd-button:hover {{ background: rgb({}, {}, {}); }} ",
1670 hover_color.r, hover_color.g, hover_color.b,
1671 );
1672
1673 css.push_str(
1675 ".csd-close:hover { background: rgb(232, 17, 35); color: rgb(255, 255, 255); } ",
1676 );
1677
1678 match self.platform {
1680 Platform::MacOs => {
1681 css.push_str(".csd-buttons { position: absolute; left: 8px; } ");
1683 css.push_str(
1684 ".csd-close { background: rgb(255, 95, 86); width: 12px; height: 12px; \
1685 border-radius: 50%; } ",
1686 );
1687 css.push_str(
1688 ".csd-minimize { background: rgb(255, 189, 46); width: 12px; height: 12px; \
1689 border-radius: 50%; } ",
1690 );
1691 css.push_str(
1692 ".csd-maximize { background: rgb(40, 201, 64); width: 12px; height: 12px; \
1693 border-radius: 50%; } ",
1694 );
1695 }
1696 Platform::Linux(_) => {
1697 css.push_str(".csd-title { text-align: left; } ");
1699 }
1700 _ => {
1701 }
1703 }
1704
1705 let (mut parsed_css, _warnings) = new_from_str(&css);
1707 for rule in parsed_css.rules.as_mut() {
1709 rule.priority = crate::css::rule_priority::SYSTEM;
1710 }
1711 parsed_css
1712 }
1713}
1714
1715#[must_use] pub fn detect_linux_desktop_env() -> DesktopEnvironment {
1720 if let Ok(desktop) = std::env::var("XDG_CURRENT_DESKTOP") {
1722 let desktop_lower = desktop.to_lowercase();
1723 if desktop_lower.contains("gnome") {
1724 return DesktopEnvironment::Gnome;
1725 }
1726 if desktop_lower.contains("kde") || desktop_lower.contains("plasma") {
1727 return DesktopEnvironment::Kde;
1728 }
1729 if desktop_lower.contains("xfce") {
1730 return DesktopEnvironment::Other(AzString::from_const_str("XFCE"));
1731 }
1732 if desktop_lower.contains("unity") {
1733 return DesktopEnvironment::Other(AzString::from_const_str("Unity"));
1734 }
1735 if desktop_lower.contains("cinnamon") {
1736 return DesktopEnvironment::Other(AzString::from_const_str("Cinnamon"));
1737 }
1738 if desktop_lower.contains("mate") {
1739 return DesktopEnvironment::Other(AzString::from_const_str("MATE"));
1740 }
1741 if desktop_lower.contains("lxde") || desktop_lower.contains("lxqt") {
1742 return DesktopEnvironment::Other(AzString::from(desktop.to_uppercase()));
1743 }
1744 if desktop_lower.contains("budgie") {
1745 return DesktopEnvironment::Other(AzString::from_const_str("Budgie"));
1746 }
1747 if desktop_lower.contains("pantheon") {
1748 return DesktopEnvironment::Other(AzString::from_const_str("Pantheon"));
1749 }
1750 if desktop_lower.contains("deepin") {
1751 return DesktopEnvironment::Other(AzString::from_const_str("Deepin"));
1752 }
1753 if desktop_lower.contains("hyprland") {
1754 return DesktopEnvironment::Other(AzString::from_const_str("Hyprland"));
1755 }
1756 if desktop_lower.contains("sway") {
1757 return DesktopEnvironment::Other(AzString::from_const_str("Sway"));
1758 }
1759 if desktop_lower.contains("i3") {
1760 return DesktopEnvironment::Other(AzString::from_const_str("i3"));
1761 }
1762 return DesktopEnvironment::Other(AzString::from(desktop));
1763 }
1764
1765 if let Ok(session) = std::env::var("DESKTOP_SESSION") {
1767 let session_lower = session.to_lowercase();
1768 if session_lower.contains("gnome") {
1769 return DesktopEnvironment::Gnome;
1770 }
1771 if session_lower.contains("plasma") || session_lower.contains("kde") {
1772 return DesktopEnvironment::Kde;
1773 }
1774 if session_lower.contains("xfce") {
1775 return DesktopEnvironment::Other(AzString::from_const_str("XFCE"));
1776 }
1777 if session_lower.contains("cinnamon") {
1778 return DesktopEnvironment::Other(AzString::from_const_str("Cinnamon"));
1779 }
1780 return DesktopEnvironment::Other(AzString::from(session));
1781 }
1782
1783 if std::env::var("GNOME_DESKTOP_SESSION_ID").is_ok() {
1785 return DesktopEnvironment::Gnome;
1786 }
1787 if std::env::var("KDE_FULL_SESSION").is_ok() {
1788 return DesktopEnvironment::Kde;
1789 }
1790 if std::env::var("HYPRLAND_INSTANCE_SIGNATURE").is_ok() {
1791 return DesktopEnvironment::Other(AzString::from_const_str("Hyprland"));
1792 }
1793 if std::env::var("SWAYSOCK").is_ok() {
1794 return DesktopEnvironment::Other(AzString::from_const_str("Sway"));
1795 }
1796 if std::env::var("I3SOCK").is_ok() {
1797 return DesktopEnvironment::Other(AzString::from_const_str("i3"));
1798 }
1799
1800 DesktopEnvironment::Other(AzString::from_const_str("Unknown"))
1801}
1802
1803#[must_use] pub fn detect_system_language() -> AzString {
1809 let env_vars = ["LANGUAGE", "LC_ALL", "LC_MESSAGES", "LANG"];
1810 for var in &env_vars {
1811 if let Ok(value) = std::env::var(var) {
1812 let value = value.trim();
1813 if value.is_empty() || value == "C" || value == "POSIX" {
1814 continue;
1815 }
1816 let lang = value
1818 .split('.') .next()
1820 .unwrap_or(value)
1821 .split(':') .next()
1823 .unwrap_or(value);
1824 if !lang.is_empty() {
1825 return AzString::from(lang.replace('_', "-"));
1826 }
1827 }
1828 }
1829 AzString::from_const_str("en-US")
1830}
1831
1832pub mod defaults {
1833 use super::{
1841 AccessibilitySettings, AnimationMetrics, AudioMetrics, FocusVisuals, InputMetrics,
1842 LinuxCustomization, ScrollbarPreferences, TextRenderingHints, VisualHints,
1843 };
1844 use crate::{
1845 corety::{AzString, OptionF32, OptionString},
1846 dynamic_selector::{BoolCondition, OsVersion},
1847 props::{
1848 basic::{
1849 color::{ColorU, OptionColorU},
1850 pixel::{PixelValue, OptionPixelValue},
1851 },
1852 layout::{
1853 dimensions::LayoutWidth,
1854 spacing::{LayoutPaddingLeft, LayoutPaddingRight},
1855 },
1856 style::{
1857 background::StyleBackgroundContent,
1858 scrollbar::{
1859 ComputedScrollbarStyle, OverflowScrolling, OverscrollBehavior, ScrollBehavior,
1860 ScrollPhysics, ScrollbarInfo,
1861 SCROLLBAR_ANDROID_DARK, SCROLLBAR_ANDROID_LIGHT, SCROLLBAR_CLASSIC_DARK,
1862 SCROLLBAR_CLASSIC_LIGHT, SCROLLBAR_IOS_DARK, SCROLLBAR_IOS_LIGHT,
1863 SCROLLBAR_MACOS_DARK, SCROLLBAR_MACOS_LIGHT, SCROLLBAR_WINDOWS_DARK,
1864 SCROLLBAR_WINDOWS_LIGHT,
1865 },
1866 },
1867 },
1868 system::{
1869 DesktopEnvironment, Platform, SystemColors, SystemFonts, SystemMetrics, SystemStyle,
1870 Theme, IconStyleOptions, TitlebarMetrics,
1871 },
1872 };
1873
1874 pub const SCROLLBAR_WINDOWS_CLASSIC: ScrollbarInfo = ScrollbarInfo {
1878 width: LayoutWidth::Px(PixelValue::const_px(17)),
1879 padding_left: LayoutPaddingLeft {
1880 inner: PixelValue::const_px(0),
1881 },
1882 padding_right: LayoutPaddingRight {
1883 inner: PixelValue::const_px(0),
1884 },
1885 track: StyleBackgroundContent::Color(ColorU {
1886 r: 223,
1887 g: 223,
1888 b: 223,
1889 a: 255,
1890 }), thumb: StyleBackgroundContent::Color(ColorU {
1892 r: 208,
1893 g: 208,
1894 b: 208,
1895 a: 255,
1896 }), button: StyleBackgroundContent::Color(ColorU {
1898 r: 208,
1899 g: 208,
1900 b: 208,
1901 a: 255,
1902 }),
1903 corner: StyleBackgroundContent::Color(ColorU {
1904 r: 223,
1905 g: 223,
1906 b: 223,
1907 a: 255,
1908 }),
1909 resizer: StyleBackgroundContent::Color(ColorU::TRANSPARENT),
1910 clip_to_container_border: false,
1911 scroll_behavior: ScrollBehavior::Auto,
1912 overscroll_behavior_x: OverscrollBehavior::None,
1913 overscroll_behavior_y: OverscrollBehavior::None,
1914 overflow_scrolling: OverflowScrolling::Auto,
1915 };
1916
1917 pub const SCROLLBAR_MACOS_AQUA: ScrollbarInfo = ScrollbarInfo {
1919 width: LayoutWidth::Px(PixelValue::const_px(15)),
1920 padding_left: LayoutPaddingLeft {
1921 inner: PixelValue::const_px(0),
1922 },
1923 padding_right: LayoutPaddingRight {
1924 inner: PixelValue::const_px(0),
1925 },
1926 track: StyleBackgroundContent::Color(ColorU {
1927 r: 238,
1928 g: 238,
1929 b: 238,
1930 a: 128,
1931 }), thumb: StyleBackgroundContent::Color(ColorU {
1933 r: 105,
1934 g: 173,
1935 b: 255,
1936 a: 255,
1937 }), button: StyleBackgroundContent::Color(ColorU {
1939 r: 105,
1940 g: 173,
1941 b: 255,
1942 a: 255,
1943 }),
1944 corner: StyleBackgroundContent::Color(ColorU::TRANSPARENT),
1945 resizer: StyleBackgroundContent::Color(ColorU::TRANSPARENT),
1946 clip_to_container_border: true,
1947 scroll_behavior: ScrollBehavior::Smooth,
1948 overscroll_behavior_x: OverscrollBehavior::Auto,
1949 overscroll_behavior_y: OverscrollBehavior::Auto,
1950 overflow_scrolling: OverflowScrolling::Auto,
1951 };
1952
1953 pub const SCROLLBAR_KDE_OXYGEN: ScrollbarInfo = ScrollbarInfo {
1955 width: LayoutWidth::Px(PixelValue::const_px(14)),
1956 padding_left: LayoutPaddingLeft {
1957 inner: PixelValue::const_px(2),
1958 },
1959 padding_right: LayoutPaddingRight {
1960 inner: PixelValue::const_px(2),
1961 },
1962 track: StyleBackgroundContent::Color(ColorU {
1963 r: 242,
1964 g: 242,
1965 b: 242,
1966 a: 255,
1967 }),
1968 thumb: StyleBackgroundContent::Color(ColorU {
1969 r: 177,
1970 g: 177,
1971 b: 177,
1972 a: 255,
1973 }),
1974 button: StyleBackgroundContent::Color(ColorU {
1975 r: 216,
1976 g: 216,
1977 b: 216,
1978 a: 255,
1979 }),
1980 corner: StyleBackgroundContent::Color(ColorU::TRANSPARENT),
1981 resizer: StyleBackgroundContent::Color(ColorU::TRANSPARENT),
1982 clip_to_container_border: false,
1983 scroll_behavior: ScrollBehavior::Auto,
1984 overscroll_behavior_x: OverscrollBehavior::Auto,
1985 overscroll_behavior_y: OverscrollBehavior::Auto,
1986 overflow_scrolling: OverflowScrolling::Auto,
1987 };
1988
1989 fn scrollbar_info_to_computed(info: &ScrollbarInfo) -> ComputedScrollbarStyle {
1991 ComputedScrollbarStyle {
1992 width: Some(info.width.clone()),
1993 thumb_color: match info.thumb {
1994 StyleBackgroundContent::Color(c) => Some(c),
1995 _ => None,
1996 },
1997 track_color: match info.track {
1998 StyleBackgroundContent::Color(c) => Some(c),
1999 _ => None,
2000 },
2001 }
2002 }
2003
2004 #[must_use] pub fn windows_11_light() -> SystemStyle {
2008 SystemStyle {
2009 theme: Theme::Light,
2010 platform: Platform::Windows,
2011 colors: SystemColors {
2012 text: OptionColorU::Some(ColorU::new_rgb(0, 0, 0)),
2013 background: OptionColorU::Some(ColorU::new_rgb(243, 243, 243)),
2014 accent: OptionColorU::Some(ColorU::new_rgb(0, 95, 184)),
2015 window_background: OptionColorU::Some(ColorU::new_rgb(255, 255, 255)),
2016 selection_background: OptionColorU::Some(ColorU::new_rgb(0, 120, 215)),
2017 selection_text: OptionColorU::Some(ColorU::new_rgb(255, 255, 255)),
2018 ..Default::default()
2019 },
2020 fonts: SystemFonts {
2021 ui_font: OptionString::Some("Segoe UI Variable Text".into()),
2022 ui_font_size: OptionF32::Some(9.0),
2023 monospace_font: OptionString::Some("Consolas".into()),
2024 ..Default::default()
2025 },
2026 metrics: SystemMetrics {
2027 corner_radius: OptionPixelValue::Some(PixelValue::px(4.0)),
2028 border_width: OptionPixelValue::Some(PixelValue::px(1.0)),
2029 button_padding_horizontal: OptionPixelValue::Some(PixelValue::px(12.0)),
2030 button_padding_vertical: OptionPixelValue::Some(PixelValue::px(6.0)),
2031 titlebar: TitlebarMetrics::windows(),
2032 },
2033 scrollbar: Some(Box::new(scrollbar_info_to_computed(&SCROLLBAR_WINDOWS_LIGHT))),
2034 app_specific_stylesheet: None,
2035 run_destructor: true,
2036 icon_style: IconStyleOptions::default(),
2037 language: AzString::from_const_str("en-US"),
2038 os_version: OsVersion::WIN_11,
2039 prefers_reduced_motion: BoolCondition::False,
2040 prefers_high_contrast: BoolCondition::False,
2041 scroll_physics: ScrollPhysics::windows(),
2042 linux: LinuxCustomization::default(),
2043 focus_visuals: FocusVisuals::default(),
2044 accessibility: AccessibilitySettings::default(),
2045 input: InputMetrics::default(),
2046 text_rendering: TextRenderingHints::default(),
2047 scrollbar_preferences: ScrollbarPreferences::default(),
2048 visual_hints: VisualHints::default(),
2049 animation: AnimationMetrics::default(),
2050 audio: AudioMetrics::default(),
2051 }
2052 }
2053
2054 #[must_use] pub fn windows_11_dark() -> SystemStyle {
2056 SystemStyle {
2057 theme: Theme::Dark,
2058 platform: Platform::Windows,
2059 colors: SystemColors {
2060 text: OptionColorU::Some(ColorU::new_rgb(255, 255, 255)),
2061 background: OptionColorU::Some(ColorU::new_rgb(32, 32, 32)),
2062 accent: OptionColorU::Some(ColorU::new_rgb(0, 120, 215)),
2063 window_background: OptionColorU::Some(ColorU::new_rgb(25, 25, 25)),
2064 selection_background: OptionColorU::Some(ColorU::new_rgb(0, 120, 215)),
2065 selection_text: OptionColorU::Some(ColorU::new_rgb(255, 255, 255)),
2066 ..Default::default()
2067 },
2068 fonts: SystemFonts {
2069 ui_font: OptionString::Some("Segoe UI Variable Text".into()),
2070 ui_font_size: OptionF32::Some(9.0),
2071 monospace_font: OptionString::Some("Consolas".into()),
2072 ..Default::default()
2073 },
2074 metrics: SystemMetrics {
2075 corner_radius: OptionPixelValue::Some(PixelValue::px(4.0)),
2076 border_width: OptionPixelValue::Some(PixelValue::px(1.0)),
2077 button_padding_horizontal: OptionPixelValue::Some(PixelValue::px(12.0)),
2078 button_padding_vertical: OptionPixelValue::Some(PixelValue::px(6.0)),
2079 titlebar: TitlebarMetrics::windows(),
2080 },
2081 scrollbar: Some(Box::new(scrollbar_info_to_computed(&SCROLLBAR_WINDOWS_DARK))),
2082 app_specific_stylesheet: None,
2083 run_destructor: true,
2084 icon_style: IconStyleOptions::default(),
2085 language: AzString::from_const_str("en-US"),
2086 os_version: OsVersion::WIN_11,
2087 prefers_reduced_motion: BoolCondition::False,
2088 prefers_high_contrast: BoolCondition::False,
2089 scroll_physics: ScrollPhysics::windows(),
2090 linux: LinuxCustomization::default(),
2091 focus_visuals: FocusVisuals::default(),
2092 accessibility: AccessibilitySettings::default(),
2093 input: InputMetrics::default(),
2094 text_rendering: TextRenderingHints::default(),
2095 scrollbar_preferences: ScrollbarPreferences::default(),
2096 visual_hints: VisualHints::default(),
2097 animation: AnimationMetrics::default(),
2098 audio: AudioMetrics::default(),
2099 }
2100 }
2101
2102 #[must_use] pub fn windows_7_aero() -> SystemStyle {
2104 SystemStyle {
2105 theme: Theme::Light,
2106 platform: Platform::Windows,
2107 colors: SystemColors {
2108 text: OptionColorU::Some(ColorU::new_rgb(0, 0, 0)),
2109 background: OptionColorU::Some(ColorU::new_rgb(240, 240, 240)),
2110 accent: OptionColorU::Some(ColorU::new_rgb(51, 153, 255)),
2111 window_background: OptionColorU::Some(ColorU::new_rgb(255, 255, 255)),
2112 selection_background: OptionColorU::Some(ColorU::new_rgb(51, 153, 255)),
2113 selection_text: OptionColorU::Some(ColorU::new_rgb(255, 255, 255)),
2114 ..Default::default()
2115 },
2116 fonts: SystemFonts {
2117 ui_font: OptionString::Some("Segoe UI".into()),
2118 ui_font_size: OptionF32::Some(9.0),
2119 monospace_font: OptionString::Some("Consolas".into()),
2120 ..Default::default()
2121 },
2122 metrics: SystemMetrics {
2123 corner_radius: OptionPixelValue::Some(PixelValue::px(6.0)),
2124 border_width: OptionPixelValue::Some(PixelValue::px(1.0)),
2125 button_padding_horizontal: OptionPixelValue::Some(PixelValue::px(10.0)),
2126 button_padding_vertical: OptionPixelValue::Some(PixelValue::px(5.0)),
2127 titlebar: TitlebarMetrics::windows(),
2128 },
2129 scrollbar: Some(Box::new(scrollbar_info_to_computed(&SCROLLBAR_CLASSIC_LIGHT))),
2130 app_specific_stylesheet: None,
2131 run_destructor: true,
2132 icon_style: IconStyleOptions::default(),
2133 language: AzString::from_const_str("en-US"),
2134 os_version: OsVersion::WIN_7,
2135 prefers_reduced_motion: BoolCondition::False,
2136 prefers_high_contrast: BoolCondition::False,
2137 scroll_physics: ScrollPhysics::windows(),
2138 linux: LinuxCustomization::default(),
2139 focus_visuals: FocusVisuals::default(),
2140 accessibility: AccessibilitySettings::default(),
2141 input: InputMetrics::default(),
2142 text_rendering: TextRenderingHints::default(),
2143 scrollbar_preferences: ScrollbarPreferences::default(),
2144 visual_hints: VisualHints::default(),
2145 animation: AnimationMetrics::default(),
2146 audio: AudioMetrics::default(),
2147 }
2148 }
2149
2150 #[must_use] pub fn windows_xp_luna() -> SystemStyle {
2152 SystemStyle {
2153 theme: Theme::Light,
2154 platform: Platform::Windows,
2155 colors: SystemColors {
2156 text: OptionColorU::Some(ColorU::new_rgb(0, 0, 0)),
2157 background: OptionColorU::Some(ColorU::new_rgb(236, 233, 216)),
2158 accent: OptionColorU::Some(ColorU::new_rgb(49, 106, 197)),
2159 window_background: OptionColorU::Some(ColorU::new_rgb(255, 255, 255)),
2160 selection_background: OptionColorU::Some(ColorU::new_rgb(49, 106, 197)),
2161 selection_text: OptionColorU::Some(ColorU::new_rgb(255, 255, 255)),
2162 ..Default::default()
2163 },
2164 fonts: SystemFonts {
2165 ui_font: OptionString::Some("Tahoma".into()),
2166 ui_font_size: OptionF32::Some(8.0),
2167 monospace_font: OptionString::Some("Lucida Console".into()),
2168 ..Default::default()
2169 },
2170 metrics: SystemMetrics {
2171 corner_radius: OptionPixelValue::Some(PixelValue::px(3.0)),
2172 border_width: OptionPixelValue::Some(PixelValue::px(1.0)),
2173 button_padding_horizontal: OptionPixelValue::Some(PixelValue::px(8.0)),
2174 button_padding_vertical: OptionPixelValue::Some(PixelValue::px(4.0)),
2175 titlebar: TitlebarMetrics::windows(),
2176 },
2177 scrollbar: Some(Box::new(scrollbar_info_to_computed(&SCROLLBAR_WINDOWS_CLASSIC))),
2178 app_specific_stylesheet: None,
2179 run_destructor: true,
2180 icon_style: IconStyleOptions::default(),
2181 language: AzString::from_const_str("en-US"),
2182 os_version: OsVersion::WIN_XP,
2183 prefers_reduced_motion: BoolCondition::False,
2184 prefers_high_contrast: BoolCondition::False,
2185 scroll_physics: ScrollPhysics::windows(),
2186 linux: LinuxCustomization::default(),
2187 focus_visuals: FocusVisuals::default(),
2188 accessibility: AccessibilitySettings::default(),
2189 input: InputMetrics::default(),
2190 text_rendering: TextRenderingHints::default(),
2191 scrollbar_preferences: ScrollbarPreferences::default(),
2192 visual_hints: VisualHints::default(),
2193 animation: AnimationMetrics::default(),
2194 audio: AudioMetrics::default(),
2195 }
2196 }
2197
2198 #[must_use] pub fn macos_modern_light() -> SystemStyle {
2202 SystemStyle {
2203 platform: Platform::MacOs,
2204 theme: Theme::Light,
2205 colors: SystemColors {
2206 text: OptionColorU::Some(ColorU::new(0, 0, 0, 221)),
2207 background: OptionColorU::Some(ColorU::new_rgb(242, 242, 247)),
2208 accent: OptionColorU::Some(ColorU::new_rgb(0, 122, 255)),
2209 window_background: OptionColorU::Some(ColorU::new_rgb(255, 255, 255)),
2210 selection_background: OptionColorU::Some(ColorU::new(0, 122, 255, 128)),
2212 selection_text: OptionColorU::Some(ColorU::new_rgb(0, 0, 0)),
2213 ..Default::default()
2214 },
2215 fonts: SystemFonts {
2216 ui_font: OptionString::Some(".SF NS".into()),
2217 ui_font_size: OptionF32::Some(13.0),
2218 monospace_font: OptionString::Some("Menlo".into()),
2219 ..Default::default()
2220 },
2221 metrics: SystemMetrics {
2222 corner_radius: OptionPixelValue::Some(PixelValue::px(8.0)),
2223 border_width: OptionPixelValue::Some(PixelValue::px(1.0)),
2224 button_padding_horizontal: OptionPixelValue::Some(PixelValue::px(16.0)),
2225 button_padding_vertical: OptionPixelValue::Some(PixelValue::px(6.0)),
2226 titlebar: TitlebarMetrics::macos(),
2227 },
2228 scrollbar: Some(Box::new(scrollbar_info_to_computed(&SCROLLBAR_MACOS_LIGHT))),
2229 app_specific_stylesheet: None,
2230 run_destructor: true,
2231 icon_style: IconStyleOptions::default(),
2232 language: AzString::from_const_str("en-US"),
2233 os_version: OsVersion::MACOS_SONOMA,
2234 prefers_reduced_motion: BoolCondition::False,
2235 prefers_high_contrast: BoolCondition::False,
2236 scroll_physics: ScrollPhysics::macos(),
2237 linux: LinuxCustomization::default(),
2238 focus_visuals: FocusVisuals::default(),
2239 accessibility: AccessibilitySettings::default(),
2240 input: InputMetrics::default(),
2241 text_rendering: TextRenderingHints::default(),
2242 scrollbar_preferences: ScrollbarPreferences::default(),
2243 visual_hints: VisualHints::default(),
2244 animation: AnimationMetrics::default(),
2245 audio: AudioMetrics::default(),
2246 }
2247 }
2248
2249 #[must_use] pub fn macos_modern_dark() -> SystemStyle {
2251 SystemStyle {
2252 platform: Platform::MacOs,
2253 theme: Theme::Dark,
2254 colors: SystemColors {
2255 text: OptionColorU::Some(ColorU::new(255, 255, 255, 221)),
2256 background: OptionColorU::Some(ColorU::new_rgb(28, 28, 30)),
2257 accent: OptionColorU::Some(ColorU::new_rgb(10, 132, 255)),
2258 window_background: OptionColorU::Some(ColorU::new_rgb(44, 44, 46)),
2259 selection_background: OptionColorU::Some(ColorU::new(10, 132, 255, 128)),
2261 selection_text: OptionColorU::Some(ColorU::new_rgb(255, 255, 255)),
2262 ..Default::default()
2263 },
2264 fonts: SystemFonts {
2265 ui_font: OptionString::Some(".SF NS".into()),
2266 ui_font_size: OptionF32::Some(13.0),
2267 monospace_font: OptionString::Some("SF Mono".into()),
2268 monospace_font_size: OptionF32::Some(12.0),
2269 title_font: OptionString::Some(".SF NS".into()),
2270 title_font_size: OptionF32::Some(13.0),
2271 menu_font: OptionString::Some(".SF NS".into()),
2272 menu_font_size: OptionF32::Some(13.0),
2273 small_font: OptionString::Some(".SF NS".into()),
2274 small_font_size: OptionF32::Some(11.0),
2275 ..Default::default()
2276 },
2277 metrics: SystemMetrics {
2278 corner_radius: OptionPixelValue::Some(PixelValue::px(8.0)),
2279 border_width: OptionPixelValue::Some(PixelValue::px(1.0)),
2280 button_padding_horizontal: OptionPixelValue::Some(PixelValue::px(16.0)),
2281 button_padding_vertical: OptionPixelValue::Some(PixelValue::px(6.0)),
2282 titlebar: TitlebarMetrics::macos(),
2283 },
2284 scrollbar: Some(Box::new(scrollbar_info_to_computed(&SCROLLBAR_MACOS_DARK))),
2285 app_specific_stylesheet: None,
2286 run_destructor: true,
2287 icon_style: IconStyleOptions::default(),
2288 language: AzString::from_const_str("en-US"),
2289 os_version: OsVersion::MACOS_SONOMA,
2290 prefers_reduced_motion: BoolCondition::False,
2291 prefers_high_contrast: BoolCondition::False,
2292 scroll_physics: ScrollPhysics::macos(),
2293 linux: LinuxCustomization::default(),
2294 focus_visuals: FocusVisuals::default(),
2295 accessibility: AccessibilitySettings::default(),
2296 input: InputMetrics::default(),
2297 text_rendering: TextRenderingHints::default(),
2298 scrollbar_preferences: ScrollbarPreferences::default(),
2299 visual_hints: VisualHints::default(),
2300 animation: AnimationMetrics::default(),
2301 audio: AudioMetrics::default(),
2302 }
2303 }
2304
2305 #[must_use] pub fn macos_aqua() -> SystemStyle {
2307 SystemStyle {
2308 platform: Platform::MacOs,
2309 theme: Theme::Light,
2310 colors: SystemColors {
2311 text: OptionColorU::Some(ColorU::new_rgb(0, 0, 0)),
2312 background: OptionColorU::Some(ColorU::new_rgb(229, 229, 229)),
2313 accent: OptionColorU::Some(ColorU::new_rgb(63, 128, 234)),
2314 window_background: OptionColorU::Some(ColorU::new_rgb(255, 255, 255)),
2315 ..Default::default()
2316 },
2317 fonts: SystemFonts {
2318 ui_font: OptionString::Some("Lucida Grande".into()),
2319 ui_font_size: OptionF32::Some(13.0),
2320 monospace_font: OptionString::Some("Monaco".into()),
2321 monospace_font_size: OptionF32::Some(12.0),
2322 ..Default::default()
2323 },
2324 metrics: SystemMetrics {
2325 corner_radius: OptionPixelValue::Some(PixelValue::px(12.0)),
2326 border_width: OptionPixelValue::Some(PixelValue::px(1.0)),
2327 button_padding_horizontal: OptionPixelValue::Some(PixelValue::px(16.0)),
2328 button_padding_vertical: OptionPixelValue::Some(PixelValue::px(6.0)),
2329 titlebar: TitlebarMetrics::macos(),
2330 },
2331 scrollbar: Some(Box::new(scrollbar_info_to_computed(&SCROLLBAR_MACOS_AQUA))),
2332 app_specific_stylesheet: None,
2333 run_destructor: true,
2334 icon_style: IconStyleOptions::default(),
2335 language: AzString::from_const_str("en-US"),
2336 os_version: OsVersion::MACOS_TIGER,
2337 prefers_reduced_motion: BoolCondition::False,
2338 prefers_high_contrast: BoolCondition::False,
2339 scroll_physics: ScrollPhysics::macos(),
2340 linux: LinuxCustomization::default(),
2341 focus_visuals: FocusVisuals::default(),
2342 accessibility: AccessibilitySettings::default(),
2343 input: InputMetrics::default(),
2344 text_rendering: TextRenderingHints::default(),
2345 scrollbar_preferences: ScrollbarPreferences::default(),
2346 visual_hints: VisualHints::default(),
2347 animation: AnimationMetrics::default(),
2348 audio: AudioMetrics::default(),
2349 }
2350 }
2351
2352 #[must_use] pub fn gnome_adwaita_light() -> SystemStyle {
2356 SystemStyle {
2357 platform: Platform::Linux(DesktopEnvironment::Gnome),
2358 theme: Theme::Light,
2359 colors: SystemColors {
2360 text: OptionColorU::Some(ColorU::new_rgb(46, 52, 54)),
2361 background: OptionColorU::Some(ColorU::new_rgb(249, 249, 249)),
2362 accent: OptionColorU::Some(ColorU::new_rgb(53, 132, 228)),
2363 window_background: OptionColorU::Some(ColorU::new_rgb(237, 237, 237)),
2364 ..Default::default()
2365 },
2366 fonts: SystemFonts {
2367 ui_font: OptionString::Some("Cantarell".into()),
2368 ui_font_size: OptionF32::Some(11.0),
2369 monospace_font: OptionString::Some("Monospace".into()),
2370 ..Default::default()
2371 },
2372 metrics: SystemMetrics {
2373 corner_radius: OptionPixelValue::Some(PixelValue::px(4.0)),
2374 border_width: OptionPixelValue::Some(PixelValue::px(1.0)),
2375 button_padding_horizontal: OptionPixelValue::Some(PixelValue::px(12.0)),
2376 button_padding_vertical: OptionPixelValue::Some(PixelValue::px(8.0)),
2377 titlebar: TitlebarMetrics::linux_gnome(),
2378 },
2379 scrollbar: Some(Box::new(scrollbar_info_to_computed(&SCROLLBAR_CLASSIC_LIGHT))),
2380 app_specific_stylesheet: None,
2381 run_destructor: true,
2382 icon_style: IconStyleOptions::default(),
2383 language: AzString::from_const_str("en-US"),
2384 os_version: OsVersion::LINUX_6_0,
2385 prefers_reduced_motion: BoolCondition::False,
2386 prefers_high_contrast: BoolCondition::False,
2387 scroll_physics: ScrollPhysics::default(),
2388 linux: LinuxCustomization::default(),
2389 focus_visuals: FocusVisuals::default(),
2390 accessibility: AccessibilitySettings::default(),
2391 input: InputMetrics::default(),
2392 text_rendering: TextRenderingHints::default(),
2393 scrollbar_preferences: ScrollbarPreferences::default(),
2394 visual_hints: VisualHints::default(),
2395 animation: AnimationMetrics::default(),
2396 audio: AudioMetrics::default(),
2397 }
2398 }
2399
2400 #[must_use] pub fn gnome_adwaita_dark() -> SystemStyle {
2402 SystemStyle {
2403 platform: Platform::Linux(DesktopEnvironment::Gnome),
2404 theme: Theme::Dark,
2405 colors: SystemColors {
2406 text: OptionColorU::Some(ColorU::new_rgb(238, 238, 236)),
2407 background: OptionColorU::Some(ColorU::new_rgb(36, 36, 36)),
2408 accent: OptionColorU::Some(ColorU::new_rgb(53, 132, 228)),
2409 window_background: OptionColorU::Some(ColorU::new_rgb(48, 48, 48)),
2410 ..Default::default()
2411 },
2412 fonts: SystemFonts {
2413 ui_font: OptionString::Some("Cantarell".into()),
2414 ui_font_size: OptionF32::Some(11.0),
2415 monospace_font: OptionString::Some("Monospace".into()),
2416 ..Default::default()
2417 },
2418 metrics: SystemMetrics {
2419 corner_radius: OptionPixelValue::Some(PixelValue::px(4.0)),
2420 border_width: OptionPixelValue::Some(PixelValue::px(1.0)),
2421 button_padding_horizontal: OptionPixelValue::Some(PixelValue::px(12.0)),
2422 button_padding_vertical: OptionPixelValue::Some(PixelValue::px(8.0)),
2423 titlebar: TitlebarMetrics::linux_gnome(),
2424 },
2425 scrollbar: Some(Box::new(scrollbar_info_to_computed(&SCROLLBAR_CLASSIC_DARK))),
2426 app_specific_stylesheet: None,
2427 run_destructor: true,
2428 icon_style: IconStyleOptions::default(),
2429 language: AzString::from_const_str("en-US"),
2430 os_version: OsVersion::LINUX_6_0,
2431 prefers_reduced_motion: BoolCondition::False,
2432 prefers_high_contrast: BoolCondition::False,
2433 scroll_physics: ScrollPhysics::default(),
2434 linux: LinuxCustomization::default(),
2435 focus_visuals: FocusVisuals::default(),
2436 accessibility: AccessibilitySettings::default(),
2437 input: InputMetrics::default(),
2438 text_rendering: TextRenderingHints::default(),
2439 scrollbar_preferences: ScrollbarPreferences::default(),
2440 visual_hints: VisualHints::default(),
2441 animation: AnimationMetrics::default(),
2442 audio: AudioMetrics::default(),
2443 }
2444 }
2445
2446 #[must_use] pub fn gtk2_clearlooks() -> SystemStyle {
2448 SystemStyle {
2449 platform: Platform::Linux(DesktopEnvironment::Gnome),
2450 theme: Theme::Light,
2451 colors: SystemColors {
2452 text: OptionColorU::Some(ColorU::new_rgb(0, 0, 0)),
2453 background: OptionColorU::Some(ColorU::new_rgb(239, 239, 239)),
2454 accent: OptionColorU::Some(ColorU::new_rgb(245, 121, 0)),
2455 ..Default::default()
2456 },
2457 fonts: SystemFonts {
2458 ui_font: OptionString::Some("DejaVu Sans".into()),
2459 ui_font_size: OptionF32::Some(10.0),
2460 monospace_font: OptionString::Some("DejaVu Sans Mono".into()),
2461 ..Default::default()
2462 },
2463 metrics: SystemMetrics {
2464 corner_radius: OptionPixelValue::Some(PixelValue::px(4.0)),
2465 border_width: OptionPixelValue::Some(PixelValue::px(1.0)),
2466 button_padding_horizontal: OptionPixelValue::Some(PixelValue::px(10.0)),
2467 button_padding_vertical: OptionPixelValue::Some(PixelValue::px(6.0)),
2468 titlebar: TitlebarMetrics::linux_gnome(),
2469 },
2470 scrollbar: Some(Box::new(scrollbar_info_to_computed(&SCROLLBAR_CLASSIC_LIGHT))),
2471 app_specific_stylesheet: None,
2472 run_destructor: true,
2473 icon_style: IconStyleOptions::default(),
2474 language: AzString::from_const_str("en-US"),
2475 os_version: OsVersion::LINUX_2_6,
2476 prefers_reduced_motion: BoolCondition::False,
2477 prefers_high_contrast: BoolCondition::False,
2478 scroll_physics: ScrollPhysics::default(),
2479 linux: LinuxCustomization::default(),
2480 focus_visuals: FocusVisuals::default(),
2481 accessibility: AccessibilitySettings::default(),
2482 input: InputMetrics::default(),
2483 text_rendering: TextRenderingHints::default(),
2484 scrollbar_preferences: ScrollbarPreferences::default(),
2485 visual_hints: VisualHints::default(),
2486 animation: AnimationMetrics::default(),
2487 audio: AudioMetrics::default(),
2488 }
2489 }
2490
2491 #[must_use] pub fn kde_breeze_light() -> SystemStyle {
2493 SystemStyle {
2494 platform: Platform::Linux(DesktopEnvironment::Kde),
2495 theme: Theme::Light,
2496 colors: SystemColors {
2497 text: OptionColorU::Some(ColorU::new_rgb(31, 36, 39)),
2498 background: OptionColorU::Some(ColorU::new_rgb(239, 240, 241)),
2499 accent: OptionColorU::Some(ColorU::new_rgb(61, 174, 233)),
2500 ..Default::default()
2501 },
2502 fonts: SystemFonts {
2503 ui_font: OptionString::Some("Noto Sans".into()),
2504 ui_font_size: OptionF32::Some(10.0),
2505 monospace_font: OptionString::Some("Hack".into()),
2506 ..Default::default()
2507 },
2508 metrics: SystemMetrics {
2509 corner_radius: OptionPixelValue::Some(PixelValue::px(4.0)),
2510 border_width: OptionPixelValue::Some(PixelValue::px(1.0)),
2511 button_padding_horizontal: OptionPixelValue::Some(PixelValue::px(12.0)),
2512 button_padding_vertical: OptionPixelValue::Some(PixelValue::px(6.0)),
2513 titlebar: TitlebarMetrics::linux_gnome(),
2514 },
2515 scrollbar: Some(Box::new(scrollbar_info_to_computed(&SCROLLBAR_KDE_OXYGEN))),
2516 app_specific_stylesheet: None,
2517 run_destructor: true,
2518 icon_style: IconStyleOptions::default(),
2519 language: AzString::from_const_str("en-US"),
2520 os_version: OsVersion::LINUX_6_0,
2521 prefers_reduced_motion: BoolCondition::False,
2522 prefers_high_contrast: BoolCondition::False,
2523 scroll_physics: ScrollPhysics::default(),
2524 linux: LinuxCustomization::default(),
2525 focus_visuals: FocusVisuals::default(),
2526 accessibility: AccessibilitySettings::default(),
2527 input: InputMetrics::default(),
2528 text_rendering: TextRenderingHints::default(),
2529 scrollbar_preferences: ScrollbarPreferences::default(),
2530 visual_hints: VisualHints::default(),
2531 animation: AnimationMetrics::default(),
2532 audio: AudioMetrics::default(),
2533 }
2534 }
2535
2536 #[must_use] pub fn android_material_light() -> SystemStyle {
2540 SystemStyle {
2541 platform: Platform::Android,
2542 theme: Theme::Light,
2543 colors: SystemColors {
2544 text: OptionColorU::Some(ColorU::new_rgb(0, 0, 0)),
2545 background: OptionColorU::Some(ColorU::new_rgb(255, 255, 255)),
2546 accent: OptionColorU::Some(ColorU::new_rgb(98, 0, 238)),
2547 ..Default::default()
2548 },
2549 fonts: SystemFonts {
2550 ui_font: OptionString::Some("Roboto".into()),
2551 ui_font_size: OptionF32::Some(14.0),
2552 monospace_font: OptionString::Some("Droid Sans Mono".into()),
2553 ..Default::default()
2554 },
2555 metrics: SystemMetrics {
2556 corner_radius: OptionPixelValue::Some(PixelValue::px(12.0)),
2557 border_width: OptionPixelValue::Some(PixelValue::px(1.0)),
2558 button_padding_horizontal: OptionPixelValue::Some(PixelValue::px(16.0)),
2559 button_padding_vertical: OptionPixelValue::Some(PixelValue::px(10.0)),
2560 titlebar: TitlebarMetrics::android(),
2561 },
2562 scrollbar: Some(Box::new(scrollbar_info_to_computed(&SCROLLBAR_ANDROID_LIGHT))),
2563 app_specific_stylesheet: None,
2564 run_destructor: true,
2565 icon_style: IconStyleOptions::default(),
2566 language: AzString::from_const_str("en-US"),
2567 os_version: OsVersion::ANDROID_14,
2568 prefers_reduced_motion: BoolCondition::False,
2569 prefers_high_contrast: BoolCondition::False,
2570 scroll_physics: ScrollPhysics::android(),
2571 linux: LinuxCustomization::default(),
2572 focus_visuals: FocusVisuals::default(),
2573 accessibility: AccessibilitySettings::default(),
2574 input: InputMetrics::default(),
2575 text_rendering: TextRenderingHints::default(),
2576 scrollbar_preferences: ScrollbarPreferences::default(),
2577 visual_hints: VisualHints::default(),
2578 animation: AnimationMetrics::default(),
2579 audio: AudioMetrics::default(),
2580 }
2581 }
2582
2583 #[must_use] pub fn android_holo_dark() -> SystemStyle {
2585 SystemStyle {
2586 platform: Platform::Android,
2587 theme: Theme::Dark,
2588 colors: SystemColors {
2589 text: OptionColorU::Some(ColorU::new_rgb(255, 255, 255)),
2590 background: OptionColorU::Some(ColorU::new_rgb(0, 0, 0)),
2591 accent: OptionColorU::Some(ColorU::new_rgb(51, 181, 229)),
2592 ..Default::default()
2593 },
2594 fonts: SystemFonts {
2595 ui_font: OptionString::Some("Roboto".into()),
2596 ui_font_size: OptionF32::Some(14.0),
2597 monospace_font: OptionString::Some("Droid Sans Mono".into()),
2598 ..Default::default()
2599 },
2600 metrics: SystemMetrics {
2601 corner_radius: OptionPixelValue::Some(PixelValue::px(2.0)),
2602 border_width: OptionPixelValue::Some(PixelValue::px(1.0)),
2603 button_padding_horizontal: OptionPixelValue::Some(PixelValue::px(12.0)),
2604 button_padding_vertical: OptionPixelValue::Some(PixelValue::px(8.0)),
2605 titlebar: TitlebarMetrics::android(),
2606 },
2607 scrollbar: Some(Box::new(scrollbar_info_to_computed(&SCROLLBAR_ANDROID_DARK))),
2608 app_specific_stylesheet: None,
2609 run_destructor: true,
2610 icon_style: IconStyleOptions::default(),
2611 language: AzString::from_const_str("en-US"),
2612 os_version: OsVersion::ANDROID_ICE_CREAM_SANDWICH,
2613 prefers_reduced_motion: BoolCondition::False,
2614 prefers_high_contrast: BoolCondition::False,
2615 scroll_physics: ScrollPhysics::android(),
2616 linux: LinuxCustomization::default(),
2617 focus_visuals: FocusVisuals::default(),
2618 accessibility: AccessibilitySettings::default(),
2619 input: InputMetrics::default(),
2620 text_rendering: TextRenderingHints::default(),
2621 scrollbar_preferences: ScrollbarPreferences::default(),
2622 visual_hints: VisualHints::default(),
2623 animation: AnimationMetrics::default(),
2624 audio: AudioMetrics::default(),
2625 }
2626 }
2627
2628 #[must_use] pub fn ios_light() -> SystemStyle {
2630 SystemStyle {
2631 platform: Platform::Ios,
2632 theme: Theme::Light,
2633 colors: SystemColors {
2634 text: OptionColorU::Some(ColorU::new_rgb(0, 0, 0)),
2635 background: OptionColorU::Some(ColorU::new_rgb(242, 242, 247)),
2636 accent: OptionColorU::Some(ColorU::new_rgb(0, 122, 255)),
2637 ..Default::default()
2638 },
2639 fonts: SystemFonts {
2640 ui_font: OptionString::Some(".SFUI-Display-Regular".into()),
2641 ui_font_size: OptionF32::Some(17.0),
2642 monospace_font: OptionString::Some("Menlo".into()),
2643 ..Default::default()
2644 },
2645 metrics: SystemMetrics {
2646 corner_radius: OptionPixelValue::Some(PixelValue::px(10.0)),
2647 border_width: OptionPixelValue::Some(PixelValue::px(0.5)),
2648 button_padding_horizontal: OptionPixelValue::Some(PixelValue::px(20.0)),
2649 button_padding_vertical: OptionPixelValue::Some(PixelValue::px(12.0)),
2650 titlebar: TitlebarMetrics::ios(),
2651 },
2652 scrollbar: Some(Box::new(scrollbar_info_to_computed(&SCROLLBAR_IOS_LIGHT))),
2653 app_specific_stylesheet: None,
2654 run_destructor: true,
2655 icon_style: IconStyleOptions::default(),
2656 language: AzString::from_const_str("en-US"),
2657 os_version: OsVersion::IOS_17,
2658 prefers_reduced_motion: BoolCondition::False,
2659 prefers_high_contrast: BoolCondition::False,
2660 scroll_physics: ScrollPhysics::ios(),
2661 linux: LinuxCustomization::default(),
2662 focus_visuals: FocusVisuals::default(),
2663 accessibility: AccessibilitySettings::default(),
2664 input: InputMetrics::default(),
2665 text_rendering: TextRenderingHints::default(),
2666 scrollbar_preferences: ScrollbarPreferences::default(),
2667 visual_hints: VisualHints::default(),
2668 animation: AnimationMetrics::default(),
2669 audio: AudioMetrics::default(),
2670 }
2671 }
2672}