Better list view resizable items
This commit is contained in:
parent
0f56ca0187
commit
5f9ddc91e2
|
@ -18,4 +18,5 @@ czkawka_core = { version = "6.1.0", path = "../czkawka_core" }
|
|||
chrono = "0.4.31"
|
||||
|
||||
[build-dependencies]
|
||||
#slint-build = "1.2.2"
|
||||
slint-build = { git = "https://github.com/slint-ui/slint.git", branch = "olivier/fix-3700"}
|
|
@ -9,21 +9,17 @@ pub fn connect_delete_button(app: &MainWindow) {
|
|||
|
||||
let mut r = app.get_empty_folder_model();
|
||||
let m = r.borrow_mut();
|
||||
let length_before = m.iter().count();
|
||||
let (entries_to_delete, entries_left): (Vec<_>, Vec<_>) = m.iter().partition(|(checked, _selected_row, _header_row, _data)| *checked);
|
||||
let mut s: Vec<_> = m.iter().filter(|(checked, _selected_row, _header_row, _data)| !*checked).collect();
|
||||
let (entries_to_delete, mut entries_left): (Vec<_>, Vec<_>) = m.iter().partition(|(checked, _header_row, _selected_row, _data)| *checked);
|
||||
|
||||
entries_to_delete.into_iter().for_each(|(_checked, _selected_row, _header_row, _data)| {
|
||||
// TODO delete in parallel items, consider to add progress bar
|
||||
});
|
||||
|
||||
let length_after = s.len();
|
||||
if length_before != length_after {
|
||||
dbg!(format!("Items to remove {}", length_before - length_after));
|
||||
s.iter_mut().for_each(|(_checked, selected_row, _header_row, _data)| {
|
||||
if !entries_to_delete.is_empty() {
|
||||
dbg!(format!("Items to remove {}", entries_to_delete.len()));
|
||||
entries_to_delete.into_iter().for_each(|(_checked, _header_row, _selected_row, _data)| {
|
||||
// TODO delete in parallel items, consider to add progress bar
|
||||
});
|
||||
entries_left.iter_mut().for_each(|(_checked, _header_row, selected_row, _data)| {
|
||||
*selected_row = false;
|
||||
});
|
||||
let r = ModelRc::new(VecModel::from(s));
|
||||
let r = ModelRc::new(VecModel::from(entries_left));
|
||||
app.set_empty_folder_model(r.into());
|
||||
}
|
||||
});
|
||||
|
|
|
@ -39,7 +39,7 @@ fn scan_empty_folders(a: Weak<MainWindow>) {
|
|||
});
|
||||
|
||||
a.upgrade_in_event_loop(move |app| {
|
||||
let mut folder_map = ef.get_empty_folder_list();
|
||||
let folder_map = ef.get_empty_folder_list();
|
||||
let items = Rc::new(VecModel::default());
|
||||
for path in vector {
|
||||
let (directory, file) = split_path(&path);
|
||||
|
|
|
@ -1,37 +1,40 @@
|
|||
mod connect_delete;
|
||||
mod connect_scan;
|
||||
|
||||
use std::borrow::BorrowMut;
|
||||
use std::path::Path;
|
||||
use std::rc::Rc;
|
||||
|
||||
use crate::connect_delete::connect_delete_button;
|
||||
use crate::connect_scan::connect_scan_button;
|
||||
|
||||
use czkawka_core::common_tool::CommonData;
|
||||
use czkawka_core::empty_folder::EmptyFolder;
|
||||
use slint::{Model, ModelRc, SharedString, VecModel};
|
||||
use slint::{ModelRc, SharedString, VecModel};
|
||||
|
||||
slint::include_modules!();
|
||||
fn main() {
|
||||
let app = MainWindow::new().unwrap(); //.run().unwrap();
|
||||
|
||||
to_remove_debug(&app);
|
||||
|
||||
connect_delete_button(&app);
|
||||
connect_scan_button(&app);
|
||||
|
||||
app.run().unwrap();
|
||||
}
|
||||
|
||||
// TODO remove this after trying
|
||||
pub fn to_remove_debug(app: &MainWindow) {
|
||||
let row_data: Rc<VecModel<(bool, bool, bool, ModelRc<SharedString>)>> = Rc::new(VecModel::default());
|
||||
|
||||
for r in 0..1000 {
|
||||
for r in 0..100000 {
|
||||
let items = VecModel::default();
|
||||
|
||||
for c in 0..3 {
|
||||
items.push(slint::format!("Item {r}.{c}").into());
|
||||
}
|
||||
|
||||
row_data.push((r % 2 == 0, false, true, ModelRc::new(items)));
|
||||
row_data.push((r % 2 == 0, r % 3 == 0, false, ModelRc::new(items)));
|
||||
}
|
||||
app.set_empty_folder_model(row_data.into());
|
||||
|
||||
connect_delete_button(&app);
|
||||
connect_scan_button(&app);
|
||||
|
||||
app.run().unwrap();
|
||||
}
|
||||
|
||||
pub fn split_path(path: &Path) -> (String, String) {
|
||||
|
|
|
@ -4,29 +4,38 @@ import {LeftSidePanel} from "left_side_panel.slint";
|
|||
import {CurrentTab} from "common.slint";
|
||||
|
||||
export component MainWindow inherits Window {
|
||||
callback deleted;
|
||||
callback deleted;
|
||||
callback scanned(CurrentTab);
|
||||
min-width: 300px;
|
||||
|
||||
in-out property <bool> scanning: false;
|
||||
|
||||
in-out property <CurrentTab> active-tab: CurrentTab.EmptyFolders;
|
||||
in-out property <[{checked: bool, selected_row: bool, header_row: bool, val:[string]}]> empty_folder_model: [
|
||||
in-out property <[{checked: bool, header_row: bool, selected_row: bool, val:[string]}]> empty_folder_model: [
|
||||
{checked: false, selected_row: false, header_row: true, val: ["kropkarz", "/Xd1", "24.10.2023"]} ,
|
||||
{checked: false, selected_row: true, header_row: false, val: ["witasphere", "/Xd1/Imagerren2", "25.11.1991"]} ,
|
||||
{checked: false, selected_row: false, header_row: false, val: ["witasphere", "/Xd1/Imagerren2", "25.11.1991"]} ,
|
||||
{checked: false, selected_row: false, header_row: false, val: ["witasphere", "/Xd1/Imagerren2", "25.11.1991"]} ,
|
||||
{checked: false, selected_row: false, header_row: false, val: ["witasphere", "/Xd1/Imagerren2", "25.11.1991"]} ,
|
||||
{checked: false, selected_row: false, header_row: false, val: ["witasphere", "/Xd1/Imagerren2", "25.11.1991"]} ,
|
||||
{checked: false, selected_row: false, header_row: false, val: ["witasphere", "/Xd1/Imagerren2", "25.11.1991"]} ,
|
||||
{checked: false, selected_row: false, header_row: false, val: ["witasphere", "/Xd1/Imagerren2", "25.11.1991"]} ,
|
||||
{checked: false, selected_row: false, header_row: false, val: ["witasphere", "/Xd1/Imagerren2", "25.11.1991"]} ,
|
||||
{checked: false, selected_row: false, header_row: false, val: ["witasphere", "/Xd1/Imagerren2", "25.11.1991"]} ,
|
||||
{checked: false, selected_row: false, header_row: false, val: ["witasphere", "/Xd1/Imagerren2", "25.11.1991"]} ,
|
||||
{checked: true, selected_row: false, header_row: false, val: ["lokkaler", "/Xd1/Vide2", "01.23.1911"]}
|
||||
];
|
||||
in-out property <[{checked: bool, selected_row: bool, header_row: bool, val:[string]}]> empty_files_model: [];
|
||||
in-out property <[{checked: bool, selected_row: bool, header_row: bool, val:[string]}]> similar_images_model: [];
|
||||
in-out property <[{checked: bool, header_row: bool, selected_row: bool, val:[string]}]> empty_files_model: [];
|
||||
in-out property <[{checked: bool, header_row: bool, selected_row: bool, val:[string]}]> similar_images_model: [];
|
||||
|
||||
title: root.active-tab == CurrentTab.EmptyFiles ? "EmptyFiles" : (root.active-tab == CurrentTab.EmptyFolders ? "EmptyFolders" : "Similar Images");
|
||||
|
||||
min-width: 200px;
|
||||
VerticalBox {
|
||||
HorizontalBox {
|
||||
// min-width: 600px;
|
||||
preferred-height: 300px;
|
||||
|
||||
LeftSidePanel {
|
||||
max-width: 10px; // Just forces the smallest possible
|
||||
scanning: root.scanning;
|
||||
active-tab <=> root.active-tab;
|
||||
}
|
||||
|
@ -35,20 +44,22 @@ export component MainWindow inherits Window {
|
|||
if root.active-tab == CurrentTab.EmptyFolders: SelectableTableView {
|
||||
min-width: 200px;
|
||||
|
||||
columns: ["Selection", "Folder Name", "Path", "Modification Date"];
|
||||
values: empty-folder-model;
|
||||
columns: ["Selection", "Folder Name", "Path"];
|
||||
last-column: "Modification Date";
|
||||
column-sizes: [30px, 100px, 100px, 100px];
|
||||
values <=> empty-folder-model;
|
||||
}
|
||||
if root.active-tab == CurrentTab.EmptyFiles: SelectableTableView {
|
||||
min-width: 200px;
|
||||
|
||||
columns: ["Selection", "Folder Name", "Path", "Modification Date"];
|
||||
values: empty-files-model;
|
||||
values <=> empty-files-model;
|
||||
}
|
||||
if root.active-tab == CurrentTab.SimilarImages: SelectableTableView {
|
||||
min-width: 200px;
|
||||
|
||||
columns: ["Selection", "Folder Name", "Path", "Modification Date"];
|
||||
values: similar-images-model;
|
||||
values <=> similar-images-model;
|
||||
}
|
||||
}
|
||||
HorizontalBox {
|
||||
|
|
|
@ -2,11 +2,15 @@ import { Button, VerticalBox , HorizontalBox, TabWidget, ListView, StandardListV
|
|||
|
||||
export component SelectableTableView inherits Rectangle {
|
||||
in property <[string]> columns;
|
||||
in property <[{checked: bool, selected_row: bool, header_row: bool, val:[string]}]> values;
|
||||
in property <string> last_column;
|
||||
in-out property <[{checked: bool, header_row: bool, selected_row: bool, val:[string]}]> values;
|
||||
|
||||
private property <[length]> column_sizes: [30px, 100px, 100px, 100px];
|
||||
in-out property <[length]> column_sizes: [200px, 100px, 100px, 100px];
|
||||
private property <[length]> real_sizes: [0px,0px,0px,0px,0px,0px,0px,0px,0px,0px,0px,0px,0px,0px,0px,0px,0px,0px];
|
||||
private property <int> column_number: 4;
|
||||
|
||||
in-out property <int> selected_item: -1;
|
||||
|
||||
VerticalBox {
|
||||
padding: 5px;
|
||||
// Widgets
|
||||
|
@ -15,12 +19,13 @@ export component SelectableTableView inherits Rectangle {
|
|||
spacing: 5px;
|
||||
vertical-stretch: 0;
|
||||
for title[idx] in root.columns : HorizontalLayout {
|
||||
width: root.column_sizes[idx];
|
||||
width: root.column-sizes[idx];
|
||||
|
||||
Text { overflow: elide; text: title; }
|
||||
Rectangle {
|
||||
width: 1px;
|
||||
background: gray;
|
||||
|
||||
|
||||
TouchArea {
|
||||
width: 5px;
|
||||
x: (parent.width - self.width) / 2;
|
||||
|
@ -42,17 +47,29 @@ export component SelectableTableView inherits Rectangle {
|
|||
}
|
||||
}
|
||||
}
|
||||
Text { overflow: elide; text: last-column; }
|
||||
}
|
||||
list_view:= ListView {
|
||||
list_view := ListView {
|
||||
min-width: 100px;
|
||||
for r[idx] in root.values : Rectangle {
|
||||
height: 30px;
|
||||
background: r.header-row ? #888888 : (touch-area.has-hover ? (r.selected_row ? #cccccc : #dddddd) : (r.selected_row ? #cccccc: #dddddd));
|
||||
// background: touch-area.has-hover ? (selected ? #333333 : #222222) : (selected ? #333333: #222222);
|
||||
|
||||
touch_area:= TouchArea {
|
||||
clicked => {
|
||||
if (!r.header_row) {
|
||||
r.selected_row = !r.selected_row
|
||||
r.selected_row = !r.selected_row;
|
||||
if (root.selected-item == -1) {
|
||||
root.selected-item = idx;
|
||||
} else {
|
||||
if (r.selected_row == true) {
|
||||
root.values[root.selected-item].selected_row = false;
|
||||
root.selected-item = idx;
|
||||
} else {
|
||||
root.selected-item = -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -60,7 +77,6 @@ export component SelectableTableView inherits Rectangle {
|
|||
HorizontalLayout {
|
||||
padding: 5px;
|
||||
spacing: 5px;
|
||||
//width: root.column_sizes[idx];
|
||||
|
||||
CheckBox {
|
||||
//min-width: 200px;
|
||||
|
@ -74,11 +90,12 @@ export component SelectableTableView inherits Rectangle {
|
|||
}
|
||||
|
||||
HorizontalLayout {
|
||||
padding: 5px;
|
||||
spacing: 5px;
|
||||
for f[idx] in r.val : Text {
|
||||
width: root.column-sizes[idx + 1];
|
||||
text: f;
|
||||
font-size: 12px;
|
||||
|
||||
vertical-alignment: center;
|
||||
|
||||
overflow: elide;
|
||||
|
|
Loading…
Reference in a new issue