it can start!

This commit is contained in:
Viv Lim 2023-09-23 21:35:51 -07:00
parent 7a06eb9221
commit 959bf44c89
12 changed files with 1901 additions and 1452 deletions

64
.vscode/launch.json vendored Normal file
View File

@ -0,0 +1,64 @@
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"type": "lldb",
"request": "launch",
"name": "Debug executable 'voxel-level-editor'",
"cargo": {
"args": [
"build",
"--bin=voxel-level-editor",
"--package=voxel-level-editor"
],
"filter": {
"name": "voxel-level-editor",
"kind": "bin"
}
},
"args": [],
"cwd": "${workspaceFolder}"
},
{
"type": "lldb",
"request": "launch",
"name": "Debug unit tests in executable 'voxel-level-editor'",
"cargo": {
"args": [
"test",
"--no-run",
"--bin=voxel-level-editor",
"--package=voxel-level-editor"
],
"filter": {
"name": "voxel-level-editor",
"kind": "bin"
}
},
"args": [],
"cwd": "${workspaceFolder}"
},
{
"type": "lldb",
"request": "launch",
"name": "Debug unit tests in library 'common'",
"cargo": {
"args": [
"test",
"--no-run",
"--lib",
"--package=common"
],
"filter": {
"name": "common",
"kind": "lib"
}
},
"args": [],
"cwd": "${workspaceFolder}"
}
]
}

2689
Cargo.lock generated

File diff suppressed because it is too large Load Diff

View File

@ -8,12 +8,13 @@ resolver = "2"
[dependencies]
common = { path = "../common", features = [ "two_dimensional", "three_dimensional", "serde", "bevy", "import_dot_vox" ] }
bevy = { version = "0.8", default-features = false, features = ["bevy_winit", "bevy_render", "render", "png", "x11"] }
bevy = { version = "0.11", default-features = true, features = ["bevy_winit", "bevy_render", "bevy_pbr", "bevy_scene", "png", "x11"] }
serde = { version = "1", features = ["derive"] }
block-mesh = "0.2.0"
bevy_egui = "0.15.1"
egui = "0.18"
egui_extras = "0.18"
smooth-bevy-cameras = "0.5.0"
bevy_egui = "0.21.0"
egui = "0.22"
egui_extras = "0.22"
smooth-bevy-cameras = "0.9.0"
itertools = "0.10"
rfd = "0.8"
async-channel = "1.6.1"

View File

