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
45#[derive(Debug, Clone, Copy, PartialEq, Eq)]
51pub enum RicingMode {
52 Off,
55 Default,
58 Force,
62}
63
64impl Default for RicingMode {
65 fn default() -> Self { RicingMode::Default }
66}
67
68pub fn ricing_mode() -> RicingMode {
72 let raw = match std::env::var("AZ_RICING") {
73 Ok(s) => s,
74 Err(_) => return RicingMode::Default,
75 };
76 match raw.trim().to_ascii_lowercase().as_str() {
77 "off" | "disabled" | "none" | "0" | "false" => RicingMode::Off,
78 "force" | "prefer" | "aggressive" | "1" | "true" => RicingMode::Force,
79 _ => RicingMode::Default,
80 }
81}
82
83pub fn ricing_enabled() -> bool {
86 !matches!(ricing_mode(), RicingMode::Off)
87}
88
89#[derive(Debug, Default, Clone, PartialEq, Eq)]
93#[repr(C, u8)]
94pub enum Platform {
95 Windows,
96 MacOs,
97 Linux(DesktopEnvironment),
98 Android,
99 Ios,
100 #[default]
101 Unknown,
102}
103
104impl Platform {
105 #[inline]
107 pub fn current() -> Self {
108 #[cfg(target_os = "macos")]
109 { Platform::MacOs }
110 #[cfg(target_os = "windows")]
111 { Platform::Windows }
112 #[cfg(target_os = "linux")]
113 { Platform::Linux(DesktopEnvironment::Other(AzString::from_const_str("unknown"))) }
114 #[cfg(target_os = "android")]
115 { Platform::Android }
116 #[cfg(target_os = "ios")]
117 { Platform::Ios }
118 #[cfg(not(any(target_os = "macos", target_os = "windows", target_os = "linux", target_os = "android", target_os = "ios")))]
119 { Platform::Unknown }
120 }
121}
122
123#[derive(Debug, Clone, PartialEq, Eq)]
125#[repr(C, u8)]
126pub enum DesktopEnvironment {
127 Gnome,
128 Kde,
129 Other(AzString),
130}
131
132#[derive(Debug, Default, Clone, Copy, PartialEq, Eq)]
134#[repr(C)]
135pub enum Theme {
136 #[default]
137 Light,
138 Dark,
139}
140
141#[derive(Debug, Default, Clone, PartialEq)]
143#[repr(C)]
144pub struct SystemStyle {
145 pub fonts: SystemFonts,
146 pub metrics: SystemMetrics,
147 pub linux: LinuxCustomization,
149 pub platform: Platform,
150 pub focus_visuals: FocusVisuals,
152 pub language: AzString,
155 pub app_specific_stylesheet: Option<Box<Css>>,
160 pub scrollbar: Option<Box<ComputedScrollbarStyle>>,
162 pub scroll_physics: ScrollPhysics,
166 pub theme: Theme,
167 pub os_version: crate::dynamic_selector::OsVersion,
169 pub prefers_reduced_motion: crate::dynamic_selector::BoolCondition,
171 pub prefers_high_contrast: crate::dynamic_selector::BoolCondition,
173 pub accessibility: AccessibilitySettings,
175 pub input: InputMetrics,
177 pub text_rendering: TextRenderingHints,
179 pub scrollbar_preferences: ScrollbarPreferences,
181 pub visual_hints: VisualHints,
183 pub animation: AnimationMetrics,
185 pub colors: SystemColors,
186 pub icon_style: IconStyleOptions,
188 pub audio: AudioMetrics,
190}
191
192#[derive(Debug, Default, Clone, PartialEq)]
197#[repr(C)]
198pub struct IconStyleOptions {
199 pub prefer_grayscale: bool,
202 pub tint_color: OptionColorU,
205 pub inherit_text_color: bool,
208}
209
210#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
221#[repr(C)]
222#[derive(Default)]
223pub enum SystemFontType {
224 #[default]
226 Ui,
227 UiBold,
229 Monospace,
231 MonospaceBold,
233 MonospaceItalic,
235 Title,
237 TitleBold,
239 Menu,
241 Small,
243 Serif,
245 SerifBold,
247}
248
249
250impl SystemFontType {
251 pub fn from_css_str(s: &str) -> Option<Self> {
261 let s = s.trim();
262 if !s.starts_with("system:") {
263 return None;
264 }
265 let rest = &s[7..]; match rest {
267 "ui" => Some(SystemFontType::Ui),
268 "ui:bold" => Some(SystemFontType::UiBold),
269 "monospace" => Some(SystemFontType::Monospace),
270 "monospace:bold" => Some(SystemFontType::MonospaceBold),
271 "monospace:italic" => Some(SystemFontType::MonospaceItalic),
272 "title" => Some(SystemFontType::Title),
273 "title:bold" => Some(SystemFontType::TitleBold),
274 "menu" => Some(SystemFontType::Menu),
275 "small" => Some(SystemFontType::Small),
276 "serif" => Some(SystemFontType::Serif),
277 "serif:bold" => Some(SystemFontType::SerifBold),
278 _ => None,
279 }
280 }
281
282 pub fn as_css_str(&self) -> &'static str {
284 match self {
285 SystemFontType::Ui => "system:ui",
286 SystemFontType::UiBold => "system:ui:bold",
287 SystemFontType::Monospace => "system:monospace",
288 SystemFontType::MonospaceBold => "system:monospace:bold",
289 SystemFontType::MonospaceItalic => "system:monospace:italic",
290 SystemFontType::Title => "system:title",
291 SystemFontType::TitleBold => "system:title:bold",
292 SystemFontType::Menu => "system:menu",
293 SystemFontType::Small => "system:small",
294 SystemFontType::Serif => "system:serif",
295 SystemFontType::SerifBold => "system:serif:bold",
296 }
297 }
298
299 pub fn is_bold(&self) -> bool {
302 matches!(
303 self,
304 SystemFontType::UiBold
305 | SystemFontType::MonospaceBold
306 | SystemFontType::TitleBold
307 | SystemFontType::SerifBold
308 )
309 }
310
311 pub fn is_italic(&self) -> bool {
313 matches!(self, SystemFontType::MonospaceItalic)
314 }
315}
316
317#[derive(Debug, Default, Clone, PartialEq)]
325#[repr(C)]
326pub struct AccessibilitySettings {
327 pub text_scale_factor: f32,
329 pub prefers_bold_text: bool,
334 pub prefers_larger_text: bool,
339 pub prefers_high_contrast: bool,
344 pub prefers_reduced_motion: bool,
349 pub prefers_reduced_transparency: bool,
354 pub screen_reader_active: bool,
356 pub differentiate_without_color: bool,
359}
360
361#[derive(Debug, Default, Clone, PartialEq)]
370#[repr(C)]
371pub struct SystemColors {
372 pub text: OptionColorU,
375 pub secondary_text: OptionColorU,
377 pub tertiary_text: OptionColorU,
379 pub background: OptionColorU,
381
382 pub accent: OptionColorU,
385 pub accent_text: OptionColorU,
387
388 pub button_face: OptionColorU,
391 pub button_text: OptionColorU,
393 pub disabled_text: OptionColorU,
395
396 pub window_background: OptionColorU,
399 pub under_page_background: OptionColorU,
401
402 pub selection_background: OptionColorU,
405 pub selection_text: OptionColorU,
407 pub selection_background_inactive: OptionColorU,
410 pub selection_text_inactive: OptionColorU,
412
413 pub link: OptionColorU,
416 pub separator: OptionColorU,
418 pub grid: OptionColorU,
420 pub find_highlight: OptionColorU,
422
423 pub sidebar_background: OptionColorU,
426 pub sidebar_selection: OptionColorU,
428}
429
430#[derive(Debug, Default, Clone, PartialEq)]
436#[repr(C)]
437pub struct SystemFonts {
438 pub ui_font: OptionString,
443 pub ui_font_size: OptionF32,
445 pub monospace_font: OptionString,
450 pub monospace_font_size: OptionF32,
452 pub ui_font_bold: OptionString,
454 pub title_font: OptionString,
456 pub title_font_size: OptionF32,
458 pub menu_font: OptionString,
460 pub menu_font_size: OptionF32,
462 pub small_font: OptionString,
464 pub small_font_size: OptionF32,
466}
467
468#[derive(Debug, Default, Clone, PartialEq)]
470#[repr(C)]
471pub struct SystemMetrics {
472 pub corner_radius: OptionPixelValue,
474 pub border_width: OptionPixelValue,
476 pub button_padding_horizontal: OptionPixelValue,
478 pub button_padding_vertical: OptionPixelValue,
480 pub titlebar: TitlebarMetrics,
482}
483
484#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Default)]
486#[repr(C)]
487pub enum TitlebarButtonSide {
488 Left,
490 #[default]
492 Right,
493}
494
495#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
497#[repr(C)]
498pub struct TitlebarButtons {
499 pub has_close: bool,
501 pub has_minimize: bool,
503 pub has_maximize: bool,
505 pub has_fullscreen: bool,
507}
508
509impl Default for TitlebarButtons {
510 fn default() -> Self {
511 Self {
512 has_close: true,
513 has_minimize: true,
514 has_maximize: true,
515 has_fullscreen: false,
516 }
517 }
518}
519
520#[derive(Debug, Default, Clone, Copy, PartialEq)]
526#[repr(C)]
527pub struct SafeAreaInsets {
528 pub top: OptionPixelValue,
530 pub bottom: OptionPixelValue,
532 pub left: OptionPixelValue,
534 pub right: OptionPixelValue,
536}
537
538#[derive(Debug, Clone, PartialEq)]
543#[repr(C)]
544pub struct TitlebarMetrics {
545 pub button_side: TitlebarButtonSide,
547 pub buttons: TitlebarButtons,
549 pub height: OptionPixelValue,
551 pub button_area_width: OptionPixelValue,
554 pub padding_horizontal: OptionPixelValue,
556 pub safe_area: SafeAreaInsets,
558 pub title_font: OptionString,
560 pub title_font_size: OptionF32,
562 pub title_font_weight: OptionU16,
564}
565
566impl Default for TitlebarMetrics {
567 fn default() -> Self {
568 Self {
569 button_side: TitlebarButtonSide::Right,
570 buttons: TitlebarButtons::default(),
571 height: OptionPixelValue::Some(PixelValue::px(32.0)),
572 button_area_width: OptionPixelValue::Some(PixelValue::px(100.0)),
573 padding_horizontal: OptionPixelValue::Some(PixelValue::px(8.0)),
574 safe_area: SafeAreaInsets::default(),
575 title_font: OptionString::None,
576 title_font_size: OptionF32::Some(13.0),
577 title_font_weight: OptionU16::Some(600), }
579 }
580}
581
582impl TitlebarMetrics {
583 pub fn windows() -> Self {
585 Self {
586 button_side: TitlebarButtonSide::Right,
587 buttons: TitlebarButtons {
588 has_close: true,
589 has_minimize: true,
590 has_maximize: true,
591 has_fullscreen: false,
592 },
593 height: OptionPixelValue::Some(PixelValue::px(32.0)),
594 button_area_width: OptionPixelValue::Some(PixelValue::px(138.0)), padding_horizontal: OptionPixelValue::Some(PixelValue::px(8.0)),
596 safe_area: SafeAreaInsets::default(),
597 title_font: OptionString::Some("Segoe UI Variable Text".into()),
598 title_font_size: OptionF32::Some(12.0),
599 title_font_weight: OptionU16::Some(400), }
601 }
602
603 pub fn macos() -> Self {
605 Self {
606 button_side: TitlebarButtonSide::Left,
607 buttons: TitlebarButtons {
608 has_close: true,
609 has_minimize: true,
610 has_maximize: false, has_fullscreen: true,
612 },
613 height: OptionPixelValue::Some(PixelValue::px(28.0)),
614 button_area_width: OptionPixelValue::Some(PixelValue::px(78.0)), padding_horizontal: OptionPixelValue::Some(PixelValue::px(8.0)),
616 safe_area: SafeAreaInsets::default(),
617 title_font: OptionString::Some(".SF NS".into()),
618 title_font_size: OptionF32::Some(13.0),
619 title_font_weight: OptionU16::Some(600), }
621 }
622
623 pub fn linux_gnome() -> Self {
625 Self {
626 button_side: TitlebarButtonSide::Right, buttons: TitlebarButtons {
628 has_close: true,
629 has_minimize: true,
630 has_maximize: true,
631 has_fullscreen: false,
632 },
633 height: OptionPixelValue::Some(PixelValue::px(35.0)),
634 button_area_width: OptionPixelValue::Some(PixelValue::px(100.0)),
635 padding_horizontal: OptionPixelValue::Some(PixelValue::px(12.0)),
636 safe_area: SafeAreaInsets::default(),
637 title_font: OptionString::Some("Cantarell".into()),
638 title_font_size: OptionF32::Some(11.0),
639 title_font_weight: OptionU16::Some(700), }
641 }
642
643 pub fn ios() -> Self {
645 Self {
646 button_side: TitlebarButtonSide::Left,
647 buttons: TitlebarButtons {
648 has_close: false, has_minimize: false,
650 has_maximize: false,
651 has_fullscreen: false,
652 },
653 height: OptionPixelValue::Some(PixelValue::px(44.0)),
654 button_area_width: OptionPixelValue::Some(PixelValue::px(0.0)),
655 padding_horizontal: OptionPixelValue::Some(PixelValue::px(16.0)),
656 safe_area: SafeAreaInsets {
657 top: OptionPixelValue::Some(PixelValue::px(47.0)),
659 bottom: OptionPixelValue::Some(PixelValue::px(34.0)),
660 left: OptionPixelValue::None,
661 right: OptionPixelValue::None,
662 },
663 title_font: OptionString::Some(".SFUI-Semibold".into()),
664 title_font_size: OptionF32::Some(17.0),
665 title_font_weight: OptionU16::Some(600),
666 }
667 }
668
669 pub fn android() -> Self {
671 Self {
672 button_side: TitlebarButtonSide::Left, buttons: TitlebarButtons {
674 has_close: false,
675 has_minimize: false,
676 has_maximize: false,
677 has_fullscreen: false,
678 },
679 height: OptionPixelValue::Some(PixelValue::px(56.0)),
680 button_area_width: OptionPixelValue::Some(PixelValue::px(48.0)), padding_horizontal: OptionPixelValue::Some(PixelValue::px(16.0)),
682 safe_area: SafeAreaInsets::default(),
683 title_font: OptionString::Some("Roboto Medium".into()),
684 title_font_size: OptionF32::Some(20.0),
685 title_font_weight: OptionU16::Some(500),
686 }
687 }
688}
689
690#[derive(Debug, Clone, Copy, PartialEq)]
703#[repr(C)]
704pub struct InputMetrics {
705 pub double_click_time_ms: u32,
707 pub double_click_distance_px: f32,
709 pub drag_threshold_px: f32,
711 pub caret_blink_rate_ms: u32,
713 pub caret_width_px: f32,
715 pub wheel_scroll_lines: u32,
717 pub hover_time_ms: u32,
720}
721
722impl Default for InputMetrics {
723 fn default() -> Self {
724 Self {
725 double_click_time_ms: 500,
726 double_click_distance_px: 4.0,
727 drag_threshold_px: 5.0,
728 caret_blink_rate_ms: 530,
729 caret_width_px: 1.0,
730 wheel_scroll_lines: 3,
731 hover_time_ms: 400,
732 }
733 }
734}
735
736#[derive(Debug, Default, Clone, Copy, PartialEq, Eq)]
740#[repr(C)]
741pub enum SubpixelType {
742 #[default]
744 None,
745 Rgb,
747 Bgr,
749 VRgb,
751 VBgr,
753}
754
755#[derive(Debug, Clone, Copy, PartialEq)]
760#[repr(C)]
761pub struct TextRenderingHints {
762 pub subpixel_type: SubpixelType,
764 pub font_smoothing_gamma: u32,
766 pub font_smoothing_enabled: bool,
768 pub increased_contrast: bool,
770}
771
772impl Default for TextRenderingHints {
773 fn default() -> Self {
774 Self {
775 subpixel_type: SubpixelType::None,
776 font_smoothing_gamma: 1000,
777 font_smoothing_enabled: true,
778 increased_contrast: false,
779 }
780 }
781}
782
783#[derive(Debug, Default, Clone, Copy, PartialEq)]
790#[repr(C)]
791pub struct FocusVisuals {
792 pub focus_ring_color: OptionColorU,
795 pub focus_border_width: OptionPixelValue,
798 pub focus_border_height: OptionPixelValue,
800}
801
802#[derive(Debug, Default, Clone, Copy, PartialEq, Eq)]
806#[repr(C)]
807pub enum ScrollbarVisibility {
808 Always,
810 #[default]
812 WhenScrolling,
813 Automatic,
815}
816
817#[derive(Debug, Default, Clone, Copy, PartialEq, Eq)]
819#[repr(C)]
820pub enum ScrollbarTrackClick {
821 JumpToPosition,
823 #[default]
825 PageUpDown,
826}
827
828#[derive(Debug, Clone, Copy, PartialEq)]
833#[repr(C)]
834pub struct ScrollbarPreferences {
835 pub visibility: ScrollbarVisibility,
838 pub track_click: ScrollbarTrackClick,
840}
841
842impl Default for ScrollbarPreferences {
843 fn default() -> Self {
844 Self {
845 visibility: ScrollbarVisibility::WhenScrolling,
846 track_click: ScrollbarTrackClick::PageUpDown,
847 }
848 }
849}
850
851#[derive(Debug, Default, Clone, PartialEq)]
858#[repr(C)]
859pub struct LinuxCustomization {
860 pub gtk_theme: OptionString,
862 pub icon_theme: OptionString,
864 pub cursor_theme: OptionString,
866 pub cursor_size: u32,
868 pub titlebar_button_layout: OptionString,
871}
872
873#[derive(Debug, Default, Clone, Copy, PartialEq, Eq)]
877#[repr(C)]
878pub enum ToolbarStyle {
879 #[default]
881 IconsOnly,
882 TextOnly,
884 TextBesideIcon,
886 TextBelowIcon,
888}
889
890#[derive(Debug, Clone, Copy, PartialEq)]
895#[repr(C)]
896pub struct VisualHints {
897 pub toolbar_style: ToolbarStyle,
900 pub show_button_images: bool,
903 pub show_menu_images: bool,
906 pub show_tooltips: bool,
908 pub flash_on_alert: bool,
910}
911
912impl Default for VisualHints {
913 fn default() -> Self {
914 Self {
915 toolbar_style: ToolbarStyle::IconsOnly,
916 show_button_images: false,
917 show_menu_images: true,
918 show_tooltips: true,
919 flash_on_alert: true,
920 }
921 }
922}
923
924#[derive(Debug, Default, Clone, Copy, PartialEq, Eq)]
928#[repr(C)]
929pub enum FocusBehavior {
930 #[default]
932 AlwaysVisible,
933 KeyboardOnly,
936}
937
938#[derive(Debug, Clone, Copy, PartialEq)]
950#[repr(C)]
951pub struct AnimationMetrics {
952 pub animations_enabled: bool,
954 pub animation_duration_factor: f32,
957 pub focus_indicator_behavior: FocusBehavior,
959}
960
961impl Default for AnimationMetrics {
962 fn default() -> Self {
963 Self {
964 animations_enabled: true,
965 animation_duration_factor: 1.0,
966 focus_indicator_behavior: FocusBehavior::AlwaysVisible,
967 }
968 }
969}
970
971#[derive(Debug, Clone, Copy, PartialEq, Eq)]
984#[repr(C)]
985pub struct AudioMetrics {
986 pub event_sounds_enabled: bool,
988 pub input_feedback_sounds_enabled: bool,
990}
991
992impl Default for AudioMetrics {
993 fn default() -> Self {
994 Self {
995 event_sounds_enabled: true,
996 input_feedback_sounds_enabled: false,
997 }
998 }
999}
1000
1001pub mod apple_fonts {
1007 pub const SYSTEM_FONT: &str = "System Font";
1010
1011 pub const SF_NS_ROUNDED: &str = "SF NS Rounded";
1013
1014 pub const SF_COMPACT: &str = "SF Compact";
1017
1018 pub const SF_MONO: &str = "SF NS Mono Light";
1021
1022 pub const NEW_YORK: &str = "New York";
1025
1026 pub const SF_ARABIC: &str = "SF Arabic";
1028
1029 pub const SF_ARMENIAN: &str = "SF Armenian";
1031
1032 pub const SF_GEORGIAN: &str = "SF Georgian";
1034
1035 pub const SF_HEBREW: &str = "SF Hebrew";
1037
1038 pub const MENLO: &str = "Menlo";
1040 pub const MENLO_REGULAR: &str = "Menlo Regular";
1041 pub const MENLO_BOLD: &str = "Menlo Bold";
1042 pub const MONACO: &str = "Monaco";
1043 pub const LUCIDA_GRANDE: &str = "Lucida Grande";
1044 pub const LUCIDA_GRANDE_BOLD: &str = "Lucida Grande Bold";
1045 pub const HELVETICA_NEUE: &str = "Helvetica Neue";
1046 pub const HELVETICA_NEUE_BOLD: &str = "Helvetica Neue Bold";
1047}
1048
1049pub mod windows_fonts {
1051 pub const SEGOE_UI_VARIABLE: &str = "Segoe UI Variable";
1053 pub const SEGOE_UI_VARIABLE_TEXT: &str = "Segoe UI Variable Text";
1054 pub const SEGOE_UI_VARIABLE_DISPLAY: &str = "Segoe UI Variable Display";
1055
1056 pub const SEGOE_UI: &str = "Segoe UI";
1058 pub const CONSOLAS: &str = "Consolas";
1059 pub const CASCADIA_CODE: &str = "Cascadia Code";
1060 pub const CASCADIA_MONO: &str = "Cascadia Mono";
1061
1062 pub const TAHOMA: &str = "Tahoma";
1064 pub const MS_SANS_SERIF: &str = "MS Sans Serif";
1065 pub const LUCIDA_CONSOLE: &str = "Lucida Console";
1066 pub const COURIER_NEW: &str = "Courier New";
1067}
1068
1069pub mod linux_fonts {
1071 pub const CANTARELL: &str = "Cantarell";
1073 pub const ADWAITA: &str = "Adwaita";
1074
1075 pub const UBUNTU: &str = "Ubuntu";
1077 pub const UBUNTU_MONO: &str = "Ubuntu Mono";
1078
1079 pub const DEJAVU_SANS: &str = "DejaVu Sans";
1081 pub const DEJAVU_SANS_MONO: &str = "DejaVu Sans Mono";
1082 pub const DEJAVU_SERIF: &str = "DejaVu Serif";
1083
1084 pub const LIBERATION_SANS: &str = "Liberation Sans";
1086 pub const LIBERATION_MONO: &str = "Liberation Mono";
1087 pub const LIBERATION_SERIF: &str = "Liberation Serif";
1088
1089 pub const NOTO_SANS: &str = "Noto Sans";
1091 pub const NOTO_MONO: &str = "Noto Sans Mono";
1092 pub const NOTO_SERIF: &str = "Noto Serif";
1093
1094 pub const HACK: &str = "Hack";
1096
1097 pub const MONOSPACE: &str = "Monospace";
1099 pub const SANS_SERIF: &str = "Sans";
1100 pub const SERIF: &str = "Serif";
1101}
1102
1103impl SystemFontType {
1104 pub fn get_fallback_chain(&self, platform: &Platform) -> Vec<&'static str> {
1109 match platform {
1110 Platform::MacOs | Platform::Ios => self.macos_fallback_chain(),
1111 Platform::Windows => self.windows_fallback_chain(),
1112 Platform::Linux(_) => self.linux_fallback_chain(),
1113 Platform::Android => self.android_fallback_chain(),
1114 Platform::Unknown => self.generic_fallback_chain(),
1115 }
1116 }
1117
1118 fn macos_fallback_chain(&self) -> Vec<&'static str> {
1119 match self {
1120 SystemFontType::Ui => vec![
1122 apple_fonts::SYSTEM_FONT,
1123 apple_fonts::HELVETICA_NEUE,
1124 apple_fonts::LUCIDA_GRANDE,
1125 ],
1126 SystemFontType::UiBold => vec![
1128 apple_fonts::HELVETICA_NEUE, apple_fonts::LUCIDA_GRANDE,
1130 ],
1131 SystemFontType::Monospace => vec![
1133 apple_fonts::MENLO,
1134 apple_fonts::MONACO,
1135 ],
1136 SystemFontType::MonospaceBold | SystemFontType::MonospaceItalic => vec![
1137 apple_fonts::MENLO, apple_fonts::MONACO,
1139 ],
1140 SystemFontType::Title => vec![
1142 apple_fonts::SYSTEM_FONT,
1143 apple_fonts::HELVETICA_NEUE,
1144 ],
1145 SystemFontType::TitleBold => vec![
1146 apple_fonts::HELVETICA_NEUE, apple_fonts::LUCIDA_GRANDE,
1148 ],
1149 SystemFontType::Menu => vec![
1150 apple_fonts::SYSTEM_FONT,
1151 apple_fonts::HELVETICA_NEUE,
1152 ],
1153 SystemFontType::Small => vec![
1154 apple_fonts::SYSTEM_FONT,
1155 apple_fonts::HELVETICA_NEUE,
1156 ],
1157 SystemFontType::Serif => vec![
1159 apple_fonts::NEW_YORK,
1160 "Georgia",
1161 "Times New Roman",
1162 ],
1163 SystemFontType::SerifBold => vec![
1164 "Georgia", "Times New Roman",
1166 ],
1167 }
1168 }
1169
1170 fn windows_fallback_chain(&self) -> Vec<&'static str> {
1171 match self {
1172 SystemFontType::Ui | SystemFontType::UiBold => vec![
1173 windows_fonts::SEGOE_UI_VARIABLE_TEXT,
1174 windows_fonts::SEGOE_UI,
1175 windows_fonts::TAHOMA,
1176 ],
1177 SystemFontType::Monospace | SystemFontType::MonospaceBold | SystemFontType::MonospaceItalic => vec![
1178 windows_fonts::CASCADIA_MONO,
1179 windows_fonts::CASCADIA_CODE,
1180 windows_fonts::CONSOLAS,
1181 windows_fonts::LUCIDA_CONSOLE,
1182 windows_fonts::COURIER_NEW,
1183 ],
1184 SystemFontType::Title | SystemFontType::TitleBold => vec![
1185 windows_fonts::SEGOE_UI_VARIABLE_DISPLAY,
1186 windows_fonts::SEGOE_UI,
1187 ],
1188 SystemFontType::Menu => vec![
1189 windows_fonts::SEGOE_UI,
1190 windows_fonts::TAHOMA,
1191 ],
1192 SystemFontType::Small => vec![
1193 windows_fonts::SEGOE_UI,
1194 ],
1195 SystemFontType::Serif | SystemFontType::SerifBold => vec![
1196 "Cambria",
1197 "Georgia",
1198 "Times New Roman",
1199 ],
1200 }
1201 }
1202
1203 fn linux_fallback_chain(&self) -> Vec<&'static str> {
1204 match self {
1205 SystemFontType::Ui | SystemFontType::UiBold => vec![
1206 linux_fonts::CANTARELL,
1207 linux_fonts::UBUNTU,
1208 linux_fonts::NOTO_SANS,
1209 linux_fonts::DEJAVU_SANS,
1210 linux_fonts::LIBERATION_SANS,
1211 linux_fonts::SANS_SERIF,
1212 ],
1213 SystemFontType::Monospace | SystemFontType::MonospaceBold | SystemFontType::MonospaceItalic => vec![
1214 linux_fonts::UBUNTU_MONO,
1215 linux_fonts::HACK,
1216 linux_fonts::NOTO_MONO,
1217 linux_fonts::DEJAVU_SANS_MONO,
1218 linux_fonts::LIBERATION_MONO,
1219 linux_fonts::MONOSPACE,
1220 ],
1221 SystemFontType::Title | SystemFontType::TitleBold => vec![
1222 linux_fonts::CANTARELL,
1223 linux_fonts::UBUNTU,
1224 linux_fonts::NOTO_SANS,
1225 ],
1226 SystemFontType::Menu => vec![
1227 linux_fonts::CANTARELL,
1228 linux_fonts::UBUNTU,
1229 linux_fonts::NOTO_SANS,
1230 ],
1231 SystemFontType::Small => vec![
1232 linux_fonts::CANTARELL,
1233 linux_fonts::UBUNTU,
1234 linux_fonts::NOTO_SANS,
1235 ],
1236 SystemFontType::Serif | SystemFontType::SerifBold => vec![
1237 linux_fonts::NOTO_SERIF,
1238 linux_fonts::DEJAVU_SERIF,
1239 linux_fonts::LIBERATION_SERIF,
1240 linux_fonts::SERIF,
1241 ],
1242 }
1243 }
1244
1245 fn android_fallback_chain(&self) -> Vec<&'static str> {
1246 match self {
1247 SystemFontType::Ui | SystemFontType::UiBold => vec!["Roboto", "Noto Sans"],
1248 SystemFontType::Monospace | SystemFontType::MonospaceBold | SystemFontType::MonospaceItalic => {
1249 vec!["Roboto Mono", "Droid Sans Mono", "monospace"]
1250 }
1251 SystemFontType::Title | SystemFontType::TitleBold => vec!["Roboto", "Noto Sans"],
1252 SystemFontType::Menu => vec!["Roboto"],
1253 SystemFontType::Small => vec!["Roboto"],
1254 SystemFontType::Serif | SystemFontType::SerifBold => vec!["Noto Serif", "Droid Serif", "serif"],
1255 }
1256 }
1257
1258 fn generic_fallback_chain(&self) -> Vec<&'static str> {
1259 match self {
1260 SystemFontType::Ui | SystemFontType::UiBold => vec!["sans-serif"],
1261 SystemFontType::Monospace | SystemFontType::MonospaceBold | SystemFontType::MonospaceItalic => {
1262 vec!["monospace"]
1263 }
1264 SystemFontType::Title | SystemFontType::TitleBold => vec!["sans-serif"],
1265 SystemFontType::Menu => vec!["sans-serif"],
1266 SystemFontType::Small => vec!["sans-serif"],
1267 SystemFontType::Serif | SystemFontType::SerifBold => vec!["serif"],
1268 }
1269 }
1270}
1271
1272impl SystemStyle {
1273
1274 pub fn to_json_string(&self) -> AzString {
1279 use alloc::format;
1280
1281 fn opt_color(c: &OptionColorU) -> alloc::string::String {
1282 match c.as_ref() {
1283 Some(c) => format!("\"#{:02x}{:02x}{:02x}{:02x}\"", c.r, c.g, c.b, c.a),
1284 None => "null".into(),
1285 }
1286 }
1287 fn opt_str(s: &OptionString) -> alloc::string::String {
1288 match s.as_ref() {
1289 Some(s) => format!("\"{}\"", s.as_str()),
1290 None => "null".into(),
1291 }
1292 }
1293 fn opt_f32(v: &OptionF32) -> alloc::string::String {
1294 match v.into_option() {
1295 Some(v) => format!("{:.2}", v),
1296 None => "null".into(),
1297 }
1298 }
1299 fn opt_u16(v: &OptionU16) -> alloc::string::String {
1300 match v.into_option() {
1301 Some(v) => format!("{}", v),
1302 None => "null".into(),
1303 }
1304 }
1305 fn opt_px(v: &OptionPixelValue) -> alloc::string::String {
1306 match v.as_ref() {
1307 Some(v) => format!("{:.1}", v.to_pixels_internal(0.0, 0.0, 0.0)),
1308 None => "null".into(),
1309 }
1310 }
1311
1312 let tm = &self.metrics.titlebar;
1313 let inp = &self.input;
1314 let tr = &self.text_rendering;
1315 let acc = &self.accessibility;
1316 let sp = &self.scrollbar_preferences;
1317 let lnx = &self.linux;
1318 let vh = &self.visual_hints;
1319 let anim = &self.animation;
1320 let audio = &self.audio;
1321
1322 let json = format!(
1323r#"{{
1324 "theme": "{:?}",
1325 "platform": "{:?}",
1326 "os_version": "{:?}:{}",
1327 "language": "{}",
1328 "prefers_reduced_motion": {:?},
1329 "prefers_high_contrast": {:?},
1330 "colors": {{
1331 "text": {},
1332 "secondary_text": {},
1333 "tertiary_text": {},
1334 "background": {},
1335 "accent": {},
1336 "accent_text": {},
1337 "button_face": {},
1338 "button_text": {},
1339 "disabled_text": {},
1340 "window_background": {},
1341 "under_page_background": {},
1342 "selection_background": {},
1343 "selection_text": {},
1344 "selection_background_inactive": {},
1345 "selection_text_inactive": {},
1346 "link": {},
1347 "separator": {},
1348 "grid": {},
1349 "find_highlight": {},
1350 "sidebar_background": {},
1351 "sidebar_selection": {}
1352 }},
1353 "fonts": {{
1354 "ui_font": {},
1355 "ui_font_size": {},
1356 "monospace_font": {},
1357 "title_font": {},
1358 "menu_font": {},
1359 "small_font": {}
1360 }},
1361 "titlebar": {{
1362 "button_side": "{:?}",
1363 "height": {},
1364 "button_area_width": {},
1365 "padding_horizontal": {},
1366 "title_font": {},
1367 "title_font_size": {},
1368 "title_font_weight": {},
1369 "has_close": {},
1370 "has_minimize": {},
1371 "has_maximize": {},
1372 "has_fullscreen": {}
1373 }},
1374 "input": {{
1375 "double_click_time_ms": {},
1376 "double_click_distance_px": {:.1},
1377 "drag_threshold_px": {:.1},
1378 "caret_blink_rate_ms": {},
1379 "caret_width_px": {:.1},
1380 "wheel_scroll_lines": {},
1381 "hover_time_ms": {}
1382 }},
1383 "text_rendering": {{
1384 "font_smoothing_enabled": {},
1385 "subpixel_type": "{:?}",
1386 "font_smoothing_gamma": {},
1387 "increased_contrast": {}
1388 }},
1389 "accessibility": {{
1390 "prefers_bold_text": {},
1391 "prefers_larger_text": {},
1392 "text_scale_factor": {:.2},
1393 "prefers_high_contrast": {},
1394 "prefers_reduced_motion": {},
1395 "prefers_reduced_transparency": {},
1396 "screen_reader_active": {},
1397 "differentiate_without_color": {}
1398 }},
1399 "scrollbar_preferences": {{
1400 "visibility": "{:?}",
1401 "track_click": "{:?}"
1402 }},
1403 "linux": {{
1404 "gtk_theme": {},
1405 "icon_theme": {},
1406 "cursor_theme": {},
1407 "cursor_size": {},
1408 "titlebar_button_layout": {}
1409 }},
1410 "visual_hints": {{
1411 "show_button_images": {},
1412 "show_menu_images": {},
1413 "toolbar_style": "{:?}",
1414 "show_tooltips": {}
1415 }},
1416 "animation": {{
1417 "animations_enabled": {},
1418 "animation_duration_factor": {:.2},
1419 "focus_indicator_behavior": "{:?}"
1420 }},
1421 "audio": {{
1422 "event_sounds_enabled": {},
1423 "input_feedback_sounds_enabled": {}
1424 }}
1425}}"#,
1426 self.theme,
1428 self.platform,
1429 self.os_version.os, self.os_version.version_id,
1430 self.language.as_str(),
1431 self.prefers_reduced_motion,
1432 self.prefers_high_contrast,
1433 opt_color(&self.colors.text),
1435 opt_color(&self.colors.secondary_text),
1436 opt_color(&self.colors.tertiary_text),
1437 opt_color(&self.colors.background),
1438 opt_color(&self.colors.accent),
1439 opt_color(&self.colors.accent_text),
1440 opt_color(&self.colors.button_face),
1441 opt_color(&self.colors.button_text),
1442 opt_color(&self.colors.disabled_text),
1443 opt_color(&self.colors.window_background),
1444 opt_color(&self.colors.under_page_background),
1445 opt_color(&self.colors.selection_background),
1446 opt_color(&self.colors.selection_text),
1447 opt_color(&self.colors.selection_background_inactive),
1448 opt_color(&self.colors.selection_text_inactive),
1449 opt_color(&self.colors.link),
1450 opt_color(&self.colors.separator),
1451 opt_color(&self.colors.grid),
1452 opt_color(&self.colors.find_highlight),
1453 opt_color(&self.colors.sidebar_background),
1454 opt_color(&self.colors.sidebar_selection),
1455 opt_str(&self.fonts.ui_font),
1457 opt_f32(&self.fonts.ui_font_size),
1458 opt_str(&self.fonts.monospace_font),
1459 opt_str(&self.fonts.title_font),
1460 opt_str(&self.fonts.menu_font),
1461 opt_str(&self.fonts.small_font),
1462 tm.button_side,
1464 opt_px(&tm.height),
1465 opt_px(&tm.button_area_width),
1466 opt_px(&tm.padding_horizontal),
1467 opt_str(&tm.title_font),
1468 opt_f32(&tm.title_font_size),
1469 opt_u16(&tm.title_font_weight),
1470 tm.buttons.has_close,
1471 tm.buttons.has_minimize,
1472 tm.buttons.has_maximize,
1473 tm.buttons.has_fullscreen,
1474 inp.double_click_time_ms,
1476 inp.double_click_distance_px,
1477 inp.drag_threshold_px,
1478 inp.caret_blink_rate_ms,
1479 inp.caret_width_px,
1480 inp.wheel_scroll_lines,
1481 inp.hover_time_ms,
1482 tr.font_smoothing_enabled,
1484 tr.subpixel_type,
1485 tr.font_smoothing_gamma,
1486 tr.increased_contrast,
1487 acc.prefers_bold_text,
1489 acc.prefers_larger_text,
1490 acc.text_scale_factor,
1491 acc.prefers_high_contrast,
1492 acc.prefers_reduced_motion,
1493 acc.prefers_reduced_transparency,
1494 acc.screen_reader_active,
1495 acc.differentiate_without_color,
1496 sp.visibility,
1498 sp.track_click,
1499 opt_str(&lnx.gtk_theme),
1501 opt_str(&lnx.icon_theme),
1502 opt_str(&lnx.cursor_theme),
1503 lnx.cursor_size,
1504 opt_str(&lnx.titlebar_button_layout),
1505 vh.show_button_images,
1507 vh.show_menu_images,
1508 vh.toolbar_style,
1509 vh.show_tooltips,
1510 anim.animations_enabled,
1512 anim.animation_duration_factor,
1513 anim.focus_indicator_behavior,
1514 audio.event_sounds_enabled,
1516 audio.input_feedback_sounds_enabled,
1517 );
1518
1519 AzString::from(json)
1520 }
1521
1522 pub fn detect() -> Self {
1528 Self::default_for_platform()
1529 }
1530
1531 pub fn default_for_platform() -> Self {
1533 #[cfg(target_os = "windows")]
1534 { defaults::windows_11_light() }
1535 #[cfg(target_os = "macos")]
1536 { defaults::macos_modern_light() }
1537 #[cfg(target_os = "linux")]
1538 { defaults::gnome_adwaita_light() }
1539 #[cfg(target_os = "android")]
1540 { defaults::android_material_light() }
1541 #[cfg(target_os = "ios")]
1542 { defaults::ios_light() }
1543 #[cfg(not(any(
1544 target_os = "linux",
1545 target_os = "windows",
1546 target_os = "macos",
1547 target_os = "android",
1548 target_os = "ios"
1549 )))]
1550 { Self::default() }
1551 }
1552
1553 #[inline(always)]
1555 pub fn new() -> Self {
1556 Self::detect()
1557 }
1558
1559 pub fn create_csd_stylesheet(&self) -> Css {
1565 use alloc::format;
1566
1567 use crate::parser2::new_from_str;
1568
1569 let mut css = String::new();
1571
1572 let bg_color = self
1574 .colors
1575 .window_background
1576 .as_option()
1577 .copied()
1578 .unwrap_or(ColorU::new_rgb(240, 240, 240));
1579 let text_color = self
1580 .colors
1581 .text
1582 .as_option()
1583 .copied()
1584 .unwrap_or(ColorU::new_rgb(0, 0, 0));
1585 let accent_color = self
1586 .colors
1587 .accent
1588 .as_option()
1589 .copied()
1590 .unwrap_or(ColorU::new_rgb(0, 120, 215));
1591 let border_color = match self.theme {
1592 Theme::Dark => ColorU::new_rgb(60, 60, 60),
1593 Theme::Light => ColorU::new_rgb(200, 200, 200),
1594 };
1595
1596 let corner_radius = self
1598 .metrics
1599 .corner_radius
1600 .map(|px| {
1601 use crate::props::basic::pixel::DEFAULT_FONT_SIZE;
1602 format!("{}px", px.to_pixels_internal(1.0, DEFAULT_FONT_SIZE, DEFAULT_FONT_SIZE))
1603 })
1604 .unwrap_or_else(|| "4px".to_string());
1605
1606 css.push_str(&format!(
1608 ".csd-titlebar {{ width: 100%; height: 32px; background: rgb({}, {}, {}); \
1609 border-bottom: 1px solid rgb({}, {}, {}); display: flex; flex-direction: row; \
1610 align-items: center; justify-content: space-between; padding: 0 8px; \
1611 cursor: grab; user-select: none; }} ",
1612 bg_color.r, bg_color.g, bg_color.b, border_color.r, border_color.g, border_color.b,
1613 ));
1614
1615 css.push_str(&format!(
1617 ".csd-title {{ color: rgb({}, {}, {}); font-size: 13px; flex-grow: 1; text-align: \
1618 center; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; \
1619 user-select: none; }} ",
1620 text_color.r, text_color.g, text_color.b,
1621 ));
1622
1623 css.push_str(".csd-buttons { display: flex; flex-direction: row; gap: 4px; } ");
1625
1626 css.push_str(&format!(
1628 ".csd-button {{ width: 32px; height: 24px; border-radius: {}; background: \
1629 transparent; color: rgb({}, {}, {}); font-size: 16px; line-height: 24px; text-align: \
1630 center; cursor: pointer; user-select: none; }} ",
1631 corner_radius, text_color.r, text_color.g, text_color.b,
1632 ));
1633
1634 let hover_color = match self.theme {
1636 Theme::Dark => ColorU::new_rgb(60, 60, 60),
1637 Theme::Light => ColorU::new_rgb(220, 220, 220),
1638 };
1639 css.push_str(&format!(
1640 ".csd-button:hover {{ background: rgb({}, {}, {}); }} ",
1641 hover_color.r, hover_color.g, hover_color.b,
1642 ));
1643
1644 css.push_str(
1646 ".csd-close:hover { background: rgb(232, 17, 35); color: rgb(255, 255, 255); } ",
1647 );
1648
1649 match self.platform {
1651 Platform::MacOs => {
1652 css.push_str(".csd-buttons { position: absolute; left: 8px; } ");
1654 css.push_str(
1655 ".csd-close { background: rgb(255, 95, 86); width: 12px; height: 12px; \
1656 border-radius: 50%; } ",
1657 );
1658 css.push_str(
1659 ".csd-minimize { background: rgb(255, 189, 46); width: 12px; height: 12px; \
1660 border-radius: 50%; } ",
1661 );
1662 css.push_str(
1663 ".csd-maximize { background: rgb(40, 201, 64); width: 12px; height: 12px; \
1664 border-radius: 50%; } ",
1665 );
1666 }
1667 Platform::Linux(_) => {
1668 css.push_str(".csd-title { text-align: left; } ");
1670 }
1671 _ => {
1672 }
1674 }
1675
1676 let (mut parsed_css, _warnings) = new_from_str(&css);
1678 for rule in parsed_css.rules.as_mut() {
1680 rule.priority = crate::css::rule_priority::SYSTEM;
1681 }
1682 parsed_css
1683 }
1684}
1685
1686pub fn detect_linux_desktop_env() -> DesktopEnvironment {
1691 if let Ok(desktop) = std::env::var("XDG_CURRENT_DESKTOP") {
1693 let desktop_lower = desktop.to_lowercase();
1694 if desktop_lower.contains("gnome") {
1695 return DesktopEnvironment::Gnome;
1696 }
1697 if desktop_lower.contains("kde") || desktop_lower.contains("plasma") {
1698 return DesktopEnvironment::Kde;
1699 }
1700 if desktop_lower.contains("xfce") {
1701 return DesktopEnvironment::Other(AzString::from_const_str("XFCE"));
1702 }
1703 if desktop_lower.contains("unity") {
1704 return DesktopEnvironment::Other(AzString::from_const_str("Unity"));
1705 }
1706 if desktop_lower.contains("cinnamon") {
1707 return DesktopEnvironment::Other(AzString::from_const_str("Cinnamon"));
1708 }
1709 if desktop_lower.contains("mate") {
1710 return DesktopEnvironment::Other(AzString::from_const_str("MATE"));
1711 }
1712 if desktop_lower.contains("lxde") || desktop_lower.contains("lxqt") {
1713 return DesktopEnvironment::Other(AzString::from(desktop.to_uppercase()));
1714 }
1715 if desktop_lower.contains("budgie") {
1716 return DesktopEnvironment::Other(AzString::from_const_str("Budgie"));
1717 }
1718 if desktop_lower.contains("pantheon") {
1719 return DesktopEnvironment::Other(AzString::from_const_str("Pantheon"));
1720 }
1721 if desktop_lower.contains("deepin") {
1722 return DesktopEnvironment::Other(AzString::from_const_str("Deepin"));
1723 }
1724 if desktop_lower.contains("hyprland") {
1725 return DesktopEnvironment::Other(AzString::from_const_str("Hyprland"));
1726 }
1727 if desktop_lower.contains("sway") {
1728 return DesktopEnvironment::Other(AzString::from_const_str("Sway"));
1729 }
1730 if desktop_lower.contains("i3") {
1731 return DesktopEnvironment::Other(AzString::from_const_str("i3"));
1732 }
1733 return DesktopEnvironment::Other(AzString::from(desktop));
1734 }
1735
1736 if let Ok(session) = std::env::var("DESKTOP_SESSION") {
1738 let session_lower = session.to_lowercase();
1739 if session_lower.contains("gnome") {
1740 return DesktopEnvironment::Gnome;
1741 }
1742 if session_lower.contains("plasma") || session_lower.contains("kde") {
1743 return DesktopEnvironment::Kde;
1744 }
1745 if session_lower.contains("xfce") {
1746 return DesktopEnvironment::Other(AzString::from_const_str("XFCE"));
1747 }
1748 if session_lower.contains("cinnamon") {
1749 return DesktopEnvironment::Other(AzString::from_const_str("Cinnamon"));
1750 }
1751 return DesktopEnvironment::Other(AzString::from(session));
1752 }
1753
1754 if std::env::var("GNOME_DESKTOP_SESSION_ID").is_ok() {
1756 return DesktopEnvironment::Gnome;
1757 }
1758 if std::env::var("KDE_FULL_SESSION").is_ok() {
1759 return DesktopEnvironment::Kde;
1760 }
1761 if std::env::var("HYPRLAND_INSTANCE_SIGNATURE").is_ok() {
1762 return DesktopEnvironment::Other(AzString::from_const_str("Hyprland"));
1763 }
1764 if std::env::var("SWAYSOCK").is_ok() {
1765 return DesktopEnvironment::Other(AzString::from_const_str("Sway"));
1766 }
1767 if std::env::var("I3SOCK").is_ok() {
1768 return DesktopEnvironment::Other(AzString::from_const_str("i3"));
1769 }
1770
1771 DesktopEnvironment::Other(AzString::from_const_str("Unknown"))
1772}
1773
1774pub fn detect_system_language() -> AzString {
1780 let env_vars = ["LANGUAGE", "LC_ALL", "LC_MESSAGES", "LANG"];
1781 for var in &env_vars {
1782 if let Ok(value) = std::env::var(var) {
1783 let value = value.trim();
1784 if value.is_empty() || value == "C" || value == "POSIX" {
1785 continue;
1786 }
1787 let lang = value
1789 .split('.') .next()
1791 .unwrap_or(value)
1792 .split(':') .next()
1794 .unwrap_or(value);
1795 if !lang.is_empty() {
1796 return AzString::from(lang.replace('_', "-"));
1797 }
1798 }
1799 }
1800 AzString::from_const_str("en-US")
1801}
1802
1803pub mod defaults {
1804 use crate::{
1810 corety::{AzString, OptionF32, OptionString},
1811 dynamic_selector::{BoolCondition, OsVersion},
1812 props::{
1813 basic::{
1814 color::{ColorU, OptionColorU},
1815 pixel::{PixelValue, OptionPixelValue},
1816 },
1817 layout::{
1818 dimensions::LayoutWidth,
1819 spacing::{LayoutPaddingLeft, LayoutPaddingRight},
1820 },
1821 style::{
1822 background::StyleBackgroundContent,
1823 scrollbar::{
1824 ComputedScrollbarStyle, OverflowScrolling, OverscrollBehavior, ScrollBehavior,
1825 ScrollPhysics, ScrollbarInfo,
1826 SCROLLBAR_ANDROID_DARK, SCROLLBAR_ANDROID_LIGHT, SCROLLBAR_CLASSIC_DARK,
1827 SCROLLBAR_CLASSIC_LIGHT, SCROLLBAR_IOS_DARK, SCROLLBAR_IOS_LIGHT,
1828 SCROLLBAR_MACOS_DARK, SCROLLBAR_MACOS_LIGHT, SCROLLBAR_WINDOWS_DARK,
1829 SCROLLBAR_WINDOWS_LIGHT,
1830 },
1831 },
1832 },
1833 system::{
1834 DesktopEnvironment, Platform, SystemColors, SystemFonts, SystemMetrics, SystemStyle,
1835 Theme, IconStyleOptions, TitlebarMetrics,
1836 },
1837 };
1838
1839 pub const SCROLLBAR_WINDOWS_CLASSIC: ScrollbarInfo = ScrollbarInfo {
1843 width: LayoutWidth::Px(crate::props::basic::pixel::PixelValue::const_px(17)),
1844 padding_left: LayoutPaddingLeft {
1845 inner: crate::props::basic::pixel::PixelValue::const_px(0),
1846 },
1847 padding_right: LayoutPaddingRight {
1848 inner: crate::props::basic::pixel::PixelValue::const_px(0),
1849 },
1850 track: StyleBackgroundContent::Color(ColorU {
1851 r: 223,
1852 g: 223,
1853 b: 223,
1854 a: 255,
1855 }), thumb: StyleBackgroundContent::Color(ColorU {
1857 r: 208,
1858 g: 208,
1859 b: 208,
1860 a: 255,
1861 }), button: StyleBackgroundContent::Color(ColorU {
1863 r: 208,
1864 g: 208,
1865 b: 208,
1866 a: 255,
1867 }),
1868 corner: StyleBackgroundContent::Color(ColorU {
1869 r: 223,
1870 g: 223,
1871 b: 223,
1872 a: 255,
1873 }),
1874 resizer: StyleBackgroundContent::Color(ColorU::TRANSPARENT),
1875 clip_to_container_border: false,
1876 scroll_behavior: ScrollBehavior::Auto,
1877 overscroll_behavior_x: OverscrollBehavior::None,
1878 overscroll_behavior_y: OverscrollBehavior::None,
1879 overflow_scrolling: OverflowScrolling::Auto,
1880 };
1881
1882 pub const SCROLLBAR_MACOS_AQUA: ScrollbarInfo = ScrollbarInfo {
1884 width: LayoutWidth::Px(crate::props::basic::pixel::PixelValue::const_px(15)),
1885 padding_left: LayoutPaddingLeft {
1886 inner: crate::props::basic::pixel::PixelValue::const_px(0),
1887 },
1888 padding_right: LayoutPaddingRight {
1889 inner: crate::props::basic::pixel::PixelValue::const_px(0),
1890 },
1891 track: StyleBackgroundContent::Color(ColorU {
1892 r: 238,
1893 g: 238,
1894 b: 238,
1895 a: 128,
1896 }), thumb: StyleBackgroundContent::Color(ColorU {
1898 r: 105,
1899 g: 173,
1900 b: 255,
1901 a: 255,
1902 }), button: StyleBackgroundContent::Color(ColorU {
1904 r: 105,
1905 g: 173,
1906 b: 255,
1907 a: 255,
1908 }),
1909 corner: StyleBackgroundContent::Color(ColorU::TRANSPARENT),
1910 resizer: StyleBackgroundContent::Color(ColorU::TRANSPARENT),
1911 clip_to_container_border: true,
1912 scroll_behavior: ScrollBehavior::Smooth,
1913 overscroll_behavior_x: OverscrollBehavior::Auto,
1914 overscroll_behavior_y: OverscrollBehavior::Auto,
1915 overflow_scrolling: OverflowScrolling::Auto,
1916 };
1917
1918 pub const SCROLLBAR_KDE_OXYGEN: ScrollbarInfo = ScrollbarInfo {
1920 width: LayoutWidth::Px(crate::props::basic::pixel::PixelValue::const_px(14)),
1921 padding_left: LayoutPaddingLeft {
1922 inner: crate::props::basic::pixel::PixelValue::const_px(2),
1923 },
1924 padding_right: LayoutPaddingRight {
1925 inner: crate::props::basic::pixel::PixelValue::const_px(2),
1926 },
1927 track: StyleBackgroundContent::Color(ColorU {
1928 r: 242,
1929 g: 242,
1930 b: 242,
1931 a: 255,
1932 }),
1933 thumb: StyleBackgroundContent::Color(ColorU {
1934 r: 177,
1935 g: 177,
1936 b: 177,
1937 a: 255,
1938 }),
1939 button: StyleBackgroundContent::Color(ColorU {
1940 r: 216,
1941 g: 216,
1942 b: 216,
1943 a: 255,
1944 }),
1945 corner: StyleBackgroundContent::Color(ColorU::TRANSPARENT),
1946 resizer: StyleBackgroundContent::Color(ColorU::TRANSPARENT),
1947 clip_to_container_border: false,
1948 scroll_behavior: ScrollBehavior::Auto,
1949 overscroll_behavior_x: OverscrollBehavior::Auto,
1950 overscroll_behavior_y: OverscrollBehavior::Auto,
1951 overflow_scrolling: OverflowScrolling::Auto,
1952 };
1953
1954 fn scrollbar_info_to_computed(info: &ScrollbarInfo) -> ComputedScrollbarStyle {
1956 ComputedScrollbarStyle {
1957 width: Some(info.width.clone()),
1958 thumb_color: match info.thumb {
1959 StyleBackgroundContent::Color(c) => Some(c),
1960 _ => None,
1961 },
1962 track_color: match info.track {
1963 StyleBackgroundContent::Color(c) => Some(c),
1964 _ => None,
1965 },
1966 }
1967 }
1968
1969 pub fn windows_11_light() -> SystemStyle {
1973 SystemStyle {
1974 theme: Theme::Light,
1975 platform: Platform::Windows,
1976 colors: SystemColors {
1977 text: OptionColorU::Some(ColorU::new_rgb(0, 0, 0)),
1978 background: OptionColorU::Some(ColorU::new_rgb(243, 243, 243)),
1979 accent: OptionColorU::Some(ColorU::new_rgb(0, 95, 184)),
1980 window_background: OptionColorU::Some(ColorU::new_rgb(255, 255, 255)),
1981 selection_background: OptionColorU::Some(ColorU::new_rgb(0, 120, 215)),
1982 selection_text: OptionColorU::Some(ColorU::new_rgb(255, 255, 255)),
1983 ..Default::default()
1984 },
1985 fonts: SystemFonts {
1986 ui_font: OptionString::Some("Segoe UI Variable Text".into()),
1987 ui_font_size: OptionF32::Some(9.0),
1988 monospace_font: OptionString::Some("Consolas".into()),
1989 ..Default::default()
1990 },
1991 metrics: SystemMetrics {
1992 corner_radius: OptionPixelValue::Some(PixelValue::px(4.0)),
1993 border_width: OptionPixelValue::Some(PixelValue::px(1.0)),
1994 button_padding_horizontal: OptionPixelValue::Some(PixelValue::px(12.0)),
1995 button_padding_vertical: OptionPixelValue::Some(PixelValue::px(6.0)),
1996 titlebar: TitlebarMetrics::windows(),
1997 },
1998 scrollbar: Some(Box::new(scrollbar_info_to_computed(&SCROLLBAR_WINDOWS_LIGHT))),
1999 app_specific_stylesheet: None,
2000 icon_style: IconStyleOptions::default(),
2001 language: AzString::from_const_str("en-US"),
2002 os_version: OsVersion::WIN_11,
2003 prefers_reduced_motion: BoolCondition::False,
2004 prefers_high_contrast: BoolCondition::False,
2005 scroll_physics: ScrollPhysics::windows(),
2006 ..Default::default()
2007 }
2008 }
2009
2010 pub fn windows_11_dark() -> SystemStyle {
2012 SystemStyle {
2013 theme: Theme::Dark,
2014 platform: Platform::Windows,
2015 colors: SystemColors {
2016 text: OptionColorU::Some(ColorU::new_rgb(255, 255, 255)),
2017 background: OptionColorU::Some(ColorU::new_rgb(32, 32, 32)),
2018 accent: OptionColorU::Some(ColorU::new_rgb(0, 120, 215)),
2019 window_background: OptionColorU::Some(ColorU::new_rgb(25, 25, 25)),
2020 selection_background: OptionColorU::Some(ColorU::new_rgb(0, 120, 215)),
2021 selection_text: OptionColorU::Some(ColorU::new_rgb(255, 255, 255)),
2022 ..Default::default()
2023 },
2024 fonts: SystemFonts {
2025 ui_font: OptionString::Some("Segoe UI Variable Text".into()),
2026 ui_font_size: OptionF32::Some(9.0),
2027 monospace_font: OptionString::Some("Consolas".into()),
2028 ..Default::default()
2029 },
2030 metrics: SystemMetrics {
2031 corner_radius: OptionPixelValue::Some(PixelValue::px(4.0)),
2032 border_width: OptionPixelValue::Some(PixelValue::px(1.0)),
2033 button_padding_horizontal: OptionPixelValue::Some(PixelValue::px(12.0)),
2034 button_padding_vertical: OptionPixelValue::Some(PixelValue::px(6.0)),
2035 titlebar: TitlebarMetrics::windows(),
2036 },
2037 scrollbar: Some(Box::new(scrollbar_info_to_computed(&SCROLLBAR_WINDOWS_DARK))),
2038 app_specific_stylesheet: None,
2039 icon_style: IconStyleOptions::default(),
2040 language: AzString::from_const_str("en-US"),
2041 os_version: OsVersion::WIN_11,
2042 prefers_reduced_motion: BoolCondition::False,
2043 prefers_high_contrast: BoolCondition::False,
2044 scroll_physics: ScrollPhysics::windows(),
2045 ..Default::default()
2046 }
2047 }
2048
2049 pub fn windows_7_aero() -> SystemStyle {
2051 SystemStyle {
2052 theme: Theme::Light,
2053 platform: Platform::Windows,
2054 colors: SystemColors {
2055 text: OptionColorU::Some(ColorU::new_rgb(0, 0, 0)),
2056 background: OptionColorU::Some(ColorU::new_rgb(240, 240, 240)),
2057 accent: OptionColorU::Some(ColorU::new_rgb(51, 153, 255)),
2058 window_background: OptionColorU::Some(ColorU::new_rgb(255, 255, 255)),
2059 selection_background: OptionColorU::Some(ColorU::new_rgb(51, 153, 255)),
2060 selection_text: OptionColorU::Some(ColorU::new_rgb(255, 255, 255)),
2061 ..Default::default()
2062 },
2063 fonts: SystemFonts {
2064 ui_font: OptionString::Some("Segoe UI".into()),
2065 ui_font_size: OptionF32::Some(9.0),
2066 monospace_font: OptionString::Some("Consolas".into()),
2067 ..Default::default()
2068 },
2069 metrics: SystemMetrics {
2070 corner_radius: OptionPixelValue::Some(PixelValue::px(6.0)),
2071 border_width: OptionPixelValue::Some(PixelValue::px(1.0)),
2072 button_padding_horizontal: OptionPixelValue::Some(PixelValue::px(10.0)),
2073 button_padding_vertical: OptionPixelValue::Some(PixelValue::px(5.0)),
2074 titlebar: TitlebarMetrics::windows(),
2075 },
2076 scrollbar: Some(Box::new(scrollbar_info_to_computed(&SCROLLBAR_CLASSIC_LIGHT))),
2077 app_specific_stylesheet: None,
2078 icon_style: IconStyleOptions::default(),
2079 language: AzString::from_const_str("en-US"),
2080 os_version: OsVersion::WIN_7,
2081 prefers_reduced_motion: BoolCondition::False,
2082 prefers_high_contrast: BoolCondition::False,
2083 scroll_physics: ScrollPhysics::windows(),
2084 ..Default::default()
2085 }
2086 }
2087
2088 pub fn windows_xp_luna() -> SystemStyle {
2090 SystemStyle {
2091 theme: Theme::Light,
2092 platform: Platform::Windows,
2093 colors: SystemColors {
2094 text: OptionColorU::Some(ColorU::new_rgb(0, 0, 0)),
2095 background: OptionColorU::Some(ColorU::new_rgb(236, 233, 216)),
2096 accent: OptionColorU::Some(ColorU::new_rgb(49, 106, 197)),
2097 window_background: OptionColorU::Some(ColorU::new_rgb(255, 255, 255)),
2098 selection_background: OptionColorU::Some(ColorU::new_rgb(49, 106, 197)),
2099 selection_text: OptionColorU::Some(ColorU::new_rgb(255, 255, 255)),
2100 ..Default::default()
2101 },
2102 fonts: SystemFonts {
2103 ui_font: OptionString::Some("Tahoma".into()),
2104 ui_font_size: OptionF32::Some(8.0),
2105 monospace_font: OptionString::Some("Lucida Console".into()),
2106 ..Default::default()
2107 },
2108 metrics: SystemMetrics {
2109 corner_radius: OptionPixelValue::Some(PixelValue::px(3.0)),
2110 border_width: OptionPixelValue::Some(PixelValue::px(1.0)),
2111 button_padding_horizontal: OptionPixelValue::Some(PixelValue::px(8.0)),
2112 button_padding_vertical: OptionPixelValue::Some(PixelValue::px(4.0)),
2113 titlebar: TitlebarMetrics::windows(),
2114 },
2115 scrollbar: Some(Box::new(scrollbar_info_to_computed(&SCROLLBAR_WINDOWS_CLASSIC))),
2116 app_specific_stylesheet: None,
2117 icon_style: IconStyleOptions::default(),
2118 language: AzString::from_const_str("en-US"),
2119 os_version: OsVersion::WIN_XP,
2120 prefers_reduced_motion: BoolCondition::False,
2121 prefers_high_contrast: BoolCondition::False,
2122 scroll_physics: ScrollPhysics::windows(),
2123 ..Default::default()
2124 }
2125 }
2126
2127 pub fn macos_modern_light() -> SystemStyle {
2131 SystemStyle {
2132 platform: Platform::MacOs,
2133 theme: Theme::Light,
2134 colors: SystemColors {
2135 text: OptionColorU::Some(ColorU::new(0, 0, 0, 221)),
2136 background: OptionColorU::Some(ColorU::new_rgb(242, 242, 247)),
2137 accent: OptionColorU::Some(ColorU::new_rgb(0, 122, 255)),
2138 window_background: OptionColorU::Some(ColorU::new_rgb(255, 255, 255)),
2139 selection_background: OptionColorU::Some(ColorU::new(0, 122, 255, 128)),
2141 selection_text: OptionColorU::Some(ColorU::new_rgb(0, 0, 0)),
2142 ..Default::default()
2143 },
2144 fonts: SystemFonts {
2145 ui_font: OptionString::Some(".SF NS".into()),
2146 ui_font_size: OptionF32::Some(13.0),
2147 monospace_font: OptionString::Some("Menlo".into()),
2148 ..Default::default()
2149 },
2150 metrics: SystemMetrics {
2151 corner_radius: OptionPixelValue::Some(PixelValue::px(8.0)),
2152 border_width: OptionPixelValue::Some(PixelValue::px(1.0)),
2153 button_padding_horizontal: OptionPixelValue::Some(PixelValue::px(16.0)),
2154 button_padding_vertical: OptionPixelValue::Some(PixelValue::px(6.0)),
2155 titlebar: TitlebarMetrics::macos(),
2156 },
2157 scrollbar: Some(Box::new(scrollbar_info_to_computed(&SCROLLBAR_MACOS_LIGHT))),
2158 app_specific_stylesheet: None,
2159 icon_style: IconStyleOptions::default(),
2160 language: AzString::from_const_str("en-US"),
2161 os_version: OsVersion::MACOS_SONOMA,
2162 prefers_reduced_motion: BoolCondition::False,
2163 prefers_high_contrast: BoolCondition::False,
2164 scroll_physics: ScrollPhysics::macos(),
2165 ..Default::default()
2166 }
2167 }
2168
2169 pub fn macos_modern_dark() -> SystemStyle {
2171 SystemStyle {
2172 platform: Platform::MacOs,
2173 theme: Theme::Dark,
2174 colors: SystemColors {
2175 text: OptionColorU::Some(ColorU::new(255, 255, 255, 221)),
2176 background: OptionColorU::Some(ColorU::new_rgb(28, 28, 30)),
2177 accent: OptionColorU::Some(ColorU::new_rgb(10, 132, 255)),
2178 window_background: OptionColorU::Some(ColorU::new_rgb(44, 44, 46)),
2179 selection_background: OptionColorU::Some(ColorU::new(10, 132, 255, 128)),
2181 selection_text: OptionColorU::Some(ColorU::new_rgb(255, 255, 255)),
2182 ..Default::default()
2183 },
2184 fonts: SystemFonts {
2185 ui_font: OptionString::Some(".SF NS".into()),
2186 ui_font_size: OptionF32::Some(13.0),
2187 monospace_font: OptionString::Some("SF Mono".into()),
2188 monospace_font_size: OptionF32::Some(12.0),
2189 title_font: OptionString::Some(".SF NS".into()),
2190 title_font_size: OptionF32::Some(13.0),
2191 menu_font: OptionString::Some(".SF NS".into()),
2192 menu_font_size: OptionF32::Some(13.0),
2193 small_font: OptionString::Some(".SF NS".into()),
2194 small_font_size: OptionF32::Some(11.0),
2195 ..Default::default()
2196 },
2197 metrics: SystemMetrics {
2198 corner_radius: OptionPixelValue::Some(PixelValue::px(8.0)),
2199 border_width: OptionPixelValue::Some(PixelValue::px(1.0)),
2200 button_padding_horizontal: OptionPixelValue::Some(PixelValue::px(16.0)),
2201 button_padding_vertical: OptionPixelValue::Some(PixelValue::px(6.0)),
2202 titlebar: TitlebarMetrics::macos(),
2203 },
2204 scrollbar: Some(Box::new(scrollbar_info_to_computed(&SCROLLBAR_MACOS_DARK))),
2205 app_specific_stylesheet: None,
2206 icon_style: IconStyleOptions::default(),
2207 language: AzString::from_const_str("en-US"),
2208 os_version: OsVersion::MACOS_SONOMA,
2209 prefers_reduced_motion: BoolCondition::False,
2210 prefers_high_contrast: BoolCondition::False,
2211 scroll_physics: ScrollPhysics::macos(),
2212 ..Default::default()
2213 }
2214 }
2215
2216 pub fn macos_aqua() -> SystemStyle {
2218 SystemStyle {
2219 platform: Platform::MacOs,
2220 theme: Theme::Light,
2221 colors: SystemColors {
2222 text: OptionColorU::Some(ColorU::new_rgb(0, 0, 0)),
2223 background: OptionColorU::Some(ColorU::new_rgb(229, 229, 229)),
2224 accent: OptionColorU::Some(ColorU::new_rgb(63, 128, 234)),
2225 window_background: OptionColorU::Some(ColorU::new_rgb(255, 255, 255)),
2226 ..Default::default()
2227 },
2228 fonts: SystemFonts {
2229 ui_font: OptionString::Some("Lucida Grande".into()),
2230 ui_font_size: OptionF32::Some(13.0),
2231 monospace_font: OptionString::Some("Monaco".into()),
2232 monospace_font_size: OptionF32::Some(12.0),
2233 ..Default::default()
2234 },
2235 metrics: SystemMetrics {
2236 corner_radius: OptionPixelValue::Some(PixelValue::px(12.0)),
2237 border_width: OptionPixelValue::Some(PixelValue::px(1.0)),
2238 button_padding_horizontal: OptionPixelValue::Some(PixelValue::px(16.0)),
2239 button_padding_vertical: OptionPixelValue::Some(PixelValue::px(6.0)),
2240 titlebar: TitlebarMetrics::macos(),
2241 },
2242 scrollbar: Some(Box::new(scrollbar_info_to_computed(&SCROLLBAR_MACOS_AQUA))),
2243 app_specific_stylesheet: None,
2244 icon_style: IconStyleOptions::default(),
2245 language: AzString::from_const_str("en-US"),
2246 os_version: OsVersion::MACOS_TIGER,
2247 prefers_reduced_motion: BoolCondition::False,
2248 prefers_high_contrast: BoolCondition::False,
2249 scroll_physics: ScrollPhysics::macos(),
2250 ..Default::default()
2251 }
2252 }
2253
2254 pub fn gnome_adwaita_light() -> SystemStyle {
2258 SystemStyle {
2259 platform: Platform::Linux(DesktopEnvironment::Gnome),
2260 theme: Theme::Light,
2261 colors: SystemColors {
2262 text: OptionColorU::Some(ColorU::new_rgb(46, 52, 54)),
2263 background: OptionColorU::Some(ColorU::new_rgb(249, 249, 249)),
2264 accent: OptionColorU::Some(ColorU::new_rgb(53, 132, 228)),
2265 window_background: OptionColorU::Some(ColorU::new_rgb(237, 237, 237)),
2266 ..Default::default()
2267 },
2268 fonts: SystemFonts {
2269 ui_font: OptionString::Some("Cantarell".into()),
2270 ui_font_size: OptionF32::Some(11.0),
2271 monospace_font: OptionString::Some("Monospace".into()),
2272 ..Default::default()
2273 },
2274 metrics: SystemMetrics {
2275 corner_radius: OptionPixelValue::Some(PixelValue::px(4.0)),
2276 border_width: OptionPixelValue::Some(PixelValue::px(1.0)),
2277 button_padding_horizontal: OptionPixelValue::Some(PixelValue::px(12.0)),
2278 button_padding_vertical: OptionPixelValue::Some(PixelValue::px(8.0)),
2279 titlebar: TitlebarMetrics::linux_gnome(),
2280 },
2281 scrollbar: Some(Box::new(scrollbar_info_to_computed(&SCROLLBAR_CLASSIC_LIGHT))),
2282 app_specific_stylesheet: None,
2283 icon_style: IconStyleOptions::default(),
2284 language: AzString::from_const_str("en-US"),
2285 os_version: OsVersion::LINUX_6_0,
2286 prefers_reduced_motion: BoolCondition::False,
2287 prefers_high_contrast: BoolCondition::False,
2288 ..Default::default()
2289 }
2290 }
2291
2292 pub fn gnome_adwaita_dark() -> SystemStyle {
2294 SystemStyle {
2295 platform: Platform::Linux(DesktopEnvironment::Gnome),
2296 theme: Theme::Dark,
2297 colors: SystemColors {
2298 text: OptionColorU::Some(ColorU::new_rgb(238, 238, 236)),
2299 background: OptionColorU::Some(ColorU::new_rgb(36, 36, 36)),
2300 accent: OptionColorU::Some(ColorU::new_rgb(53, 132, 228)),
2301 window_background: OptionColorU::Some(ColorU::new_rgb(48, 48, 48)),
2302 ..Default::default()
2303 },
2304 fonts: SystemFonts {
2305 ui_font: OptionString::Some("Cantarell".into()),
2306 ui_font_size: OptionF32::Some(11.0),
2307 monospace_font: OptionString::Some("Monospace".into()),
2308 ..Default::default()
2309 },
2310 metrics: SystemMetrics {
2311 corner_radius: OptionPixelValue::Some(PixelValue::px(4.0)),
2312 border_width: OptionPixelValue::Some(PixelValue::px(1.0)),
2313 button_padding_horizontal: OptionPixelValue::Some(PixelValue::px(12.0)),
2314 button_padding_vertical: OptionPixelValue::Some(PixelValue::px(8.0)),
2315 titlebar: TitlebarMetrics::linux_gnome(),
2316 },
2317 scrollbar: Some(Box::new(scrollbar_info_to_computed(&SCROLLBAR_CLASSIC_DARK))),
2318 app_specific_stylesheet: None,
2319 icon_style: IconStyleOptions::default(),
2320 language: AzString::from_const_str("en-US"),
2321 os_version: OsVersion::LINUX_6_0,
2322 prefers_reduced_motion: BoolCondition::False,
2323 prefers_high_contrast: BoolCondition::False,
2324 ..Default::default()
2325 }
2326 }
2327
2328 pub fn gtk2_clearlooks() -> SystemStyle {
2330 SystemStyle {
2331 platform: Platform::Linux(DesktopEnvironment::Gnome),
2332 theme: Theme::Light,
2333 colors: SystemColors {
2334 text: OptionColorU::Some(ColorU::new_rgb(0, 0, 0)),
2335 background: OptionColorU::Some(ColorU::new_rgb(239, 239, 239)),
2336 accent: OptionColorU::Some(ColorU::new_rgb(245, 121, 0)),
2337 ..Default::default()
2338 },
2339 fonts: SystemFonts {
2340 ui_font: OptionString::Some("DejaVu Sans".into()),
2341 ui_font_size: OptionF32::Some(10.0),
2342 monospace_font: OptionString::Some("DejaVu Sans Mono".into()),
2343 ..Default::default()
2344 },
2345 metrics: SystemMetrics {
2346 corner_radius: OptionPixelValue::Some(PixelValue::px(4.0)),
2347 border_width: OptionPixelValue::Some(PixelValue::px(1.0)),
2348 button_padding_horizontal: OptionPixelValue::Some(PixelValue::px(10.0)),
2349 button_padding_vertical: OptionPixelValue::Some(PixelValue::px(6.0)),
2350 titlebar: TitlebarMetrics::linux_gnome(),
2351 },
2352 scrollbar: Some(Box::new(scrollbar_info_to_computed(&SCROLLBAR_CLASSIC_LIGHT))),
2353 app_specific_stylesheet: None,
2354 icon_style: IconStyleOptions::default(),
2355 language: AzString::from_const_str("en-US"),
2356 os_version: OsVersion::LINUX_2_6,
2357 prefers_reduced_motion: BoolCondition::False,
2358 prefers_high_contrast: BoolCondition::False,
2359 ..Default::default()
2360 }
2361 }
2362
2363 pub fn kde_breeze_light() -> SystemStyle {
2365 SystemStyle {
2366 platform: Platform::Linux(DesktopEnvironment::Kde),
2367 theme: Theme::Light,
2368 colors: SystemColors {
2369 text: OptionColorU::Some(ColorU::new_rgb(31, 36, 39)),
2370 background: OptionColorU::Some(ColorU::new_rgb(239, 240, 241)),
2371 accent: OptionColorU::Some(ColorU::new_rgb(61, 174, 233)),
2372 ..Default::default()
2373 },
2374 fonts: SystemFonts {
2375 ui_font: OptionString::Some("Noto Sans".into()),
2376 ui_font_size: OptionF32::Some(10.0),
2377 monospace_font: OptionString::Some("Hack".into()),
2378 ..Default::default()
2379 },
2380 metrics: SystemMetrics {
2381 corner_radius: OptionPixelValue::Some(PixelValue::px(4.0)),
2382 border_width: OptionPixelValue::Some(PixelValue::px(1.0)),
2383 button_padding_horizontal: OptionPixelValue::Some(PixelValue::px(12.0)),
2384 button_padding_vertical: OptionPixelValue::Some(PixelValue::px(6.0)),
2385 titlebar: TitlebarMetrics::linux_gnome(),
2386 },
2387 scrollbar: Some(Box::new(scrollbar_info_to_computed(&SCROLLBAR_KDE_OXYGEN))),
2388 app_specific_stylesheet: None,
2389 icon_style: IconStyleOptions::default(),
2390 language: AzString::from_const_str("en-US"),
2391 os_version: OsVersion::LINUX_6_0,
2392 prefers_reduced_motion: BoolCondition::False,
2393 prefers_high_contrast: BoolCondition::False,
2394 ..Default::default()
2395 }
2396 }
2397
2398 pub fn android_material_light() -> SystemStyle {
2402 SystemStyle {
2403 platform: Platform::Android,
2404 theme: Theme::Light,
2405 colors: SystemColors {
2406 text: OptionColorU::Some(ColorU::new_rgb(0, 0, 0)),
2407 background: OptionColorU::Some(ColorU::new_rgb(255, 255, 255)),
2408 accent: OptionColorU::Some(ColorU::new_rgb(98, 0, 238)),
2409 ..Default::default()
2410 },
2411 fonts: SystemFonts {
2412 ui_font: OptionString::Some("Roboto".into()),
2413 ui_font_size: OptionF32::Some(14.0),
2414 monospace_font: OptionString::Some("Droid Sans Mono".into()),
2415 ..Default::default()
2416 },
2417 metrics: SystemMetrics {
2418 corner_radius: OptionPixelValue::Some(PixelValue::px(12.0)),
2419 border_width: OptionPixelValue::Some(PixelValue::px(1.0)),
2420 button_padding_horizontal: OptionPixelValue::Some(PixelValue::px(16.0)),
2421 button_padding_vertical: OptionPixelValue::Some(PixelValue::px(10.0)),
2422 titlebar: TitlebarMetrics::android(),
2423 },
2424 scrollbar: Some(Box::new(scrollbar_info_to_computed(&SCROLLBAR_ANDROID_LIGHT))),
2425 app_specific_stylesheet: None,
2426 icon_style: IconStyleOptions::default(),
2427 language: AzString::from_const_str("en-US"),
2428 os_version: OsVersion::ANDROID_14,
2429 prefers_reduced_motion: BoolCondition::False,
2430 prefers_high_contrast: BoolCondition::False,
2431 scroll_physics: ScrollPhysics::android(),
2432 ..Default::default()
2433 }
2434 }
2435
2436 pub fn android_holo_dark() -> SystemStyle {
2438 SystemStyle {
2439 platform: Platform::Android,
2440 theme: Theme::Dark,
2441 colors: SystemColors {
2442 text: OptionColorU::Some(ColorU::new_rgb(255, 255, 255)),
2443 background: OptionColorU::Some(ColorU::new_rgb(0, 0, 0)),
2444 accent: OptionColorU::Some(ColorU::new_rgb(51, 181, 229)),
2445 ..Default::default()
2446 },
2447 fonts: SystemFonts {
2448 ui_font: OptionString::Some("Roboto".into()),
2449 ui_font_size: OptionF32::Some(14.0),
2450 monospace_font: OptionString::Some("Droid Sans Mono".into()),
2451 ..Default::default()
2452 },
2453 metrics: SystemMetrics {
2454 corner_radius: OptionPixelValue::Some(PixelValue::px(2.0)),
2455 border_width: OptionPixelValue::Some(PixelValue::px(1.0)),
2456 button_padding_horizontal: OptionPixelValue::Some(PixelValue::px(12.0)),
2457 button_padding_vertical: OptionPixelValue::Some(PixelValue::px(8.0)),
2458 titlebar: TitlebarMetrics::android(),
2459 },
2460 scrollbar: Some(Box::new(scrollbar_info_to_computed(&SCROLLBAR_ANDROID_DARK))),
2461 app_specific_stylesheet: None,
2462 icon_style: IconStyleOptions::default(),
2463 language: AzString::from_const_str("en-US"),
2464 os_version: OsVersion::ANDROID_ICE_CREAM_SANDWICH,
2465 prefers_reduced_motion: BoolCondition::False,
2466 prefers_high_contrast: BoolCondition::False,
2467 scroll_physics: ScrollPhysics::android(),
2468 ..Default::default()
2469 }
2470 }
2471
2472 pub fn ios_light() -> SystemStyle {
2474 SystemStyle {
2475 platform: Platform::Ios,
2476 theme: Theme::Light,
2477 colors: SystemColors {
2478 text: OptionColorU::Some(ColorU::new_rgb(0, 0, 0)),
2479 background: OptionColorU::Some(ColorU::new_rgb(242, 242, 247)),
2480 accent: OptionColorU::Some(ColorU::new_rgb(0, 122, 255)),
2481 ..Default::default()
2482 },
2483 fonts: SystemFonts {
2484 ui_font: OptionString::Some(".SFUI-Display-Regular".into()),
2485 ui_font_size: OptionF32::Some(17.0),
2486 monospace_font: OptionString::Some("Menlo".into()),
2487 ..Default::default()
2488 },
2489 metrics: SystemMetrics {
2490 corner_radius: OptionPixelValue::Some(PixelValue::px(10.0)),
2491 border_width: OptionPixelValue::Some(PixelValue::px(0.5)),
2492 button_padding_horizontal: OptionPixelValue::Some(PixelValue::px(20.0)),
2493 button_padding_vertical: OptionPixelValue::Some(PixelValue::px(12.0)),
2494 titlebar: TitlebarMetrics::ios(),
2495 },
2496 scrollbar: Some(Box::new(scrollbar_info_to_computed(&SCROLLBAR_IOS_LIGHT))),
2497 app_specific_stylesheet: None,
2498 icon_style: IconStyleOptions::default(),
2499 language: AzString::from_const_str("en-US"),
2500 os_version: OsVersion::IOS_17,
2501 prefers_reduced_motion: BoolCondition::False,
2502 prefers_high_contrast: BoolCondition::False,
2503 scroll_physics: ScrollPhysics::ios(),
2504 ..Default::default()
2505 }
2506 }
2507}