Added a few rhai API utilities
parent
5e9f2dd159
commit
7d681268b9
|
@ -0,0 +1,38 @@
|
||||||
|
mod rect;
|
||||||
|
mod sprite;
|
||||||
|
mod spritebuilder;
|
||||||
|
mod state;
|
||||||
|
mod textboxbuilder;
|
||||||
|
mod util;
|
||||||
|
|
||||||
|
use rhai::{exported_module, Engine};
|
||||||
|
|
||||||
|
pub fn register_into_engine(engine: &mut Engine) {
|
||||||
|
engine
|
||||||
|
.build_type::<State>()
|
||||||
|
.build_type::<Rect>()
|
||||||
|
.build_type::<SpriteElement>()
|
||||||
|
.build_type::<SpriteBuilder>()
|
||||||
|
.build_type::<TextBoxBuilder>()
|
||||||
|
.register_type_with_name::<SpriteAnchor>("SpriteAnchor")
|
||||||
|
.register_static_module("SpriteAnchor", exported_module!(spriteanchor_mod).into())
|
||||||
|
.register_type_with_name::<TextBoxFont>("TextBoxFont")
|
||||||
|
.register_static_module(
|
||||||
|
"TextBoxFont",
|
||||||
|
exported_module!(util::textboxfont_mod).into(),
|
||||||
|
)
|
||||||
|
.register_type_with_name::<TextBoxJustify>("TextBoxJustify")
|
||||||
|
.register_static_module(
|
||||||
|
"TextBoxJustify",
|
||||||
|
exported_module!(textboxjustify_mod).into(),
|
||||||
|
)
|
||||||
|
.register_type_with_name::<SceneAction>("SceneAction")
|
||||||
|
.register_static_module("SceneAction", exported_module!(sceneaction_mod).into());
|
||||||
|
}
|
||||||
|
|
||||||
|
pub use rect::*;
|
||||||
|
pub use sprite::*;
|
||||||
|
pub use spritebuilder::*;
|
||||||
|
pub use state::*;
|
||||||
|
pub use textboxbuilder::*;
|
||||||
|
pub use util::*;
|
|
@ -0,0 +1,126 @@
|
||||||
|
use nalgebra::{Point2, Vector2};
|
||||||
|
use rhai::{CustomType, TypeBuilder};
|
||||||
|
use winit::dpi::LogicalSize;
|
||||||
|
|
||||||
|
use super::SpriteAnchor;
|
||||||
|
use crate::{RenderInput, RenderState};
|
||||||
|
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
|
pub struct Rect {
|
||||||
|
pub pos: Point2<f32>,
|
||||||
|
pub dim: Vector2<f32>,
|
||||||
|
pub anchor_self: SpriteAnchor,
|
||||||
|
pub anchor_parent: SpriteAnchor,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Rect {
|
||||||
|
pub fn new(
|
||||||
|
x: f32,
|
||||||
|
y: f32,
|
||||||
|
w: f32,
|
||||||
|
h: f32,
|
||||||
|
anchor_self: SpriteAnchor,
|
||||||
|
anchor_parent: SpriteAnchor,
|
||||||
|
) -> Self {
|
||||||
|
Self {
|
||||||
|
pos: Point2::new(x, y),
|
||||||
|
dim: Vector2::new(w, h),
|
||||||
|
anchor_self,
|
||||||
|
anchor_parent,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn to_centered(&self, state: &RenderState, ui_scale: f32) -> CenteredRect {
|
||||||
|
let w: LogicalSize<f32> = state.window_size.to_logical(state.window.scale_factor());
|
||||||
|
let w = Vector2::new(w.width, w.height);
|
||||||
|
|
||||||
|
let mut pos = self.pos * ui_scale;
|
||||||
|
let dim = self.dim * ui_scale;
|
||||||
|
|
||||||
|
// Origin
|
||||||
|
match self.anchor_parent {
|
||||||
|
SpriteAnchor::Center => {}
|
||||||
|
|
||||||
|
SpriteAnchor::NorthWest => {
|
||||||
|
pos += Vector2::new(-w.x, w.y) / 2.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
SpriteAnchor::SouthWest => {
|
||||||
|
pos += Vector2::new(-w.x, -w.y) / 2.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
SpriteAnchor::NorthEast => {
|
||||||
|
pos += Vector2::new(w.x, w.y) / 2.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
SpriteAnchor::SouthEast => {
|
||||||
|
pos += Vector2::new(w.x, -w.y) / 2.0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Offset for self dimensions
|
||||||
|
match self.anchor_self {
|
||||||
|
SpriteAnchor::Center => {}
|
||||||
|
|
||||||
|
SpriteAnchor::NorthWest => {
|
||||||
|
pos += Vector2::new(dim.x, -dim.y) / 2.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
SpriteAnchor::NorthEast => {
|
||||||
|
pos += Vector2::new(-dim.x, -dim.y) / 2.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
SpriteAnchor::SouthWest => {
|
||||||
|
pos += Vector2::new(dim.x, dim.y) / 2.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
SpriteAnchor::SouthEast => {
|
||||||
|
pos += Vector2::new(-dim.x, dim.y) / 2.0;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return CenteredRect { pos, dim };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl CustomType for Rect {
|
||||||
|
fn build(mut builder: TypeBuilder<Self>) {
|
||||||
|
builder.with_name("Rect").with_fn("Rect", Self::new);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 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)
|
||||||
|
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
|
||||||
|
pub dim: Vector2<f32>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl CenteredRect {
|
||||||
|
pub fn contains_point(&self, pt: Point2<f32>) -> bool {
|
||||||
|
let ne = self.pos + Vector2::new(-self.dim.x, self.dim.y) / 2.0;
|
||||||
|
let sw = self.pos + Vector2::new(self.dim.x, -self.dim.y) / 2.0;
|
||||||
|
return (pt.y < ne.y && pt.y > sw.y) && (pt.x > ne.x && pt.x < sw.x);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn contains_mouse(&self, input: &RenderInput, state: &RenderState) -> bool {
|
||||||
|
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 self.contains_point(mouse_pos);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,61 @@
|
||||||
|
use galactica_content::{resolve_edge_as_edge, Content};
|
||||||
|
use log::error;
|
||||||
|
use rhai::{CustomType, TypeBuilder};
|
||||||
|
use std::{cell::RefCell, rc::Rc};
|
||||||
|
|
||||||
|
use crate::ui::util::Sprite;
|
||||||
|
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
|
pub struct SpriteElement {
|
||||||
|
pub sprite: Rc<RefCell<Sprite>>,
|
||||||
|
pub ct: Rc<Content>,
|
||||||
|
}
|
||||||
|
|
||||||
|
unsafe impl Send for SpriteElement {}
|
||||||
|
unsafe impl Sync for SpriteElement {}
|
||||||
|
|
||||||
|
impl SpriteElement {
|
||||||
|
pub fn new(ct: Rc<Content>, sprite: Rc<RefCell<Sprite>>) -> Self {
|
||||||
|
Self { ct, sprite }
|
||||||
|
}
|
||||||
|
|
||||||
|
// This MUST be &mut, or rhai won't recognize it.
|
||||||
|
pub fn has_name(&mut self, s: String) -> bool {
|
||||||
|
self.sprite.as_ref().borrow().name == s
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn take_edge(&mut self, edge_name: &str, duration: f32) {
|
||||||
|
let sprite_handle = self.sprite.as_ref().borrow().anim.get_sprite();
|
||||||
|
let sprite = self.ct.get_sprite(sprite_handle);
|
||||||
|
|
||||||
|
let edge = resolve_edge_as_edge(edge_name, duration, |x| {
|
||||||
|
sprite.get_section_handle_by_name(x)
|
||||||
|
});
|
||||||
|
let edge = match edge {
|
||||||
|
Err(x) => {
|
||||||
|
error!(
|
||||||
|
"UI script reference invalid section `{}` in sprite `{}`, skipping",
|
||||||
|
edge_name, sprite.name
|
||||||
|
);
|
||||||
|
error!("error: {:?}", x);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Ok(s) => s,
|
||||||
|
};
|
||||||
|
|
||||||
|
self.sprite
|
||||||
|
.as_ref()
|
||||||
|
.borrow_mut()
|
||||||
|
.anim
|
||||||
|
.jump_to(&self.ct, edge);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl CustomType for SpriteElement {
|
||||||
|
fn build(mut builder: TypeBuilder<Self>) {
|
||||||
|
builder
|
||||||
|
.with_name("SpriteElement")
|
||||||
|
.with_fn("has_name", Self::has_name)
|
||||||
|
.with_fn("take_edge", Self::take_edge);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,35 @@
|
||||||
|
use rhai::{CustomType, TypeBuilder};
|
||||||
|
|
||||||
|
use super::Rect;
|
||||||
|
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
|
pub struct SpriteBuilder {
|
||||||
|
pub name: String,
|
||||||
|
pub rect: Rect,
|
||||||
|
pub sprite: String,
|
||||||
|
pub mask: Option<String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl SpriteBuilder {
|
||||||
|
pub fn new(name: String, sprite: String, rect: Rect) -> Self {
|
||||||
|
Self {
|
||||||
|
name,
|
||||||
|
rect,
|
||||||
|
sprite,
|
||||||
|
mask: None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn set_mask(&mut self, mask: String) {
|
||||||
|
self.mask = Some(mask);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl CustomType for SpriteBuilder {
|
||||||
|
fn build(mut builder: TypeBuilder<Self>) {
|
||||||
|
builder
|
||||||
|
.with_name("SpriteBuilder")
|
||||||
|
.with_fn("SpriteBuilder", Self::new)
|
||||||
|
.with_fn("set_mask", Self::set_mask);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,7 @@
|
||||||
|
use rhai::{CustomType, TypeBuilder};
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, CustomType)]
|
||||||
|
pub struct State {
|
||||||
|
pub planet_landscape: String,
|
||||||
|
pub planet_name: String,
|
||||||
|
}
|
|
@ -0,0 +1,48 @@
|
||||||
|
use rhai::{CustomType, TypeBuilder};
|
||||||
|
|
||||||
|
use super::{Rect, TextBoxFont, TextBoxJustify};
|
||||||
|
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
|
pub struct TextBoxBuilder {
|
||||||
|
pub name: String,
|
||||||
|
pub font_size: f32,
|
||||||
|
pub line_height: f32,
|
||||||
|
pub font: TextBoxFont,
|
||||||
|
pub justify: TextBoxJustify,
|
||||||
|
pub rect: Rect,
|
||||||
|
pub text: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TextBoxBuilder {
|
||||||
|
pub fn new(
|
||||||
|
name: String,
|
||||||
|
font_size: f32,
|
||||||
|
line_height: f32,
|
||||||
|
font: TextBoxFont,
|
||||||
|
justify: TextBoxJustify,
|
||||||
|
rect: Rect,
|
||||||
|
) -> Self {
|
||||||
|
Self {
|
||||||
|
name,
|
||||||
|
font_size,
|
||||||
|
line_height,
|
||||||
|
font,
|
||||||
|
justify,
|
||||||
|
rect,
|
||||||
|
text: String::new(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn set_text(&mut self, text: String) {
|
||||||
|
self.text = text
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl CustomType for TextBoxBuilder {
|
||||||
|
fn build(mut builder: TypeBuilder<Self>) {
|
||||||
|
builder
|
||||||
|
.with_name("TextBoxBuilder")
|
||||||
|
.with_fn("TextBoxBuilder", Self::new)
|
||||||
|
.with_fn("set_text", Self::set_text);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,81 @@
|
||||||
|
use rhai::plugin::*;
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Eq, PartialEq, Hash)]
|
||||||
|
pub enum SpriteAnchor {
|
||||||
|
Center,
|
||||||
|
NorthWest,
|
||||||
|
SouthWest,
|
||||||
|
NorthEast,
|
||||||
|
SouthEast,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[export_module]
|
||||||
|
pub mod spriteanchor_mod {
|
||||||
|
#[allow(non_upper_case_globals)]
|
||||||
|
pub const Center: SpriteAnchor = SpriteAnchor::Center;
|
||||||
|
|
||||||
|
#[allow(non_upper_case_globals)]
|
||||||
|
pub const NorthWest: SpriteAnchor = SpriteAnchor::NorthWest;
|
||||||
|
|
||||||
|
#[allow(non_upper_case_globals)]
|
||||||
|
pub const NorthEast: SpriteAnchor = SpriteAnchor::NorthEast;
|
||||||
|
|
||||||
|
#[allow(non_upper_case_globals)]
|
||||||
|
pub const SouthWest: SpriteAnchor = SpriteAnchor::SouthWest;
|
||||||
|
|
||||||
|
#[allow(non_upper_case_globals)]
|
||||||
|
pub const SouthEast: SpriteAnchor = SpriteAnchor::SouthEast;
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Eq, PartialEq, Hash)]
|
||||||
|
pub enum TextBoxFont {
|
||||||
|
Serif,
|
||||||
|
SansSerif,
|
||||||
|
Monospace,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[export_module]
|
||||||
|
pub mod textboxfont_mod {
|
||||||
|
#[allow(non_upper_case_globals)]
|
||||||
|
pub const Serif: TextBoxFont = TextBoxFont::Serif;
|
||||||
|
|
||||||
|
#[allow(non_upper_case_globals)]
|
||||||
|
pub const SansSerif: TextBoxFont = TextBoxFont::SansSerif;
|
||||||
|
|
||||||
|
#[allow(non_upper_case_globals)]
|
||||||
|
pub const Monospace: TextBoxFont = TextBoxFont::Monospace;
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Eq, PartialEq, Hash)]
|
||||||
|
pub enum TextBoxJustify {
|
||||||
|
Center,
|
||||||
|
Left,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[export_module]
|
||||||
|
pub mod textboxjustify_mod {
|
||||||
|
#[allow(non_upper_case_globals)]
|
||||||
|
pub const Center: TextBoxJustify = TextBoxJustify::Center;
|
||||||
|
|
||||||
|
#[allow(non_upper_case_globals)]
|
||||||
|
pub const Left: TextBoxJustify = TextBoxJustify::Left;
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Eq, PartialEq, Hash)]
|
||||||
|
pub enum SceneAction {
|
||||||
|
None,
|
||||||
|
SceneOutfitter,
|
||||||
|
SceneLanded,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[export_module]
|
||||||
|
pub mod sceneaction_mod {
|
||||||
|
#[allow(non_upper_case_globals)]
|
||||||
|
pub const None: SceneAction = SceneAction::None;
|
||||||
|
|
||||||
|
#[allow(non_upper_case_globals)]
|
||||||
|
pub const SceneOutfitter: SceneAction = SceneAction::SceneOutfitter;
|
||||||
|
|
||||||
|
#[allow(non_upper_case_globals)]
|
||||||
|
pub const SceneLanded: SceneAction = SceneAction::SceneLanded;
|
||||||
|
}
|
Loading…
Reference in New Issue