1use jag_draw::ColorLinPremul;
4
5use crate::ThemeMode;
6
7#[derive(Debug, Clone, Copy, PartialEq, Eq)]
9pub enum CursorHint {
10 Default,
11 ResizeHorizontal,
12 ResizeVertical,
13 Pointer,
14}
15
16#[derive(Debug, Clone, PartialEq)]
18pub enum WidgetEvent {
19 Ignored,
21 Consumed,
23 TabSelected { index: usize },
25 TabClose { index: usize },
27 PopupItemSelected { index: usize },
29 PopupDismissed,
31 SetCursor(CursorHint),
33}
34
35#[derive(Debug, Clone, Copy)]
37pub struct WidgetColors {
38 pub bg: ColorLinPremul,
40 pub surface: ColorLinPremul,
42 pub hover: ColorLinPremul,
44 pub active: ColorLinPremul,
46 pub accent: ColorLinPremul,
48 pub text: ColorLinPremul,
50 pub text_muted: ColorLinPremul,
52 pub border: ColorLinPremul,
54 pub close_icon: ColorLinPremul,
56 pub dirty_dot: ColorLinPremul,
58 pub shadow: ColorLinPremul,
60}
61
62impl WidgetColors {
63 pub fn from_theme_mode(mode: ThemeMode) -> Self {
65 match mode {
66 ThemeMode::Dark => Self {
67 bg: ColorLinPremul::from_srgba_u8([22, 27, 47, 255]),
68 surface: ColorLinPremul::from_srgba_u8([30, 35, 55, 255]),
69 hover: ColorLinPremul::from_srgba_u8([40, 46, 70, 255]),
70 active: ColorLinPremul::from_srgba_u8([50, 56, 82, 255]),
71 accent: ColorLinPremul::from_srgba_u8([100, 140, 255, 255]),
72 text: ColorLinPremul::from_srgba_u8([220, 225, 240, 255]),
73 text_muted: ColorLinPremul::from_srgba_u8([140, 150, 170, 255]),
74 border: ColorLinPremul::from_srgba_u8([60, 65, 85, 255]),
75 close_icon: ColorLinPremul::from_srgba_u8([100, 110, 130, 255]),
76 dirty_dot: ColorLinPremul::from_srgba_u8([255, 200, 50, 255]),
77 shadow: ColorLinPremul::from_srgba_u8([0, 0, 0, 120]),
78 },
79 ThemeMode::Light => Self {
80 bg: ColorLinPremul::from_srgba_u8([248, 250, 252, 255]),
81 surface: ColorLinPremul::from_srgba_u8([241, 245, 249, 255]),
82 hover: ColorLinPremul::from_srgba_u8([226, 232, 240, 255]),
83 active: ColorLinPremul::from_srgba_u8([203, 213, 225, 255]),
84 accent: ColorLinPremul::from_srgba_u8([59, 130, 246, 255]),
85 text: ColorLinPremul::from_srgba_u8([15, 23, 42, 255]),
86 text_muted: ColorLinPremul::from_srgba_u8([100, 116, 139, 255]),
87 border: ColorLinPremul::from_srgba_u8([226, 232, 240, 255]),
88 close_icon: ColorLinPremul::from_srgba_u8([148, 163, 184, 255]),
89 dirty_dot: ColorLinPremul::from_srgba_u8([245, 158, 11, 255]),
90 shadow: ColorLinPremul::from_srgba_u8([0, 0, 0, 40]),
91 },
92 }
93 }
94}
95
96#[cfg(test)]
101mod tests {
102 use super::*;
103
104 #[test]
105 fn widget_event_equality() {
106 assert_eq!(WidgetEvent::Ignored, WidgetEvent::Ignored);
107 assert_ne!(WidgetEvent::Ignored, WidgetEvent::Consumed);
108 assert_eq!(
109 WidgetEvent::TabSelected { index: 1 },
110 WidgetEvent::TabSelected { index: 1 }
111 );
112 assert_ne!(
113 WidgetEvent::TabSelected { index: 0 },
114 WidgetEvent::TabClose { index: 0 }
115 );
116 }
117
118 #[test]
119 fn widget_colors_dark_and_light_differ() {
120 let dark = WidgetColors::from_theme_mode(ThemeMode::Dark);
121 let light = WidgetColors::from_theme_mode(ThemeMode::Light);
122 assert_ne!(dark.bg, light.bg);
124 }
125
126 #[test]
127 fn cursor_hint_variants() {
128 let hints = [
129 CursorHint::Default,
130 CursorHint::ResizeHorizontal,
131 CursorHint::ResizeVertical,
132 CursorHint::Pointer,
133 ];
134 for (i, a) in hints.iter().enumerate() {
135 for (j, b) in hints.iter().enumerate() {
136 if i != j {
137 assert_ne!(a, b);
138 }
139 }
140 }
141 }
142}