IMPORT AND EXPORT
This commit is contained in:
parent
43221c02a7
commit
ab9e0fd719
7 changed files with 337 additions and 27 deletions
38
Cargo.lock
generated
38
Cargo.lock
generated
|
@ -41,6 +41,18 @@ dependencies = [
|
||||||
"version_check",
|
"version_check",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "ahash"
|
||||||
|
version = "0.8.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "57e6e951cfbb2db8de1828d49073a113a29fd7117b1596caa781a258c7e38d72"
|
||||||
|
dependencies = [
|
||||||
|
"cfg-if 1.0.0",
|
||||||
|
"getrandom",
|
||||||
|
"once_cell",
|
||||||
|
"version_check",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "aho-corasick"
|
name = "aho-corasick"
|
||||||
version = "0.7.18"
|
version = "0.7.18"
|
||||||
|
@ -400,9 +412,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "bevy_egui"
|
name = "bevy_egui"
|
||||||
version = "0.15.1"
|
version = "0.16.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "acbf44ff770566dca66b805a6829df783f64700bd01d35aec1034dff31b531a4"
|
checksum = "e92efd442c1c99edb841c21b51248e0b472d9fc92ecd8124bc7bcfb5346760e9"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"arboard",
|
"arboard",
|
||||||
"bevy",
|
"bevy",
|
||||||
|
@ -841,7 +853,7 @@ version = "0.8.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "f6e9aa1866c1cf7ee000f281ce9e90d02d701f5c7380a107252017e58e2f5246"
|
checksum = "f6e9aa1866c1cf7ee000f281ce9e90d02d701f5c7380a107252017e58e2f5246"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"ahash",
|
"ahash 0.7.6",
|
||||||
"getrandom",
|
"getrandom",
|
||||||
"hashbrown",
|
"hashbrown",
|
||||||
"instant",
|
"instant",
|
||||||
|
@ -1386,20 +1398,20 @@ checksum = "9ea835d29036a4087793836fa931b08837ad5e957da9e23886b29586fb9b6650"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "egui"
|
name = "egui"
|
||||||
version = "0.18.1"
|
version = "0.19.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "eb095a8b9feb9b7ff8f00b6776dffcef059538a3f4a91238e03c900e9c9ad9a2"
|
checksum = "fc9fcd393c3daaaf5909008a1d948319d538b79c51871e4df0993260260a94e4"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"ahash",
|
"ahash 0.8.0",
|
||||||
"epaint",
|
"epaint",
|
||||||
"nohash-hasher",
|
"nohash-hasher",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "emath"
|
name = "emath"
|
||||||
version = "0.18.0"
|
version = "0.19.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "c223f58c7e38abe1770f367b969f1b3fbd4704b67666bcb65dbb1adb0980ba72"
|
checksum = "9542a40106fdba943a055f418d1746a050e1a903a049b030c2b097d4686a33cf"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bytemuck",
|
"bytemuck",
|
||||||
]
|
]
|
||||||
|
@ -1448,12 +1460,12 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "epaint"
|
name = "epaint"
|
||||||
version = "0.18.1"
|
version = "0.19.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "0c29567088888e8ac3e8f61bbb2ddc820207ebb8d69eefde5bcefa06d65e4e89"
|
checksum = "5ba04741be7f6602b1a1b28f1082cce45948a7032961c52814f8946b28493300"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"ab_glyph",
|
"ab_glyph",
|
||||||
"ahash",
|
"ahash 0.8.0",
|
||||||
"atomic_refcell",
|
"atomic_refcell",
|
||||||
"bytemuck",
|
"bytemuck",
|
||||||
"emath",
|
"emath",
|
||||||
|
@ -1901,7 +1913,7 @@ version = "0.12.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888"
|
checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"ahash",
|
"ahash 0.7.6",
|
||||||
"serde",
|
"serde",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -3078,6 +3090,8 @@ dependencies = [
|
||||||
"bevy_egui",
|
"bevy_egui",
|
||||||
"bevy_prototype_lyon",
|
"bevy_prototype_lyon",
|
||||||
"rfd",
|
"rfd",
|
||||||
|
"serde",
|
||||||
|
"serde_json",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
|
@ -6,7 +6,9 @@ edition = "2021"
|
||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
bevy = "0.8.0"
|
bevy = "0.8.1"
|
||||||
bevy_egui = { version = "0.15.0", features = ["manage_clipboard"] }
|
bevy_egui = { version = "0.16.0", features = ["manage_clipboard"] }
|
||||||
bevy_prototype_lyon = "0.6.0"
|
bevy_prototype_lyon = "0.6.0"
|
||||||
rfd = "0.10.0"
|
rfd = "0.10.0"
|
||||||
|
serde = "1.0.144"
|
||||||
|
serde_json = "1.0.85"
|
||||||
|
|
|
@ -26,9 +26,8 @@ Eventually, this will be a level editor... But until then, I guess it's just fun
|
||||||
- [x] Show/Hide grid(also make a visible grid in the first place)
|
- [x] Show/Hide grid(also make a visible grid in the first place)
|
||||||
- [x] Make grid fill the screen at all times
|
- [x] Make grid fill the screen at all times
|
||||||
- [x] Comment/Editor note for shapes
|
- [x] Comment/Editor note for shapes
|
||||||
- [ ] Save? (maybe just import and export directly?)
|
- [x] Export
|
||||||
- [ ] Export
|
- [x] Import
|
||||||
- [ ] Import
|
|
||||||
|
|
||||||
## Quality of life todo
|
## Quality of life todo
|
||||||
|
|
||||||
|
@ -36,6 +35,7 @@ Eventually, this will be a level editor... But until then, I guess it's just fun
|
||||||
- [ ] Grab shapes instead of center points
|
- [ ] Grab shapes instead of center points
|
||||||
- [ ] Reorder items tree
|
- [ ] Reorder items tree
|
||||||
- [ ] Select item by clicking/double clicking on the relevant shape/image
|
- [ ] Select item by clicking/double clicking on the relevant shape/image
|
||||||
|
- [ ] Allow for more types of export/import
|
||||||
|
|
||||||
## Maybe, just maybe todo
|
## Maybe, just maybe todo
|
||||||
|
|
||||||
|
|
267
src/export.rs
Normal file
267
src/export.rs
Normal file
|
@ -0,0 +1,267 @@
|
||||||
|
use std::io::Write;
|
||||||
|
|
||||||
|
use bevy::math::Vec3Swizzles;
|
||||||
|
use bevy::prelude::*;
|
||||||
|
use bevy_prototype_lyon::prelude::*;
|
||||||
|
use crate::*;
|
||||||
|
use serde::{Serialize, Deserialize};
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||||
|
pub enum ExportData {
|
||||||
|
Image {
|
||||||
|
path: String,
|
||||||
|
scale: Vec2,
|
||||||
|
},
|
||||||
|
Square {
|
||||||
|
size: Vec2,
|
||||||
|
},
|
||||||
|
Triangle {
|
||||||
|
/// Relative to translation!
|
||||||
|
vertex: [Vec2; 3],
|
||||||
|
},
|
||||||
|
Circle {
|
||||||
|
radius: f32,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#[derive(Debug, Serialize)]
|
||||||
|
pub struct ExportItem<'a> {
|
||||||
|
pub name: &'a str,
|
||||||
|
pub note: &'a str,
|
||||||
|
pub translation: Vec3,
|
||||||
|
pub rotation: f32,
|
||||||
|
pub color: Color,
|
||||||
|
pub data: ExportData,
|
||||||
|
}
|
||||||
|
#[derive(Debug, Deserialize)]
|
||||||
|
pub struct ImportItem {
|
||||||
|
pub name: String,
|
||||||
|
pub note: String,
|
||||||
|
pub translation: Vec3,
|
||||||
|
pub rotation: f32,
|
||||||
|
pub color: Color,
|
||||||
|
pub data: ExportData,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn toml_save_sys(
|
||||||
|
mut imp_exp: ResMut<ShouldImportExport>,
|
||||||
|
shapes: Query<&ShapeData>,
|
||||||
|
images: Query<(&ImageData, &Transform)>,
|
||||||
|
transforms: Query<&Transform>,
|
||||||
|
draw_modes: Query<&DrawMode>,
|
||||||
|
) {
|
||||||
|
imp_exp.export = false;
|
||||||
|
let file = rfd::FileDialog::new()
|
||||||
|
.set_directory("./")
|
||||||
|
.set_title("Just pick where you wanna save that file...")
|
||||||
|
.save_file();
|
||||||
|
|
||||||
|
if let Some(path) = file {
|
||||||
|
let file = std::fs::File::create(path);
|
||||||
|
if let Ok(mut file) = file {
|
||||||
|
let items: Vec<ExportItem> = images.iter().map(|(id, tr)| {
|
||||||
|
ExportItem {
|
||||||
|
name: &id.name,
|
||||||
|
note: &id.note,
|
||||||
|
translation: tr.translation,
|
||||||
|
rotation: tr.rotation.to_euler(EulerRot::XYZ).2,
|
||||||
|
data: ExportData::Image { path: id.path.clone(), scale: tr.scale.xy() },
|
||||||
|
color: Color::WHITE,
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.chain(shapes.iter().map(|sd| {
|
||||||
|
let trans = transforms.get(sd.main_shape).unwrap();
|
||||||
|
let color = draw_modes.get(sd.main_shape).map(|dm|
|
||||||
|
if let DrawMode::Outlined { fill_mode: fm, outline_mode: _ } = dm {
|
||||||
|
fm.color
|
||||||
|
} else {
|
||||||
|
Color::WHITE
|
||||||
|
}
|
||||||
|
).unwrap_or(Color::WHITE);
|
||||||
|
|
||||||
|
ExportItem {
|
||||||
|
name: &sd.name,
|
||||||
|
note: &sd.note,
|
||||||
|
translation: trans.translation,
|
||||||
|
rotation: trans.rotation.to_euler(EulerRot::XYZ).2,
|
||||||
|
data: get_export_data_for_shape(sd, &transforms),
|
||||||
|
color,
|
||||||
|
}
|
||||||
|
}))
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
let json = match serde_json::to_string_pretty(&items) {
|
||||||
|
Ok(t) => t,
|
||||||
|
Err(e) => {
|
||||||
|
println!("json error: {:?}", e);
|
||||||
|
return;
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
file.write(json.as_bytes()).expect("Could not write to save file");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn import_sys(
|
||||||
|
mut coms: Commands,
|
||||||
|
mut imp_exp: ResMut<ShouldImportExport>,
|
||||||
|
assets: Res<AssetServer>,
|
||||||
|
p_size: Res<PointSize>,
|
||||||
|
|
||||||
|
) {
|
||||||
|
imp_exp.import = false;
|
||||||
|
let file = rfd::FileDialog::new()
|
||||||
|
.set_directory("./")
|
||||||
|
.set_title("Please pick a valid json file to load from <3")
|
||||||
|
.pick_file();
|
||||||
|
|
||||||
|
if let Some(file_path) = file {
|
||||||
|
let file = std::fs::OpenOptions::new().read(true).open(file_path);
|
||||||
|
if let Ok(f) = file {
|
||||||
|
let items: Vec<ImportItem> = match serde_json::from_reader(f) {
|
||||||
|
Ok(itms) => itms,
|
||||||
|
Err(_) => {
|
||||||
|
bevy::log::error!("Invalid json file");
|
||||||
|
return;
|
||||||
|
},
|
||||||
|
};
|
||||||
|
let outline_mode = StrokeMode::new(Color::rgba(0.0, 0.5, 0.5, 0.6), 3.0);
|
||||||
|
let dots_dm = DrawMode::Fill(FillMode::color(Color::RED));
|
||||||
|
let dot_shape = shapes::Circle { radius: p_size.0, center: Vec2::ZERO };
|
||||||
|
|
||||||
|
for i in items {
|
||||||
|
let ImportItem { name, note, translation, rotation, color, data } = i;
|
||||||
|
let transform = Transform::from_translation(translation)
|
||||||
|
.with_rotation(Quat::from_rotation_z(rotation));
|
||||||
|
let center = coms.spawn_bundle(GeometryBuilder::build_as(
|
||||||
|
&dot_shape,
|
||||||
|
dots_dm,
|
||||||
|
Transform::from_xyz(0.0, 0.0, 0.5)
|
||||||
|
)).id();
|
||||||
|
let main_shape_dm = DrawMode::Outlined { fill_mode: FillMode::color(color), outline_mode: outline_mode };
|
||||||
|
match data {
|
||||||
|
ExportData::Image { path, scale } => {
|
||||||
|
let image: Handle<Image> = assets.load(&path);
|
||||||
|
coms.spawn_bundle(SpriteBundle {
|
||||||
|
texture: image,
|
||||||
|
..Default::default()
|
||||||
|
})
|
||||||
|
.insert(ImageData { name, note, path })
|
||||||
|
.insert(transform.with_scale(scale.extend(1.0))
|
||||||
|
);
|
||||||
|
|
||||||
|
coms.entity(center).despawn(); // We dont need the center in an image
|
||||||
|
},
|
||||||
|
ExportData::Square { size } => {
|
||||||
|
let e1 = coms.spawn_bundle(GeometryBuilder::build_as(
|
||||||
|
&dot_shape,
|
||||||
|
dots_dm,
|
||||||
|
Transform::from_translation((size * 0.5).extend(0.5))
|
||||||
|
)).id();
|
||||||
|
let e2 = coms.spawn_bundle(GeometryBuilder::build_as(
|
||||||
|
&dot_shape,
|
||||||
|
dots_dm,
|
||||||
|
Transform::from_translation((-size * 0.5).extend(0.5))
|
||||||
|
)).id();
|
||||||
|
|
||||||
|
let main_id = coms.spawn_bundle(GeometryBuilder::build_as(
|
||||||
|
&shapes::Rectangle { extents: size, ..Default::default() },
|
||||||
|
main_shape_dm,
|
||||||
|
transform
|
||||||
|
)).id();
|
||||||
|
|
||||||
|
coms.entity(main_id).insert(ShapeData {
|
||||||
|
name,
|
||||||
|
shape: CreateShape::Square,
|
||||||
|
main_shape: main_id,
|
||||||
|
edges: Vec::from([e1,e2]),
|
||||||
|
center: Some(center),
|
||||||
|
note,
|
||||||
|
})
|
||||||
|
.add_child(center)
|
||||||
|
.add_child(e1)
|
||||||
|
.add_child(e2);
|
||||||
|
},
|
||||||
|
ExportData::Triangle { vertex } => {
|
||||||
|
let main_shape = shapes::Polygon { points: vertex.clone().to_vec(), closed: true };
|
||||||
|
let vertex = vertex.map(|v| {
|
||||||
|
coms.spawn_bundle(GeometryBuilder::build_as(
|
||||||
|
&dot_shape,
|
||||||
|
dots_dm,
|
||||||
|
Transform::from_translation(v.extend(0.5))
|
||||||
|
)).id()
|
||||||
|
});
|
||||||
|
|
||||||
|
let main_id = coms.spawn_bundle(GeometryBuilder::build_as(
|
||||||
|
&main_shape,
|
||||||
|
main_shape_dm,
|
||||||
|
transform
|
||||||
|
)).id();
|
||||||
|
coms.entity(main_id).insert(ShapeData {
|
||||||
|
name,
|
||||||
|
shape: CreateShape::Triangle,
|
||||||
|
main_shape: main_id,
|
||||||
|
edges: vertex.clone().to_vec(),
|
||||||
|
center: Some(center),
|
||||||
|
note,
|
||||||
|
})
|
||||||
|
.add_child(vertex[0])
|
||||||
|
.add_child(vertex[1])
|
||||||
|
.add_child(vertex[2])
|
||||||
|
.add_child(center);
|
||||||
|
},
|
||||||
|
ExportData::Circle { radius } => {
|
||||||
|
let edge = coms.spawn_bundle(GeometryBuilder::build_as(
|
||||||
|
&dot_shape,
|
||||||
|
dots_dm,
|
||||||
|
Transform::from_xyz(radius, 0.0, 0.5)
|
||||||
|
)).id();
|
||||||
|
|
||||||
|
let main_id = coms.spawn_bundle(GeometryBuilder::build_as(
|
||||||
|
&shapes::Circle { radius, center: Vec2::ZERO },
|
||||||
|
main_shape_dm,
|
||||||
|
transform
|
||||||
|
)).id();
|
||||||
|
coms.entity(main_id).insert(ShapeData {
|
||||||
|
name,
|
||||||
|
shape: CreateShape::Circle,
|
||||||
|
main_shape: main_id,
|
||||||
|
edges: [edge].to_vec(),
|
||||||
|
center: Some(center),
|
||||||
|
note,
|
||||||
|
})
|
||||||
|
.add_child(center)
|
||||||
|
.add_child(edge);
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_export_data_for_shape(sd: &ShapeData, transforms: &Query<&Transform>,) -> ExportData {
|
||||||
|
match sd.shape {
|
||||||
|
CreateShape::Triangle => {
|
||||||
|
assert_eq!(sd.edges.len(), 3);
|
||||||
|
|
||||||
|
let mut edges = sd.edges.iter().take(3).map(|e| transforms.get(*e).unwrap().translation.xy());
|
||||||
|
let edges = [edges.next().unwrap(), edges.next().unwrap(), edges.next().unwrap()];
|
||||||
|
ExportData::Triangle { vertex: edges }
|
||||||
|
},
|
||||||
|
CreateShape::Square => {
|
||||||
|
assert_eq!(sd.edges.len(), 2);
|
||||||
|
let e1 = transforms.get(sd.edges[0]).unwrap().translation.xy();
|
||||||
|
let e2 = transforms.get(sd.edges[1]).unwrap().translation.xy();
|
||||||
|
|
||||||
|
let size = (e1 - e2).abs();
|
||||||
|
ExportData::Square { size }
|
||||||
|
},
|
||||||
|
CreateShape::Circle => {
|
||||||
|
assert_eq!(sd.edges.len(), 1);
|
||||||
|
|
||||||
|
let radius = transforms.get(sd.edges[0]).unwrap().translation.xy().length();
|
||||||
|
ExportData::Circle { radius }
|
||||||
|
},
|
||||||
|
CreateShape::Capsule => unimplemented!(),
|
||||||
|
}
|
||||||
|
}
|
16
src/lib.rs
16
src/lib.rs
|
@ -6,6 +6,7 @@ pub mod helpers;
|
||||||
pub mod modify;
|
pub mod modify;
|
||||||
pub mod ui;
|
pub mod ui;
|
||||||
pub mod infinite_grid;
|
pub mod infinite_grid;
|
||||||
|
pub mod export;
|
||||||
pub use modify::modify_sys;
|
pub use modify::modify_sys;
|
||||||
pub use create::create_sys;
|
pub use create::create_sys;
|
||||||
pub use helpers::*;
|
pub use helpers::*;
|
||||||
|
@ -40,10 +41,12 @@ impl Default for SnapGrid {
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct PointSize(pub f32);
|
pub struct PointSize(pub f32);
|
||||||
|
|
||||||
#[derive(Component, Debug, Deref, DerefMut)]
|
#[derive(Component, Debug)]
|
||||||
pub struct ImageName(pub String);
|
pub struct ImageData {
|
||||||
#[derive(Component, Debug, Deref, DerefMut)]
|
pub name: String,
|
||||||
pub struct ImageSize(pub Vec2);
|
pub note: String,
|
||||||
|
pub path: String,
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Component, Debug)]
|
#[derive(Component, Debug)]
|
||||||
pub struct ShapeData {
|
pub struct ShapeData {
|
||||||
|
@ -96,6 +99,11 @@ impl UiState {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#[derive(Default, Clone, Debug)]
|
||||||
|
pub struct ShouldImportExport {
|
||||||
|
pub import: bool,
|
||||||
|
pub export: bool,
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct ButtonsColors {
|
pub struct ButtonsColors {
|
||||||
|
|
|
@ -27,6 +27,7 @@ fn main() {
|
||||||
.insert_resource(PointSize(6.0))
|
.insert_resource(PointSize(6.0))
|
||||||
.insert_resource(SnapGrid::default())
|
.insert_resource(SnapGrid::default())
|
||||||
.insert_resource(ui::SelectedItem::default())
|
.insert_resource(ui::SelectedItem::default())
|
||||||
|
.insert_resource(ShouldImportExport::default())
|
||||||
;
|
;
|
||||||
|
|
||||||
app
|
app
|
||||||
|
@ -64,6 +65,12 @@ fn main() {
|
||||||
.add_system(delete_selected_item_on_del_sys.with_run_criteria(|mut ec: ResMut<EguiContext>|
|
.add_system(delete_selected_item_on_del_sys.with_run_criteria(|mut ec: ResMut<EguiContext>|
|
||||||
if ec.ctx_mut().wants_keyboard_input() { ShouldRun::No } else { ShouldRun::Yes }
|
if ec.ctx_mut().wants_keyboard_input() { ShouldRun::No } else { ShouldRun::Yes }
|
||||||
))
|
))
|
||||||
|
.add_system(export::toml_save_sys.with_run_criteria(|ie: Res<ShouldImportExport>| {
|
||||||
|
if ie.export { ShouldRun::Yes } else { ShouldRun::No }
|
||||||
|
}))
|
||||||
|
.add_system(export::import_sys.with_run_criteria(|ie: Res<ShouldImportExport>| {
|
||||||
|
if ie.import { ShouldRun::Yes} else { ShouldRun::No }
|
||||||
|
}))
|
||||||
;
|
;
|
||||||
|
|
||||||
app.run();
|
app.run();
|
||||||
|
|
24
src/ui.rs
24
src/ui.rs
|
@ -40,12 +40,13 @@ pub fn action_bar_sys(
|
||||||
.pick_file();
|
.pick_file();
|
||||||
if let Some(file) = file {
|
if let Some(file) = file {
|
||||||
let name = String::from(file.file_name().unwrap().to_str().unwrap_or("Image"));
|
let name = String::from(file.file_name().unwrap().to_str().unwrap_or("Image"));
|
||||||
|
let path = file.to_str().unwrap().to_string();
|
||||||
let image: Handle<Image> = assets.load(file);
|
let image: Handle<Image> = assets.load(file);
|
||||||
coms.spawn_bundle(SpriteBundle {
|
coms.spawn_bundle(SpriteBundle {
|
||||||
texture: image,
|
texture: image,
|
||||||
..Default::default()
|
..Default::default()
|
||||||
})
|
})
|
||||||
.insert(ImageName(name));
|
.insert(ImageData { name, note: String::new(), path });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -118,17 +119,29 @@ pub fn grid_window_sys(
|
||||||
/// TODO: Allow drag and drop to re-order + reparent
|
/// TODO: Allow drag and drop to re-order + reparent
|
||||||
pub fn items_tree_sys(
|
pub fn items_tree_sys(
|
||||||
mut selected: ResMut<SelectedItem>,
|
mut selected: ResMut<SelectedItem>,
|
||||||
|
mut imp_exp: ResMut<ShouldImportExport>,
|
||||||
mut egui_ctx: ResMut<EguiContext>,
|
mut egui_ctx: ResMut<EguiContext>,
|
||||||
shapes:Query<(Entity, &ShapeData)>,
|
shapes:Query<(Entity, &ShapeData)>,
|
||||||
images: Query<(Entity, &ImageName), With<Sprite>>,
|
images: Query<(Entity, &ImageData), With<Sprite>>,
|
||||||
mut draw_modes: Query<&mut DrawMode, With<ShapeData>>,
|
mut draw_modes: Query<&mut DrawMode, With<ShapeData>>,
|
||||||
mut visible: Query<&mut Visibility, Or<(With<Path>, With<Sprite>)>>,
|
mut visible: Query<&mut Visibility, Or<(With<Path>, With<Sprite>)>>,
|
||||||
) {
|
) {
|
||||||
egui::Window::new("Items")
|
egui::Window::new("Items")
|
||||||
.default_pos((10.0,100.0))
|
.default_pos((10.0,100.0))
|
||||||
|
.fixed_size((150.0, f32::INFINITY))
|
||||||
.title_bar(true)
|
.title_bar(true)
|
||||||
.resizable(false)
|
.resizable(false)
|
||||||
.show(egui_ctx.ctx_mut(), |ui| {
|
.show(egui_ctx.ctx_mut(), |ui| {
|
||||||
|
ui.horizontal(|hui| {
|
||||||
|
if hui.button("Import").clicked() {
|
||||||
|
imp_exp.import = true;
|
||||||
|
}
|
||||||
|
if hui.button("Export").clicked() {
|
||||||
|
imp_exp.export = true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
ui.separator();
|
||||||
|
|
||||||
for (e, sd) in shapes.iter() {
|
for (e, sd) in shapes.iter() {
|
||||||
let entity_selected = if let Some(se) = **selected && se == e { true } else { false };
|
let entity_selected = if let Some(se) = **selected && se == e { true } else { false };
|
||||||
ui.horizontal(|hui| {
|
ui.horizontal(|hui| {
|
||||||
|
@ -162,7 +175,7 @@ pub fn items_tree_sys(
|
||||||
|
|
||||||
ui.horizontal(|hui| {
|
ui.horizontal(|hui| {
|
||||||
let color = if entity_selected { egui::Color32::GOLD } else { egui::Color32::WHITE };
|
let color = if entity_selected { egui::Color32::GOLD } else { egui::Color32::WHITE };
|
||||||
let label = egui::Label::new(egui::RichText::new(&**n).color(color)).sense(egui::Sense::click());
|
let label = egui::Label::new(egui::RichText::new(&n.name).color(color)).sense(egui::Sense::click());
|
||||||
if hui.add(label).clicked() {
|
if hui.add(label).clicked() {
|
||||||
if entity_selected {
|
if entity_selected {
|
||||||
**selected = None;
|
**selected = None;
|
||||||
|
@ -180,7 +193,6 @@ pub fn items_tree_sys(
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -194,7 +206,7 @@ pub fn inspector_sys(
|
||||||
mut paths: Query<&mut Path>,
|
mut paths: Query<&mut Path>,
|
||||||
mut draw_modes: Query<&mut DrawMode, With<Path>>,
|
mut draw_modes: Query<&mut DrawMode, With<Path>>,
|
||||||
mut visible: Query<&mut Visibility, Or<(With<Path>, With<Sprite>)>>,
|
mut visible: Query<&mut Visibility, Or<(With<Path>, With<Sprite>)>>,
|
||||||
mut images: Query<&mut ImageName, With<Sprite>>,
|
mut images: Query<&mut ImageData, With<Sprite>>,
|
||||||
) {
|
) {
|
||||||
if let Some(e) = **selected {
|
if let Some(e) = **selected {
|
||||||
let mut open = true;
|
let mut open = true;
|
||||||
|
@ -294,7 +306,7 @@ pub fn inspector_sys(
|
||||||
else if let Ok(mut name) = images.get_mut(e) {
|
else if let Ok(mut name) = images.get_mut(e) {
|
||||||
ui.horizontal(|hui| {
|
ui.horizontal(|hui| {
|
||||||
hui.label("Name:");
|
hui.label("Name:");
|
||||||
hui.text_edit_singleline(&mut **name);
|
hui.text_edit_singleline(&mut name.name);
|
||||||
});
|
});
|
||||||
ui.separator();
|
ui.separator();
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue