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 false,
100 true,
101 );
102 }
103}
104
105fn schedule_system_fonts_update<T: RelayoutWhenSystemFontsChangeMixin>(
106 this: Handle<T>,
107 app: &mut App,
108) {
109 RenderHandle::from_handle(this).schedule_system_fonts_update(app);
110}
111
112fn run_system_fonts_update<T: RelayoutWhenSystemFontsChangeMixin>(
113 this: Handle<T>,
114 app: &mut App,
115 _time_stamp: Duration,
116) {
117 let this = RenderHandle::from_handle(this);
118 if app.is_disposed(this.handle()) {
119 return;
120 }
121 debug_assert!(
122 this.relayout_when_system_fonts_change_data(app)
123 .has_pending_system_fonts_did_change_callback
124 );
125 this.relayout_when_system_fonts_change_data_mut(app)
126 .has_pending_system_fonts_did_change_callback = false;
127 if this.as_render_object(app).attached(app) {
128 RelayoutWhenSystemFontsChangeMixin::system_fonts_did_change(this, app);
129 }
130}