add button to clone solutions
This commit is contained in:
parent
1ce5291777
commit
2720735a58
5 changed files with 42 additions and 29 deletions
|
@ -57,7 +57,7 @@ blueprint rotation?
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"level_id": "00_zeroes",
|
"level_id": "00_zeroes",
|
||||||
"solution_id": "solution_0",
|
"solution_id": 0,
|
||||||
"name": "unnamed 1",
|
"name": "unnamed 1",
|
||||||
"board": "oo\nP*\n|-",
|
"board": "oo\nP*\n|-",
|
||||||
"score": {
|
"score": {
|
||||||
|
@ -71,7 +71,7 @@ blueprint rotation?
|
||||||
`blueprints/blueprint_0.json`
|
`blueprints/blueprint_0.json`
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"id": "blueprint_0",
|
"id": 0,
|
||||||
"name": "zero_printer",
|
"name": "zero_printer",
|
||||||
"board": "o -B I\n> * < \n"
|
"board": "o -B I\n> * < \n"
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,7 +8,7 @@ use raylib::prelude::*;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
blueprint::Blueprint,
|
blueprint::Blueprint,
|
||||||
draw_scaled_texture, draw_usize,
|
draw_scaled_texture, draw_usize, get_free_id, get_scroll,
|
||||||
level::Level,
|
level::Level,
|
||||||
marble_engine::{
|
marble_engine::{
|
||||||
board::Board,
|
board::Board,
|
||||||
|
@ -18,7 +18,7 @@ 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, get_scroll, userdata_dir, Scroll, Textures,
|
text_input, texture_option_button, userdata_dir, Scroll, Textures,
|
||||||
};
|
};
|
||||||
|
|
||||||
const HEADER_HEIGHT: i32 = 40;
|
const HEADER_HEIGHT: i32 = 40;
|
||||||
|
@ -254,16 +254,7 @@ impl Editor {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
board.trim_size(0);
|
board.trim_size(0);
|
||||||
let mut id = 0;
|
let id = get_free_id(&self.blueprints, Blueprint::id);
|
||||||
'outer: loop {
|
|
||||||
for b in &self.blueprints {
|
|
||||||
if b.id() == id {
|
|
||||||
id += 1;
|
|
||||||
continue 'outer;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
let mut blueprint = Blueprint::new(&board, id);
|
let mut blueprint = Blueprint::new(&board, id);
|
||||||
if !self.new_blueprint_name.is_empty() {
|
if !self.new_blueprint_name.is_empty() {
|
||||||
blueprint.name = self.new_blueprint_name.clone();
|
blueprint.name = self.new_blueprint_name.clone();
|
||||||
|
|
25
src/main.rs
25
src/main.rs
|
@ -203,10 +203,10 @@ impl Game {
|
||||||
solution_y += solution_entry_height + 10;
|
solution_y += solution_entry_height + 10;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let next_id = get_free_id(solutions, Solution::id);
|
||||||
if simple_button(d, level_list_width + 10, solution_y, entry_width, 30) {
|
if simple_button(d, level_list_width + 10, solution_y, entry_width, 30) {
|
||||||
let n = solutions.len();
|
|
||||||
self.selected_solution = solutions.len();
|
self.selected_solution = solutions.len();
|
||||||
solutions.push(Solution::new(level, n));
|
solutions.push(Solution::new(level, next_id));
|
||||||
}
|
}
|
||||||
d.draw_text(
|
d.draw_text(
|
||||||
"new solution",
|
"new solution",
|
||||||
|
@ -227,14 +227,23 @@ impl Game {
|
||||||
24,
|
24,
|
||||||
true,
|
true,
|
||||||
);
|
);
|
||||||
d.draw_text(solution.id(), column_x, y + 35, 10, Color::GRAY);
|
let id_text = format!("{}", solution.id());
|
||||||
|
d.draw_text(&id_text, column_x, y + 35, 10, Color::GRAY);
|
||||||
|
|
||||||
if simple_button(d, column_x, y + 50, 220, 30) {
|
if simple_button(d, column_x, y + 50, 220, 30) {
|
||||||
|
let cloned = solution.new_copy(next_id);
|
||||||
|
self.selected_solution = solutions.len();
|
||||||
|
solutions.push(cloned);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
d.draw_text("clone", column_x + 5, y + 55, 20, Color::WHITE);
|
||||||
|
|
||||||
|
if simple_button(d, column_x, y + 85, 220, 30) {
|
||||||
let mut editor = Editor::new(solution.clone(), level.clone());
|
let mut editor = Editor::new(solution.clone(), level.clone());
|
||||||
editor.center_view(d);
|
editor.center_view(d);
|
||||||
self.open_editor = Some(editor);
|
self.open_editor = Some(editor);
|
||||||
}
|
}
|
||||||
d.draw_text("edit", column_x + 5, y + 55, 20, Color::WHITE);
|
d.draw_text("edit", column_x + 5, y + 90, 20, Color::WHITE);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
self.solutions.insert(level.id().to_owned(), Vec::new());
|
self.solutions.insert(level.id().to_owned(), Vec::new());
|
||||||
|
@ -263,7 +272,7 @@ fn get_levels() -> Vec<Level> {
|
||||||
add_level(d.path());
|
add_level(d.path());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
levels.sort_by_key(Level::sort_order);
|
levels.sort_unstable_by_key(Level::sort_order);
|
||||||
levels
|
levels
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -275,7 +284,6 @@ fn get_solutions() -> HashMap<String, Vec<Solution>> {
|
||||||
if dir.path().is_dir() {
|
if dir.path().is_dir() {
|
||||||
let level_name = dir.file_name().to_string_lossy().to_string();
|
let level_name = dir.file_name().to_string_lossy().to_string();
|
||||||
let mut solutions = Vec::new();
|
let mut solutions = Vec::new();
|
||||||
|
|
||||||
if let Ok(files) = read_dir(dir.path()) {
|
if let Ok(files) = read_dir(dir.path()) {
|
||||||
for file in files.flatten() {
|
for file in files.flatten() {
|
||||||
let s = read_to_string(file.path())
|
let s = read_to_string(file.path())
|
||||||
|
@ -286,12 +294,11 @@ fn get_solutions() -> HashMap<String, Vec<Solution>> {
|
||||||
solutions.push(solution)
|
solutions.push(solution)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
solutions.sort_unstable_by_key(Solution::id);
|
||||||
by_level.insert(level_name, solutions);
|
|
||||||
}
|
}
|
||||||
|
by_level.insert(level_name, solutions);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
by_level
|
by_level
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,7 +9,7 @@ use crate::{level::Level, userdata_dir};
|
||||||
|
|
||||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||||
pub struct Solution {
|
pub struct Solution {
|
||||||
solution_id: String,
|
solution_id: usize,
|
||||||
level_id: String,
|
level_id: String,
|
||||||
pub name: String,
|
pub name: String,
|
||||||
pub board: String,
|
pub board: String,
|
||||||
|
@ -25,18 +25,25 @@ pub struct Score {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Solution {
|
impl Solution {
|
||||||
pub fn new(level: &Level, number: usize) -> Self {
|
pub fn new(level: &Level, id: usize) -> Self {
|
||||||
Self {
|
Self {
|
||||||
solution_id: format!("solution_{number}"),
|
solution_id: id,
|
||||||
level_id: level.id().to_owned(),
|
level_id: level.id().to_owned(),
|
||||||
name: format!("Unnamed {number}"),
|
name: format!("Unnamed {id}"),
|
||||||
board: level.init_board().unwrap_or(String::from(" ")),
|
board: level.init_board().unwrap_or(String::from(" ")),
|
||||||
score: None,
|
score: None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn id(&self) -> &str {
|
pub fn new_copy(&self, id: usize) -> Self {
|
||||||
&self.solution_id
|
let mut new = self.clone();
|
||||||
|
new.solution_id = id;
|
||||||
|
new.score = None;
|
||||||
|
new
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn id(&self) -> usize {
|
||||||
|
self.solution_id
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn save(&self) {
|
pub fn save(&self) {
|
||||||
|
|
|
@ -307,3 +307,11 @@ pub fn get_scroll(rl: &RaylibHandle) -> Option<Scroll> {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn get_free_id<T>(items: &[T], id_fn: fn(&T) -> usize) -> usize {
|
||||||
|
let mut id = 0;
|
||||||
|
while items.iter().any(|i| id_fn(i) == id) {
|
||||||
|
id += 1;
|
||||||
|
}
|
||||||
|
id
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue