make comments disappear when pasting over them, but not when placing single tiles

This commit is contained in:
Crispy 2025-03-29 01:10:02 +01:00
parent ae42cd10a4
commit 6b8b2e6e6e
3 changed files with 78 additions and 40 deletions

View file

@ -81,7 +81,7 @@ impl Board {
let y = comment.y * tile_size + offset.y as i32;
for (i, line) in comment.text.lines().enumerate() {
let y = y + line_space * i as i32;
d.draw_text(&line, x, y, font_size, Color::ORANGE);
d.draw_text(line, x, y, font_size, Color::ORANGE);
}
}
}
@ -90,7 +90,7 @@ impl Board {
let comments = self
.comments
.iter()
.filter(|c| c.in_area(pos, width, height))
.filter(|c| c.in_area(pos, (width, height)))
.map(|c| {
let mut c = c.clone();
c.x -= pos.x as i32;
@ -105,6 +105,16 @@ impl Board {
}
pub fn paste_board(&mut self, pos: Pos, board: &Board) {
// remove comments that are obscured by new board
let mut i = 0;
while i < self.comments.len() {
if !self.comments[i].in_area(pos, board.grid.size()) {
i += 1;
} else {
self.comments.remove(i);
}
}
self.grid.paste_grid(pos, &board.grid);
for c in &board.comments {
let mut comment = c.clone();
@ -143,18 +153,10 @@ impl Board {
comments: Vec::new(),
})
}
pub fn width(&self) -> usize {
self.grid.width()
}
pub fn height(&self) -> usize {
self.grid.height()
}
}
impl Comment {
fn in_area(&self, pos: Pos, width: usize, height: usize) -> bool {
fn in_area(&self, pos: Pos, (width, height): (usize, usize)) -> bool {
self.x >= pos.x as i32
&& self.y >= pos.y as i32
&& self.x < pos.x as i32 + width as i32

View file

@ -26,7 +26,7 @@ const END_POPUP_HEIGHT: i32 = 165;
const MAX_ZOOM: f32 = 8.;
const MIN_ZOOM: f32 = 0.25;
const BOARD_MARGIN: PosInt = 3;
const BOARD_MARGIN: usize = 3;
const MAX_SPEED_POWER: u8 = 16;
const SPEED_DIGITS: i32 = 5;
const MAX_FRAME_TIME_MICROS: u128 = 1_000_000 / 30;
@ -79,6 +79,7 @@ pub struct Editor {
#[derive(Debug, Clone)]
enum Action {
SetTile(ResizeDeltas, Pos, Tile, Tile),
SetArea(ResizeDeltas, Pos, Board, Board),
}
@ -207,6 +208,11 @@ impl Editor {
self.source_board.grow(&deltas);
self.source_board.paste_board(pos, &new);
}
Action::SetTile(deltas, pos, _old, new) => {
self.shift_world(deltas.x_neg as f32, deltas.y_neg as f32);
self.source_board.grow(&deltas);
self.source_board.grid.set(pos, new);
}
}
}
@ -222,6 +228,11 @@ impl Editor {
self.source_board.shrink(deltas);
self.shift_world(-(deltas.x_neg as f32), -(deltas.y_neg as f32));
}
Action::SetTile(deltas, pos, old, _new) => {
self.source_board.grid.set(*pos, *old);
self.source_board.shrink(deltas);
self.shift_world(-(deltas.x_neg as f32), -(deltas.y_neg as f32));
}
}
}
@ -356,8 +367,8 @@ impl Editor {
pub fn center_view(&mut self, d: &RaylibHandle) {
let tile_size = TILE_TEXTURE_SIZE * self.zoom;
let tile_x = self.source_board.width() as f32 / 2. * tile_size;
let tile_y = self.source_board.height() as f32 / 2. * tile_size;
let tile_x = self.source_board.grid.width() as f32 / 2. * tile_size;
let tile_y = self.source_board.grid.height() as f32 / 2. * tile_size;
let screen_x = d.get_screen_width() as f32 / 2.;
let screen_y = d.get_screen_height() as f32 / 2.;
self.view_offset.x = (screen_x - tile_x).floor();
@ -408,34 +419,18 @@ impl Editor {
}
fn set_area(&mut self, pos: Pos, area: Board) {
let old_area = self.source_board.get_rect(pos, area.width(), area.height());
let old_area = self
.source_board
.get_rect(pos, area.grid.width(), area.grid.height());
if area == old_area {
return;
}
let width = self.source_board.width() as PosInt;
let height = self.source_board.height() as PosInt;
let resize = ResizeDeltas {
x_pos: if (pos.x + BOARD_MARGIN + area.width() as PosInt) > width {
pos.x + BOARD_MARGIN + area.width() as PosInt - width
} else {
0
} as usize,
x_neg: if pos.x < BOARD_MARGIN {
BOARD_MARGIN - pos.x
} else {
0
} as usize,
y_pos: if (pos.y + BOARD_MARGIN + area.height() as PosInt) > height {
pos.y + BOARD_MARGIN + area.height() as PosInt - height
} else {
0
} as usize,
y_neg: if pos.y < BOARD_MARGIN {
BOARD_MARGIN - pos.y
} else {
0
} as usize,
};
let resize = ResizeDeltas::new(
BOARD_MARGIN,
self.source_board.grid.size(),
pos,
area.grid.size(),
);
let mut pos = pos;
pos.x += resize.x_neg as PosInt;
pos.y += resize.y_neg as PosInt;
@ -443,7 +438,15 @@ impl Editor {
}
fn set_tile(&mut self, pos: Pos, tile: Tile) {
self.set_area(pos, Board::single_tile(tile));
let old_tile = self.source_board.grid.get_or_blank(pos);
if tile == old_tile {
return;
}
let resize = ResizeDeltas::new(BOARD_MARGIN, self.source_board.grid.size(), pos, (1, 1));
let mut pos = pos;
pos.x += resize.x_neg as PosInt;
pos.y += resize.y_neg as PosInt;
self.push_action(Action::SetTile(resize, pos, old_tile, tile));
}
pub fn update(&mut self, rl: &RaylibHandle) {

View file

@ -23,6 +23,35 @@ pub struct ResizeDeltas {
pub y_neg: usize,
}
impl ResizeDeltas {
pub fn new(
margin: usize,
(width, height): (usize, usize),
pos: Pos,
(new_width, new_height): (usize, usize),
) -> Self {
let margin = margin as PosInt;
let width = width as PosInt;
let height = height as PosInt;
let new_width = new_width as PosInt;
let new_height = new_height as PosInt;
Self {
x_pos: if (pos.x + margin + new_width) > width {
pos.x + margin + new_width - width
} else {
0
} as usize,
x_neg: if pos.x < margin { margin - pos.x } else { 0 } as usize,
y_pos: if (pos.y + margin + new_height) > height {
pos.y + margin + new_height - height
} else {
0
} as usize,
y_neg: if pos.y < margin { margin - pos.y } else { 0 } as usize,
}
}
}
impl Grid {
pub fn parse(source: &str) -> Self {
let mut rows = Vec::new();
@ -185,6 +214,10 @@ impl Grid {
self.height
}
pub fn size(&self) -> (usize, usize) {
(self.width, self.height)
}
pub fn get_marbles(&self) -> Vec<Pos> {
let mut out = Vec::new();
for y in 0..self.height {