From d52354fac522252a33bec4d454017ada027fb4eb Mon Sep 17 00:00:00 2001 From: joshuaboud Date: Tue, 20 Jul 2021 14:23:49 -0300 Subject: [PATCH] overhaul selection functions --- navigator/components/NavDir.js | 12 +++ navigator/components/NavEntry.js | 10 +- navigator/components/NavWindow.js | 160 +++++++++++++++++------------- 3 files changed, 112 insertions(+), 70 deletions(-) diff --git a/navigator/components/NavDir.js b/navigator/components/NavDir.js index a946120..d77afd0 100644 --- a/navigator/components/NavDir.js +++ b/navigator/components/NavDir.js @@ -213,6 +213,18 @@ export class NavDir extends NavEntry { } super.show_properties(extra_properties); } + + style_selected() { + this.dom_element.nav_item_icon.classList.remove("fa-folder"); + this.dom_element.nav_item_icon.classList.add("fa-folder-open"); + super.style_selected(); + } + + unstyle_selected() { + this.dom_element.nav_item_icon.classList.add("fa-folder"); + this.dom_element.nav_item_icon.classList.remove("fa-folder-open"); + super.unstyle_selected(); + } } export class NavDirLink extends NavDir{ diff --git a/navigator/components/NavEntry.js b/navigator/components/NavEntry.js index a3fcb51..a4685f7 100644 --- a/navigator/components/NavEntry.js +++ b/navigator/components/NavEntry.js @@ -111,7 +111,7 @@ export class NavEntry { default: break; } - } + } this.nav_window_ref.set_selected(this, e.shiftKey, e.ctrlKey); this.context_menu_ref.hide(); break; @@ -374,4 +374,12 @@ export class NavEntry { document.getElementById("nav-edit-owner").value = this.stat["owner"]; document.getElementById("nav-edit-group").value = this.stat["group"]; } + + style_selected() { + this.dom_element.classList.add("nav-item-selected"); + } + + unstyle_selected() { + this.dom_element.classList.remove("nav-item-selected"); + } } diff --git a/navigator/components/NavWindow.js b/navigator/components/NavWindow.js index 7144438..e5a7f04 100644 --- a/navigator/components/NavWindow.js +++ b/navigator/components/NavWindow.js @@ -38,7 +38,6 @@ export class NavWindow { this.window.addEventListener("click", this); this.window.addEventListener("contextmenu", this); window.addEventListener("keydown", this); - this.last_selected_index = -1; this.context_menu = new NavContextMenu("nav-context-menu", this); @@ -56,11 +55,11 @@ export class NavWindow { * @param {Event} e */ handleEvent(e) { - console.log(e); + e.stopPropagation(); switch (e.type) { case "click": if (e.target === this.window) { - this.clear_selected(); + this.reset_selection(); this.show_selected_properties(); } break; @@ -75,7 +74,7 @@ export class NavWindow { this.select_all(); e.preventDefault(); } else if (e.keyCode === 27) { - this.clear_selected(); + this.reset_selection(); } else if (e.keyCode === 67 && e.ctrlKey) { this.copy(); } else if (e.keyCode === 86 && e.ctrlKey) { @@ -132,7 +131,7 @@ export class NavWindow { file.context_menu_ref = this.context_menu; }); document.getElementById("pwd").value = this.pwd().path_str(); - this.set_selected(this.pwd(), false, false); + this.reset_selection(); this.show_selected_properties(); document.getElementById("nav-num-dirs").innerText = `${num_dirs} Director${(num_dirs === 1)? "y" : "ies"}`; document.getElementById("nav-num-files").innerText = `${num_files} File${(num_files === 1)? "" : "s"}`; @@ -181,66 +180,84 @@ export class NavWindow { this.cd(new NavDir(this.pwd().parent_dir())); } + clear_selected() { + for (let entry of this.selected_entries) { + entry.unstyle_selected(); + } + this.selected_entries.clear(); + } + /** * * @param {NavEntry} entry - * @param {Boolean} select_range - * @param {Boolean} append */ - set_selected(entry, select_range, append) { - this.hide_edit_selected(); - for (let i of this.selected_entries) { - i.dom_element.classList.remove("nav-item-selected"); - if (i.nav_type === "dir") { - i.dom_element.nav_item_icon.classList.remove("fa-folder-open"); - i.dom_element.nav_item_icon.classList.add("fa-folder"); - } - } - var to_be_selected = []; - if (append && this.selected_entries.has(entry)) { - this.selected_entries.delete(entry); - if (this.selected_entries.size === 0) { - this.clear_selected(); - } - } else if (select_range && this.last_selected_index !== -1) { - var start = this.last_selected_index; - var end = this.entries.indexOf(entry); - if (end < start) - [start, end] = [end, start]; - if (end === -1) - return; - to_be_selected = this.entries.slice(start, end + 1).filter(entry => !entry.stat["inaccessible"]); - } else { - if (!append) - this.selected_entries.clear(); - to_be_selected = [entry]; - } - to_be_selected = to_be_selected.filter((entry) => entry.visible); - for (let i of to_be_selected) { - this.selected_entries.add(i); - } - for (let i of this.selected_entries) { - i.dom_element.classList.add("nav-item-selected"); - if (i.nav_type === "dir") { - i.dom_element.nav_item_icon.classList.remove("fa-folder"); - i.dom_element.nav_item_icon.classList.add("fa-folder-open"); - } - } - if (this.selected_entries.size > 1){ - var name_fields = document.getElementsByClassName("nav-info-column-filename"); - for (let name_field of name_fields) { - name_field.innerText = this.selected_entries.size.toString() + " selected" - name_field.title = name_field.innerText; - } - document.getElementById("nav-info-column-properties").innerHTML = ""; - } else { - this.show_selected_properties(); - } - this.last_selected_index = this.entries.indexOf(entry); + select_one(entry) { + entry.style_selected(); + this.selected_entries.add(entry); } - - clear_selected() { - this.set_selected(this.pwd(), false, false); + + deselect_one(entry) { + entry.unstyle_selected(); + this.selected_entries.delete(entry); + } + + /** + * + * @param {NavEntry} start + * @param {NavEntry} end + */ + select_range(start, end) { + let start_ind = this.entries.indexOf(start); + let end_ind = this.entries.indexOf(end); + if (start_ind === -1 || end_ind === -1) + return; + if (end_ind === start_ind) + this.select_one(start); + else if (end_ind < start_ind) + [start_ind, end_ind] = [end_ind, start_ind]; + for (let i = start_ind; i <= end_ind; i++) { + let entry = this.entries[i]; + if (entry.visible && (!entry.is_hidden_file || this.show_hidden)) + this.select_one(entry); + } + } + + reset_selection() { + this.clear_selected(); + this.select_one(this.pwd()); + this.last_selected_entry = null; + this.update_selection_info(); + } + + /** + * + * @param {NavEntry} target + * @param {Boolean} shift + * @param {Boolean} ctrl + */ + set_selected(target, shift, ctrl) { + if (!ctrl && !shift) + this.clear_selected(); + if (!shift || !this.last_selected_entry) + this.last_selected_entry = target; + if (shift) { + if (!ctrl) + this.clear_selected(); + this.select_range( + this.last_selected_entry ?? this.entries[0], + target + ); + } else if (ctrl && this.selected_entries.has(target)) { + this.deselect_one(target) + } else { + this.select_one(target); + } + this.update_selection_info(); + } + + select_all() { + this.select_range(this.entries[0], this.entries[this.entries.length - 1]); + this.update_selection_info(); } selected_entry() { @@ -255,6 +272,20 @@ export class NavWindow { this.selected_entry()?.show_properties?.(); } + update_selection_info() { + if (this.selected_entries.size > 1){ + var name_fields = document.getElementsByClassName("nav-info-column-filename"); + for (let name_field of name_fields) { + name_field.innerText = this.selected_entries.size.toString() + " selected" + name_field.title = name_field.innerText; + } + document.getElementById("nav-info-column-properties").innerHTML = ""; + } else { + console.log("Single selected"); + this.show_selected_properties(); + } + } + async show_edit_selected() { var dangerous_dirs = [ "/", @@ -808,15 +839,6 @@ export class NavWindow { this.set_nav_button_state(); } - select_all() { - this.selected_entries.clear(); - for (let entry of this.entries) { - if (!entry.is_hidden_file || this.show_hidden) { - this.set_selected(entry, false, true); - } - } - } - async switch_item_display() { var button = document.getElementById("nav-item-display-icon"); if (this.item_display === "grid") {