Skip to content
Snippets Groups Projects
context.rs 40.9 KiB
Newer Older
NiseVoid's avatar
NiseVoid committed
            .add_system(crate::input::process_events.in_base_set(CoreSet::Update))
            .add_system(update_widgets_sys.in_base_set(CoreSet::PostUpdate))
            .add_system(
                calculate_ui
                    .after(update_widgets_sys)
                    .in_base_set(CoreSet::PostUpdate),
            );
            // .add_system(crate::window_size::update_window_size);

        // Register reflection types.
        // A bit annoying..
        app.register_type::<ComputedStyles>()
            .register_type::<KStyle>()
            .register_type::<KChildren>()
            .register_type::<WidgetName>()
            .register_type::<StyleProp<Color>>()
            .register_type::<StyleProp<Corner<f32>>>()
            .register_type::<StyleProp<Edge<f32>>>()
            .register_type::<StyleProp<Units>>()
            .register_type::<StyleProp<KCursorIcon>>()
            .register_type::<StyleProp<String>>()
            .register_type::<StyleProp<f32>>()
            .register_type::<StyleProp<LayoutType>>()
            .register_type::<StyleProp<Edge<Units>>>()
            .register_type::<StyleProp<PointerEvents>>()
            .register_type::<StyleProp<KPositionType>>()
            .register_type::<StyleProp<RenderCommand>>()
            .register_type::<StyleProp<i32>>();
pub use crate::window_size::update_window_size;

StarToaster's avatar
StarToaster committed
fn calculate_ui(world: &mut World) {
    // dbg!("Calculating nodes!");
    let mut context_data = Vec::new();
    query_world::<Query<(Entity, &mut EventDispatcher, &mut KayakRootContext)>, _, _>(
        |mut query| {
            for (entity, mut event_dispatcher, mut kayak_root_context) in query.iter_mut() {
                context_data.push((
                    entity,
                    std::mem::take(&mut *event_dispatcher),
                    std::mem::take(&mut *kayak_root_context),
                ));
            }
        },
        world,
    );
    for (entity, event_dispatcher, mut context) in context_data.drain(..) {
        let mut node_system = IntoSystem::into_system(calculate_nodes);
        node_system.initialize(world);
        let mut layout_system = IntoSystem::into_system(calculate_layout);
        layout_system.initialize(world);
        for _ in 0..3 {
            context = node_system.run(context, world);
            node_system.apply_buffers(world);

            context = layout_system.run(context, world);
            layout_system.apply_buffers(world);
            LayoutEventDispatcher::dispatch(&mut context, world);
        }
        if event_dispatcher.hovered.is_none() {
            context.current_cursor = CursorIcon::Default;
        } else {
StarToaster's avatar
StarToaster committed
            let hovered = event_dispatcher.hovered.unwrap();
            if let Some(entity) = world.get_entity(hovered.0) {
                if let Some(node) = entity.get::<crate::node::Node>() {
                    let icon = node.resolved_styles.cursor.resolve();
                    context.current_cursor = icon.0;
                }
            }

NiseVoid's avatar
NiseVoid committed
            if let Ok(mut window) = world
                .query_filtered::<&mut Window, With<PrimaryWindow>>()
                .get_single_mut(world)
            {
                window.cursor.icon = context.current_cursor;
        world.entity_mut(entity).insert((event_dispatcher, context));
    }
StarToaster's avatar
StarToaster committed
    // dbg!("Finished calculating nodes!");

    // dbg!("Dispatching layout events!");
    // dbg!("Finished dispatching layout events!");
}

/// A simple component that stores the type name of a widget
/// This is used by Kayak in order to find out which systems to run.
#[derive(Component, Reflect, Debug, Clone, PartialEq, Eq)]
#[reflect(Component)]
StarToaster's avatar
StarToaster committed
pub struct WidgetName(pub String);

impl Default for WidgetName {
    fn default() -> Self {
        log::warn!("You did not specify a widget name for a widget!");
        Self("NO_NAME".to_string())
    }
}

StarToaster's avatar
StarToaster committed
impl From<String> for WidgetName {
    fn from(value: String) -> Self {
        WidgetName(value)
    }
}

impl Into<String> for WidgetName {
    fn into(self) -> String {