selection tool (selections are not useful yet)
This commit is contained in:
parent
92d540c29b
commit
49917d18a9
6 changed files with 63 additions and 15 deletions
|
@ -5,7 +5,6 @@ logic mostly like https://git.crispypin.cc/CrispyPin/marble
|
||||||
|
|
||||||
## todo
|
## todo
|
||||||
cleanup: unpowered texture names x_off -> x
|
cleanup: unpowered texture names x_off -> x
|
||||||
sim/speed control gui
|
|
||||||
(option) display input as numbers
|
(option) display input as numbers
|
||||||
scroll output
|
scroll output
|
||||||
default i/o text modes specified per level
|
default i/o text modes specified per level
|
||||||
|
|
BIN
assets/area_corner.png
Normal file
BIN
assets/area_corner.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 109 B |
BIN
assets/area_full.png
Normal file
BIN
assets/area_full.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 122 B |
|
@ -61,7 +61,7 @@ enum Tool {
|
||||||
Wire,
|
Wire,
|
||||||
Arrow,
|
Arrow,
|
||||||
Mirror,
|
Mirror,
|
||||||
// SelectArea,
|
SelectArea(Option<(Pos, Pos)>, bool),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq)]
|
#[derive(Debug, Clone, PartialEq)]
|
||||||
|
@ -123,6 +123,10 @@ impl Editor {
|
||||||
self.score.clone()
|
self.score.clone()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn pos_to_screen(&self, pos: Vector2) -> Vector2 {
|
||||||
|
pos * (16 << self.zoom) as f32 + self.view_offset
|
||||||
|
}
|
||||||
|
|
||||||
fn start_sim(&mut self) {
|
fn start_sim(&mut self) {
|
||||||
self.machine.reset();
|
self.machine.reset();
|
||||||
self.machine.set_board(self.source_board.clone());
|
self.machine.set_board(self.source_board.clone());
|
||||||
|
@ -196,9 +200,7 @@ impl Editor {
|
||||||
WireType::Cross => WireType::Vertical,
|
WireType::Cross => WireType::Vertical,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Tool::None => (),
|
Tool::None | Tool::SetTile(_) | Tool::Digits(_) | Tool::SelectArea(_, _) => (),
|
||||||
Tool::SetTile(_) => (),
|
|
||||||
Tool::Digits(_) => (),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -469,6 +471,7 @@ impl Editor {
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
tool_button((0, -2), "eraser", Tool::SetTile(Tile::from_char(' ')));
|
tool_button((0, -2), "eraser", Tool::SetTile(Tile::from_char(' ')));
|
||||||
|
tool_button((1, -2), "selection", Tool::SelectArea(None, false));
|
||||||
tool_button((0, -1), "digit_tool", Tool::Digits(None));
|
tool_button((0, -1), "digit_tool", Tool::Digits(None));
|
||||||
tool_button((1, -1), "transparent", Tool::None);
|
tool_button((1, -1), "transparent", Tool::None);
|
||||||
|
|
||||||
|
@ -569,14 +572,16 @@ impl Editor {
|
||||||
fn board_overlay(&mut self, d: &mut RaylibDrawHandle, textures: &Textures) {
|
fn board_overlay(&mut self, d: &mut RaylibDrawHandle, textures: &Textures) {
|
||||||
let footer_top = (d.get_screen_height() - FOOTER_HEIGHT) as f32;
|
let footer_top = (d.get_screen_height() - FOOTER_HEIGHT) as f32;
|
||||||
let mouse_pos = d.get_mouse_position();
|
let mouse_pos = d.get_mouse_position();
|
||||||
|
let tile_scale = (1 << self.zoom) as f32;
|
||||||
|
let tile_size = 16 << self.zoom;
|
||||||
if self.sim_state == SimState::Editing {
|
if self.sim_state == SimState::Editing {
|
||||||
if let Tool::Digits(Some(pos)) = &mut self.active_tool {
|
if let Tool::Digits(Some(pos)) = &mut self.active_tool {
|
||||||
let tile_screen_pos = pos.to_vec() * (16 << self.zoom) as f32 + self.view_offset;
|
let tile_screen_pos = pos.to_vec() * tile_size as f32 + self.view_offset;
|
||||||
d.draw_texture_ex(
|
d.draw_texture_ex(
|
||||||
textures.get("selection"),
|
textures.get("selection"),
|
||||||
tile_screen_pos,
|
tile_screen_pos,
|
||||||
0.,
|
0.,
|
||||||
(1 << self.zoom) as f32,
|
tile_scale,
|
||||||
Color::new(255, 180, 20, 255),
|
Color::new(255, 180, 20, 255),
|
||||||
);
|
);
|
||||||
if d.is_key_pressed(KeyboardKey::KEY_LEFT) {
|
if d.is_key_pressed(KeyboardKey::KEY_LEFT) {
|
||||||
|
@ -599,10 +604,10 @@ impl Editor {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if mouse_pos.y < footer_top && mouse_pos.y > HEADER_HEIGHT as f32 {
|
if mouse_pos.y < footer_top && mouse_pos.y > HEADER_HEIGHT as f32 {
|
||||||
let tile_pos = (mouse_pos - self.view_offset) / (16 << self.zoom) as f32;
|
let tile_pos = (mouse_pos - self.view_offset) / tile_size as f32;
|
||||||
let tile_pos = Vector2::new(tile_pos.x.floor(), tile_pos.y.floor());
|
let tile_pos = Vector2::new(tile_pos.x.floor(), tile_pos.y.floor());
|
||||||
|
|
||||||
let tile_screen_pos = tile_pos * (16 << self.zoom) as f32 + self.view_offset;
|
let tile_screen_pos = self.pos_to_screen(tile_pos);
|
||||||
|
|
||||||
if self.active_tool != Tool::None {
|
if self.active_tool != Tool::None {
|
||||||
let tex = match self.active_tool {
|
let tex = match self.active_tool {
|
||||||
|
@ -620,17 +625,18 @@ impl Editor {
|
||||||
Tool::Arrow => self.tool_menu_arrow.arrow_texture_name().into(),
|
Tool::Arrow => self.tool_menu_arrow.arrow_texture_name().into(),
|
||||||
Tool::Mirror => self.tool_menu_mirror.texture_name().into(),
|
Tool::Mirror => self.tool_menu_mirror.texture_name().into(),
|
||||||
Tool::Digits(_) => "selection".into(),
|
Tool::Digits(_) => "selection".into(),
|
||||||
|
Tool::SelectArea(_, _) => "area_full".into(),
|
||||||
};
|
};
|
||||||
|
|
||||||
d.draw_texture_ex(
|
d.draw_texture_ex(
|
||||||
textures.get(&tex),
|
textures.get(&tex),
|
||||||
tile_screen_pos,
|
tile_screen_pos,
|
||||||
0.,
|
0.,
|
||||||
(1 << self.zoom) as f32,
|
tile_scale,
|
||||||
Color::new(255, 255, 255, 100),
|
Color::new(255, 255, 255, 100),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
if d.is_mouse_button_down(MouseButton::MOUSE_BUTTON_LEFT) {
|
if d.is_mouse_button_pressed(MouseButton::MOUSE_BUTTON_LEFT) {
|
||||||
match self.active_tool {
|
match self.active_tool {
|
||||||
Tool::None => (),
|
Tool::None => (),
|
||||||
Tool::SetTile(tile) => self.set_tile(tile_pos.into(), tile),
|
Tool::SetTile(tile) => self.set_tile(tile_pos.into(), tile),
|
||||||
|
@ -661,8 +667,40 @@ impl Editor {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Tool::SelectArea(_, _) => (),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if let Tool::SelectArea(selection, is_selecting) = &mut self.active_tool {
|
||||||
|
if d.is_mouse_button_down(MouseButton::MOUSE_BUTTON_LEFT) {
|
||||||
|
if *is_selecting {
|
||||||
|
if let Some((_start, end)) = selection {
|
||||||
|
*end = tile_pos.into();
|
||||||
|
} else {
|
||||||
|
*selection = Some((tile_pos.into(), tile_pos.into()));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
*selection = Some((tile_pos.into(), tile_pos.into()));
|
||||||
|
*is_selecting = true;
|
||||||
|
}
|
||||||
|
} else if d.is_mouse_button_released(MouseButton::MOUSE_BUTTON_LEFT) {
|
||||||
|
*is_selecting = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// draw selection
|
||||||
|
if let Tool::SelectArea(Some((start, end)), _) = self.active_tool {
|
||||||
|
let min = start.min(end);
|
||||||
|
let max = start.max(end);
|
||||||
|
let p_min = self.pos_to_screen(min.to_vec());
|
||||||
|
let p_max = self.pos_to_screen(max.to_vec());
|
||||||
|
let tex = textures.get("area_corner");
|
||||||
|
d.draw_texture_ex(tex, p_min, 0., tile_scale, Color::WHITE);
|
||||||
|
let one_xy = Vector2::new(tile_size as f32, tile_size as f32);
|
||||||
|
d.draw_texture_ex(tex, p_max + one_xy, 180., tile_scale, Color::WHITE);
|
||||||
|
let top_right = Vector2::new(p_max.x + tile_size as f32, p_min.y);
|
||||||
|
d.draw_texture_ex(tex, top_right, 90., tile_scale, Color::WHITE);
|
||||||
|
let bot_left = Vector2::new(p_min.x, p_max.y + tile_size as f32);
|
||||||
|
d.draw_texture_ex(tex, bot_left, -90., tile_scale, Color::WHITE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -673,6 +711,7 @@ impl PartialEq for Tool {
|
||||||
match (self, other) {
|
match (self, other) {
|
||||||
(Self::SetTile(l0), Self::SetTile(r0)) => l0 == r0,
|
(Self::SetTile(l0), Self::SetTile(r0)) => l0 == r0,
|
||||||
(Self::Digits(_), Self::Digits(_)) => true,
|
(Self::Digits(_), Self::Digits(_)) => true,
|
||||||
|
(Self::SelectArea(_, _), Self::SelectArea(_, _)) => true,
|
||||||
_ => ::core::mem::discriminant(self) == ::core::mem::discriminant(other),
|
_ => ::core::mem::discriminant(self) == ::core::mem::discriminant(other),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,6 +16,20 @@ impl Pos {
|
||||||
y: self.y as f32,
|
y: self.y as f32,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn min(self, other: Self) -> Self {
|
||||||
|
Self {
|
||||||
|
x: self.x.min(other.x),
|
||||||
|
y: self.y.min(other.y),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn max(self, other: Self) -> Self {
|
||||||
|
Self {
|
||||||
|
x: self.x.max(other.x),
|
||||||
|
y: self.y.max(other.y),
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<(usize, usize)> for Pos {
|
impl From<(usize, usize)> for Pos {
|
||||||
|
|
|
@ -45,10 +45,6 @@ impl Solution {
|
||||||
file.write_all(json.as_bytes()).unwrap();
|
file.write_all(json.as_bytes()).unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn level_id(&self) -> &str {
|
|
||||||
&self.level_id
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn score_text(&self) -> String {
|
pub fn score_text(&self) -> String {
|
||||||
if let Some(score) = &self.score {
|
if let Some(score) = &self.score {
|
||||||
format!(
|
format!(
|
||||||
|
|
Loading…
Reference in a new issue