gui experiments, add zooming
This commit is contained in:
parent
de09b785d0
commit
af31531869
4 changed files with 161 additions and 13 deletions
83
src/main.rs
83
src/main.rs
|
@ -1,12 +1,22 @@
|
||||||
use std::{
|
use std::{
|
||||||
collections::HashMap,
|
collections::HashMap,
|
||||||
fs::{read_dir, read_to_string},
|
fs::{read_dir, read_to_string},
|
||||||
|
ops::Rem,
|
||||||
};
|
};
|
||||||
|
|
||||||
use marble_engine::parse;
|
use marble_engine::parse;
|
||||||
use raylib::prelude::*;
|
use raylib::prelude::*;
|
||||||
|
|
||||||
mod marble_engine;
|
mod marble_engine;
|
||||||
|
mod util;
|
||||||
|
use util::*;
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, PartialEq)]
|
||||||
|
enum EditorState {
|
||||||
|
Editing,
|
||||||
|
Playing,
|
||||||
|
Stepping,
|
||||||
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let (mut rl, thread) = raylib::init()
|
let (mut rl, thread) = raylib::init()
|
||||||
|
@ -18,6 +28,12 @@ fn main() {
|
||||||
let board = parse(&read_to_string("boards/adder.mbl").unwrap());
|
let board = parse(&read_to_string("boards/adder.mbl").unwrap());
|
||||||
let mut pos_offset = Vector2::zero();
|
let mut pos_offset = Vector2::zero();
|
||||||
let mut machine = marble_engine::Machine::new(board, "Vec::new()".bytes().collect());
|
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<String, Texture2D> = HashMap::new();
|
let mut textures: HashMap<String, Texture2D> = HashMap::new();
|
||||||
for d in read_dir("assets/tiles").unwrap().flatten() {
|
for d in read_dir("assets/tiles").unwrap().flatten() {
|
||||||
|
@ -32,9 +48,15 @@ fn main() {
|
||||||
}
|
}
|
||||||
|
|
||||||
while !rl.window_should_close() {
|
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();
|
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) {
|
if rl.is_mouse_button_down(MouseButton::MOUSE_BUTTON_MIDDLE) {
|
||||||
pos_offset += rl.get_mouse_delta()
|
pos_offset += rl.get_mouse_delta()
|
||||||
}
|
}
|
||||||
|
@ -45,7 +67,64 @@ fn main() {
|
||||||
let mut d = rl.begin_drawing(&thread);
|
let mut d = rl.begin_drawing(&thread);
|
||||||
d.clear_background(Color::new(64, 64, 64, 255));
|
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);
|
d.draw_fps(2, 2);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
|
||||||
use raylib::{drawing::RaylibDrawHandle, math::Vector2, texture::Texture2D};
|
use raylib::prelude::*;
|
||||||
|
|
||||||
mod board;
|
mod board;
|
||||||
mod tile;
|
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<u8> {
|
||||||
|
&mut self.input
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn set_input(&mut self, bytes: Vec<u8>) {
|
||||||
|
self.input = bytes;
|
||||||
|
}
|
||||||
|
|
||||||
pub fn new(grid: Board, input: Vec<u8>) -> Self {
|
pub fn new(grid: Board, input: Vec<u8>) -> Self {
|
||||||
// let (grid, marbles) = parse(source);
|
// let (grid, marbles) = parse(source);
|
||||||
let mut marbles = Vec::new();
|
let mut marbles = Vec::new();
|
||||||
|
@ -55,14 +71,15 @@ impl Machine {
|
||||||
d: &mut RaylibDrawHandle,
|
d: &mut RaylibDrawHandle,
|
||||||
textures: &HashMap<String, Texture2D>,
|
textures: &HashMap<String, Texture2D>,
|
||||||
offset: Vector2,
|
offset: Vector2,
|
||||||
|
zoom: i32,
|
||||||
) {
|
) {
|
||||||
let tile_size = 32;
|
let tile_size = 16 << zoom;
|
||||||
for x in 0..self.board.width() {
|
for x in 0..self.board.width() {
|
||||||
for y in 0..self.board.height() {
|
for y in 0..self.board.height() {
|
||||||
if let Some(tile) = self.board.get((x, y).into()) {
|
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 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;
|
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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,12 +1,6 @@
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
|
||||||
use raylib::{
|
use raylib::prelude::*;
|
||||||
color::Color,
|
|
||||||
drawing::{RaylibDraw, RaylibDrawHandle},
|
|
||||||
ffi::Rectangle,
|
|
||||||
math::Vector2,
|
|
||||||
texture::Texture2D,
|
|
||||||
};
|
|
||||||
|
|
||||||
use super::board::Pos;
|
use super::board::Pos;
|
||||||
|
|
||||||
|
@ -98,6 +92,7 @@ impl Tile {
|
||||||
x: i32,
|
x: i32,
|
||||||
y: i32,
|
y: i32,
|
||||||
size: i32,
|
size: i32,
|
||||||
|
zoom:i32,
|
||||||
) {
|
) {
|
||||||
let tex_name = match self {
|
let tex_name = match self {
|
||||||
Tile::Blank => "",
|
Tile::Blank => "",
|
||||||
|
@ -150,7 +145,7 @@ impl Tile {
|
||||||
texture,
|
texture,
|
||||||
Vector2::new((x - size / 2) as f32, (y - size / 2) as f32),
|
Vector2::new((x - size / 2) as f32, (y - size / 2) as f32),
|
||||||
0.0,
|
0.0,
|
||||||
2.0,
|
(1<<zoom) as f32,
|
||||||
Color::WHITE,
|
Color::WHITE,
|
||||||
);
|
);
|
||||||
return;
|
return;
|
||||||
|
|
57
src/util.rs
Normal file
57
src/util.rs
Normal file
|
@ -0,0 +1,57 @@
|
||||||
|
use raylib::prelude::*;
|
||||||
|
|
||||||
|
pub fn text_input(
|
||||||
|
d: &mut RaylibDrawHandle,
|
||||||
|
bounds: Rectangle,
|
||||||
|
text: &mut String,
|
||||||
|
is_selected: &mut bool,
|
||||||
|
) -> 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.,
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue