use crate::*;
use bevy::{render::primitives::Aabb, sprite::Anchor, text::{Text2dBounds, TextLayoutInfo}};
pub trait UiState where Self: Send + Sync + 'static {
const INDEX: usize;
}
#[derive(Component, Debug, Copy, Clone, PartialEq, Eq)]
pub struct Base;
impl UiState for Base {
const INDEX: usize = 0;
}
#[derive(Component, Debug, Copy, Clone, PartialEq, Eq)]
pub struct Hover;
impl UiState for Hover {
const INDEX: usize = 1;
}
#[derive(Component, Debug, Copy, Clone, PartialEq, Eq)]
pub struct Clicked;
impl UiState for Clicked {
const INDEX: usize = 2;
}
#[derive(Component, Debug, Copy, Clone, PartialEq, Eq)]
pub struct Selected;
impl UiState for Selected {
const INDEX: usize = 3;
}
#[derive(Component, Debug, Copy, Clone, PartialEq, Eq)]
pub struct Intro;
impl UiState for Intro {
const INDEX: usize = 4;
}
#[derive(Component, Debug, Copy, Clone, PartialEq, Eq)]
pub struct Outro;
impl UiState for Outro {
const INDEX: usize = 5;
}
#[derive(Component, Debug, Default, Clone, Copy, PartialEq)]
pub struct MovableByCamera;
#[derive(Component, Debug, Default, Clone, Copy, PartialEq)]
pub struct Element;
#[derive(Component, Debug, Default, Clone, Copy, PartialEq)]
pub struct Dimension {
pub size: Vec2,
}
impl Dimension {
pub fn new(size: impl Into<Vec2>) -> Self {
Dimension {
size: size.into()
}
}
}
#[derive(Component, Debug, Default, Clone, Copy, PartialEq)]
pub struct UiContent {
pub size: Vec2,
}
impl UiContent {
pub fn new(size: impl Into<Vec2>) -> Self {
UiContent { size: size.into() }
}
}
#[derive(Component, Debug, Copy, Clone, PartialEq)]
pub struct UiLayout<S = Base> {
pub layout: Layout,
state: PhantomData<S>,
}
impl UiLayout {
pub fn boundary() -> ui::Boundary {
ui::Boundary::new()
}
pub fn window() -> ui::Window {
ui::Window::new()
}
pub fn window_full() -> ui::Window {
ui::Window::full()
}
pub fn solid() -> ui::Solid {
ui::Solid::new()
}
pub fn div() -> ui::Div {
ui::Div::new()
}
}
impl <S> UiLayout<S> {
pub fn from(layout: impl Into<Layout>) -> UiLayout<S> {
UiLayout {
layout: layout.into(),
state: PhantomData,
}
}
}
impl <S> Default for UiLayout<S> {
fn default() -> Self {
UiLayout {
layout: Layout::default(),
state: PhantomData,
}
}
}
pub trait PackageLayout {
fn pack<S>(self) -> UiLayout<S>;
}
impl <S> Into<UiLayout<S>> for ui::Boundary {
fn into(self) -> UiLayout<S> {
self.pack::<S>()
}
}
impl PackageLayout for ui::Boundary {
fn pack<S>(self) -> UiLayout<S> {
UiLayout::<S>::from(self)
}
}
impl <S> Into<UiLayout<S>> for ui::Window {
fn into(self) -> UiLayout<S> {
self.pack::<S>()
}
}
impl PackageLayout for ui::Window {
fn pack<S>(self) -> UiLayout<S> {
UiLayout::<S>::from(self)
}
}
impl <S> Into<UiLayout<S>> for ui::Solid {
fn into(self) -> UiLayout<S> {
self.pack::<S>()
}
}
impl PackageLayout for ui::Solid {
fn pack<S>(self) -> UiLayout<S> {
UiLayout::<S>::from(self)
}
}
impl <S> Into<UiLayout<S>> for ui::Div {
fn into(self) -> UiLayout<S> {
self.pack::<S>()
}
}
impl PackageLayout for ui::Div {
fn pack<S>(self) -> UiLayout<S> {
UiLayout::<S>::from(self)
}
}
#[derive(Component, Debug, Clone, PartialEq)]
pub struct UiLayoutController {
pub index: [usize; 2],
pub tween: f32,
pub method: fn(f32) -> f32,
}
impl Default for UiLayoutController {
fn default() -> Self {
UiLayoutController {
index: [0, 0],
tween: 0.0,
method: |i|{i},
}
}
}
#[derive(Component, Debug, Clone, PartialEq)]
pub struct UiLink<T = MainUi> {
pub path: String,
marker: PhantomData<T>,
}
impl <T> UiLink<T> {
pub fn path( path: impl Borrow<str>) -> Self {
UiLink {
path: path.borrow().to_string(),
marker: PhantomData,
}
}
pub fn add( &self, path: impl Borrow<str>) -> Self {
UiLink {
path: format!("{}/{}", self.path, path.borrow()),
marker: PhantomData,
}
}
pub fn new() -> Self {
UiLink {
path: format!("/"),
marker: PhantomData,
}
}
}
impl <T> Default for UiLink<T> {
fn default() -> Self {
UiLink {
path: String::new(),
marker: PhantomData,
}
}
}
#[derive(Component, Debug, Default, Clone, Copy, PartialEq)]
pub struct UiDepthBias (pub f32);
#[derive(Bundle, Debug, Clone)]
pub struct UiTreeBundle <T:Component = MainUi, N:Default + Component = NoData> {
pub link: UiLink<T>,
pub tree: UiTree<T, N>,
pub spatial: UiSpatialBundle,
}
impl <T:Component, N:Default + Component> From<UiTree<T, N>> for UiTreeBundle<T, N> {
fn from(value: UiTree<T, N>) -> Self {
UiTreeBundle::<T, N> {
tree: value,
..default()
}
}
}
impl <T:Component, N:Default + Component> Default for UiTreeBundle<T, N> {
fn default() -> Self {
UiTreeBundle {
link: Default::default(),
tree: Default::default(),
spatial: Default::default(),
}
}
}
#[derive(Bundle, Debug, Clone, Default)]
pub struct UiNodeBundle<T: Component = MainUi> {
pub link: UiLink<T>,
pub layout: UiLayout,
}
#[derive(Bundle, Debug, Clone, Default)]
pub struct UiElementBundle {
pub element: Element,
pub spatial: UiSpatialBundle,
}
#[derive(Bundle, Default)]
pub struct UiZoneBundle {
pub pickable: PickableBundle,
pub spatial: UiSpatialBundle,
}
#[derive(Bundle, Debug, Clone, Default)]
pub struct UiSpatialBundle {
pub dimension: Dimension,
pub spatial: SpatialBundle
}
#[derive(Bundle, Debug, Default, Clone)]
pub struct UiMaterial3dBundle {
pub mesh: Handle<Mesh>,
pub material: Handle<StandardMaterial>,
pub aabb: Aabb,
pub element: UiElementBundle,
}
impl From<Handle<StandardMaterial>> for UiMaterial3dBundle {
fn from(value: Handle<StandardMaterial>) -> Self {
UiMaterial3dBundle {
material: value,
..default()
}
}
}
impl UiMaterial3dBundle {
pub fn from_image(materials: &mut ResMut<'_, Assets<StandardMaterial>>, value: Handle<Image>) -> Self {
UiMaterial3dBundle {
material: materials.add(StandardMaterial { base_color_texture: Some(value), unlit: true, ..default() }),
..default()
}
}
pub fn from_transparent_image(materials: &mut ResMut<'_, Assets<StandardMaterial>>, value: Handle<Image>) -> Self {
UiMaterial3dBundle {
material: materials.add(StandardMaterial { base_color_texture: Some(value), unlit: true, alpha_mode: AlphaMode::Blend, ..default() }),
..default()
}
}
}
#[derive(Bundle, Clone, Debug, Default)]
pub struct UiImage2dBundle {
pub sprite: Sprite,
pub texture: Handle<Image>,
pub aabb: Aabb,
pub element: UiElementBundle,
}
impl From<Handle<Image>> for UiImage2dBundle {
fn from(value: Handle<Image>) -> Self {
UiImage2dBundle {
texture: value,
..default()
}
}
}
#[derive(Bundle, Clone, Debug, Default)]
pub struct UiText2dBundle {
pub text: Text,
pub text_anchor: Anchor,
pub text_2d_bounds: Text2dBounds,
pub text_layout_info: TextLayoutInfo,
pub element: UiElementBundle,
}