Added sprite perserve_aspect

master
Mark 2024-02-05 14:11:47 -08:00
parent a817ad0d0f
commit cbcb060c66
Signed by: Mark
GPG Key ID: C6D63995FE72FD80
6 changed files with 50 additions and 15 deletions

View File

@ -8,7 +8,6 @@
- Mouse colliders
- UI captures input?
- No UI zoom scroll
- Preserve aspect for icons
- outfitter
## Small jobs

2
assets

@ -1 +1 @@
Subproject commit dc5962ffb96f6d4c7fc271a1b132865b280b528c
Subproject commit fba4f1083b5a07a10445cf28bcae4bb05c2cede6

View File

@ -57,6 +57,7 @@ fn init(state) {
Anchor::NorthWest
)
);
sprite::preserve_aspect("ship_thumb", true);
textbox::add(
"ship_name", 10.0, 10.0,
@ -119,6 +120,8 @@ fn init(state) {
Anchor::NorthEast
)
);
sprite::preserve_aspect("outfit_thumb", true);
textbox::add(
"outfit_name", 16.0, 16.0,

View File

@ -39,6 +39,17 @@ pub fn build_sprite_module(ct_src: Arc<Content>, state_src: Rc<RefCell<UiState>>
},
);
let state = state_src.clone();
let _ = FuncRegistration::new("exists")
.with_namespace(FnNamespace::Internal)
.set_into_module(&mut module, move |name: ImmutableString| {
let mut ui_state = state.borrow_mut();
match ui_state.get_mut_by_name(&name) {
Some(UiElement::Sprite(_)) => true,
_ => false,
}
});
let state = state_src.clone();
let _ = FuncRegistration::new("remove")
.with_namespace(FnNamespace::Internal)
@ -155,15 +166,16 @@ pub fn build_sprite_module(ct_src: Arc<Content>, state_src: Rc<RefCell<UiState>>
});
let state = state_src.clone();
let _ = FuncRegistration::new("exists")
let _ = FuncRegistration::new("preserve_aspect")
.with_namespace(FnNamespace::Internal)
.set_into_module(&mut module, move |name: ImmutableString| {
.set_into_module(&mut module, move |name: ImmutableString, x: bool| {
let mut ui_state = state.borrow_mut();
match ui_state.get_mut_by_name(&name) {
Some(UiElement::Sprite(_)) => true,
_ => false,
Some(UiElement::Sprite(s)) => s.set_preserve_aspect(x),
_ => {
error!("called `sprite::set_preserve_aspect` on an invalid name `{name}`")
}
}
});
return module;
}

View File

@ -85,12 +85,11 @@ impl CustomType for Rect {
/// Represents a rectangular region, in absolute coordinates relative to the screen center.
#[derive(Debug, Clone, Copy)]
pub(crate) struct CenteredRect {
/// The position of the top-left corner of this rectangle, in fractional units.
/// (0.0 is left edge of sprite, 1.0 is right edge)
/// The position of the center of this rectangle, in post-scale logical pixels,
/// relative to (0, 0) in the center of the screen.
pub pos: Point2<f32>,
/// The width and height of this rectangle, in fractional units.
/// 1.0 will be as tall as the sprite, 0.5 will be half as tall
/// The width and height of this rectangle, in post-scale logical pixels.
pub dim: Vector2<f32>,
}

View File

@ -16,6 +16,10 @@ pub struct Sprite {
/// Sprite angle, in degrees
angle: f32,
/// If true, this sprite will be scaled to fit in its box without affecting aspect ratio.
/// If false, this sprite will be stretched to fit in its box
preserve_aspect: bool,
rect: Rect,
mask: Option<SpriteHandle>,
color: Color,
@ -38,6 +42,7 @@ impl Sprite {
has_mouse: false,
has_click: false,
waiting_for_release: false,
preserve_aspect: false,
}
}
@ -57,15 +62,32 @@ impl Sprite {
self.color = color;
}
pub fn set_preserve_aspect(&mut self, preserve_aspect: bool) {
self.preserve_aspect = preserve_aspect;
}
pub fn push_to_buffer(&self, input: &RenderInput, state: &mut RenderState) {
let rect = self
let mut rect = self
.rect
.to_centered(&state.window, input.ct.get_config().ui_scale);
// TODO: use both dimensions,
// not just height
let anim_state = self.anim.get_texture_idx();
if self.preserve_aspect {
let rect_aspect = rect.dim.x / rect.dim.y;
let sprite_aspect = input.ct.get_sprite(self.anim.get_sprite()).aspect;
// "wide rect" case => match height, reduce width
if rect_aspect > sprite_aspect {
let shrink = rect.dim.x - rect.dim.y * sprite_aspect;
rect.dim.x -= shrink;
// "tall rect" case => match width, reduce height
} else if rect_aspect < sprite_aspect {
let shrink = rect.dim.y - rect.dim.x / sprite_aspect;
rect.dim.y -= shrink;
}
}
let anim_state = self.anim.get_texture_idx();
state.push_ui_buffer(UiInstance {
position: rect.pos.into(),
angle: to_radians(90.0 + self.angle),