use galactica_content::{Content, SectionEdge, SpriteAutomaton, SpriteHandle, UiSpriteConfig}; use galactica_util::to_radians; use nalgebra::{Point2, Vector2}; use super::{CenteredSpriteRect, SpriteRect}; use crate::{vertexbuffer::types::UiInstance, RenderInput, RenderState}; pub struct UiSprite { pub anim: SpriteAutomaton, mask: Option, rect: SpriteRect, has_mouse: bool, on_mouse_enter: Option, on_mouse_leave: Option, } impl UiSprite { pub fn new( ct: &Content, sprite: SpriteHandle, mask: Option, rect: SpriteRect, on_mouse_enter: Option, on_mouse_leave: Option, ) -> Self { return Self { anim: SpriteAutomaton::new(ct, sprite), mask, rect, has_mouse: false, on_mouse_enter, on_mouse_leave, }; } pub fn from(ct: &Content, ui: &UiSpriteConfig) -> Self { if ui.sprite.is_none() { unreachable!("called `UiSprite.from()` on a UiSprite with a None sprite!") } Self::from_with_sprite(ct, ui, ui.sprite.unwrap()) } pub fn from_with_sprite(ct: &Content, ui: &UiSpriteConfig, sprite: SpriteHandle) -> Self { Self::new( ct, sprite, ui.mask, SpriteRect { pos: ui.rect.pos, dim: ui.rect.dim, anchor_self: ui.rect.anchor_self, anchor_parent: ui.rect.anchor_parent, }, ui.on_mouse_enter, ui.on_mouse_leave, ) } pub fn step(&mut self, input: &RenderInput, state: &RenderState) { if self.contains_mouse(input, state) && !self.has_mouse && self.on_mouse_enter.is_some() { self.has_mouse = true; self.anim.jump_to(input.ct, self.on_mouse_enter.unwrap()) } else if !self.contains_mouse(input, state) && self.has_mouse && self.on_mouse_leave.is_some() { self.has_mouse = false; self.anim.jump_to(input.ct, self.on_mouse_leave.unwrap()) } self.anim.step(input.ct, input.time_since_last_run); } pub fn contains_mouse(&self, input: &RenderInput, state: &RenderState) -> bool { let rect = self.get_rect(state); let fac = state.window.scale_factor() as f32; let window_size = Vector2::new( state.window_size.width as f32 / fac, state.window_size.height as f32 / fac, ); let pos = input.player.input.get_mouse_pos(); let mouse_pos = Point2::new( pos.x / fac - window_size.x / 2.0, window_size.y / 2.0 - pos.y / fac, ); return rect.contains_point(mouse_pos); } pub fn get_rect( &self, state: &RenderState, //parent: Option, ) -> CenteredSpriteRect { /* if let Some(parent) = parent { return self.rect.to_centered_relative(parent); } else { return self.rect.to_centered(state); }*/ return self.rect.to_centered(state); } /// Add this image to the gpu sprite buffer pub fn push_to_buffer(&self, input: &RenderInput, state: &mut RenderState) { let rect = self.get_rect(state); // TODO: use both dimensions, // not just height let anim_state = self.anim.get_texture_idx(); state.push_ui_buffer(UiInstance { anchor: crate::PositionAnchor::CC.to_int(), position: rect.pos.into(), angle: to_radians(90.0), dim: rect.dim.into(), color: [1.0, 1.0, 1.0, 1.0], texture_index: anim_state.texture_index(), texture_fade: anim_state.fade, mask_index: self .mask .map(|x| { let sprite = input.ct.get_sprite(x); let texture_b = sprite.get_first_frame(); // ANIMATE [1, texture_b] }) .unwrap_or([0, 0]), }); } }