add option to delete solutions, with a confirmation dialog
This commit is contained in:
parent
14e90a7849
commit
2c522c1fe0
2 changed files with 45 additions and 4 deletions
34
src/main.rs
34
src/main.rs
|
@ -18,7 +18,7 @@ use editor::{Editor, ExitState};
|
|||
use level::{Chapter, Level};
|
||||
use solution::Solution;
|
||||
use theme::*;
|
||||
use ui::{simple_option_button, text_button, text_input, ShapedText};
|
||||
use ui::{simple_option_button, tex32_button, text_button, text_input, ShapedText, Tooltip};
|
||||
use util::*;
|
||||
|
||||
const TITLE_TEXT: &str = concat!("Marble Machinations v", env!("CARGO_PKG_VERSION"));
|
||||
|
@ -33,6 +33,7 @@ struct Game {
|
|||
textures: Textures,
|
||||
selected_level: usize,
|
||||
selected_solution: usize,
|
||||
delete_solution: Option<usize>,
|
||||
editing_solution_name: bool,
|
||||
level_desc_text: ShapedText,
|
||||
}
|
||||
|
@ -74,6 +75,7 @@ impl Game {
|
|||
textures,
|
||||
selected_level: 0,
|
||||
selected_solution,
|
||||
delete_solution: None,
|
||||
editing_solution_name: false,
|
||||
level_desc_text: ShapedText::new(20),
|
||||
}
|
||||
|
@ -112,6 +114,9 @@ impl Game {
|
|||
fn draw(&mut self, d: &mut RaylibDrawHandle) {
|
||||
d.clear_background(BG_DARK);
|
||||
|
||||
let mut tooltip = Tooltip::default();
|
||||
tooltip.init_frame(d);
|
||||
|
||||
d.draw_text(
|
||||
TITLE_TEXT,
|
||||
d.get_screen_width() - 275,
|
||||
|
@ -159,6 +164,7 @@ impl Game {
|
|||
self.editing_solution_name = false;
|
||||
self.selected_level = level_index;
|
||||
self.selected_solution = 0;
|
||||
self.delete_solution = None;
|
||||
// select the last solution of the level, if there is one
|
||||
if let Some(solutions) = self.solutions.get(level.id()) {
|
||||
self.selected_solution = solutions.len().saturating_sub(1);
|
||||
|
@ -236,6 +242,14 @@ impl Game {
|
|||
10,
|
||||
Color::WHITE,
|
||||
);
|
||||
if tex32_button(
|
||||
(d, &mouse),
|
||||
(level_list_width + entry_width + 15, solution_y + 4),
|
||||
self.textures.get("cancel"),
|
||||
(&mut tooltip, "delete"),
|
||||
) {
|
||||
self.delete_solution = Some(solution_index);
|
||||
}
|
||||
solution_y += solution_entry_height + 10;
|
||||
}
|
||||
|
||||
|
@ -252,8 +266,23 @@ impl Game {
|
|||
solutions.push(Solution::new(level, next_id));
|
||||
}
|
||||
|
||||
if let Some(i) = self.delete_solution {
|
||||
let text = format!("really delete solution '{}'?", &solutions[i].name);
|
||||
let y = (solution_y + 40).max(240);
|
||||
let x = level_list_width + 10;
|
||||
d.draw_text(&text, x, y, 20, Color::ORANGE);
|
||||
if text_button(d, &mouse, x, y + 30, 100, "yes") {
|
||||
solutions[i].remove_file();
|
||||
solutions.remove(i);
|
||||
self.delete_solution = None;
|
||||
}
|
||||
if text_button(d, &mouse, x + 110, y + 30, 100, "no") {
|
||||
self.delete_solution = None;
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(solution) = solutions.get_mut(self.selected_solution) {
|
||||
let column_x = level_list_width + entry_width + 20;
|
||||
let column_x = level_list_width + entry_width + 56;
|
||||
let bounds = Rectangle::new(column_x as f32, y as f32, 220., 30.);
|
||||
if text_input(
|
||||
d,
|
||||
|
@ -286,6 +315,7 @@ impl Game {
|
|||
self.solutions.insert(level.id().to_owned(), Vec::new());
|
||||
}
|
||||
}
|
||||
tooltip.draw(d);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
use std::{
|
||||
fs::{self, File},
|
||||
io::Write,
|
||||
path::PathBuf,
|
||||
};
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
@ -45,16 +46,26 @@ impl Solution {
|
|||
self.solution_id
|
||||
}
|
||||
|
||||
pub fn save(&self) {
|
||||
fn path(&self) -> PathBuf {
|
||||
let dir = userdata_dir().join("solutions").join(&self.level_id);
|
||||
fs::create_dir_all(&dir).unwrap();
|
||||
let path = dir.join(format!("solution_{}.json", &self.solution_id));
|
||||
dir.join(format!("solution_{}.json", &self.solution_id))
|
||||
}
|
||||
|
||||
pub fn save(&self) {
|
||||
let path = self.path();
|
||||
let json = serde_json::to_string_pretty(self).unwrap();
|
||||
let mut file = File::create(path).unwrap();
|
||||
file.write_all(json.as_bytes()).unwrap();
|
||||
}
|
||||
|
||||
pub fn remove_file(&self) {
|
||||
let path = self.path();
|
||||
if let Err(e) = fs::remove_file(path) {
|
||||
eprint!("Error removing solution file: {e}");
|
||||
}
|
||||
}
|
||||
|
||||
pub fn score_text(&self) -> String {
|
||||
if let Some(score) = &self.score {
|
||||
format!("C: {} T: {}", score.cycles, score.tiles)
|
||||
|
|
Loading…
Reference in a new issue