From af31531869fd47824ca17340ebe51112a0efd024 Mon Sep 17 00:00:00 2001 From: CrispyPin Date: Fri, 4 Oct 2024 21:20:53 +0200 Subject: [PATCH] gui experiments, add zooming --- src/main.rs | 83 ++++++++++++++++++++++++++++++++++++++- src/marble_engine.rs | 23 +++++++++-- src/marble_engine/tile.rs | 11 ++---- src/util.rs | 57 +++++++++++++++++++++++++++ 4 files changed, 161 insertions(+), 13 deletions(-) create mode 100644 src/util.rs diff --git a/src/main.rs b/src/main.rs index 9bd8656..0cfabc4 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,12 +1,22 @@ use std::{ collections::HashMap, fs::{read_dir, read_to_string}, + ops::Rem, }; use marble_engine::parse; use raylib::prelude::*; mod marble_engine; +mod util; +use util::*; + +#[derive(Debug, Clone, PartialEq)] +enum EditorState { + Editing, + Playing, + Stepping, +} fn main() { let (mut rl, thread) = raylib::init() @@ -18,6 +28,12 @@ fn main() { let board = parse(&read_to_string("boards/adder.mbl").unwrap()); let mut pos_offset = Vector2::zero(); let mut machine = marble_engine::Machine::new(board, "Vec::new()".bytes().collect()); + let mut editor_state = EditorState::Editing; + let mut output_as_text = false; + let mut input_as_text = true; + let mut input_text_selected = false; + + let mut zoom = 1; let mut textures: HashMap = HashMap::new(); for d in read_dir("assets/tiles").unwrap().flatten() { @@ -32,9 +48,15 @@ fn main() { } while !rl.window_should_close() { - if rl.is_key_pressed(KeyboardKey::KEY_SPACE) { + if rl.is_key_pressed(KeyboardKey::KEY_SPACE) || rl.is_key_down(KeyboardKey::KEY_ENTER) { machine.step(); } + if rl.get_mouse_wheel_move() > 0. && zoom < 3 { + zoom += 1; + } + if rl.get_mouse_wheel_move() < 0. && zoom > 0 { + zoom -= 1; + } if rl.is_mouse_button_down(MouseButton::MOUSE_BUTTON_MIDDLE) { pos_offset += rl.get_mouse_delta() } @@ -45,7 +67,64 @@ fn main() { let mut d = rl.begin_drawing(&thread); d.clear_background(Color::new(64, 64, 64, 255)); - machine.draw(&mut d, &textures, pos_offset); + machine.draw(&mut d, &textures, pos_offset, zoom); + + // UI + // d.draw_rectangle(x, y, width, height, color); + let height = d.get_screen_height(); + let footer_height = 100; + let footer_top = (height - footer_height) as f32; + d.draw_rectangle( + 0, + height - footer_height, + d.get_screen_width(), + footer_height, + Color::new(32, 32, 32, 255), + ); + + let tile_size = (16 << zoom) as f32; + let grid_spill_x = (pos_offset.x).rem(tile_size) - tile_size; + let grid_spill_y = (pos_offset.y).rem(tile_size) - tile_size; + d.gui_grid( + Rectangle::new( + grid_spill_x, + grid_spill_y, + d.get_screen_width() as f32 * 2., + height as f32 - grid_spill_y - footer_height as f32, + ), + None, + tile_size, + 1, + ); + + d.gui_check_box( + Rectangle::new(5., footer_top + 5., 25., 25.), + Some(rstr!("output as text")), + &mut output_as_text, + ); + let out_text = if output_as_text { + String::from_utf8_lossy(machine.output()).to_string() + } else { + format!("{:?}", machine.output()) + }; + d.draw_text(&out_text, 5, footer_top as i32 + 35, 20, Color::WHITE); + + let mut input_text = String::from_utf8_lossy(machine.input()).to_string(); + if text_input( + &mut d, + Rectangle::new(350., footer_top + 60., 200., 25.), + &mut input_text, + &mut input_text_selected, + ) { + machine.set_input(input_text.into_bytes()); + } + + if d.gui_button( + Rectangle::new(0., height as f32 - 40., 100.0, 30.0), + Some(rstr!("meow")), + ) { + println!("meow"); + } d.draw_fps(2, 2); } diff --git a/src/marble_engine.rs b/src/marble_engine.rs index 519477d..d96fd3b 100644 --- a/src/marble_engine.rs +++ b/src/marble_engine.rs @@ -1,6 +1,6 @@ use std::collections::HashMap; -use raylib::{drawing::RaylibDrawHandle, math::Vector2, texture::Texture2D}; +use raylib::prelude::*; mod board; mod tile; @@ -30,6 +30,22 @@ impl Machine { } } + pub fn output(&self) -> &[u8] { + &self.output + } + + pub fn input(&self) -> &[u8] { + &self.input + } + + pub fn input_mut(&mut self) -> &mut Vec { + &mut self.input + } + + pub fn set_input(&mut self, bytes: Vec) { + self.input = bytes; + } + pub fn new(grid: Board, input: Vec) -> Self { // let (grid, marbles) = parse(source); let mut marbles = Vec::new(); @@ -55,14 +71,15 @@ impl Machine { d: &mut RaylibDrawHandle, textures: &HashMap, offset: Vector2, + zoom: i32, ) { - let tile_size = 32; + let tile_size = 16 << zoom; for x in 0..self.board.width() { for y in 0..self.board.height() { if let Some(tile) = self.board.get((x, y).into()) { let px = x as i32 * tile_size + offset.x as i32 + tile_size / 2; let py = y as i32 * tile_size + offset.y as i32 + tile_size / 2; - tile.draw(d, textures, px, py, tile_size); + tile.draw(d, textures, px, py, tile_size, zoom); } } } diff --git a/src/marble_engine/tile.rs b/src/marble_engine/tile.rs index 6e59097..aea08e1 100644 --- a/src/marble_engine/tile.rs +++ b/src/marble_engine/tile.rs @@ -1,12 +1,6 @@ use std::collections::HashMap; -use raylib::{ - color::Color, - drawing::{RaylibDraw, RaylibDrawHandle}, - ffi::Rectangle, - math::Vector2, - texture::Texture2D, -}; +use raylib::prelude::*; use super::board::Pos; @@ -98,6 +92,7 @@ impl Tile { x: i32, y: i32, size: i32, + zoom:i32, ) { let tex_name = match self { Tile::Blank => "", @@ -150,7 +145,7 @@ impl Tile { texture, Vector2::new((x - size / 2) as f32, (y - size / 2) as f32), 0.0, - 2.0, + (1< bool { + let mut changed = false; + let (bg, border) = if *is_selected { + (Color::DARKCYAN, Color::CYAN) + } else { + (Color::GRAY, Color::DIMGRAY) + }; + d.draw_rectangle_rec(bounds, border); + d.draw_rectangle_rec(shrink_rec(bounds, 2.), bg); + d.draw_text( + text, + bounds.x as i32 + 4, + bounds.y as i32 + 4, + 10, + Color::WHITE, + ); + let mouse_pos = d.get_mouse_position(); + if d.is_mouse_button_pressed(MouseButton::MOUSE_BUTTON_LEFT) + && (bounds.check_collision_point_rec(mouse_pos) || *is_selected) + { + *is_selected = !*is_selected; + } + + if *is_selected { + if d.is_key_pressed(KeyboardKey::KEY_BACKSPACE) { + changed = true; + text.pop(); + } + let char_code = unsafe { ffi::GetCharPressed() }; + let c = if char_code > 0 { + char::from_u32(char_code as u32) + } else { + None + }; + if let Some(c) = c { + changed = true; + text.push(c); + } + } + changed +} + +pub fn shrink_rec(rec: Rectangle, a: f32) -> Rectangle { + Rectangle { + x: rec.x + a, + y: rec.y + a, + width: rec.width - a * 2., + height: rec.height - a * 2., + } +}