use std::time::Duration;
use inset_foundation::{App, Handle, Listenable, Listener};
use inset_painting::PaintingBinding;
use inset_scheduler::{FrameCallback, SchedulerBinding};
use crate::object::{RenderHandle, RenderObject};
#[derive(Debug, Default)]
pub struct RelayoutWhenSystemFontsChangeData {
has_pending_system_fonts_did_change_callback: bool,
}
impl RelayoutWhenSystemFontsChangeData {
pub const fn new() -> RelayoutWhenSystemFontsChangeData {
RelayoutWhenSystemFontsChangeData {
has_pending_system_fonts_did_change_callback: false,
}
}
}
pub trait RelayoutWhenSystemFontsChangeMixin: RenderObject {
fn relayout_when_system_fonts_change_data(
self: RenderHandle<Self>,
app: &App,
) -> &RelayoutWhenSystemFontsChangeData;
fn relayout_when_system_fonts_change_data_mut(
self: RenderHandle<Self>,
app: &mut App,
) -> &mut RelayoutWhenSystemFontsChangeData;
fn system_fonts_did_change(self: RenderHandle<Self>, app: &mut App) {
self.as_render_object(app).mark_needs_layout(app);
}
fn attach_system_fonts(self: RenderHandle<Self>, app: &mut App) {
debug_assert!(
!self
.relayout_when_system_fonts_change_data(app)
.has_pending_system_fonts_did_change_callback
);
PaintingBinding::instance(app)
.system_fonts(app)
.add_listener(app, self.system_fonts_listener());
}
fn detach_system_fonts(self: RenderHandle<Self>, app: &mut App) {
debug_assert!(
!self
.relayout_when_system_fonts_change_data(app)
.has_pending_system_fonts_did_change_callback
);
PaintingBinding::instance(app)
.system_fonts(app)
.remove_listener(app, &self.system_fonts_listener());
}
fn system_fonts_listener(self: RenderHandle<Self>) -> Listener {
Listener::handle_method(self.handle(), schedule_system_fonts_update::<Self>)
}
fn schedule_system_fonts_update(self: RenderHandle<Self>, app: &mut App) {
if self
.relayout_when_system_fonts_change_data(app)
.has_pending_system_fonts_did_change_callback
{
return;
}
self.relayout_when_system_fonts_change_data_mut(app)
.has_pending_system_fonts_did_change_callback = true;
SchedulerBinding::schedule_frame_callback(
app,
FrameCallback::handle_method(self.handle(), run_system_fonts_update::<Self>),
None,
false,
true,
);
}
}
fn schedule_system_fonts_update<T: RelayoutWhenSystemFontsChangeMixin>(
this: Handle<T>,
app: &mut App,
) {
RenderHandle::from_handle(this).schedule_system_fonts_update(app);
}
fn run_system_fonts_update<T: RelayoutWhenSystemFontsChangeMixin>(
this: Handle<T>,
app: &mut App,
_time_stamp: Duration,
) {
let this = RenderHandle::from_handle(this);
if app.is_disposed(this.handle()) {
return;
}
debug_assert!(
this.relayout_when_system_fonts_change_data(app)
.has_pending_system_fonts_did_change_callback
);
this.relayout_when_system_fonts_change_data_mut(app)
.has_pending_system_fonts_did_change_callback = false;
if this.as_render_object(app).attached(app) {
RelayoutWhenSystemFontsChangeMixin::system_fonts_did_change(this, app);
}
}