Start implementing sort and shuffle features
This commit is contained in:
parent
17f2985bb7
commit
f73cc8f7ea
1
Cargo.lock
generated
1
Cargo.lock
generated
@ -1868,6 +1868,7 @@ dependencies = [
|
||||
"env_logger",
|
||||
"log",
|
||||
"opener",
|
||||
"rand",
|
||||
"relm4",
|
||||
"relm4-components",
|
||||
"relm4-icons",
|
||||
|
@ -29,6 +29,7 @@ chrono = "0.4.33"
|
||||
|
||||
strum = "0.26"
|
||||
strum_macros = "0.26"
|
||||
rand = "0.8.5"
|
||||
# strum = { version = "0.26", features = ["derive"] }
|
||||
|
||||
[profile.dev.package.sqlx-macros]
|
||||
|
18
flake.lock
generated
18
flake.lock
generated
@ -21,11 +21,11 @@
|
||||
},
|
||||
"nixpkgs": {
|
||||
"locked": {
|
||||
"lastModified": 1704842529,
|
||||
"narHash": "sha256-OTeQA+F8d/Evad33JMfuXC89VMetQbsU4qcaePchGr4=",
|
||||
"lastModified": 1707907779,
|
||||
"narHash": "sha256-dtktfFJn+36yBkZ1mnQGdiDsqnzC9pXt/Ecpsui0hiY=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "eabe8d3eface69f5bb16c18f8662a702f50c20d5",
|
||||
"rev": "c5e9528855e4e6feda2b16dec28de880ce774b93",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@ -35,11 +35,11 @@
|
||||
},
|
||||
"nixpkgs_2": {
|
||||
"locked": {
|
||||
"lastModified": 1704842529,
|
||||
"narHash": "sha256-OTeQA+F8d/Evad33JMfuXC89VMetQbsU4qcaePchGr4=",
|
||||
"lastModified": 1707907779,
|
||||
"narHash": "sha256-dtktfFJn+36yBkZ1mnQGdiDsqnzC9pXt/Ecpsui0hiY=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "eabe8d3eface69f5bb16c18f8662a702f50c20d5",
|
||||
"rev": "c5e9528855e4e6feda2b16dec28de880ce774b93",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@ -76,11 +76,11 @@
|
||||
"systems": "systems"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1701680307,
|
||||
"narHash": "sha256-kAuep2h5ajznlPMD9rnQyffWG8EM/C73lejGofXvdM8=",
|
||||
"lastModified": 1705309234,
|
||||
"narHash": "sha256-uNRRNRKmJyCRC/8y1RqBkqWBLM034y4qN7EprSdmgyA=",
|
||||
"owner": "numtide",
|
||||
"repo": "flake-utils",
|
||||
"rev": "4022d587cbbfd70fe950c1e2083a02621806a725",
|
||||
"rev": "1ef2e671c3b0c19053962c07dbda38332dcebf26",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
|
@ -1,5 +1,6 @@
|
||||
use chrono::Utc;
|
||||
use gtk::prelude::*;
|
||||
use log::debug;
|
||||
use relm4::{
|
||||
component::{AsyncComponent, AsyncComponentParts},
|
||||
prelude::*,
|
||||
@ -22,12 +23,17 @@ pub struct AppModel {
|
||||
database: Database,
|
||||
mcdu: Controller<McduModel>,
|
||||
sheets_listing: Controller<SheetListingModel>,
|
||||
edit_mode: bool,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum AppInput {
|
||||
SearchStarted(String),
|
||||
SheetPressed(Sheet),
|
||||
Refresh,
|
||||
Sort,
|
||||
Shuffle,
|
||||
SetEditMode(bool),
|
||||
}
|
||||
|
||||
pub struct AppInitData {
|
||||
@ -54,6 +60,32 @@ impl AsyncComponent for AppModel {
|
||||
gtk::Box {
|
||||
set_orientation: gtk::Orientation::Vertical,
|
||||
set_hexpand: true,
|
||||
gtk::Box {
|
||||
set_orientation: gtk::Orientation::Horizontal,
|
||||
set_margin_all: 10,
|
||||
set_spacing: 3,
|
||||
gtk::Button {
|
||||
set_icon_name: "view-refresh-symbolic",
|
||||
set_margin_end: 10,
|
||||
connect_clicked[sender] => move |_| sender.input(AppInput::Refresh),
|
||||
},
|
||||
gtk::ToggleButton {
|
||||
set_icon_name: "document-edit-symbolic",
|
||||
set_margin_end: 10,
|
||||
connect_clicked[sender] => move |button| sender.input(AppInput::SetEditMode(button.is_active())),
|
||||
},
|
||||
#[name = "button_sort"]
|
||||
gtk::ToggleButton {
|
||||
set_icon_name: "view-sort-descending-symbolic",
|
||||
set_active: true,
|
||||
connect_clicked[sender] => move |_| sender.input(AppInput::Sort),
|
||||
},
|
||||
gtk::ToggleButton {
|
||||
set_icon_name: "media-playlist-shuffle-symbolic",
|
||||
set_group: Some(&button_sort),
|
||||
connect_clicked[sender] => move |_| sender.input(AppInput::Shuffle),
|
||||
},
|
||||
},
|
||||
gtk::ScrolledWindow {
|
||||
model.sheets_listing.widget(),
|
||||
set_vexpand: true,
|
||||
@ -93,6 +125,7 @@ impl AsyncComponent for AppModel {
|
||||
database: init_data.database,
|
||||
mcdu,
|
||||
sheets_listing,
|
||||
edit_mode: false,
|
||||
};
|
||||
|
||||
let widgets = view_output!();
|
||||
@ -112,14 +145,21 @@ impl AsyncComponent for AppModel {
|
||||
.emit(SheetListingInput::Query(query.clone()));
|
||||
}
|
||||
AppInput::SheetPressed(sheet) => {
|
||||
sheet.open_file();
|
||||
// TODO: updating directly does not work
|
||||
let mut sheet = sheet;
|
||||
sheet.last_opened = I64DateTime(Utc::now());
|
||||
sheet_dao::update_sheet_last_opened(&self.database, &sheet)
|
||||
.await
|
||||
.unwrap();
|
||||
if self.edit_mode {
|
||||
debug!("Sheet pressed, but we are in edit mode!");
|
||||
} else {
|
||||
sheet.open_file();
|
||||
let mut sheet = sheet;
|
||||
sheet.last_opened = I64DateTime(Utc::now());
|
||||
sheet_dao::update_sheet_last_opened(&self.database, &sheet)
|
||||
.await
|
||||
.unwrap();
|
||||
}
|
||||
}
|
||||
AppInput::Refresh => todo!(),
|
||||
AppInput::Sort => self.sheets_listing.emit(SheetListingInput::Sort),
|
||||
AppInput::Shuffle => self.sheets_listing.emit(SheetListingInput::Shuffle),
|
||||
AppInput::SetEditMode(edit_mode) => self.edit_mode = edit_mode,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user