add info box and disable some ui while a popup is active

This commit is contained in:
Crispy 2024-12-23 00:44:47 +01:00
parent b9f76bb486
commit 6fc41bdb17
4 changed files with 280 additions and 151 deletions

View file

@ -21,8 +21,8 @@ use crate::{
const HEADER_HEIGHT: i32 = 40; const HEADER_HEIGHT: i32 = 40;
const FOOTER_HEIGHT: i32 = 95; const FOOTER_HEIGHT: i32 = 95;
const SIDEBAR_WIDTH: i32 = 200 + 32 * 2 + 5 * 4; const SIDEBAR_WIDTH: i32 = 200 + 32 * 2 + 5 * 4;
const POPUP_WIDTH: i32 = 320; const END_POPUP_WIDTH: i32 = 320;
const POPUP_HEIGHT: i32 = 165; 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;
@ -56,9 +56,11 @@ pub struct Editor {
exit_state: ExitState, exit_state: ExitState,
exit_menu: bool, exit_menu: bool,
total_steps: usize, total_steps: usize,
popup: EndPopup, popup: Popup,
score: Option<Score>, score: Option<Score>,
tooltip: Tooltip, tooltip: Tooltip,
mouse: MouseInput,
info_text: ShapedText,
blueprints: Vec<Blueprint>, blueprints: Vec<Blueprint>,
selected_blueprint: usize, selected_blueprint: usize,
@ -80,10 +82,12 @@ enum Action {
} }
#[derive(Debug, PartialEq)] #[derive(Debug, PartialEq)]
enum EndPopup { enum Popup {
None, None,
Success, Success,
Failure, Failure,
LevelInfo,
PauseMenu,
Dismissed, Dismissed,
} }
@ -134,6 +138,8 @@ impl Editor {
input_as_text = i.input().is_text(); input_as_text = i.input().is_text();
machine.set_input(i.input().as_bytes().to_owned()); machine.set_input(i.input().as_bytes().to_owned());
} }
let mut info_text = ShapedText::new(20);
info_text.set_text(level.description());
Self { Self {
source_board: Board::parse(&solution.board), source_board: Board::parse(&solution.board),
@ -158,7 +164,8 @@ impl Editor {
level, level,
exit_state: ExitState::Dont, exit_state: ExitState::Dont,
exit_menu: false, exit_menu: false,
popup: EndPopup::None, popup: Popup::None,
info_text,
score: solution.score, score: solution.score,
total_steps: 0, total_steps: 0,
blueprints: get_blueprints(), blueprints: get_blueprints(),
@ -172,6 +179,7 @@ impl Editor {
undo_history: Vec::new(), undo_history: Vec::new(),
undo_index: 0, undo_index: 0,
tooltip: Tooltip::default(), tooltip: Tooltip::default(),
mouse: MouseInput::default(),
} }
} }
@ -292,18 +300,18 @@ impl Editor {
self.machine.step(); self.machine.step();
if let Some(i) = self.stage { if let Some(i) = self.stage {
if self.popup != EndPopup::None { if self.popup != Popup::None {
self.popup = EndPopup::Dismissed; self.popup = Popup::Dismissed;
} }
let stage = &self.level.stages()[i]; let stage = &self.level.stages()[i];
if self.popup == EndPopup::None { if self.popup == Popup::None {
if stage.output().as_bytes() == self.machine.output() { if stage.output().as_bytes() == self.machine.output() {
if i + 1 < self.level.stages().len() { if i + 1 < self.level.stages().len() {
self.stage = Some(i + 1); self.stage = Some(i + 1);
self.total_steps += self.machine.step_count(); self.total_steps += self.machine.step_count();
self.reset_machine(); self.reset_machine();
} else { } else {
self.popup = EndPopup::Success; self.popup = Popup::Success;
println!("completed in {:?}", self.start_time.elapsed()); println!("completed in {:?}", self.start_time.elapsed());
self.exit_state = ExitState::Save; self.exit_state = ExitState::Save;
self.sim_state = SimState::Stepping; self.sim_state = SimState::Stepping;
@ -313,7 +321,7 @@ impl Editor {
}); });
} }
} else if !stage.output().as_bytes().starts_with(self.machine.output()) { } else if !stage.output().as_bytes().starts_with(self.machine.output()) {
self.popup = EndPopup::Failure; self.popup = Popup::Failure;
self.sim_state = SimState::Stepping; self.sim_state = SimState::Stepping;
} }
} }
@ -437,7 +445,7 @@ impl Editor {
pub fn update(&mut self, rl: &RaylibHandle) { pub fn update(&mut self, rl: &RaylibHandle) {
if rl.is_key_pressed(KeyboardKey::KEY_ESCAPE) { if rl.is_key_pressed(KeyboardKey::KEY_ESCAPE) {
self.sim_state = SimState::Editing; self.sim_state = SimState::Editing;
self.popup = EndPopup::None; self.popup = Popup::None;
} }
if self.sim_state == SimState::Running { if self.sim_state == SimState::Running {
self.time_since_step += rl.get_frame_time(); self.time_since_step += rl.get_frame_time();
@ -478,7 +486,7 @@ impl Editor {
} }
SimState::Running => { SimState::Running => {
self.sim_state = SimState::Editing; self.sim_state = SimState::Editing;
self.popup = EndPopup::None; self.popup = Popup::None;
} }
SimState::Stepping => self.sim_state = SimState::Running, SimState::Stepping => self.sim_state = SimState::Running,
} }
@ -563,6 +571,10 @@ impl Editor {
} }
self.tooltip.init_frame(d); self.tooltip.init_frame(d);
self.mouse = MouseInput::get(d);
if !matches!(self.popup, Popup::None | Popup::Dismissed) {
self.mouse.clear();
}
self.draw_board(d, textures); self.draw_board(d, textures);
self.board_overlay(d, textures); self.board_overlay(d, textures);
@ -570,6 +582,31 @@ impl Editor {
self.draw_top_bar(d, textures); self.draw_top_bar(d, textures);
if self.active_tool == Tool::Blueprint { if self.active_tool == Tool::Blueprint {
self.draw_blueprint_sidebar(d, textures);
}
self.mouse = MouseInput::get(d);
match self.popup {
Popup::Success | Popup::Failure => {
self.tooltip.reset();
self.draw_end_popup(d, textures);
}
Popup::LevelInfo => {
self.tooltip.reset();
let bounds = screen_centered_rect_dyn(d, 100, 100);
d.draw_rectangle_rec(bounds, BG_MEDIUM);
d.draw_text(self.level.name(), 110, 110, 30, Color::LIGHTBLUE);
self.info_text.update_width(d, bounds.width as i32 - 20);
self.info_text.draw(d, 110, 140);
}
_ => (),
}
self.tooltip.draw(d);
}
fn draw_blueprint_sidebar(&mut self, d: &mut RaylibDrawHandle, textures: &Textures) {
let sidebar_height = d.get_screen_height() - FOOTER_HEIGHT - HEADER_HEIGHT - 40; let sidebar_height = d.get_screen_height() - FOOTER_HEIGHT - HEADER_HEIGHT - 40;
d.draw_rectangle( d.draw_rectangle(
0, 0,
@ -591,7 +628,7 @@ impl Editor {
{ {
let i = i + self.blueprint_scroll; let i = i + self.blueprint_scroll;
self.tooltip.add(5, y, 32, 32, "Delete"); self.tooltip.add(5, y, 32, 32, "Delete");
if simple_button(d, 5, y, 32, 32) { if simple_button(d, &self.mouse, 5, y, 32, 32) {
b.remove_file(); b.remove_file();
self.blueprints.remove(i); self.blueprints.remove(i);
break; break;
@ -624,13 +661,11 @@ impl Editor {
} }
} }
self.tooltip.draw(d); fn draw_end_popup(&mut self, d: &mut RaylibDrawHandle, textures: &Textures) {
let x = d.get_screen_width() / 2 - END_POPUP_WIDTH / 2;
if matches!(self.popup, EndPopup::Success | EndPopup::Failure) { let y = d.get_screen_height() / 2 - END_POPUP_HEIGHT / 2;
let x = d.get_screen_width() / 2 - POPUP_WIDTH / 2; d.draw_rectangle(x, y, END_POPUP_WIDTH, END_POPUP_HEIGHT, BG_DARK);
let y = d.get_screen_height() / 2 - POPUP_HEIGHT / 2; if self.popup == Popup::Success {
d.draw_rectangle(x, y, POPUP_WIDTH, POPUP_HEIGHT, BG_DARK);
if self.popup == EndPopup::Success {
d.draw_text("Level Complete!", x + 45, y + 10, 30, Color::LIME); d.draw_text("Level Complete!", x + 45, y + 10, 30, Color::LIME);
if let Some(score) = &self.score { if let Some(score) = &self.score {
d.draw_text("cycles", x + 15, y + 45, 20, Color::WHITE); d.draw_text("cycles", x + 15, y + 45, 20, Color::WHITE);
@ -638,17 +673,24 @@ impl Editor {
d.draw_text("tiles", x + 215, y + 45, 20, Color::WHITE); d.draw_text("tiles", x + 215, y + 45, 20, Color::WHITE);
draw_usize(d, textures, score.tiles, x + 210, y + 70, 5, 2); draw_usize(d, textures, score.tiles, x + 210, y + 70, 5, 2);
} }
if simple_button(d, x + 10, y + 110, 140, 45) { if simple_button(d, &self.mouse, x + 10, y + 110, 140, 45) {
self.popup = EndPopup::Dismissed; self.popup = Popup::Dismissed;
} }
d.draw_text("continue\nediting", x + 15, y + 115, 20, Color::WHITE); d.draw_text("continue\nediting", x + 15, y + 115, 20, Color::WHITE);
if simple_button(d, x + POPUP_WIDTH / 2 + 5, y + 110, 140, 45) { if simple_button(
d,
&self.mouse,
x + END_POPUP_WIDTH / 2 + 5,
y + 110,
140,
45,
) {
self.exit_state = ExitState::ExitAndSave; self.exit_state = ExitState::ExitAndSave;
} }
d.draw_text( d.draw_text(
"return to\nlevel list", "return to\nlevel list",
x + POPUP_WIDTH / 2 + 10, x + END_POPUP_WIDTH / 2 + 10,
y + 115, y + 115,
20, 20,
Color::WHITE, Color::WHITE,
@ -656,13 +698,12 @@ impl Editor {
} else { } else {
d.draw_text("Level Failed!", x + 45, y + 10, 30, Color::RED); d.draw_text("Level Failed!", x + 45, y + 10, 30, Color::RED);
d.draw_text("incorrect output", x + 45, y + 45, 20, Color::WHITE); d.draw_text("incorrect output", x + 45, y + 45, 20, Color::WHITE);
if simple_button(d, x + 10, y + 110, 300, 25) { if simple_button(d, &self.mouse, x + 10, y + 110, 300, 25) {
self.popup = EndPopup::Dismissed; self.popup = Popup::Dismissed;
} }
d.draw_text("ok :(", x + 15, y + 115, 20, Color::WHITE); d.draw_text("ok :(", x + 15, y + 115, 20, Color::WHITE);
} }
} }
}
fn draw_top_bar(&mut self, d: &mut RaylibDrawHandle, textures: &Textures) { fn draw_top_bar(&mut self, d: &mut RaylibDrawHandle, textures: &Textures) {
// background // background
@ -675,32 +716,37 @@ impl Editor {
); );
if self.exit_menu { if self.exit_menu {
if simple_button(d, 4, 4, 32, 32) { if simple_button(d, &self.mouse, 4, 4, 32, 32) {
self.exit_state = ExitState::ExitAndSave; self.exit_state = ExitState::ExitAndSave;
} }
self.tooltip.add(4, 4, 32, 32, "exit"); self.tooltip.add(4, 4, 32, 32, "exit");
draw_scaled_texture(d, textures.get("exit"), 4, 4, 2.); draw_scaled_texture(d, textures.get("exit"), 4, 4, 2.);
if simple_button(d, 38, 4, 32, 32) { if simple_button(d, &self.mouse, 40, 4, 32, 32) {
self.exit_menu = false; self.exit_menu = false;
} }
draw_scaled_texture(d, textures.get("cancel"), 38, 4, 2.); draw_scaled_texture(d, textures.get("cancel"), 40, 4, 2.);
self.tooltip.add(38, 4, 32, 32, "cancel"); self.tooltip.add(40, 4, 32, 32, "cancel");
} else { } else {
if simple_button(d, 4, 4, 32, 32) { if simple_button(d, &self.mouse, 4, 4, 32, 32) {
self.exit_menu = true; self.exit_menu = true;
} }
self.tooltip.add(4, 4, 32, 32, "exit"); self.tooltip.add(4, 4, 32, 32, "exit");
draw_scaled_texture(d, textures.get("exit"), 4, 4, 2.); draw_scaled_texture(d, textures.get("exit"), 4, 4, 2.);
if simple_button(d, 38, 4, 32, 32) { if simple_button(d, &self.mouse, 40, 4, 32, 32) {
self.exit_state = ExitState::Save; self.exit_state = ExitState::Save;
} }
draw_scaled_texture(d, textures.get("save"), 38, 4, 2.); draw_scaled_texture(d, textures.get("save"), 40, 4, 2.);
self.tooltip.add(38, 4, 32, 32, "save"); self.tooltip.add(40, 4, 32, 32, "save");
} }
if simple_button(d, &self.mouse, 76, 5, 60, 30) {
self.popup = Popup::LevelInfo;
}
d.draw_text("info", 80, 10, 20, Color::WHITE);
if self.sim_state == SimState::Editing { if self.sim_state == SimState::Editing {
self.tooltip.add(150, 4, 32, 32, "Undo"); self.tooltip.add(150, 4, 32, 32, "Undo");
if simple_button(d, 150, 4, 32, 32) { if simple_button(d, &self.mouse, 150, 4, 32, 32) {
self.undo() self.undo()
} }
let undo_icon = if self.undo_index > 0 { let undo_icon = if self.undo_index > 0 {
@ -711,7 +757,7 @@ impl Editor {
draw_scaled_texture(d, textures.get(undo_icon), 150, 4, 2.); draw_scaled_texture(d, textures.get(undo_icon), 150, 4, 2.);
self.tooltip.add(186, 4, 32, 32, "Redo"); self.tooltip.add(186, 4, 32, 32, "Redo");
if simple_button(d, 186, 4, 32, 32) { if simple_button(d, &self.mouse, 186, 4, 32, 32) {
self.redo() self.redo()
} }
let redo_icon = if self.undo_index < self.undo_history.len() { let redo_icon = if self.undo_index < self.undo_history.len() {
@ -723,7 +769,7 @@ impl Editor {
} }
self.tooltip.add(223, 4, 32, 32, "Toggle overlay"); self.tooltip.add(223, 4, 32, 32, "Toggle overlay");
if simple_button(d, 223, 4, 32, 32) { if simple_button(d, &self.mouse, 223, 4, 32, 32) {
self.draw_overlay = !self.draw_overlay; self.draw_overlay = !self.draw_overlay;
} }
let overlay_btn_icon = if self.draw_overlay { let overlay_btn_icon = if self.draw_overlay {
@ -735,13 +781,13 @@ impl Editor {
if self.sim_state == SimState::Running { if self.sim_state == SimState::Running {
self.tooltip.add(260, 4, 32, 32, "Pause"); self.tooltip.add(260, 4, 32, 32, "Pause");
if simple_button(d, 260, 4, 32, 32) { if simple_button(d, &self.mouse, 260, 4, 32, 32) {
self.sim_state = SimState::Stepping; self.sim_state = SimState::Stepping;
} }
draw_scaled_texture(d, textures.get("pause"), 260, 4, 2.); draw_scaled_texture(d, textures.get("pause"), 260, 4, 2.);
} else { } else {
self.tooltip.add(260, 4, 32, 32, "Start"); self.tooltip.add(260, 4, 32, 32, "Start");
if simple_button(d, 260, 4, 32, 32) { if simple_button(d, &self.mouse, 260, 4, 32, 32) {
if self.sim_state == SimState::Editing { if self.sim_state == SimState::Editing {
self.init_sim() self.init_sim()
} }
@ -752,15 +798,15 @@ impl Editor {
if self.sim_state != SimState::Editing { if self.sim_state != SimState::Editing {
self.tooltip.add(296, 4, 32, 32, "Stop"); self.tooltip.add(296, 4, 32, 32, "Stop");
if simple_button(d, 296, 4, 32, 32) { if simple_button(d, &self.mouse, 296, 4, 32, 32) {
self.sim_state = SimState::Editing; self.sim_state = SimState::Editing;
self.popup = EndPopup::None; self.popup = Popup::None;
} }
draw_scaled_texture(d, textures.get("stop"), 296, 4, 2.); draw_scaled_texture(d, textures.get("stop"), 296, 4, 2.);
} }
self.tooltip.add(332, 4, 32, 32, "Step"); self.tooltip.add(332, 4, 32, 32, "Step");
if simple_button(d, 332, 4, 32, 32) { if simple_button(d, &self.mouse, 332, 4, 32, 32) {
self.step_pressed(); self.step_pressed();
} }
draw_scaled_texture(d, textures.get("step"), 332, 4, 2.); draw_scaled_texture(d, textures.get("step"), 332, 4, 2.);
@ -781,7 +827,7 @@ impl Editor {
draw_usize(d, textures, self.max_step_time as usize, 260, 60, 9, 1); draw_usize(d, textures, self.max_step_time as usize, 260, 60, 9, 1);
d.draw_text("input:", 603, 8, 10, Color::WHITE); d.draw_text("input:", 603, 8, 10, Color::WHITE);
if simple_button(d, 600, 20, 35, 15) { if simple_button(d, &self.mouse, 600, 20, 35, 15) {
self.input_as_text = !self.input_as_text self.input_as_text = !self.input_as_text
} }
let input_mode_text = if self.input_as_text { "text" } else { "bytes" }; let input_mode_text = if self.input_as_text { "text" } else { "bytes" };
@ -862,19 +908,21 @@ impl Editor {
let y = footer_top as i32 + 49; let y = footer_top as i32 + 49;
self.tooltip.add(100, y, 40, 40, "Cancel"); self.tooltip.add(100, y, 40, 40, "Cancel");
if simple_button(d, 100, y, 40, 40) || d.is_key_pressed(KeyboardKey::KEY_ESCAPE) { if simple_button(d, &self.mouse, 100, y, 40, 40)
|| d.is_key_pressed(KeyboardKey::KEY_ESCAPE)
{
self.active_tool = Tool::SelectArea(Selection::default()); self.active_tool = Tool::SelectArea(Selection::default());
} }
draw_scaled_texture(d, textures.get("cancel"), 104, y + 4, 2.); draw_scaled_texture(d, textures.get("cancel"), 104, y + 4, 2.);
self.tooltip.add(144, y, 40, 40, "Save blueprint"); self.tooltip.add(144, y, 40, 40, "Save blueprint");
if simple_button(d, 144, y, 40, 40) { if simple_button(d, &self.mouse, 144, y, 40, 40) {
self.save_blueprint(selection); self.save_blueprint(selection);
} }
draw_scaled_texture(d, textures.get("save"), 148, y + 4, 2.); draw_scaled_texture(d, textures.get("save"), 148, y + 4, 2.);
self.tooltip.add(188, y, 40, 40, "Copy"); self.tooltip.add(188, y, 40, 40, "Copy");
if simple_button(d, 188, y, 40, 40) if simple_button(d, &self.mouse, 188, y, 40, 40)
|| (d.is_key_pressed(KeyboardKey::KEY_C) || (d.is_key_pressed(KeyboardKey::KEY_C)
&& d.is_key_down(KeyboardKey::KEY_LEFT_CONTROL)) && d.is_key_down(KeyboardKey::KEY_LEFT_CONTROL))
{ {
@ -884,7 +932,7 @@ impl Editor {
draw_scaled_texture(d, textures.get("copy"), 192, y + 4, 2.); draw_scaled_texture(d, textures.get("copy"), 192, y + 4, 2.);
self.tooltip.add(232, y, 40, 40, "Delete"); self.tooltip.add(232, y, 40, 40, "Delete");
if simple_button(d, 232, y, 40, 40) { if simple_button(d, &self.mouse, 232, y, 40, 40) {
let min = selection.0.min(selection.1); let min = selection.0.min(selection.1);
let max = selection.0.max(selection.1); let max = selection.0.max(selection.1);
let board = let board =
@ -1042,7 +1090,7 @@ impl Editor {
let output_cell_width = 43; let output_cell_width = 43;
let output_cells = (d.get_screen_width() - output_x) as usize / output_cell_width as usize; let output_cells = (d.get_screen_width() - output_x) as usize / output_cell_width as usize;
if simple_button(d, output_x, y + 70, 65, 15) { if simple_button(d, &self.mouse, output_x, y + 70, 65, 15) {
self.output_as_text = !self.output_as_text self.output_as_text = !self.output_as_text
} }
let output_mode_text = if self.output_as_text { let output_mode_text = if self.output_as_text {

View file

@ -123,19 +123,16 @@ impl Game {
let level_list_width = (d.get_screen_width() / 3).min(400); let level_list_width = (d.get_screen_width() / 3).min(400);
let screen_height = d.get_screen_height(); let screen_height = d.get_screen_height();
d.draw_rectangle(0, 0, level_list_width, screen_height, BG_MEDIUM); d.draw_rectangle(0, 0, level_list_width, screen_height, BG_MEDIUM);
let mouse = MouseInput::get(d);
let clicked = d.is_mouse_button_pressed(MouseButton::MOUSE_BUTTON_LEFT);
let mouse_pos = d.get_mouse_position();
let scroll_delta = d.get_mouse_wheel_move();
const ENTRY_SPACING: i32 = 65; const ENTRY_SPACING: i32 = 65;
let fit_on_screen = (d.get_screen_height() / ENTRY_SPACING) as usize; let fit_on_screen = (d.get_screen_height() / ENTRY_SPACING) as usize;
let max_scroll = self.levels.len().saturating_sub(fit_on_screen); let max_scroll = self.levels.len().saturating_sub(fit_on_screen);
if mouse_pos.x < level_list_width as f32 { if mouse.pos().x < level_list_width as f32 {
if scroll_delta < 0. && self.level_scroll < max_scroll { if mouse.scroll() == Some(Scroll::Down) && self.level_scroll < max_scroll {
self.level_scroll += 1; self.level_scroll += 1;
} }
if scroll_delta > 0. && self.level_scroll > 0 { if mouse.scroll() == Some(Scroll::Up) && self.level_scroll > 0 {
self.level_scroll -= 1; self.level_scroll -= 1;
} }
} }
@ -149,7 +146,7 @@ impl Game {
width: level_list_width as f32 - 10., width: level_list_width as f32 - 10.,
height: ENTRY_SPACING as f32 - 5., height: ENTRY_SPACING as f32 - 5.,
}; };
let clicked_this = clicked && bounds.check_collision_point_rec(mouse_pos); let clicked_this = mouse.left_click() && mouse.is_over(bounds);
match level { match level {
LevelListEntry::Chapter(title, level_count) => { LevelListEntry::Chapter(title, level_count) => {
d.draw_rectangle_rec(bounds, BG_DARK); d.draw_rectangle_rec(bounds, BG_DARK);
@ -242,7 +239,14 @@ impl Game {
} }
let next_id = get_free_id(solutions, Solution::id); let next_id = get_free_id(solutions, Solution::id);
if simple_button(d, level_list_width + 10, solution_y, entry_width, 30) { if simple_button(
d,
&mouse,
level_list_width + 10,
solution_y,
entry_width,
30,
) {
self.selected_solution = solutions.len(); self.selected_solution = solutions.len();
solutions.push(Solution::new(level, next_id)); solutions.push(Solution::new(level, next_id));
} }
@ -270,7 +274,7 @@ impl Game {
let id_text = format!("{}", solution.id()); let id_text = format!("{}", solution.id());
d.draw_text(&id_text, column_x, y + 35, 10, Color::GRAY); d.draw_text(&id_text, column_x, y + 35, 10, Color::GRAY);
if simple_button(d, column_x, y + 50, 220, 30) { if simple_button(d, &mouse, column_x, y + 50, 220, 30) {
let cloned = solution.new_copy(next_id); let cloned = solution.new_copy(next_id);
self.selected_solution = solutions.len(); self.selected_solution = solutions.len();
solutions.push(cloned); solutions.push(cloned);
@ -278,7 +282,7 @@ impl Game {
} }
d.draw_text("clone", column_x + 5, y + 55, 20, Color::WHITE); d.draw_text("clone", column_x + 5, y + 55, 20, Color::WHITE);
if simple_button(d, column_x, y + 85, 220, 30) { if simple_button(d, &mouse, column_x, y + 85, 220, 30) {
let mut editor = Editor::new(solution.clone(), level.clone()); let mut editor = Editor::new(solution.clone(), level.clone());
editor.center_view(d); editor.center_view(d);
self.open_editor = Some(editor); self.open_editor = Some(editor);

View file

@ -1,6 +1,6 @@
use std::ops::Range; use std::ops::Range;
use crate::{draw_scaled_texture, theme::*, Textures}; use crate::{draw_scaled_texture, theme::*, MouseInput, Textures};
use raylib::prelude::*; use raylib::prelude::*;
#[derive(Debug)] #[derive(Debug)]
@ -120,6 +120,10 @@ impl Tooltip {
} }
} }
pub fn reset(&mut self){
self.text = None;
}
pub fn add_rec(&mut self, bounds: Rectangle, text: &'static str) { pub fn add_rec(&mut self, bounds: Rectangle, text: &'static str) {
self.add( self.add(
bounds.x as i32, bounds.x as i32,
@ -153,8 +157,15 @@ impl Tooltip {
} }
} }
pub fn simple_button(d: &mut RaylibDrawHandle, x: i32, y: i32, width: i32, height: i32) -> bool { pub fn simple_button(
let mouse_pos = d.get_mouse_position(); d: &mut RaylibDrawHandle,
mouse: &MouseInput,
x: i32,
y: i32,
width: i32,
height: i32,
) -> bool {
let mouse_pos = mouse.pos();
let bounds = Rectangle { let bounds = Rectangle {
x: x as f32, x: x as f32,
y: y as f32, y: y as f32,
@ -162,7 +173,7 @@ pub fn simple_button(d: &mut RaylibDrawHandle, x: i32, y: i32, width: i32, heigh
height: height as f32, height: height as f32,
}; };
let hover = bounds.check_collision_point_rec(mouse_pos); let hover = bounds.check_collision_point_rec(mouse_pos);
let pressed = hover && d.is_mouse_button_pressed(MouseButton::MOUSE_BUTTON_LEFT); let pressed = hover && mouse.left_click();
d.draw_rectangle(x, y, width, height, widget_bg(hover)); d.draw_rectangle(x, y, width, height, widget_bg(hover));
pressed pressed
} }
@ -379,21 +390,3 @@ pub fn slider(
} }
false false
} }
#[derive(Debug, Clone, Copy, PartialEq)]
pub enum Scroll {
Up,
Down,
}
pub fn get_scroll(rl: &RaylibHandle) -> Option<Scroll> {
const SCROLL_THRESHOLD: f32 = 0.5;
let value = rl.get_mouse_wheel_move();
if value > SCROLL_THRESHOLD {
Some(Scroll::Up)
} else if value < -SCROLL_THRESHOLD {
Some(Scroll::Down)
} else {
None
}
}

View file

@ -50,3 +50,87 @@ pub fn get_free_id<T>(items: &[T], id_fn: fn(&T) -> usize) -> usize {
} }
id id
} }
pub fn screen_centered_rect_dyn(rl: &RaylibHandle, margin_x: i32, margin_y: i32) -> Rectangle {
let w = rl.get_screen_width();
let h = rl.get_screen_height();
Rectangle {
x: margin_x as f32,
y: margin_y as f32,
width: (w - margin_x * 2) as f32,
height: (h - margin_y * 2) as f32,
}
}
#[derive(Debug, Default)]
pub struct MouseInput {
pos: Vector2,
left_click: bool,
left_hold: bool,
right_click: bool,
right_hold: bool,
scroll: Option<Scroll>,
}
impl MouseInput {
pub fn get(rl: &RaylibHandle) -> Self {
Self {
pos: rl.get_mouse_position(),
left_click: rl.is_mouse_button_pressed(MouseButton::MOUSE_BUTTON_LEFT),
left_hold: rl.is_mouse_button_down(MouseButton::MOUSE_BUTTON_LEFT),
right_click: rl.is_mouse_button_pressed(MouseButton::MOUSE_BUTTON_RIGHT),
right_hold: rl.is_mouse_button_down(MouseButton::MOUSE_BUTTON_RIGHT),
scroll: get_scroll(rl),
}
}
pub fn is_over(&self, rect: Rectangle) -> bool {
rect.check_collision_point_rec(self.pos)
}
pub fn clear(&mut self) {
*self = Self::default();
}
pub fn pos(&self) -> Vector2 {
self.pos
}
pub fn left_click(&self) -> bool {
self.left_click
}
pub fn left_hold(&self) -> bool {
self.left_hold
}
pub fn right_click(&self) -> bool {
self.right_click
}
pub fn right_hold(&self) -> bool {
self.right_hold
}
pub fn scroll(&self) -> Option<Scroll> {
self.scroll
}
}
#[derive(Debug, Clone, Copy, PartialEq)]
pub enum Scroll {
Up,
Down,
}
pub fn get_scroll(rl: &RaylibHandle) -> Option<Scroll> {
const SCROLL_THRESHOLD: f32 = 0.5;
let value = rl.get_mouse_wheel_move();
if value > SCROLL_THRESHOLD {
Some(Scroll::Up)
} else if value < -SCROLL_THRESHOLD {
Some(Scroll::Down)
} else {
None
}
}