126 lines
3.1 KiB
Rust
126 lines
3.1 KiB
Rust
use galactica_content::{Content, SpriteAutomaton, SpriteHandle};
|
|
use galactica_util::to_radians;
|
|
|
|
use super::super::api::Rect;
|
|
use crate::{
|
|
ui::mouseevent::MouseEvent, vertexbuffer::types::UiInstance, RenderInput, RenderState,
|
|
};
|
|
|
|
#[derive(Debug, Clone)]
|
|
pub struct Sprite {
|
|
pub anim: SpriteAutomaton,
|
|
pub rect: Rect,
|
|
pub mask: Option<SpriteHandle>,
|
|
pub name: String,
|
|
|
|
has_mouse: bool,
|
|
has_click: bool,
|
|
/// If true, ignore mouse events until click is released
|
|
waiting_for_release: bool,
|
|
}
|
|
|
|
impl Sprite {
|
|
pub fn new(
|
|
ct: &Content,
|
|
name: String,
|
|
sprite: String,
|
|
mask: Option<String>,
|
|
rect: Rect,
|
|
) -> Self {
|
|
let sprite_handle = ct.get_sprite_handle(&sprite).unwrap(); // TODO: errors
|
|
let mask = {
|
|
if mask.is_some() {
|
|
Some(ct.get_sprite_handle(&mask.unwrap()).unwrap())
|
|
} else {
|
|
None
|
|
}
|
|
};
|
|
|
|
Self {
|
|
name,
|
|
anim: SpriteAutomaton::new(&ct, sprite_handle),
|
|
rect,
|
|
mask,
|
|
has_mouse: false,
|
|
has_click: false,
|
|
waiting_for_release: false,
|
|
}
|
|
}
|
|
|
|
pub fn push_to_buffer(&self, input: &RenderInput, state: &mut RenderState) {
|
|
let rect = self.rect.to_centered(state, input.ct.get_config().ui_scale);
|
|
|
|
// 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(); // TODO: animate?
|
|
[1, texture_b]
|
|
})
|
|
.unwrap_or([0, 0]),
|
|
});
|
|
}
|
|
|
|
pub fn check_mouse(&mut self, input: &RenderInput, state: &mut RenderState) -> MouseEvent {
|
|
let r = self.rect.to_centered(state, input.ct.get_config().ui_scale);
|
|
|
|
if self.waiting_for_release && self.has_mouse && !input.player.input.pressed_leftclick() {
|
|
self.waiting_for_release = false;
|
|
}
|
|
|
|
if !self.waiting_for_release
|
|
&& self.has_mouse
|
|
&& !self.has_click
|
|
&& input.player.input.pressed_leftclick()
|
|
{
|
|
self.has_click = true;
|
|
return MouseEvent::Click;
|
|
}
|
|
|
|
if self.has_mouse && self.has_click && !input.player.input.pressed_leftclick() {
|
|
self.has_click = false;
|
|
return MouseEvent::Release;
|
|
}
|
|
|
|
// Release mouse when cursor leaves box
|
|
if self.has_click && !self.has_mouse {
|
|
self.has_click = false;
|
|
return MouseEvent::Release;
|
|
}
|
|
|
|
if r.contains_mouse(input, state) && !self.has_mouse {
|
|
if input.player.input.pressed_leftclick() {
|
|
// If we're holding click when the cursor enters,
|
|
// don't trigger the `Click` event.
|
|
self.waiting_for_release = true;
|
|
}
|
|
self.has_mouse = true;
|
|
return MouseEvent::Enter;
|
|
}
|
|
|
|
if !r.contains_mouse(input, state) && self.has_mouse {
|
|
self.waiting_for_release = false;
|
|
self.has_mouse = false;
|
|
return MouseEvent::Leave;
|
|
}
|
|
|
|
return MouseEvent::None;
|
|
}
|
|
|
|
pub fn step(&mut self, input: &RenderInput, _state: &mut RenderState) {
|
|
self.anim.step(&input.ct, input.time_since_last_run);
|
|
}
|
|
}
|