Skip to content

Commit 08aa75b

Browse files
authored
Add dark mode selector to style (#796)
1 parent e622a2a commit 08aa75b

File tree

4 files changed

+47
-6
lines changed

4 files changed

+47
-6
lines changed

src/app_state.rs

+7-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ use std::collections::{HashMap, HashSet};
22

33
use peniko::kurbo::{Point, Size};
44
use taffy::{AvailableSpace, NodeId};
5-
use winit::window::CursorIcon;
5+
use winit::window::{CursorIcon, Theme};
66

77
use crate::{
88
context::{DragState, FrameUpdate, InteractionState},
@@ -41,6 +41,7 @@ pub struct AppState {
4141
pub(crate) grid_bps: GridBreakpoints,
4242
pub(crate) clicking: HashSet<ViewId>,
4343
pub(crate) hovered: HashSet<ViewId>,
44+
pub(crate) os_theme: Option<winit::window::Theme>,
4445
/// This keeps track of all views that have an animation,
4546
/// regardless of the status of the animation
4647
pub(crate) cursor: Option<CursorStyle>,
@@ -76,6 +77,7 @@ impl AppState {
7677
dragging_over: HashSet::new(),
7778
clicking: HashSet::new(),
7879
hovered: HashSet::new(),
80+
os_theme: None,
7981
cursor: None,
8082
last_cursor: CursorIcon::Default,
8183
last_cursor_location: Default::default(),
@@ -161,6 +163,10 @@ impl AppState {
161163
self.clicking.contains(id)
162164
}
163165

166+
pub fn is_dark_mode(&self) -> bool {
167+
self.os_theme == Some(Theme::Dark)
168+
}
169+
164170
pub fn is_dragging(&self) -> bool {
165171
self.dragging
166172
.as_ref()

src/context.rs

+2
Original file line numberDiff line numberDiff line change
@@ -519,6 +519,7 @@ pub struct InteractionState {
519519
pub(crate) is_disabled: bool,
520520
pub(crate) is_focused: bool,
521521
pub(crate) is_clicking: bool,
522+
pub(crate) is_dark_mode: bool,
522523
pub(crate) using_keyboard_navigation: bool,
523524
}
524525

@@ -563,6 +564,7 @@ impl<'a> StyleCx<'a> {
563564
is_disabled: self.app_state.is_disabled(id),
564565
is_focused: self.app_state.is_focused(id),
565566
is_clicking: self.app_state.is_clicking(id),
567+
is_dark_mode: self.app_state.is_dark_mode(),
566568
using_keyboard_navigation: self.app_state.keyboard_navigation,
567569
}
568570
}

src/style.rs

+22
Original file line numberDiff line numberDiff line change
@@ -1236,6 +1236,12 @@ impl Style {
12361236
self.apply_mut(map);
12371237
}
12381238
}
1239+
if interact_state.is_dark_mode {
1240+
if let Some(mut map) = self.get_nested_map(StyleSelector::DarkMode.to_key()) {
1241+
map.apply_interact_state(interact_state, screen_size_bp);
1242+
self.apply_mut(map);
1243+
}
1244+
}
12391245

12401246
let focused_keyboard =
12411247
interact_state.using_keyboard_navigation && interact_state.is_focused;
@@ -1383,6 +1389,7 @@ pub enum StyleSelector {
13831389
Focus,
13841390
FocusVisible,
13851391
Disabled,
1392+
DarkMode,
13861393
Active,
13871394
Dragging,
13881395
Selected,
@@ -1410,6 +1417,10 @@ style_key_selector!(
14101417
selected,
14111418
StyleSelectors::new().set(StyleSelector::Selected, true)
14121419
);
1420+
style_key_selector!(
1421+
darkmode,
1422+
StyleSelectors::new().set(StyleSelector::DarkMode, true)
1423+
);
14131424

14141425
impl StyleSelector {
14151426
fn to_key(self) -> StyleKey {
@@ -1421,6 +1432,7 @@ impl StyleSelector {
14211432
StyleSelector::Active => active(),
14221433
StyleSelector::Dragging => dragging(),
14231434
StyleSelector::Selected => selected(),
1435+
StyleSelector::DarkMode => darkmode(),
14241436
}
14251437
}
14261438
}
@@ -1866,6 +1878,10 @@ impl Style {
18661878
self.selector(StyleSelector::Disabled, style)
18671879
}
18681880

1881+
pub fn dark_mode(self, style: impl FnOnce(Style) -> Style) -> Self {
1882+
self.selector(StyleSelector::DarkMode, style)
1883+
}
1884+
18691885
pub fn active(self, style: impl FnOnce(Style) -> Style) -> Self {
18701886
self.selector(StyleSelector::Active, style)
18711887
}
@@ -2556,6 +2572,12 @@ pub trait CustomStyle: Default + Clone + Into<Style> + From<Style> {
25562572
new.into()
25572573
}
25582574

2575+
fn dark_mode(self, style: impl FnOnce(Self) -> Self) -> Self {
2576+
let self_style: Style = self.into();
2577+
let new = self_style.selector(StyleSelector::DarkMode, |_| style(Self::default()).into());
2578+
new.into()
2579+
}
2580+
25592581
fn active(self, style: impl FnOnce(Self) -> Self) -> Self {
25602582
let self_style: Style = self.into();
25612583
let new = self_style.selector(StyleSelector::Active, |_| style(Self::default()).into());

src/window_handle.rs

+16-5
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ pub(crate) struct WindowHandle {
7070
size: RwSignal<Size>,
7171
theme: Option<Theme>,
7272
pub(crate) profile: Option<Profile>,
73-
os_theme: RwSignal<Option<winit::window::Theme>>,
73+
os_theme: Option<winit::window::Theme>,
7474
is_maximized: bool,
7575
transparent: bool,
7676
pub(crate) scale: f64,
@@ -99,7 +99,7 @@ impl WindowHandle {
9999
let size: LogicalSize<f64> = size.unwrap_or(window.surface_size().to_logical(scale));
100100
let size = Size::new(size.width, size.height);
101101
let size = scope.create_rw_signal(Size::new(size.width, size.height));
102-
let theme = scope.create_rw_signal(window.theme());
102+
let os_theme = window.theme();
103103
let is_maximized = window.is_maximized();
104104

105105
set_current_view(id);
@@ -160,7 +160,7 @@ impl WindowHandle {
160160
paint_state,
161161
size,
162162
theme: apply_default_theme.then(default_theme),
163-
os_theme: theme,
163+
os_theme,
164164
is_maximized,
165165
transparent,
166166
profile: None,
@@ -174,7 +174,8 @@ impl WindowHandle {
174174
dropper_file: None,
175175
};
176176
window_handle.app_state.set_root_size(size.get_untracked());
177-
if let Some(theme) = theme.get_untracked() {
177+
window_handle.app_state.os_theme = os_theme;
178+
if let Some(theme) = os_theme {
178179
window_handle.event(Event::ThemeChanged(theme));
179180
}
180181
window_handle
@@ -418,7 +419,10 @@ impl WindowHandle {
418419
}
419420

420421
pub(crate) fn os_theme_changed(&mut self, theme: winit::window::Theme) {
421-
self.os_theme.set(Some(theme));
422+
self.os_theme = Some(theme);
423+
self.app_state.os_theme = Some(theme);
424+
self.id.request_all();
425+
request_recursive_changes(self.id, ChangeFlags::STYLE);
422426
self.event(Event::ThemeChanged(theme));
423427
}
424428

@@ -1278,6 +1282,13 @@ impl WindowHandle {
12781282
}
12791283
}
12801284

1285+
fn request_recursive_changes(id: ViewId, changes: ChangeFlags) {
1286+
id.state().borrow_mut().requested_changes = changes;
1287+
for child in id.children() {
1288+
request_recursive_changes(child, changes);
1289+
}
1290+
}
1291+
12811292
pub(crate) fn get_current_view() -> ViewId {
12821293
CURRENT_RUNNING_VIEW_HANDLE.with(|running| *running.borrow())
12831294
}

0 commit comments

Comments
 (0)