use canvas zoom & a bunch of other changes

This commit is contained in:
OMGeeky
2025-04-14 19:50:37 +02:00
parent d1f07943fa
commit 26571dabd0
2 changed files with 142 additions and 25 deletions

Binary file not shown.

View File

@@ -1,17 +1,42 @@
use bevy::color::palettes::basic::RED; use crate::camera::Canvas;
// pub struct Block use bevy::color::palettes::basic::{GREEN, RED, WHITE};
use bevy::prelude::*; use bevy::prelude::*;
use bevy::text::TextBounds; use bevy::text::TextBounds;
const LABEL_SCALING_FACTOR: f32 = 0.2;
#[derive(Bundle, Debug)] #[derive(Bundle, Debug)]
pub struct BlockBundle { pub struct BlockBundle {
// name: Text2d,
block: Block, block: Block,
transform: Transform, transform: Transform,
global_transform: GlobalTransform, global_transform: GlobalTransform,
block_visuals: BlockVisuals, block_visuals: BlockVisuals,
} }
#[derive(Bundle, Debug)]
pub struct BlockLabelBundle {
text: Text2d,
font: TextFont,
text_layout: TextLayout,
text_bounds: TextBounds,
transform: Transform,
marker: CanvasText,
}
impl BlockLabelBundle {
fn new(name: impl Into<String>, size: IVec2, font: TextFont) -> Self {
Self {
text: Text2d(name.into()),
font,
text_layout: TextLayout::new(JustifyText::Justified, LineBreak::WordOrCharacter),
text_bounds: TextBounds::from(size.as_vec2() * (1.0 / LABEL_SCALING_FACTOR)),
transform: Transform::from_translation(Vec3::Z),
marker: CanvasText,
}
}
}
#[derive(Component, Debug)]
pub struct CanvasText;
#[derive(Component, Debug)] #[derive(Component, Debug)]
pub struct BlockVisuals { pub struct BlockVisuals {
size: IVec2, size: IVec2,
@@ -32,11 +57,18 @@ pub struct LogicSimPlugin;
impl Plugin for LogicSimPlugin { impl Plugin for LogicSimPlugin {
fn build(&self, app: &mut App) { fn build(&self, app: &mut App) {
app.add_systems(Startup, setup) app.add_systems(Startup, setup)
.add_systems(Update, render_blocks); .add_systems(Update, (render_blocks, scale_labels));
} }
} }
fn setup(mut commands: Commands) { fn setup(mut commands: Commands, asset_server: Res<AssetServer>) {
let size = IVec2::new(50, 40); let font = asset_server.load("fonts/arcane_nine.otf");
let text_font = TextFont {
font,
font_size: 100.0,
..default()
};
let size = IVec2::new(50, 80);
commands commands
.spawn(BlockBundle { .spawn(BlockBundle {
// name: Text2d("AND".into()), // name: Text2d("AND".into()),
@@ -45,37 +77,122 @@ fn setup(mut commands: Commands) {
color: Color::from(RED), color: Color::from(RED),
}, },
block: Block { block: Block {
inputs: vec![Connection { inputs: vec![
size: 2, Connection {
values: vec![false, true], size: 10,
}], values: vec![
false, true, false, true, false, true, false, true, false, true,
],
},
Connection {
size: 9,
values: vec![false, true, false, true, false, true, false, true, false],
},
],
outputs: vec![ outputs: vec![
Connection { Connection {
size: 1, size: 1,
values: vec![false], values: vec![false],
}, },
Connection { Connection {
size: 1, size: 2,
values: vec![true], values: vec![true, false],
},
Connection {
size: 3,
values: vec![true, false, true],
},
Connection {
size: 4,
values: vec![true, false, true, false],
}, },
], ],
}, },
global_transform: GlobalTransform::default(), global_transform: GlobalTransform::default(),
transform: Transform::default(), transform: Transform::default(),
}) })
.with_child(( .with_child(BlockLabelBundle::new("AND", size, text_font));
Text2d("AND".into()),
TextLayout::new(JustifyText::Center, LineBreak::WordBoundary),
TextBounds::from(size.as_vec2()),
Transform::from_translation(Vec3::Z),
));
} }
fn render_blocks(blocks: Query<(&BlockVisuals, &GlobalTransform)>, mut gizmos: Gizmos) { fn render_blocks(
for (block_visual, transform) in blocks.iter() { blocks: Query<(&BlockVisuals, &Block, &GlobalTransform)>,
gizmos.rect_2d( canvas: Res<Canvas>,
transform.translation().xy(), mut gizmos: Gizmos,
block_visual.size.as_vec2(), ) {
block_visual.color, for (block_visual, block, transform) in blocks.iter() {
); let size = block_visual.size.as_vec2() * canvas.zoom;
let center = transform.translation().xy();
let half_size = size / 2.0;
let top = center.y + half_size.y;
// let bottom = center.y - half_size.y;
let left = center.x - half_size.x;
let right = center.x + half_size.x;
gizmos.rect_2d(center, size, block_visual.color);
draw_connections(left, top, size.y, &block.inputs, &mut gizmos, &canvas);
draw_connections(right, top, size.y, &block.outputs, &mut gizmos, &canvas);
}
}
fn draw_connections(
x: f32,
y: f32,
available_height: f32,
connections: &[Connection],
gizmos: &mut Gizmos,
canvas: &Canvas,
) {
let input_count = connections.len();
let input_spacing = available_height / (input_count + 1) as f32;
// println!("{} -> {}", input_count, input_spacing);
for (i, connection) in connections.iter().enumerate() {
draw_connection(x, y, gizmos, input_spacing, i, connection, canvas);
}
}
fn draw_connection(
x: f32,
y: f32,
gizmos: &mut Gizmos,
input_spacing: f32,
i: usize,
connection: &Connection,
canvas: &Canvas,
) {
const CONNECTION_BIT_SIZE: f32 = 10.0;
let connection_bit_size = CONNECTION_BIT_SIZE * canvas.zoom;
let connection_bit_half_size = connection_bit_size * 0.5;
let connection_pos = Vec2::new(x, y - input_spacing * (i + 1) as f32);
let rows = if connection.size > 8 { 2 } else { 1 };
let columns = (connection.size as f32 / rows as f32).ceil() as u32;
let half_offset = Vec2::new(columns as f32, rows as f32) * (connection_bit_size / 2.0);
let one_size = Vec2::new(connection_bit_size, connection_bit_size);
let half_one_size = one_size / 2.0;
'rows: for y in 0..rows {
for x in 0..columns {
let index = y * columns + x;
if index >= connection.size {
break 'rows;
}
let pos = connection_pos
+ Vec2::new(x as f32, (rows - y - 1) as f32) * connection_bit_size
- half_offset
+ half_one_size;
let value = connection.values[index as usize];
let color = if value { RED } else { GREEN };
gizmos.circle_2d(pos, connection_bit_half_size, color);
}
}
gizmos.rect_2d(
connection_pos,
Vec2::new(columns as f32, rows as f32) * connection_bit_size,
WHITE,
);
}
fn scale_labels(mut labels: Query<(&mut Transform), With<CanvasText>>, canvas: Res<Canvas>) {
for (mut transform) in labels.iter_mut() {
transform.scale = Vec3::splat(canvas.zoom) * LABEL_SCALING_FACTOR;
} }
} }