inset_rendering/
relayout_when_system_fonts_change.rs1use std::time::Duration;
4
5use inset_foundation::{App, Handle, Listenable, Listener};
6use inset_painting::PaintingBinding;
7use inset_scheduler::{FrameCallback, SchedulerBinding};
8
9use crate::object::{RenderHandle, RenderObject};
10
11#[derive(Debug, Default)]
13pub struct RelayoutWhenSystemFontsChangeData {
14 has_pending_system_fonts_did_change_callback: bool,
15}
16
17impl RelayoutWhenSystemFontsChangeData {
18 pub const fn new() -> RelayoutWhenSystemFontsChangeData {
20 RelayoutWhenSystemFontsChangeData {
21 has_pending_system_fonts_did_change_callback: false,
22 }
23 }
24}
25
26pub trait RelayoutWhenSystemFontsChangeMixin: RenderObject {
32 fn relayout_when_system_fonts_change_data(
34 self: RenderHandle<Self>,
35 app: &App,
36 ) -> &RelayoutWhenSystemFontsChangeData;
37
38 fn relayout_when_system_fonts_change_data_mut(
40 self: RenderHandle<Self>,
41 app: &mut App,
42 ) -> &mut RelayoutWhenSystemFontsChangeData;
43
44 fn system_fonts_did_change(self: RenderHandle<Self>, app: &mut App) {
56 self.as_render_object(app).mark_needs_layout(app);
57 }
58
59 fn attach_system_fonts(self: RenderHandle<Self>, app: &mut App) {
61 debug_assert!(
62 !self
63 .relayout_when_system_fonts_change_data(app)
64 .has_pending_system_fonts_did_change_callback
65 );
66 PaintingBinding::instance(app)
67 .system_fonts(app)
68 .add_listener(app, self.system_fonts_listener());
69 }
70
71 fn detach_system_fonts(self: RenderHandle<Self>, app: &mut App) {
73 debug_assert!(
74 !self
75 .relayout_when_system_fonts_change_data(app)
76 .has_pending_system_fonts_did_change_callback
77 );
78 PaintingBinding::instance(app)
79 .system_fonts(app)
80 .remove_listener(app, &self.system_fonts_listener());
81 }
82
83 fn system_fonts_listener(self: RenderHandle<Self>) -> Listener {
84 Listener::handle_method(self.handle(), schedule_system_fonts_update::<Self>)
85 }
86
87 fn schedule_system_fonts_update(self: RenderHandle<Self>, app: &mut App) {
88 if self
89 .relayout_when_system_fonts_change_data(app)
90 .has_pending_system_fonts_did_change_callback
91 {
92 return;
93 }
94 self.relayout_when_system_fonts_change_data_mut(app)
95 .has_pending_system_fonts_did_change_callback = true;
96 SchedulerBinding::schedule_frame_callback(
97 app,
98 FrameCallback::handle_method(self.handle(), run_system_fonts_update::<Self>),
99 None,
100 false,
101 true,
102 );
103 }
104}
105
106fn schedule_system_fonts_update<T: RelayoutWhenSystemFontsChangeMixin>(
107 this: Handle<T>,
108 app: &mut App,
109) {
110 RenderHandle::from_handle(this).schedule_system_fonts_update(app);
111}
112
113fn run_system_fonts_update<T: RelayoutWhenSystemFontsChangeMixin>(
114 this: Handle<T>,
115 app: &mut App,
116 _time_stamp: Duration,
117) {
118 let this = RenderHandle::from_handle(this);
119 if app.is_disposed(this.handle()) {
120 return;
121 }
122 debug_assert!(
123 this.relayout_when_system_fonts_change_data(app)
124 .has_pending_system_fonts_did_change_callback
125 );
126 this.relayout_when_system_fonts_change_data_mut(app)
127 .has_pending_system_fonts_did_change_callback = false;
128 if this.as_render_object(app).attached(app) {
129 RelayoutWhenSystemFontsChangeMixin::system_fonts_did_change(this, app);
130 }
131}