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; let y = comment.y * tile_size + offset.y as i32;
for (i, line) in comment.text.lines().enumerate() { for (i, line) in comment.text.lines().enumerate() {
let y = y + line_space * i as i32; 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 let comments = self
.comments .comments
.iter() .iter()
.filter(|c| c.in_area(pos, width, height)) .filter(|c| c.in_area(pos, (width, height)))
.map(|c| { .map(|c| {
let mut c = c.clone(); let mut c = c.clone();
c.x -= pos.x as i32; c.x -= pos.x as i32;
@ -105,6 +105,16 @@ impl Board {
} }
pub fn paste_board(&mut self, pos: Pos, board: &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); self.grid.paste_grid(pos, &board.grid);
for c in &board.comments { for c in &board.comments {
let mut comment = c.clone(); let mut comment = c.clone();
@ -143,18 +153,10 @@ impl Board {
comments: Vec::new(), comments: Vec::new(),
}) })
} }
pub fn width(&self) -> usize {
self.grid.width()
}
pub fn height(&self) -> usize {
self.grid.height()
}
} }
impl Comment { 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.x >= pos.x as i32
&& self.y >= pos.y as i32 && self.y >= pos.y as i32
&& self.x < pos.x as i32 + width 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 MAX_ZOOM: f32 = 8.;
const MIN_ZOOM: f32 = 0.25; const MIN_ZOOM: f32 = 0.25;
const BOARD_MARGIN: PosInt = 3; const BOARD_MARGIN: usize = 3;
const MAX_SPEED_POWER: u8 = 16; const MAX_SPEED_POWER: u8 = 16;
const SPEED_DIGITS: i32 = 5; const SPEED_DIGITS: i32 = 5;
const MAX_FRAME_TIME_MICROS: u128 = 1_000_000 / 30; const MAX_FRAME_TIME_MICROS: u128 = 1_000_000 / 30;
@ -79,6 +79,7 @@ pub struct Editor {
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
enum Action { enum Action {
SetTile(ResizeDeltas, Pos, Tile, Tile),
SetArea(ResizeDeltas, Pos, Board, Board), SetArea(ResizeDeltas, Pos, Board, Board),
} }
@ -207,6 +208,11 @@ impl Editor {
self.source_board.grow(&deltas); self.source_board.grow(&deltas);
self.source_board.paste_board(pos, &new); 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.source_board.shrink(deltas);
self.shift_world(-(deltas.x_neg as f32), -(deltas.y_neg as f32)); 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) { pub fn center_view(&mut self, d: &RaylibHandle) {
let tile_size = TILE_TEXTURE_SIZE * self.zoom; let tile_size = TILE_TEXTURE_SIZE * self.zoom;
let tile_x = self.source_board.width() as f32 / 2. * tile_size; let tile_x = self.source_board.grid.width() as f32 / 2. * tile_size;
let tile_y = self.source_board.height() 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_x = d.get_screen_width() as f32 / 2.;
let screen_y = d.get_screen_height() as f32 / 2.; let screen_y = d.get_screen_height() as f32 / 2.;
self.view_offset.x = (screen_x - tile_x).floor(); self.view_offset.x = (screen_x - tile_x).floor();
@ -408,34 +419,18 @@ impl Editor {
} }
fn set_area(&mut self, pos: Pos, area: Board) { 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 { if area == old_area {
return; return;
} }
let width = self.source_board.width() as PosInt; let resize = ResizeDeltas::new(
let height = self.source_board.height() as PosInt; BOARD_MARGIN,
let resize = ResizeDeltas { self.source_board.grid.size(),
x_pos: if (pos.x + BOARD_MARGIN + area.width() as PosInt) > width { pos,
pos.x + BOARD_MARGIN + area.width() as PosInt - width area.grid.size(),
} 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 mut pos = pos; let mut pos = pos;
pos.x += resize.x_neg as PosInt; pos.x += resize.x_neg as PosInt;
pos.y += resize.y_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) { 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) { pub fn update(&mut self, rl: &RaylibHandle) {

View file

@ -23,6 +23,35 @@ pub struct ResizeDeltas {
pub y_neg: usize, 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 { impl Grid {
pub fn parse(source: &str) -> Self { pub fn parse(source: &str) -> Self {
let mut rows = Vec::new(); let mut rows = Vec::new();
@ -185,6 +214,10 @@ impl Grid {
self.height self.height
} }
pub fn size(&self) -> (usize, usize) {
(self.width, self.height)
}
pub fn get_marbles(&self) -> Vec<Pos> { pub fn get_marbles(&self) -> Vec<Pos> {
let mut out = Vec::new(); let mut out = Vec::new();
for y in 0..self.height { for y in 0..self.height {