From 866a4c7127101fc3e1db57ca0b62801ef455c0eb Mon Sep 17 00:00:00 2001 From: CrispyPin Date: Sun, 13 Oct 2024 12:45:58 +0200 Subject: [PATCH] theme overhaul --- src/editor.rs | 47 ++++++++++++----------------------------------- src/main.rs | 10 +++++----- src/theme.rs | 24 ++++++++++++++++++++++++ src/util.rs | 51 +++++++++++++-------------------------------------- 4 files changed, 54 insertions(+), 78 deletions(-) create mode 100644 src/theme.rs diff --git a/src/editor.rs b/src/editor.rs index 209eb16..c68dc74 100644 --- a/src/editor.rs +++ b/src/editor.rs @@ -18,7 +18,9 @@ use crate::{ }, simple_button, simple_option_button, slider, 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; @@ -454,49 +456,24 @@ impl Editor { 2., Color::new(255, 255, 255, if is_selected { 255 } else { 150 }), ); - - // d.draw_text(&b.name, 15, y+5, 20, Color::WHITE); y += 37; } } if self.complete_popup == Popup::Visible { - let width = 310; + let width = 320; let height = 165; let x = d.get_screen_width() / 2 - width / 2; let y = d.get_screen_height() / 2 - height / 2; - d.draw_rectangle(x, y, width, height, Color::DIMGRAY); - d.draw_text("Level Complete!", x + 10, y + 10, 30, Color::LIME); + d.draw_rectangle(x, y, width, height, BG_DARK); + d.draw_text("Level Complete!", x + 45, y + 10, 30, Color::LIME); if let Some(score) = &self.score { d.draw_text("cycles", x + 15, y + 45, 20, Color::WHITE); - d.draw_rectangle(x + 10, y + 70, 90, 30, Color::DARKGREEN); - d.draw_text( - &format!("{}", score.cycles), - x + 15, - y + 75, - 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, - ); + draw_usize(d, textures, score.cycles, x + 10, y + 70, 6, 2); + d.draw_text("tiles", x + 145, y + 45, 20, Color::WHITE); + draw_usize(d, textures, score.tiles, x + 140, y + 70, 4, 2); + d.draw_text("area", x + 155 + 80, y + 45, 20, Color::WHITE); + draw_usize(d, textures, score.area, x + 150 + 80, y + 70, 4, 2); } if simple_button(d, x + 10, y + 110, 140, 45) { self.complete_popup = Popup::Dismissed; @@ -629,7 +606,7 @@ impl Editor { for (box_index, index) in (input_start..input_end).enumerate() { let x = input_x + input_cell_width * box_index as i32; 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() { d.draw_rectangle(x + 4, 25, input_cell_width - 13, 8, Color::LIME); Color::LIGHTGREEN diff --git a/src/main.rs b/src/main.rs index 4ae388c..9e63b89 100644 --- a/src/main.rs +++ b/src/main.rs @@ -10,11 +10,13 @@ mod editor; mod level; mod marble_engine; mod solution; +mod theme; mod util; use editor::{Editor, ExitState}; use level::Level; use solution::Solution; +use theme::*; use util::*; struct Game { @@ -94,11 +96,11 @@ impl Game { } 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 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 mouse_pos = d.get_mouse_position(); @@ -130,9 +132,7 @@ impl Game { self.editing_solution_name = false; self.selected_level = index; } - if self.selected_level == index { - d.draw_rectangle_rec(bounds, Color::DARKCYAN); - } + d.draw_rectangle_rec(bounds, widget_bg(self.selected_level == index)); let mut title_color = Color::WHITE; if let Some(solutions) = self.solutions.get(level.id()) { diff --git a/src/theme.rs b/src/theme.rs new file mode 100644 index 0000000..137ede1 --- /dev/null +++ b/src/theme.rs @@ -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) +} diff --git a/src/util.rs b/src/util.rs index 732aae3..2be433a 100644 --- a/src/util.rs +++ b/src/util.rs @@ -2,6 +2,8 @@ use std::{collections::HashMap, fs::read_dir, path::PathBuf}; use raylib::prelude::*; +use crate::theme::*; + #[derive(Default)] pub struct Textures { map: HashMap, @@ -36,16 +38,9 @@ pub fn simple_button(d: &mut RaylibDrawHandle, x: i32, y: i32, width: i32, heigh width: width as f32, height: height as f32, }; - let mut pressed = false; - let color = if bounds.check_collision_point_rec(mouse_pos) { - if d.is_mouse_button_pressed(MouseButton::MOUSE_BUTTON_LEFT) { - pressed = true; - } - Color::DARKCYAN - } else { - Color::GRAY - }; - d.draw_rectangle(x, y, width, height, color); + let hover = bounds.check_collision_point_rec(mouse_pos); + let pressed = hover && d.is_mouse_button_pressed(MouseButton::MOUSE_BUTTON_LEFT); + d.draw_rectangle(x, y, width, height, widget_bg(hover)); pressed } @@ -61,17 +56,8 @@ pub fn simple_option_button( where T: PartialEq, { - let color = if &option == current { - Color::DARKCYAN - } else { - Color::GRAY - }; - let bounds = Rectangle { - x: x as f32, - y: y as f32, - width: width as f32, - height: height as f32, - }; + let bounds = Rectangle::new(x as f32, y as f32, width as f32, height as f32); + d.draw_rectangle_rec(bounds, widget_bg(&option == current)); let mouse_pos = d.get_mouse_position(); let mut changed = false; if d.is_mouse_button_pressed(MouseButton::MOUSE_BUTTON_LEFT) @@ -81,7 +67,6 @@ where *current = option; changed = true; } - d.draw_rectangle_rec(bounds, color); changed } @@ -94,12 +79,7 @@ pub fn text_input( editable: bool, ) -> bool { let mut changed = false; - let (bg, underline) = if *is_selected { - (Color::DARKCYAN, Color::CYAN) - } else { - (Color::GRAY, Color::DIMGRAY) - }; - d.draw_rectangle_rec(bounds, bg); + d.draw_rectangle_rec(bounds, widget_bg(*is_selected)); d.draw_rectangle_rec( Rectangle::new( bounds.x + 2., @@ -107,7 +87,7 @@ pub fn text_input( bounds.width - 4., 3., ), - underline, + BG_DARK, ); let drawn_text = if *is_selected { &format!("{text}_") @@ -165,18 +145,13 @@ pub fn texture_option_button( ) where T: PartialEq, { - let color = if &option == current { - Color::DARKCYAN - } else { - Color::GRAY - }; let bounds = Rectangle { x: pos.x, y: pos.y, width: 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( texture, pos + Vector2::new(border, border), @@ -205,7 +180,7 @@ pub fn draw_usize( let digits = digits as i32; let scale = scale as i32; 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 i = 0; @@ -238,7 +213,7 @@ pub fn draw_usize_small( for &digit in &digits[(MAX_DIGITS - i)..] { 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); - 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; } } @@ -255,7 +230,7 @@ pub fn slider( ) -> bool { // 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; - 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); let mouse_pos = d.get_mouse_position(); let bounds = Rectangle::new(x as f32, y as f32, width as f32, height as f32);