@ -34,20 +34,20 @@ pub const ATTRIBUTE_UV: MeshVertexAttribute =
fn main() {
App::new()
.insert_resource(WgpuSettings {
// features: WgpuFeatures::POLYGON_MODE_LINE,
..Default::default()
})
.insert_resource(Msaa { samples: 4 })
// .insert_resource(WgpuSettings {
// // features: WgpuFeatures::POLYGON_MODE_LINE,
// ..Default::default()
// })
.insert_resource(Msaa::Sample4)
.insert_resource(CommandQueue::<LayerSpawnerCommand>::default())
.insert_resource(CommandQueue::<UiSpawnerCommand>::default())
.insert_resource(UiSpawnerState::default())
.insert_resource(TaskPoolBuilder::new().num_threads(1).build())
// .insert_resource(TaskPoolBuilder::new().num_threads(1).build())
.add_plugins(DefaultPlugins)
.add_plugin(WireframePlugin)
.add_plugin(EguiPlugin)
.add_plugin(LookTransformPlugin)
.add_plugin(OrbitCameraPlugin {
.add_plugins(WireframePlugin)
.add_plugins(EguiPlugin)
.add_plugins(LookTransformPlugin)
.add_plugins(OrbitCameraPlugin {
override_input_system: false,
})
.add_system(systems::ui::layers::layer_ui)
@ -84,7 +84,7 @@ fn setup(
) {
wireframe_config.global = false;
commands.spawn_bundle(PointLightBundle {
commands.spawn(PointLightBundle {
transform: Transform::from_translation(Vec3::new(25.0, 25.0, 25.0)),
point_light: PointLight {
range: 200.0,
@ -94,12 +94,13 @@ fn setup(
..Default::default()
});
let _camera_bundle = commands
.spawn_bundle(OrbitCameraBundle::new(
.spawn(OrbitCameraBundle::new(
OrbitCameraController::default(),
Vec3::new(-10.0, 21.0, -10.0),
Vec3::new(0.0, 0.0, 0.0),
Vec3::new(0.0, 0.0, 1.0), // up ? (guess)
))
.insert_bundle(Camera3dBundle::default())
.insert(Camera3dBundle::default())
.insert(PropertyPane::new("Camera".to_string(), false));
/*.insert_bundle(Camera3dBundle {
projection: OrthographicProjection {

View File

@ -5,7 +5,7 @@ use common::space::{
use common::strum::IntoEnumIterator;
use std::collections::VecDeque;
use bevy::{prelude::*, tasks::TaskPool};
use bevy::{prelude::*, tasks::{TaskPool, AsyncComputeTaskPool}};
use common::space::two_dimensional::depth_tiles::Direction;
use super::{generic_command_queue::CommandQueue, ui::ui_spawner::{UiSpawnerCommand, build_message_box_command, build_command, EditorPopup}};
@ -17,7 +17,6 @@ pub fn layer_spawner(
mut meshes: ResMut<Assets<Mesh>>,
mut tile_hashmap_layer_query: Query<&mut VoxelHashMapLayer<LevelTile>>,
ui_spawner_commands: ResMut<CommandQueue<UiSpawnerCommand>>,
pool: Res<TaskPool>,
) {
for command in spawner_commands.get_commands() {
match command {
@ -68,6 +67,7 @@ pub fn layer_spawner(
let sender = ui_spawner_commands.get_async_sender();
if let Ok(layer) = tile_hashmap_layer_query.get_mut(source_layer) {
let mut layer = layer.into_inner().clone();
let pool = AsyncComputeTaskPool::get();
pool.spawn(async move {
match common::space::level_serde::create_export_map(&mut layer) {
Ok(map) => {

View File

@ -8,11 +8,11 @@ use crate::{
use bevy::{
prelude::{Camera, Commands, Entity, Query, Res, ResMut},
render::camera::Projection,
tasks::TaskPool,
tasks::{TaskPool, AsyncComputeTaskPool},
};
use bevy_egui::EguiContext;
use bevy_egui::{EguiContext, EguiContexts};
use egui_extras::{Size, TableBuilder};
use egui_extras::{Size, TableBuilder, Column};
use itertools::Itertools;
use smooth_bevy_cameras::LookTransform;
@ -20,7 +20,7 @@ pub fn layer_ui(
mut commands: Commands,
layer_spawner_commands: ResMut<CommandQueue<LayerSpawnerCommand>>,
ui_spawner_commands: ResMut<CommandQueue<UiSpawnerCommand>>,
mut egui_context: ResMut<EguiContext>,
mut egui_context: EguiContexts,
mut camera_query: Query<(&mut Camera, &mut Projection, &mut LookTransform)>,
mut layer_query: Query<(
&mut Named,
@ -29,7 +29,6 @@ pub fn layer_ui(
Option<&mut VoxelCursorLayer>,
)>,
property_pane_query: Query<&mut PropertyPane>,
pool: Res<TaskPool>,
) {
egui::Window::new("Layers")
.resizable(true)
@ -40,8 +39,8 @@ pub fn layer_ui(
TableBuilder::new(ui)
.striped(true)
.scroll(true)
.column(Size::initial(200.0).at_least(40.0))
.column(Size::initial(60.0))
.column(Column::auto().resizable(true))
.column(Column::auto().resizable(true))
.header(20.0, |mut header| {
header.col(|ui| {
ui.heading("Name");
@ -99,6 +98,7 @@ pub fn layer_ui(
if ui.button("Load .vox").clicked() {
let sender = layer_spawner_commands.get_async_sender();
let pool = AsyncComputeTaskPool::get();
pool.spawn(async move {
if let Some(path) = rfd::AsyncFileDialog::new()
.add_filter("MagicaVoxel .vox", &["vox"])
@ -121,6 +121,7 @@ pub fn layer_ui(
if ui.button("Popup test").clicked() {
let sender = ui_spawner_commands.get_async_sender();
let pool = AsyncComputeTaskPool::get();
pool.spawn(async move {
println!("opening 1st message box");
let (m, recv) = build_message_box_command("test 1".to_string(), "hello! i'm a test dialog".to_string(), vec!["ok cool", "so", "editor"], true);

View File

@ -1,5 +1,4 @@
pub mod layers;
pub mod properties;
pub mod util;
pub mod syntax_highlighting;
pub mod ui_spawner;

View File

@ -5,7 +5,7 @@ use bevy::{
prelude::{Camera, Commands, Component, Entity, GlobalTransform, Query, ResMut, Transform},
render::camera::Projection,
};
use bevy_egui::EguiContext;
use bevy_egui::{EguiContext, EguiContexts};
use block_mesh::Voxel;
use common::space::{
level_tile::LevelTile,
@ -31,7 +31,7 @@ use super::util::{bevy_quat_controls, bevy_vec3_controls};
pub fn properties_ui(
commands: Commands,
layer_spawner_commands: ResMut<CommandQueue<LayerSpawnerCommand>>,
mut egui_context: ResMut<EguiContext>,
mut egui_context: EguiContexts,
mut property_pane_query: Query<(&mut PropertyPane, Entity)>,
mut camera_query: Query<(&mut Camera, &mut Projection, &mut LookTransform)>,
mut transform_query: Query<(&mut Transform, &mut GlobalTransform)>,

View File

@ -1,508 +0,0 @@
// This is just copied from the egui sample
// because it's not actually packed in a crate...
// https://github.com/emilk/egui/discussions/1628#discussioncomment-2751231
// source: https://raw.githubusercontent.com/emilk/egui/master/crates/egui_demo_lib/src/syntax_highlighting.rs
use egui::text::LayoutJob;
/// View some code with syntax highlighting and selection.
pub fn code_view_ui(ui: &mut egui::Ui, mut code: &str) {
let language = "rs";
let theme = CodeTheme::from_memory(ui.ctx());
let mut layouter = |ui: &egui::Ui, string: &str, _wrap_width: f32| {
let layout_job = highlight(ui.ctx(), &theme, string, language);
// layout_job.wrap.max_width = wrap_width; // no wrapping
ui.fonts().layout_job(layout_job)
};
ui.add(
egui::TextEdit::multiline(&mut code)
.font(egui::TextStyle::Monospace) // for cursor height
.code_editor()
.desired_rows(1)
.lock_focus(true)
.layouter(&mut layouter),
);
}
/// Memoized Code highlighting
pub fn highlight(ctx: &egui::Context, theme: &CodeTheme, code: &str, language: &str) -> LayoutJob {
impl egui::util::cache::ComputerMut<(&CodeTheme, &str, &str), LayoutJob> for Highlighter {
fn compute(&mut self, (theme, code, lang): (&CodeTheme, &str, &str)) -> LayoutJob {
self.highlight(theme, code, lang)
}
}
type HighlightCache = egui::util::cache::FrameCache<LayoutJob, Highlighter>;
let mut memory = ctx.memory();
let highlight_cache = memory.caches.cache::<HighlightCache>();
highlight_cache.get((theme, code, language))
}
// ----------------------------------------------------------------------------
#[cfg(not(feature = "syntect"))]
#[derive(Clone, Copy, PartialEq)]
#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
#[derive(enum_map::Enum)]
enum TokenType {
Comment,
Keyword,
Literal,
StringLiteral,
Punctuation,
Whitespace,
}
#[cfg(feature = "syntect")]
#[derive(Clone, Copy, Hash, PartialEq)]
#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
enum SyntectTheme {
Base16EightiesDark,
Base16MochaDark,
Base16OceanDark,
Base16OceanLight,
InspiredGitHub,
SolarizedDark,
SolarizedLight,
}
#[cfg(feature = "syntect")]
impl SyntectTheme {
fn all() -> impl ExactSizeIterator<Item = Self> {
[
Self::Base16EightiesDark,
Self::Base16MochaDark,
Self::Base16OceanDark,
Self::Base16OceanLight,
Self::InspiredGitHub,
Self::SolarizedDark,
Self::SolarizedLight,
]
.iter()
.copied()
}
fn name(&self) -> &'static str {
match self {
Self::Base16EightiesDark => "Base16 Eighties (dark)",
Self::Base16MochaDark => "Base16 Mocha (dark)",
Self::Base16OceanDark => "Base16 Ocean (dark)",
Self::Base16OceanLight => "Base16 Ocean (light)",
Self::InspiredGitHub => "InspiredGitHub (light)",
Self::SolarizedDark => "Solarized (dark)",
Self::SolarizedLight => "Solarized (light)",
}
}
fn syntect_key_name(&self) -> &'static str {
match self {
Self::Base16EightiesDark => "base16-eighties.dark",
Self::Base16MochaDark => "base16-mocha.dark",
Self::Base16OceanDark => "base16-ocean.dark",
Self::Base16OceanLight => "base16-ocean.light",
Self::InspiredGitHub => "InspiredGitHub",
Self::SolarizedDark => "Solarized (dark)",
Self::SolarizedLight => "Solarized (light)",
}
}
pub fn is_dark(&self) -> bool {
match self {
Self::Base16EightiesDark
| Self::Base16MochaDark
| Self::Base16OceanDark
| Self::SolarizedDark => true,
Self::Base16OceanLight | Self::InspiredGitHub | Self::SolarizedLight => false,
}
}
}
#[derive(Clone, Hash, PartialEq)]
#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
#[cfg_attr(feature = "serde", serde(default))]
pub struct CodeTheme {
dark_mode: bool,
#[cfg(feature = "syntect")]
syntect_theme: SyntectTheme,
#[cfg(not(feature = "syntect"))]
formats: enum_map::EnumMap<TokenType, egui::TextFormat>,
}
impl Default for CodeTheme {
fn default() -> Self {
Self::dark()
}
}
impl CodeTheme {
pub fn from_style(style: &egui::Style) -> Self {
if style.visuals.dark_mode {
Self::dark()
} else {
Self::light()
}
}
pub fn from_memory(ctx: &egui::Context) -> Self {
if ctx.style().visuals.dark_mode {
ctx.data()
.get_persisted(egui::Id::new("dark"))
.unwrap_or_else(CodeTheme::dark)
} else {
ctx.data()
.get_persisted(egui::Id::new("light"))
.unwrap_or_else(CodeTheme::light)
}
}
pub fn store_in_memory(self, ctx: &egui::Context) {
if self.dark_mode {
ctx.data().insert_persisted(egui::Id::new("dark"), self);
} else {
ctx.data().insert_persisted(egui::Id::new("light"), self);
}
}
}
#[cfg(feature = "syntect")]
impl CodeTheme {
pub fn dark() -> Self {
Self {
dark_mode: true,
syntect_theme: SyntectTheme::Base16MochaDark,
}
}
pub fn light() -> Self {
Self {
dark_mode: false,
syntect_theme: SyntectTheme::SolarizedLight,
}
}
pub fn ui(&mut self, ui: &mut egui::Ui) {
egui::widgets::global_dark_light_mode_buttons(ui);
for theme in SyntectTheme::all() {
if theme.is_dark() == self.dark_mode {
ui.radio_value(&mut self.syntect_theme, theme, theme.name());
}
}
}
}
#[cfg(not(feature = "syntect"))]
impl CodeTheme {
pub fn dark() -> Self {
let font_id = egui::FontId::monospace(12.0);
use egui::{Color32, TextFormat};
Self {
dark_mode: true,
formats: enum_map::enum_map![
TokenType::Comment => TextFormat::simple(font_id.clone(), Color32::from_gray(120)),
TokenType::Keyword => TextFormat::simple(font_id.clone(), Color32::from_rgb(255, 100, 100)),
TokenType::Literal => TextFormat::simple(font_id.clone(), Color32::from_rgb(87, 165, 171)),
TokenType::StringLiteral => TextFormat::simple(font_id.clone(), Color32::from_rgb(109, 147, 226)),
TokenType::Punctuation => TextFormat::simple(font_id.clone(), Color32::LIGHT_GRAY),
TokenType::Whitespace => TextFormat::simple(font_id.clone(), Color32::TRANSPARENT),
],
}
}
pub fn light() -> Self {
let font_id = egui::FontId::monospace(12.0);
use egui::{Color32, TextFormat};
Self {
dark_mode: false,
#[cfg(not(feature = "syntect"))]
formats: enum_map::enum_map![
TokenType::Comment => TextFormat::simple(font_id.clone(), Color32::GRAY),
TokenType::Keyword => TextFormat::simple(font_id.clone(), Color32::from_rgb(235, 0, 0)),
TokenType::Literal => TextFormat::simple(font_id.clone(), Color32::from_rgb(153, 134, 255)),
TokenType::StringLiteral => TextFormat::simple(font_id.clone(), Color32::from_rgb(37, 203, 105)),
TokenType::Punctuation => TextFormat::simple(font_id.clone(), Color32::DARK_GRAY),
TokenType::Whitespace => TextFormat::simple(font_id.clone(), Color32::TRANSPARENT),
],
}
}
pub fn ui(&mut self, ui: &mut egui::Ui) {
ui.horizontal_top(|ui| {
let selected_id = egui::Id::null();
let mut selected_tt: TokenType = *ui
.data()
.get_persisted_mut_or(selected_id, TokenType::Comment);
ui.vertical(|ui| {
ui.set_width(150.0);
egui::widgets::global_dark_light_mode_buttons(ui);
ui.add_space(8.0);
ui.separator();
ui.add_space(8.0);
ui.scope(|ui| {
for (tt, tt_name) in [
(TokenType::Comment, "// comment"),
(TokenType::Keyword, "keyword"),
(TokenType::Literal, "literal"),
(TokenType::StringLiteral, "\"string literal\""),
(TokenType::Punctuation, "punctuation ;"),
// (TokenType::Whitespace, "whitespace"),
] {
let format = &mut self.formats[tt];
ui.style_mut().override_font_id = Some(format.font_id.clone());
ui.visuals_mut().override_text_color = Some(format.color);
ui.radio_value(&mut selected_tt, tt, tt_name);
}
});
let reset_value = if self.dark_mode {
CodeTheme::dark()
} else {
CodeTheme::light()
};
if ui
.add_enabled(*self != reset_value, egui::Button::new("Reset theme"))
.clicked()
{
*self = reset_value;
}
});
ui.add_space(16.0);
ui.data().insert_persisted(selected_id, selected_tt);
egui::Frame::group(ui.style())
.inner_margin(egui::Vec2::splat(2.0))
.show(ui, |ui| {
// ui.group(|ui| {
ui.style_mut().override_text_style = Some(egui::TextStyle::Small);
ui.spacing_mut().slider_width = 128.0; // Controls color picker size
egui::widgets::color_picker::color_picker_color32(
ui,
&mut self.formats[selected_tt].color,
egui::color_picker::Alpha::Opaque,
);
});
});
}
}
// ----------------------------------------------------------------------------
#[cfg(feature = "syntect")]
struct Highlighter {
ps: syntect::parsing::SyntaxSet,
ts: syntect::highlighting::ThemeSet,
}
#[cfg(feature = "syntect")]
impl Default for Highlighter {
fn default() -> Self {
Self {
ps: syntect::parsing::SyntaxSet::load_defaults_newlines(),
ts: syntect::highlighting::ThemeSet::load_defaults(),
}
}
}
#[cfg(feature = "syntect")]
impl Highlighter {
#[allow(clippy::unused_self, clippy::unnecessary_wraps)]
fn highlight(&self, theme: &CodeTheme, code: &str, lang: &str) -> LayoutJob {
self.highlight_impl(theme, code, lang).unwrap_or_else(|| {
// Fallback:
LayoutJob::simple(
code.into(),
egui::FontId::monospace(14.0),
if theme.dark_mode {
egui::Color32::LIGHT_GRAY
} else {
egui::Color32::DARK_GRAY
},
f32::INFINITY,
)
})
}
fn highlight_impl(&self, theme: &CodeTheme, text: &str, language: &str) -> Option<LayoutJob> {
use syntect::easy::HighlightLines;
use syntect::highlighting::FontStyle;
use syntect::util::LinesWithEndings;
let syntax = self
.ps
.find_syntax_by_name(language)
.or_else(|| self.ps.find_syntax_by_extension(language))?;
let theme = theme.syntect_theme.syntect_key_name();
let mut h = HighlightLines::new(syntax, &self.ts.themes[theme]);
use egui::text::{LayoutSection, TextFormat};
let mut job = LayoutJob {
text: text.into(),
..Default::default()
};
for line in LinesWithEndings::from(text) {
for (style, range) in h.highlight_line(line, &self.ps).ok()? {
let fg = style.foreground;
let text_color = egui::Color32::from_rgb(fg.r, fg.g, fg.b);
let italics = style.font_style.contains(FontStyle::ITALIC);
let underline = style.font_style.contains(FontStyle::ITALIC);
let underline = if underline {
egui::Stroke::new(1.0, text_color)
} else {
egui::Stroke::none()
};
job.sections.push(LayoutSection {
leading_space: 0.0,
byte_range: as_byte_range(text, range),
format: TextFormat {
font_id: egui::FontId::monospace(14.0),
color: text_color,
italics,
underline,
..Default::default()
},
});
}
}
Some(job)
}
}
#[cfg(feature = "syntect")]
fn as_byte_range(whole: &str, range: &str) -> std::ops::Range<usize> {
let whole_start = whole.as_ptr() as usize;
let range_start = range.as_ptr() as usize;
assert!(whole_start <= range_start);
assert!(range_start + range.len() <= whole_start + whole.len());
let offset = range_start - whole_start;
offset..(offset + range.len())
}
// ----------------------------------------------------------------------------
#[cfg(not(feature = "syntect"))]
#[derive(Default)]
struct Highlighter {}
#[cfg(not(feature = "syntect"))]
impl Highlighter {
#[allow(clippy::unused_self, clippy::unnecessary_wraps)]
fn highlight(&self, theme: &CodeTheme, mut text: &str, _language: &str) -> LayoutJob {
// Extremely simple syntax highlighter for when we compile without syntect
let mut job = LayoutJob::default();
while !text.is_empty() {
if text.starts_with("//") {
let end = text.find('\n').unwrap_or(text.len());
job.append(&text[..end], 0.0, theme.formats[TokenType::Comment].clone());
text = &text[end..];
} else if text.starts_with('"') {
let end = text[1..]
.find('"')
.map(|i| i + 2)
.or_else(|| text.find('\n'))
.unwrap_or(text.len());
job.append(
&text[..end],
0.0,
theme.formats[TokenType::StringLiteral].clone(),
);
text = &text[end..];
} else if text.starts_with(|c: char| c.is_ascii_alphanumeric()) {
let end = text[1..]
.find(|c: char| !c.is_ascii_alphanumeric())
.map_or_else(|| text.len(), |i| i + 1);
let word = &text[..end];
let tt = if is_keyword(word) {
TokenType::Keyword
} else {
TokenType::Literal
};
job.append(word, 0.0, theme.formats[tt].clone());
text = &text[end..];
} else if text.starts_with(|c: char| c.is_ascii_whitespace()) {
let end = text[1..]
.find(|c: char| !c.is_ascii_whitespace())
.map_or_else(|| text.len(), |i| i + 1);
job.append(
&text[..end],
0.0,
theme.formats[TokenType::Whitespace].clone(),
);
text = &text[end..];
} else {
let mut it = text.char_indices();
it.next();
let end = it.next().map_or(text.len(), |(idx, _chr)| idx);
job.append(
&text[..end],
0.0,
theme.formats[TokenType::Punctuation].clone(),
);
text = &text[end..];
}
}
job
}
}
#[cfg(not(feature = "syntect"))]
fn is_keyword(word: &str) -> bool {
matches!(
word,
"as" | "async"
| "await"
| "break"
| "const"
| "continue"
| "crate"
| "dyn"
| "else"
| "enum"
| "extern"
| "false"
| "fn"
| "for"
| "if"
| "impl"
| "in"
| "let"
| "loop"
| "match"
| "mod"
| "move"
| "mut"
| "pub"
| "ref"
| "return"
| "self"
| "Self"
| "static"
| "struct"
| "super"
| "trait"
| "true"
| "type"
| "unsafe"
| "use"
| "where"
| "while"
)
}

View File

@ -1,4 +1,4 @@
use bevy_egui::EguiContext;
use bevy_egui::{EguiContext, EguiContexts};
use common::space::{
level_tile::LevelTile, three_dimensional::hash_map_container::VoxelHashMapLayer,
two_dimensional::depth_tiles::DepthTileContainer,
@ -8,12 +8,12 @@ use std::{collections::VecDeque, fmt::Display, future::Future};
use bevy::prelude::*;
use super::{super::generic_command_queue::CommandQueue, syntax_highlighting::{self, CodeTheme}};
use super::{super::generic_command_queue::CommandQueue};
pub fn ui_spawner(
mut spawner_commands: ResMut<CommandQueue<UiSpawnerCommand>>,
mut state: ResMut<UiSpawnerState>,
mut egui_context: ResMut<EguiContext>,
mut egui_context: EguiContexts,
) {
for command in spawner_commands.get_commands() {
match command {
@ -86,12 +86,14 @@ impl<T> SpawnedUiElement for MessageBox<T> where T: Display + Clone {
impl SpawnedUiElement for EditorPopup {
fn display(&mut self, egui_context: &egui::Context) {
let mut layouter = |ui: &egui::Ui, string: &str, wrap_width: f32| {
let mut layout_job =
syntax_highlighting::highlight(ui.ctx(), &CodeTheme::dark(), string, "toml");
layout_job.wrap.max_width = wrap_width;
ui.fonts().layout_job(layout_job)
};
// let mut layouter = |ui: &egui::Ui, string: &str, wrap_width: f32| {
// let mut layout_job =
// syntax_highlighting::highlight(ui.ctx(), &CodeTheme::dark(), string, "toml");
// layout_job.wrap.max_width = wrap_width;
// ui.fonts().layout_job(layout_job)
// };
// new: but not hooked up
// let mut theme = egui_extras::syntax_highlighting::CodeTheme::from_memory(ui.ctx());
egui::Window::new(&self.title)
.open(&mut self.open)
@ -103,7 +105,7 @@ impl SpawnedUiElement for EditorPopup {
.desired_rows(20)
.lock_focus(true)
.desired_width(400.0)
.layouter(&mut layouter)
// .layouter(&mut layouter)
)
});
@ -135,7 +137,7 @@ where T: SpawnedUiElement + Send + Sync + 'static {
UiSpawnerCommand::CreateElement(Box::new(element))
}
#[derive(Default)]
#[derive(Default, Resource)]
pub struct UiSpawnerState {
elements: Vec<Box<dyn SpawnedUiElement + Send + Sync>>
}

View File

@ -23,10 +23,10 @@ where
let mesh = container.generate_simple_mesh(meshes);
commands
.spawn_bundle(PbrBundle {
.spawn(PbrBundle {
mesh,
material: materials.add(material),
transform: Transform::identity(),
transform: Transform::IDENTITY,
..Default::default()
})
.insert(container)

View File

@ -11,7 +11,7 @@ ron = { version = "0.8", optional = true }
serde = { version = "1.0", optional = true }
strum = { version = "0.24", optional = true }
strum_macros = { version = "0.24", optional = true }
bevy = { version = "0.8", default-features = false, optional = true }
bevy = { version = "0.11", default-features = false, optional = true }
dot_vox = { version = "4.1.0", optional = true }
thiserror = { version = "1.0", optional = true }