theme overhaul

This commit is contained in:
Crispy 2024-10-13 12:45:58 +02:00
parent 2720735a58
commit 866a4c7127
4 changed files with 54 additions and 78 deletions

View file

@ -18,7 +18,9 @@ use crate::{
}, },
simple_button, simple_option_button, slider, simple_button, simple_option_button, slider,
solution::{Score, Solution}, solution::{Score, Solution},
text_input, texture_option_button, userdata_dir, Scroll, Textures, text_input, texture_option_button,
theme::*,
userdata_dir, Scroll, Textures,
}; };
const HEADER_HEIGHT: i32 = 40; const HEADER_HEIGHT: i32 = 40;
@ -454,49 +456,24 @@ impl Editor {
2., 2.,
Color::new(255, 255, 255, if is_selected { 255 } else { 150 }), Color::new(255, 255, 255, if is_selected { 255 } else { 150 }),
); );
// d.draw_text(&b.name, 15, y+5, 20, Color::WHITE);
y += 37; y += 37;
} }
} }
if self.complete_popup == Popup::Visible { if self.complete_popup == Popup::Visible {
let width = 310; let width = 320;
let height = 165; let height = 165;
let x = d.get_screen_width() / 2 - width / 2; let x = d.get_screen_width() / 2 - width / 2;
let y = d.get_screen_height() / 2 - height / 2; let y = d.get_screen_height() / 2 - height / 2;
d.draw_rectangle(x, y, width, height, Color::DIMGRAY); d.draw_rectangle(x, y, width, height, BG_DARK);
d.draw_text("Level Complete!", x + 10, 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);
d.draw_rectangle(x + 10, y + 70, 90, 30, Color::DARKGREEN); draw_usize(d, textures, score.cycles, x + 10, y + 70, 6, 2);
d.draw_text( d.draw_text("tiles", x + 145, y + 45, 20, Color::WHITE);
&format!("{}", score.cycles), draw_usize(d, textures, score.tiles, x + 140, y + 70, 4, 2);
x + 15, d.draw_text("area", x + 155 + 80, y + 45, 20, Color::WHITE);
y + 75, draw_usize(d, textures, score.area, x + 150 + 80, y + 70, 4, 2);
20,
Color::WHITE,
);
d.draw_text("tiles", x + 115, y + 45, 20, Color::WHITE);
d.draw_rectangle(x + 110, y + 70, 90, 30, Color::DARKGREEN);
d.draw_text(
&format!("{}", score.tiles),
x + 115,
y + 75,
20,
Color::WHITE,
);
d.draw_text("area", x + 215, y + 45, 20, Color::WHITE);
d.draw_rectangle(x + 210, y + 70, 90, 30, Color::DARKGREEN);
d.draw_text(
&format!("{}", score.area),
x + 215,
y + 75,
20,
Color::WHITE,
);
} }
if simple_button(d, x + 10, y + 110, 140, 45) { if simple_button(d, x + 10, y + 110, 140, 45) {
self.complete_popup = Popup::Dismissed; self.complete_popup = Popup::Dismissed;
@ -629,7 +606,7 @@ impl Editor {
for (box_index, index) in (input_start..input_end).enumerate() { for (box_index, index) in (input_start..input_end).enumerate() {
let x = input_x + input_cell_width * box_index as i32; let x = input_x + input_cell_width * box_index as i32;
let byte = self.machine.input().get(index); let byte = self.machine.input().get(index);
d.draw_rectangle(x, 5, input_cell_width - 5, 30, Color::DIMGRAY); d.draw_rectangle(x, 5, input_cell_width - 5, 30, BG_WIDGET);
let color = if index < self.machine.input_index() { let color = if index < self.machine.input_index() {
d.draw_rectangle(x + 4, 25, input_cell_width - 13, 8, Color::LIME); d.draw_rectangle(x + 4, 25, input_cell_width - 13, 8, Color::LIME);
Color::LIGHTGREEN Color::LIGHTGREEN

View file

@ -10,11 +10,13 @@ mod editor;
mod level; mod level;
mod marble_engine; mod marble_engine;
mod solution; mod solution;
mod theme;
mod util; mod util;
use editor::{Editor, ExitState}; use editor::{Editor, ExitState};
use level::Level; use level::Level;
use solution::Solution; use solution::Solution;
use theme::*;
use util::*; use util::*;
struct Game { struct Game {
@ -94,11 +96,11 @@ impl Game {
} }
fn draw(&mut self, d: &mut RaylibDrawHandle) { fn draw(&mut self, d: &mut RaylibDrawHandle) {
d.clear_background(Color::new(64, 64, 64, 255)); d.clear_background(BG_DARK);
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, Color::GRAY); d.draw_rectangle(0, 0, level_list_width, screen_height, BG_MEDIUM);
let clicked = d.is_mouse_button_pressed(MouseButton::MOUSE_BUTTON_LEFT); let clicked = d.is_mouse_button_pressed(MouseButton::MOUSE_BUTTON_LEFT);
let mouse_pos = d.get_mouse_position(); let mouse_pos = d.get_mouse_position();
@ -130,9 +132,7 @@ impl Game {
self.editing_solution_name = false; self.editing_solution_name = false;
self.selected_level = index; self.selected_level = index;
} }
if self.selected_level == index { d.draw_rectangle_rec(bounds, widget_bg(self.selected_level == index));
d.draw_rectangle_rec(bounds, Color::DARKCYAN);
}
let mut title_color = Color::WHITE; let mut title_color = Color::WHITE;
if let Some(solutions) = self.solutions.get(level.id()) { if let Some(solutions) = self.solutions.get(level.id()) {

24
src/theme.rs Normal file
View file

@ -0,0 +1,24 @@
use raylib::prelude::*;
pub const BG_DARK: Color = gray(32);
pub const BG_MEDIUM: Color = gray(48);
pub const BG_LIGHT: Color = gray(64);
pub const BG_WIDGET: Color = gray(96);
pub const BG_WIDGET_ACTIVE: Color = rgb(80, 120, 180);
pub const FG_MARBLE_VALUE: Color = rgb(255, 80, 40);
pub const fn widget_bg(highlight: bool) -> Color {
if highlight {
BG_WIDGET_ACTIVE
} else {
BG_WIDGET
}
}
pub const fn rgb(r: u8, g: u8, b: u8) -> Color {
Color::new(r, g, b, 255)
}
pub const fn gray(value: u8) -> Color {
Color::new(value, value, value, 255)
}

View file

@ -2,6 +2,8 @@ use std::{collections::HashMap, fs::read_dir, path::PathBuf};
use raylib::prelude::*; use raylib::prelude::*;
use crate::theme::*;
#[derive(Default)] #[derive(Default)]
pub struct Textures { pub struct Textures {
map: HashMap<String, Texture2D>, map: HashMap<String, Texture2D>,
@ -36,16 +38,9 @@ pub fn simple_button(d: &mut RaylibDrawHandle, x: i32, y: i32, width: i32, heigh
width: width as f32, width: width as f32,
height: height as f32, height: height as f32,
}; };
let mut pressed = false; let hover = bounds.check_collision_point_rec(mouse_pos);
let color = if bounds.check_collision_point_rec(mouse_pos) { let pressed = hover && d.is_mouse_button_pressed(MouseButton::MOUSE_BUTTON_LEFT);
if d.is_mouse_button_pressed(MouseButton::MOUSE_BUTTON_LEFT) { d.draw_rectangle(x, y, width, height, widget_bg(hover));
pressed = true;
}
Color::DARKCYAN
} else {
Color::GRAY
};
d.draw_rectangle(x, y, width, height, color);
pressed pressed
} }
@ -61,17 +56,8 @@ pub fn simple_option_button<T>(
where where
T: PartialEq, T: PartialEq,
{ {
let color = if &option == current { let bounds = Rectangle::new(x as f32, y as f32, width as f32, height as f32);
Color::DARKCYAN d.draw_rectangle_rec(bounds, widget_bg(&option == current));
} else {
Color::GRAY
};
let bounds = Rectangle {
x: x as f32,
y: y as f32,
width: width as f32,
height: height as f32,
};
let mouse_pos = d.get_mouse_position(); let mouse_pos = d.get_mouse_position();
let mut changed = false; let mut changed = false;
if d.is_mouse_button_pressed(MouseButton::MOUSE_BUTTON_LEFT) if d.is_mouse_button_pressed(MouseButton::MOUSE_BUTTON_LEFT)
@ -81,7 +67,6 @@ where
*current = option; *current = option;
changed = true; changed = true;
} }
d.draw_rectangle_rec(bounds, color);
changed changed
} }
@ -94,12 +79,7 @@ pub fn text_input(
editable: bool, editable: bool,
) -> bool { ) -> bool {
let mut changed = false; let mut changed = false;
let (bg, underline) = if *is_selected { d.draw_rectangle_rec(bounds, widget_bg(*is_selected));
(Color::DARKCYAN, Color::CYAN)
} else {
(Color::GRAY, Color::DIMGRAY)
};
d.draw_rectangle_rec(bounds, bg);
d.draw_rectangle_rec( d.draw_rectangle_rec(
Rectangle::new( Rectangle::new(
bounds.x + 2., bounds.x + 2.,
@ -107,7 +87,7 @@ pub fn text_input(
bounds.width - 4., bounds.width - 4.,
3., 3.,
), ),
underline, BG_DARK,
); );
let drawn_text = if *is_selected { let drawn_text = if *is_selected {
&format!("{text}_") &format!("{text}_")
@ -165,18 +145,13 @@ pub fn texture_option_button<T>(
) where ) where
T: PartialEq, T: PartialEq,
{ {
let color = if &option == current {
Color::DARKCYAN
} else {
Color::GRAY
};
let bounds = Rectangle { let bounds = Rectangle {
x: pos.x, x: pos.x,
y: pos.y, y: pos.y,
width: tex_size + border * 2., width: tex_size + border * 2.,
height: tex_size + border * 2., height: tex_size + border * 2.,
}; };
d.draw_rectangle_rec(bounds, color); d.draw_rectangle_rec(bounds, widget_bg(&option == current));
d.draw_texture_ex( d.draw_texture_ex(
texture, texture,
pos + Vector2::new(border, border), pos + Vector2::new(border, border),
@ -205,7 +180,7 @@ pub fn draw_usize(
let digits = digits as i32; let digits = digits as i32;
let scale = scale as i32; let scale = scale as i32;
for i in 0..digits { for i in 0..digits {
d.draw_rectangle(x + 10 * i * scale, y, 8 * scale, 16 * scale, Color::DIMGRAY); d.draw_rectangle(x + 10 * i * scale, y, 8 * scale, 16 * scale, BG_LIGHT);
} }
let mut num = number; let mut num = number;
let mut i = 0; let mut i = 0;
@ -238,7 +213,7 @@ pub fn draw_usize_small(
for &digit in &digits[(MAX_DIGITS - i)..] { for &digit in &digits[(MAX_DIGITS - i)..] {
let source = Rectangle::new(4. * digit as f32, 0., 4., 6.); let source = Rectangle::new(4. * digit as f32, 0., 4., 6.);
let dest = Rectangle::new(x as f32, y as f32, 4. * scale, 6. * scale); let dest = Rectangle::new(x as f32, y as f32, 4. * scale, 6. * scale);
d.draw_texture_pro(texture, source, dest, Vector2::zero(), 0., Color::RED); d.draw_texture_pro(texture, source, dest, Vector2::zero(), 0., FG_MARBLE_VALUE);
x += 4 * scale as i32; x += 4 * scale as i32;
} }
} }
@ -255,7 +230,7 @@ pub fn slider(
) -> bool { ) -> bool {
// the +1 makes the lowest state look slightly filled and the max state fully filled // the +1 makes the lowest state look slightly filled and the max state fully filled
let percent = (*value - min + 1) as f32 / (max - min + 1) as f32; let percent = (*value - min + 1) as f32 / (max - min + 1) as f32;
d.draw_rectangle(x, y, width, height, Color::DIMGRAY); d.draw_rectangle(x, y, width, height, BG_WIDGET);
d.draw_rectangle(x, y, (width as f32 * percent) as i32, height, Color::CYAN); d.draw_rectangle(x, y, (width as f32 * percent) as i32, height, Color::CYAN);
let mouse_pos = d.get_mouse_position(); let mouse_pos = d.get_mouse_position();
let bounds = Rectangle::new(x as f32, y as f32, width as f32, height as f32); let bounds = Rectangle::new(x as f32, y as f32, width as f32, height as f32);