Label component
This commit is contained in:
parent
e093a3243b
commit
86c18edbfd
@ -84,6 +84,10 @@ impl<T> Assets<T> {
|
|||||||
self.assets.get_mut(&handle.id)
|
self.assets.get_mut(&handle.id)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn get_or_insert_with(&mut self, handle: Handle<T>, insert_fn: impl FnOnce() -> T) -> &mut T {
|
||||||
|
self.assets.entry(handle.id).or_insert_with(insert_fn)
|
||||||
|
}
|
||||||
|
|
||||||
pub fn iter(&self) -> impl Iterator<Item = (Handle<T>, &T)> {
|
pub fn iter(&self) -> impl Iterator<Item = (Handle<T>, &T)> {
|
||||||
self.assets.iter().map(|(k, v)| (Handle::from_id(*k), v))
|
self.assets.iter().map(|(k, v)| (Handle::from_id(*k), v))
|
||||||
}
|
}
|
||||||
|
@ -7,7 +7,7 @@ use std::ops::{Add, AddAssign};
|
|||||||
use zerocopy::AsBytes;
|
use zerocopy::AsBytes;
|
||||||
|
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
#[derive(Debug, Default, Clone, Copy, PartialEq, AsBytes)]
|
#[derive(Debug, Clone, Copy, PartialEq, AsBytes)]
|
||||||
pub struct Color {
|
pub struct Color {
|
||||||
pub r: f32,
|
pub r: f32,
|
||||||
pub g: f32,
|
pub g: f32,
|
||||||
@ -31,6 +31,12 @@ impl Color {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Default for Color {
|
||||||
|
fn default() -> Self {
|
||||||
|
Color::WHITE
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl AddAssign<Color> for Color {
|
impl AddAssign<Color> for Color {
|
||||||
fn add_assign(&mut self, rhs: Color) {
|
fn add_assign(&mut self, rhs: Color) {
|
||||||
*self = Color {
|
*self = Color {
|
||||||
|
@ -9,6 +9,7 @@ bevy_app = { path = "../bevy_app" }
|
|||||||
bevy_asset = { path = "../bevy_asset" }
|
bevy_asset = { path = "../bevy_asset" }
|
||||||
bevy_core = { path = "../bevy_core" }
|
bevy_core = { path = "../bevy_core" }
|
||||||
bevy_derive = { path = "../bevy_derive" }
|
bevy_derive = { path = "../bevy_derive" }
|
||||||
|
bevy_text = { path = "../bevy_text" }
|
||||||
bevy_transform = { path = "../bevy_transform" }
|
bevy_transform = { path = "../bevy_transform" }
|
||||||
bevy_render = { path = "../bevy_render" }
|
bevy_render = { path = "../bevy_render" }
|
||||||
bevy_window = { path = "../bevy_window" }
|
bevy_window = { path = "../bevy_window" }
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
use super::Node;
|
use super::Node;
|
||||||
use crate::{render::UI_PIPELINE_HANDLE, sprite::Sprite, ColorMaterial, Rect, QUAD_HANDLE};
|
use crate::{
|
||||||
|
render::UI_PIPELINE_HANDLE, sprite::Sprite, widget::Label, ColorMaterial, Rect, QUAD_HANDLE,
|
||||||
|
};
|
||||||
use bevy_asset::Handle;
|
use bevy_asset::Handle;
|
||||||
use bevy_derive::EntityArchetype;
|
use bevy_derive::EntityArchetype;
|
||||||
use bevy_render::{mesh::Mesh, Renderable};
|
use bevy_render::{mesh::Mesh, Renderable};
|
||||||
@ -29,6 +31,34 @@ impl Default for UiEntity {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(EntityArchetype)]
|
||||||
|
#[module(meta = false)]
|
||||||
|
pub struct LabelEntity {
|
||||||
|
pub node: Node,
|
||||||
|
pub rect: Rect,
|
||||||
|
pub mesh: Handle<Mesh>, // TODO: maybe abstract this out
|
||||||
|
pub material: Handle<ColorMaterial>,
|
||||||
|
pub renderable: Renderable,
|
||||||
|
pub label: Label,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for LabelEntity {
|
||||||
|
fn default() -> Self {
|
||||||
|
LabelEntity {
|
||||||
|
node: Default::default(),
|
||||||
|
rect: Default::default(),
|
||||||
|
mesh: QUAD_HANDLE,
|
||||||
|
// NOTE: labels each get their own material.
|
||||||
|
material: Handle::new(), // TODO: maybe abstract this out
|
||||||
|
renderable: Renderable {
|
||||||
|
pipelines: vec![UI_PIPELINE_HANDLE],
|
||||||
|
..Default::default()
|
||||||
|
},
|
||||||
|
label: Label::default(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(EntityArchetype)]
|
#[derive(EntityArchetype)]
|
||||||
#[module(meta = false)]
|
#[module(meta = false)]
|
||||||
pub struct SpriteEntity {
|
pub struct SpriteEntity {
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
mod anchors;
|
mod anchors;
|
||||||
mod color_material;
|
mod color_material;
|
||||||
pub mod entity;
|
pub mod entity;
|
||||||
|
pub mod widget;
|
||||||
mod margins;
|
mod margins;
|
||||||
mod node;
|
mod node;
|
||||||
mod rect;
|
mod rect;
|
||||||
@ -27,6 +28,7 @@ use bevy_render::{
|
|||||||
use glam::Vec2;
|
use glam::Vec2;
|
||||||
use legion::prelude::IntoSystem;
|
use legion::prelude::IntoSystem;
|
||||||
use sprite::sprite_system;
|
use sprite::sprite_system;
|
||||||
|
use widget::Label;
|
||||||
|
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
pub struct UiPlugin;
|
pub struct UiPlugin;
|
||||||
@ -36,12 +38,13 @@ pub const QUAD_HANDLE: Handle<Mesh> = Handle::from_u128(142404619811301375266013
|
|||||||
impl AppPlugin for UiPlugin {
|
impl AppPlugin for UiPlugin {
|
||||||
fn build(&self, app: &mut AppBuilder) {
|
fn build(&self, app: &mut AppBuilder) {
|
||||||
app.add_asset::<ColorMaterial>()
|
app.add_asset::<ColorMaterial>()
|
||||||
|
.add_system_to_stage(stage::POST_UPDATE, sprite_system())
|
||||||
|
.add_system_to_stage(stage::POST_UPDATE, ui_update_system())
|
||||||
|
.add_system_to_stage(stage::POST_UPDATE, Label::label_system.system())
|
||||||
.add_system_to_stage(
|
.add_system_to_stage(
|
||||||
stage::POST_UPDATE,
|
stage::POST_UPDATE,
|
||||||
asset_shader_def_system::<ColorMaterial>.system(),
|
asset_shader_def_system::<ColorMaterial>.system(),
|
||||||
)
|
);
|
||||||
.add_system_to_stage(stage::POST_UPDATE, sprite_system())
|
|
||||||
.add_system_to_stage(stage::POST_UPDATE, ui_update_system());
|
|
||||||
|
|
||||||
let resources = app.resources();
|
let resources = app.resources();
|
||||||
let mut render_graph = resources.get_mut::<RenderGraph>().unwrap();
|
let mut render_graph = resources.get_mut::<RenderGraph>().unwrap();
|
||||||
|
51
crates/bevy_ui/src/widget/label.rs
Normal file
51
crates/bevy_ui/src/widget/label.rs
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
use crate::{ColorMaterial, Rect, Res, ResMut};
|
||||||
|
use bevy_asset::{Assets, Handle};
|
||||||
|
use bevy_render::{texture::Texture, Color};
|
||||||
|
use bevy_text::Font;
|
||||||
|
use legion::prelude::Com;
|
||||||
|
|
||||||
|
pub struct Label {
|
||||||
|
pub text: String,
|
||||||
|
pub color: Color,
|
||||||
|
pub font_size: f32,
|
||||||
|
pub font: Handle<Font>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for Label {
|
||||||
|
fn default() -> Self {
|
||||||
|
Label {
|
||||||
|
text: String::new(),
|
||||||
|
color: Color::WHITE,
|
||||||
|
font_size: 12.0,
|
||||||
|
font: Handle::default(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Label {
|
||||||
|
// PERF: this is horrendously inefficient. (1) new texture every frame (2) no atlas (3) new texture for every label
|
||||||
|
pub fn label_system(
|
||||||
|
mut color_materials: ResMut<Assets<ColorMaterial>>,
|
||||||
|
mut textures: ResMut<Assets<Texture>>,
|
||||||
|
fonts: Res<Assets<Font>>,
|
||||||
|
label: Com<Label>,
|
||||||
|
rect: Com<Rect>,
|
||||||
|
color_material_handle: Com<Handle<ColorMaterial>>,
|
||||||
|
) {
|
||||||
|
if let Some(font) = fonts.get(&label.font) {
|
||||||
|
let texture = font.render_text(
|
||||||
|
&label.text,
|
||||||
|
label.color,
|
||||||
|
rect.size.x() as usize,
|
||||||
|
rect.size.y() as usize,
|
||||||
|
);
|
||||||
|
|
||||||
|
let material = color_materials.get_or_insert_with(*color_material_handle, || ColorMaterial::from(Handle::<Texture>::new()));
|
||||||
|
if let Some(texture) = material.texture {
|
||||||
|
// TODO: remove texture
|
||||||
|
}
|
||||||
|
|
||||||
|
material.texture = Some(textures.add(texture));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
3
crates/bevy_ui/src/widget/mod.rs
Normal file
3
crates/bevy_ui/src/widget/mod.rs
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
mod label;
|
||||||
|
|
||||||
|
pub use label::*;
|
@ -1,4 +1,4 @@
|
|||||||
This crate is deprecated please use [shaderc-rs](https://github.com/google/shaderc-rs) instead.
|
This crate is deprecated please use [shaderc-rs](https://github.com/google/shaderc-rs) instead.
|
||||||
|
|
||||||
|
|
||||||
BEVY NOTE: This crate is a temporary measure unit native rust shader compilation like https://github.com/gfx-rs/naga lands
|
BEVY NOTE: This crate is a temporary measure until native rust shader compilation like https://github.com/gfx-rs/naga lands
|
@ -1,5 +1,4 @@
|
|||||||
use bevy::prelude::*;
|
use bevy::prelude::*;
|
||||||
use bevy_asset::AssetServer;
|
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
App::build()
|
App::build()
|
||||||
@ -10,7 +9,7 @@ fn main() {
|
|||||||
|
|
||||||
fn setup(
|
fn setup(
|
||||||
command_buffer: &mut CommandBuffer,
|
command_buffer: &mut CommandBuffer,
|
||||||
asset_server: ResMut<AssetServer>,
|
asset_server: Res<AssetServer>,
|
||||||
mut materials: ResMut<Assets<StandardMaterial>>,
|
mut materials: ResMut<Assets<StandardMaterial>>,
|
||||||
) {
|
) {
|
||||||
// load the mesh
|
// load the mesh
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
use bevy::prelude::*;
|
use bevy::prelude::*;
|
||||||
use bevy_asset::AssetServer;
|
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
App::build()
|
App::build()
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
use bevy::prelude::*;
|
use bevy::prelude::*;
|
||||||
use bevy_asset::AssetServer;
|
|
||||||
|
|
||||||
/// Hot reloading allows you to modify assets on disk and they will be "live reloaded" while your game is running.
|
/// Hot reloading allows you to modify assets on disk and they will be "live reloaded" while your game is running.
|
||||||
/// This lets you immediately see the results of your changes without restarting the game.
|
/// This lets you immediately see the results of your changes without restarting the game.
|
@ -1,40 +1,42 @@
|
|||||||
use bevy::prelude::*;
|
use bevy::{
|
||||||
|
diagnostic::{Diagnostics, FrameTimeDiagnosticsPlugin},
|
||||||
|
prelude::*,
|
||||||
|
};
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
App::build()
|
App::build()
|
||||||
.add_default_plugins()
|
.add_default_plugins()
|
||||||
|
.add_plugin(FrameTimeDiagnosticsPlugin::default())
|
||||||
.add_startup_system(setup.system())
|
.add_startup_system(setup.system())
|
||||||
|
.add_system(text_update_system.system())
|
||||||
.run();
|
.run();
|
||||||
}
|
}
|
||||||
|
|
||||||
fn setup(
|
fn text_update_system(diagnostics: Res<Diagnostics>, mut label: ComMut<Label>) {
|
||||||
command_buffer: &mut CommandBuffer,
|
if let Some(fps) = diagnostics.get_measurement(FrameTimeDiagnosticsPlugin::FPS) {
|
||||||
asset_server: Res<AssetServer>,
|
label.text = format!("FPS: {}", fps.value.round());
|
||||||
mut fonts: ResMut<Assets<Font>>,
|
}
|
||||||
mut textures: ResMut<Assets<Texture>>,
|
}
|
||||||
mut materials: ResMut<Assets<ColorMaterial>>,
|
|
||||||
) {
|
|
||||||
let font_handle = asset_server
|
|
||||||
.load_sync(&mut fonts, "assets/fonts/FiraSans-Bold.ttf")
|
|
||||||
.unwrap();
|
|
||||||
let font = fonts.get(&font_handle).unwrap();
|
|
||||||
|
|
||||||
let texture = font.render_text("Hello from Bevy!", Color::rgba(0.9, 0.9, 0.9, 1.0), 500, 60);
|
fn setup(command_buffer: &mut CommandBuffer, asset_server: Res<AssetServer>) {
|
||||||
let half_width = texture.width as f32 / 2.0;
|
let font_handle = asset_server.load("assets/fonts/FiraSans-Bold.ttf").unwrap();
|
||||||
let half_height = texture.height as f32 / 2.0;
|
|
||||||
let texture_handle = textures.add(texture);
|
|
||||||
command_buffer
|
command_buffer
|
||||||
.build()
|
.build()
|
||||||
// 2d camera
|
// 2d camera
|
||||||
.add_entity(Camera2dEntity::default())
|
.add_entity(Camera2dEntity::default())
|
||||||
// texture
|
// texture
|
||||||
.add_entity(UiEntity {
|
.add_entity(LabelEntity {
|
||||||
node: Node::new(
|
node: Node::new(
|
||||||
math::vec2(0.0, 0.0),
|
math::vec2(0.0, 0.0),
|
||||||
Anchors::CENTER,
|
Anchors::TOP_LEFT,
|
||||||
Margins::new(-half_width, half_width, -half_height, half_height),
|
Margins::new(0.0, 250.0, 0.0, 60.0),
|
||||||
),
|
),
|
||||||
material: materials.add(ColorMaterial::texture(texture_handle)),
|
label: Label {
|
||||||
|
text: "FPS:".to_string(),
|
||||||
|
font: font_handle,
|
||||||
|
font_size: 60.0,
|
||||||
|
color: Color::WHITE,
|
||||||
|
},
|
||||||
..Default::default()
|
..Default::default()
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -34,7 +34,7 @@ pub use crate::text::Font;
|
|||||||
#[cfg(feature = "transform")]
|
#[cfg(feature = "transform")]
|
||||||
pub use crate::transform::prelude::*;
|
pub use crate::transform::prelude::*;
|
||||||
#[cfg(feature = "ui")]
|
#[cfg(feature = "ui")]
|
||||||
pub use crate::ui::{entity::*, Anchors, ColorMaterial, Margins, Node, Rect, Sprite};
|
pub use crate::ui::{entity::*, Anchors, ColorMaterial, Margins, Node, Rect, Sprite, widget::Label};
|
||||||
#[cfg(feature = "window")]
|
#[cfg(feature = "window")]
|
||||||
pub use crate::window::{Window, WindowDescriptor, WindowPlugin, Windows};
|
pub use crate::window::{Window, WindowDescriptor, WindowPlugin, Windows};
|
||||||
pub use crate::{
|
pub use crate::{
|
||||||
|
Loading…
Reference in New Issue
Block a user