Start implementing sort and shuffle features
This commit is contained in:
@@ -1,3 +1,5 @@
|
||||
use std::rc::Rc;
|
||||
|
||||
use gtk::prelude::*;
|
||||
|
||||
use relm4::factory::FactoryVecDeque;
|
||||
@@ -8,6 +10,8 @@ use crate::sheet::Sheet;
|
||||
|
||||
use super::sheet_model::{OnQueryUpdate, SheetModel};
|
||||
|
||||
use rand::{seq::SliceRandom, thread_rng};
|
||||
|
||||
pub struct SheetListingModel {
|
||||
sheets: FactoryVecDeque<SheetModel>,
|
||||
}
|
||||
@@ -16,6 +20,8 @@ pub struct SheetListingModel {
|
||||
pub enum SheetListingInput {
|
||||
Query(String),
|
||||
ListBoxRowClicked(i32),
|
||||
Sort,
|
||||
Shuffle,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
@@ -74,6 +80,74 @@ impl SimpleComponent for SheetListingModel {
|
||||
})
|
||||
.unwrap();
|
||||
}
|
||||
SheetListingInput::Sort => sort_sheets(&mut self.sheets),
|
||||
SheetListingInput::Shuffle => shuffle_sheets(&mut self.sheets),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn shuffle_sheets(sheets: &mut FactoryVecDeque<SheetModel>) {
|
||||
let mut new_order: Vec<usize> = (0..sheets.len()).collect();
|
||||
new_order.shuffle(&mut rand::thread_rng());
|
||||
order_sheets(sheets, &mut new_order);
|
||||
}
|
||||
|
||||
fn sort_sheets(sheets: &mut FactoryVecDeque<SheetModel>) {
|
||||
let mut order = Vec::new();
|
||||
{
|
||||
let guard = sheets.guard();
|
||||
let mut numerated_sheets: Vec<_> = guard.iter().enumerate().collect();
|
||||
numerated_sheets.sort_by(|a, b| a.1.sheet.cmp(&b.1.sheet).reverse());
|
||||
for (i, _) in numerated_sheets {
|
||||
order.push(i);
|
||||
}
|
||||
}
|
||||
order_sheets(sheets, &mut order);
|
||||
}
|
||||
|
||||
fn order_sheets(sheets: &mut FactoryVecDeque<SheetModel>, order: &mut Vec<usize>) {
|
||||
assert!(sheets.len() == order.len());
|
||||
|
||||
for i in 0..sheets.len() {
|
||||
let new_i = order[i];
|
||||
let old_i = i;
|
||||
|
||||
if old_i != new_i {
|
||||
sheets.guard().swap(old_i, new_i);
|
||||
order.swap(old_i, new_i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
// Note this useful idiom: importing names from outer (for mod tests) scope.
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_sort() {
|
||||
let original: Vec<usize> = (0..10).collect();
|
||||
let mut to_sort = original.clone();
|
||||
to_sort.shuffle(&mut rand::thread_rng());
|
||||
|
||||
println!("To sort: {:?}", to_sort);
|
||||
|
||||
let mut order_builder: Vec<_> = to_sort.clone().into_iter().enumerate().collect();
|
||||
order_builder.sort_by(|a, b| a.1.cmp(&b.1));
|
||||
let mut order: Vec<_> = order_builder.into_iter().map(|(i, _)| i).collect();
|
||||
|
||||
for i in 0..to_sort.len() {
|
||||
let new_i = order[i];
|
||||
let old_i = i;
|
||||
|
||||
println!("Swap {} and {}", old_i, new_i);
|
||||
if old_i != new_i {
|
||||
to_sort.swap(old_i, new_i);
|
||||
order.swap(old_i, new_i);
|
||||
}
|
||||
println!("order: {:?} - to_sort: {:?}", order, to_sort);
|
||||
}
|
||||
|
||||
assert_eq!(original, to_sort);
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user