227 lines
No EOL
7.3 KiB
Rust
227 lines
No EOL
7.3 KiB
Rust
use bevy::ecs::schedule::ShouldRun;
|
|
use bevy::input::mouse::{MouseMotion, MouseWheel};
|
|
use bevy::math::Vec3Swizzles;
|
|
use bevy::{prelude::*, window::PresentMode, winit::WinitSettings};
|
|
use bevy_egui::{egui, EguiContext, EguiPlugin};
|
|
use bevy_prototype_lyon::prelude::*;
|
|
|
|
use shape_maker::*;
|
|
|
|
fn main() {
|
|
let mut app = App::new();
|
|
|
|
app
|
|
.insert_resource(ClearColor(Color::rgb(0.1, 0.1, 0.12)))
|
|
.insert_resource(Msaa { samples: 4 })
|
|
// Optimal power saving and present mode settings for desktop apps.
|
|
.insert_resource(WinitSettings::desktop_app())
|
|
.insert_resource(WindowDescriptor {
|
|
present_mode: PresentMode::Fifo,
|
|
title: "Shape Maker".to_string(),
|
|
..Default::default()
|
|
})
|
|
.insert_resource(ButtonsColors::default())
|
|
.insert_resource(UiState::default())
|
|
.insert_resource(PointSize(6.0))
|
|
.insert_resource(SnapGrid::default())
|
|
;
|
|
|
|
app
|
|
.add_plugins(DefaultPlugins)
|
|
.add_plugin(EguiPlugin)
|
|
.add_plugin(ShapePlugin)
|
|
;
|
|
|
|
app
|
|
.add_startup_system(configure_visuals)
|
|
.add_startup_system(basic_setup_sys)
|
|
.add_system(create_sys.with_run_criteria(|state: Res<UiState>, mut ec: ResMut<EguiContext>|
|
|
if !ec.ctx_mut().is_pointer_over_area() && state.current_action == Action::Create { ShouldRun::Yes } else { ShouldRun::No }
|
|
))
|
|
.add_system(modify_sys.with_run_criteria(|state: Res<UiState>, mut ec: ResMut<EguiContext>|
|
|
if !ec.ctx_mut().is_pointer_over_area() && state.current_action == Action::Modify { ShouldRun::Yes } else { ShouldRun::No }
|
|
))
|
|
.add_system(ui::action_bar_sys)
|
|
.add_system(ui::shape_tree_sys)
|
|
.add_system(show_hide_points)
|
|
.add_system(color_points)
|
|
.add_system(drag_camera_sys)
|
|
.add_system(zoom_camera_sys)
|
|
.add_system(scale_points)
|
|
.add_system(ui::grid_window_sys)
|
|
;
|
|
|
|
app.run();
|
|
}
|
|
|
|
fn basic_setup_sys(
|
|
mut coms: Commands,
|
|
) {
|
|
coms.spawn_bundle(Camera2dBundle::default())
|
|
.insert(MainCamera);
|
|
}
|
|
|
|
fn configure_visuals(mut egui_ctx: ResMut<EguiContext>) {
|
|
egui_ctx.ctx_mut().set_visuals(egui::Visuals {
|
|
window_rounding: 0.0.into(),
|
|
..Default::default()
|
|
});
|
|
}
|
|
|
|
fn zoom_camera_sys(
|
|
mut mouse_scroll: EventReader<MouseWheel>,
|
|
mut cam: Query<&mut OrthographicProjection, With<MainCamera>>,
|
|
) {
|
|
let mut scroll = 0.0;
|
|
|
|
for m in mouse_scroll.iter() {
|
|
scroll += m.y * 0.1;
|
|
}
|
|
|
|
for mut op in cam.iter_mut() {
|
|
op.scale += scroll ;
|
|
if op.scale <= 0.05 {
|
|
op.scale = 0.05;
|
|
}
|
|
}
|
|
}
|
|
|
|
fn scale_points(
|
|
scale: Query<&OrthographicProjection, (With<MainCamera>, Changed<OrthographicProjection>)>,
|
|
shapes: Query<&ShapeData>,
|
|
p_size: Res<PointSize>,
|
|
mut paths: Query<&mut Path, With<Path>>,
|
|
) {
|
|
if let Ok(scale) = scale.get_single() {
|
|
let scale = scale.scale;
|
|
|
|
for sd in shapes.iter() {
|
|
if let Ok(mut p) = paths.get_mut(sd.center.unwrap()) {
|
|
let shape = shapes::Circle {
|
|
radius: p_size.0 * scale,
|
|
center: Vec2::ZERO,
|
|
};
|
|
*p = ShapePath::build_as(&shape);
|
|
}
|
|
for &edge in sd.edges.iter() {
|
|
if let Ok(mut p) = paths.get_mut(edge) {
|
|
let shape = shapes::Circle {
|
|
radius: p_size.0 * scale,
|
|
center: Vec2::ZERO,
|
|
};
|
|
*p = ShapePath::build_as(&shape);
|
|
}
|
|
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
fn drag_camera_sys(
|
|
mut mouse_move: EventReader<MouseMotion>,
|
|
mouse_input: Res<Input<MouseButton>>,
|
|
mut cam: Query<(&mut Transform, &OrthographicProjection), With<MainCamera>>,
|
|
) {
|
|
if mouse_input.pressed(MouseButton::Middle) {
|
|
let mut delta = Vec2::ZERO;
|
|
for m in mouse_move.iter() {
|
|
delta -= Vec2::new(m.delta.x, -m.delta.y) * 2.0;
|
|
}
|
|
for (mut t, op) in cam.iter_mut() {
|
|
t.translation += delta.extend(0.0) * op.scale;
|
|
}
|
|
}
|
|
}
|
|
|
|
fn show_hide_points(
|
|
state: Res<UiState>,
|
|
shapes: Query<&ShapeData>,
|
|
mut dots: Query<&mut Visibility, (With<Transform>, With<Path>)>,
|
|
) {
|
|
let (center, edge) = match state.current_action {
|
|
Action::Create => (false, false),
|
|
Action::Modify => (true, true),
|
|
};
|
|
|
|
for sd in shapes.iter() {
|
|
// center
|
|
if let Ok(mut v) = dots.get_mut(sd.center.unwrap()) {
|
|
if v.is_visible != center {
|
|
v.is_visible = center;
|
|
}
|
|
}
|
|
for e in sd.edges.iter() {
|
|
if let Ok(mut v) = dots.get_mut(*e) {
|
|
if v.is_visible != edge {
|
|
v.is_visible = edge;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
fn color_points(
|
|
mut current: Local<Option<Entity>>,
|
|
scale: Query<&OrthographicProjection, With<MainCamera>>,
|
|
wnds: Res<Windows>,
|
|
p_size: Res<PointSize>,
|
|
q_cam: Query<(&Camera, &GlobalTransform), With<MainCamera>>,
|
|
shapes: Query<&ShapeData>,
|
|
global_transforms: Query<&GlobalTransform, With<Path>>,
|
|
mut dots: Query<&mut DrawMode, With<Path>>,
|
|
) {
|
|
let scale = scale.get_single().map(|s| s.scale).unwrap_or(1.0);
|
|
|
|
let normal = DrawMode::Outlined { fill_mode: FillMode::color(Color::RED), outline_mode: StrokeMode::new(Color::rgb(0.9,0.0,0.0), 0.0) };
|
|
let hover = DrawMode::Outlined { fill_mode: FillMode::color(Color::RED), outline_mode: StrokeMode::new(Color::ORANGE, 3.0 * scale) };
|
|
|
|
let mouse_pos = get_mouse_pos(&q_cam, &wnds);
|
|
if let Some(mpos) = mouse_pos {
|
|
let mut hovering = false;
|
|
'shapes: for sd in shapes.iter() {
|
|
let e = sd.center.unwrap();
|
|
let p = global_transforms.get(e).unwrap().translation().xy();
|
|
if (mpos - p).length_squared() < (p_size.0 * scale).powi(2) {
|
|
if Some(e) != *current {
|
|
if let Some(c) = &*current {
|
|
if let Ok(mut md) = dots.get_mut(*c) {
|
|
*md = normal;
|
|
}
|
|
}
|
|
*current = Some(e);
|
|
if let Ok(mut md) = dots.get_mut(e) {
|
|
*md = hover;
|
|
}
|
|
}
|
|
hovering = true;
|
|
break;
|
|
}
|
|
for edge in sd.edges.iter() {
|
|
let p = global_transforms.get(*edge).unwrap().translation().xy();
|
|
if (mpos - p).length_squared() < (p_size.0 * scale).powi(2) {
|
|
if Some(*edge) != *current {
|
|
if let Some(c) = &*current {
|
|
if let Ok(mut md) = dots.get_mut(*c) {
|
|
*md = normal;
|
|
}
|
|
}
|
|
*current = Some(*edge);
|
|
if let Ok(mut md) = dots.get_mut(*edge) {
|
|
*md = hover;
|
|
}
|
|
}
|
|
hovering = true;
|
|
break 'shapes;
|
|
}
|
|
}
|
|
}
|
|
if !hovering {
|
|
if let Some(c) = &*current {
|
|
if let Ok(mut md) = dots.get_mut(*c) {
|
|
*md = normal;
|
|
}
|
|
*current = None;
|
|
}
|
|
}
|
|
}
|
|
} |