230 lines
6.3 KiB
Rust
230 lines
6.3 KiB
Rust
use crate::logic::game_board::ModifyMode;
|
|
|
|
use super::{
|
|
texture_store::TextureStore,
|
|
ui_event::{GUIEvent, GUIEvents},
|
|
Language, UIState,
|
|
};
|
|
use macroquad::{
|
|
hash,
|
|
prelude::*,
|
|
ui::{root_ui, widgets, Skin, Ui},
|
|
};
|
|
|
|
pub struct SettingsMenu {
|
|
mines: usize,
|
|
width: usize,
|
|
height: usize,
|
|
board_modify_mode: ModifyMode,
|
|
}
|
|
impl Default for SettingsMenu {
|
|
fn default() -> Self {
|
|
Self {
|
|
mines: 99,
|
|
width: 30,
|
|
height: 16,
|
|
board_modify_mode: ModifyMode::Flag,
|
|
}
|
|
}
|
|
}
|
|
|
|
impl SettingsMenu {
|
|
pub fn render(
|
|
&mut self,
|
|
ui_state: &UIState,
|
|
event_handler: &mut GUIEvents,
|
|
textures: &TextureStore,
|
|
skin: &Skin,
|
|
exit_button_skin: &Skin,
|
|
) {
|
|
let screen_width = screen_width();
|
|
let screen_height = screen_height();
|
|
let background_color = Color::from_rgba(192, 192, 192, 255);
|
|
|
|
root_ui().window(hash!(), vec2(0., 0.), vec2(screen_width, screen_height), |ui| {
|
|
draw_rectangle(0f32, 0f32, screen_width, screen_height, background_color);
|
|
ui.push_skin(&exit_button_skin);
|
|
if widgets::Button::new("").size(vec2(50.0, 50.0)).position(vec2(0f32, 0f32)).ui(ui) {
|
|
event_handler.add(GUIEvent::CloseSettings)
|
|
}
|
|
ui.pop_skin();
|
|
ui.push_skin(&skin);
|
|
let half_screen_width = screen_width * 0.5;
|
|
const MIN_MINEFIELD_WIDTH: usize = 5;
|
|
const MAX_MINEFIELD_WIDTH: usize = 100;
|
|
const MIN_MINEFIELD_HEIGHT: usize = 5;
|
|
const MAX_MINEFIELD_HEIGHT: usize = 100;
|
|
render_counter(
|
|
&mut self.width,
|
|
ui,
|
|
&textures,
|
|
vec2(half_screen_width, 100f32),
|
|
String::from("Minefield Width"),
|
|
MIN_MINEFIELD_WIDTH,
|
|
MAX_MINEFIELD_WIDTH,
|
|
);
|
|
render_counter(
|
|
&mut self.height,
|
|
ui,
|
|
&textures,
|
|
vec2(half_screen_width, 200f32),
|
|
String::from("Minefield Height"),
|
|
MIN_MINEFIELD_WIDTH,
|
|
MIN_MINEFIELD_HEIGHT,
|
|
);
|
|
render_counter(
|
|
&mut self.mines,
|
|
ui,
|
|
&textures,
|
|
vec2(half_screen_width, 300f32),
|
|
String::from("Mines"),
|
|
1,
|
|
self.width * self.height - 10,
|
|
);
|
|
const NEW_GAME_HEIGHT: f32 = 40f32;
|
|
const NEW_GAME_WIDTH: f32 = 250f32;
|
|
if widgets::Button::new("New Game")
|
|
.size(vec2(NEW_GAME_WIDTH, NEW_GAME_HEIGHT))
|
|
.position(vec2((screen_width - NEW_GAME_WIDTH) * 0.5, 0.0))
|
|
.ui(ui)
|
|
{
|
|
event_handler.add(GUIEvent::CreateNewGame(self.width, self.height, self.mines));
|
|
event_handler.add(GUIEvent::CloseSettings);
|
|
}
|
|
const BUTTON_MENU_WIDTH: f32 = 250f32;
|
|
let language_button_x = (screen_width - BUTTON_MENU_WIDTH) * 0.5;
|
|
const BUTTON_SIZE: f32 = 100f32;
|
|
const BUTTON_MENU_Y: f32 = 400f32;
|
|
let question_button_x = (screen_width - BUTTON_MENU_WIDTH) * 0.5 + (BUTTON_MENU_WIDTH - BUTTON_SIZE);
|
|
const BUTTON_MENU_LABEL_HEIGHT: f32 = 20f32;
|
|
widgets::Label::new("Language")
|
|
.position(vec2(language_button_x, BUTTON_MENU_Y - BUTTON_MENU_LABEL_HEIGHT))
|
|
.size(vec2(BUTTON_SIZE, BUTTON_MENU_LABEL_HEIGHT))
|
|
.ui(ui);
|
|
widgets::Label::new("Question Marking")
|
|
.position(vec2(question_button_x, BUTTON_MENU_Y - BUTTON_MENU_LABEL_HEIGHT))
|
|
.size(vec2(BUTTON_SIZE, BUTTON_MENU_LABEL_HEIGHT))
|
|
.ui(ui);
|
|
if let Language::English = ui_state.language {
|
|
if widgets::Button::new("English")
|
|
.size(vec2(BUTTON_SIZE, BUTTON_SIZE))
|
|
.position(vec2(language_button_x, BUTTON_MENU_Y))
|
|
.ui(ui)
|
|
{
|
|
event_handler.add(GUIEvent::SwitchLanguage(Language::Japanese));
|
|
}
|
|
} else {
|
|
if widgets::Button::new("Japanese")
|
|
.size(vec2(BUTTON_SIZE, BUTTON_SIZE))
|
|
.position(vec2(language_button_x, BUTTON_MENU_Y))
|
|
.ui(ui)
|
|
{
|
|
event_handler.add(GUIEvent::SwitchLanguage(Language::English));
|
|
}
|
|
}
|
|
if let ModifyMode::Question = self.board_modify_mode {
|
|
if widgets::Button::new("ON")
|
|
.size(vec2(BUTTON_SIZE, BUTTON_SIZE))
|
|
.position(vec2(question_button_x, BUTTON_MENU_Y))
|
|
.ui(ui)
|
|
{
|
|
self.board_modify_mode = ModifyMode::Flag;
|
|
event_handler.add(GUIEvent::SetQuestionMode(ModifyMode::Flag));
|
|
}
|
|
} else {
|
|
if widgets::Button::new("OFF")
|
|
.size(vec2(BUTTON_SIZE, BUTTON_SIZE))
|
|
.position(vec2(question_button_x, BUTTON_MENU_Y))
|
|
.ui(ui)
|
|
{
|
|
self.board_modify_mode = ModifyMode::Question;
|
|
event_handler.add(GUIEvent::SetQuestionMode(ModifyMode::Question));
|
|
}
|
|
}
|
|
});
|
|
}
|
|
}
|
|
|
|
fn render_counter(
|
|
count: &mut usize,
|
|
ui: &mut Ui,
|
|
textures: &TextureStore,
|
|
position: Vec2,
|
|
title: String,
|
|
min: usize,
|
|
max: usize,
|
|
) {
|
|
let digits: Vec<usize> = {
|
|
let digits = count.to_string();
|
|
let digits = format!("{:0>3}", digits);
|
|
digits.chars().map(|i| (i.to_digit(10u32).unwrap_or(0)) as usize).collect()
|
|
};
|
|
|
|
const COUNTER_DIGIT_WIDTH: f32 = 13f32 * 2.0;
|
|
const COUNTER_DIGIT_HEIGHT: f32 = 23f32 * 2.0;
|
|
const COUNTER_BUTTON_HEIGHT: f32 = 30f32;
|
|
const COUNTER_BUTTON_MARGIN: f32 = 10f32;
|
|
const BUTTON_OFFSET_HEIGHT: f32 = (COUNTER_DIGIT_HEIGHT - COUNTER_BUTTON_HEIGHT) * 0.5;
|
|
|
|
let counter_width = digits.len() as f32 * COUNTER_DIGIT_WIDTH;
|
|
let position = position - vec2(counter_width * 0.5, 0.0);
|
|
for (x, digit) in digits.iter().enumerate() {
|
|
let position = vec2(COUNTER_DIGIT_WIDTH * x as f32, 0f32) + position;
|
|
widgets::Texture::new(textures.numbers[*digit])
|
|
.size(COUNTER_DIGIT_WIDTH, COUNTER_DIGIT_HEIGHT)
|
|
.position(position)
|
|
.ui(ui);
|
|
}
|
|
if widgets::Button::new("+")
|
|
.size(vec2(COUNTER_BUTTON_HEIGHT, COUNTER_BUTTON_HEIGHT))
|
|
.position(position + vec2(counter_width + COUNTER_BUTTON_MARGIN, BUTTON_OFFSET_HEIGHT))
|
|
.ui(ui)
|
|
{
|
|
*count += 1;
|
|
}
|
|
if widgets::Button::new("-")
|
|
.size(vec2(COUNTER_BUTTON_HEIGHT, COUNTER_BUTTON_HEIGHT))
|
|
.position(position - vec2(COUNTER_BUTTON_HEIGHT + COUNTER_BUTTON_MARGIN, -BUTTON_OFFSET_HEIGHT))
|
|
.ui(ui)
|
|
{
|
|
if *count > min {
|
|
*count -= 1;
|
|
}
|
|
}
|
|
if widgets::Button::new("++")
|
|
.size(vec2(COUNTER_BUTTON_HEIGHT, COUNTER_BUTTON_HEIGHT))
|
|
.position(
|
|
position
|
|
+ vec2(
|
|
counter_width + COUNTER_BUTTON_MARGIN * 2.0 + COUNTER_BUTTON_HEIGHT,
|
|
BUTTON_OFFSET_HEIGHT,
|
|
),
|
|
)
|
|
.ui(ui)
|
|
{
|
|
*count += 10;
|
|
}
|
|
if widgets::Button::new("--")
|
|
.size(vec2(COUNTER_BUTTON_HEIGHT, COUNTER_BUTTON_HEIGHT))
|
|
.position(position - vec2((COUNTER_BUTTON_HEIGHT + COUNTER_BUTTON_MARGIN) * 2.0, -BUTTON_OFFSET_HEIGHT))
|
|
.ui(ui)
|
|
{
|
|
if *count as isize - 10 > min as isize {
|
|
*count -= 10;
|
|
} else {
|
|
*count = min;
|
|
}
|
|
}
|
|
if *count > max {
|
|
*count = max;
|
|
}
|
|
if *count < min {
|
|
*count = min;
|
|
}
|
|
let label_height = 20f32;
|
|
widgets::Label::new(title)
|
|
.position(position - vec2(0f32, label_height))
|
|
.size(vec2(counter_width, label_height))
|
|
.ui(ui);
|
|
}
|