Adding channel entry range selection for ealier multi channel select

canary
WolverinDEV 2020-12-04 14:44:10 +01:00
parent 6f460ae111
commit e9bf6a53d2
2 changed files with 59 additions and 22 deletions

View File

@ -3,6 +3,7 @@
- Properly logging channel creations, deletions, shows and hides - Properly logging channel creations, deletions, shows and hides
- Fixed missing collapsed arrow update after channel move - Fixed missing collapsed arrow update after channel move
- Added an option for mass channel subscription and unsubscription - Added an option for mass channel subscription and unsubscription
- Adding channel entry range selection for ealier multi channel select
* **03.12.20** * **03.12.20**
- Fixed server connection tab move handler - Fixed server connection tab move handler

View File

@ -13,7 +13,7 @@ import * as React from "react";
import {ChannelIconClass, ChannelIconsRenderer, RendererChannel} from "tc-shared/ui/tree/RendererChannel"; import {ChannelIconClass, ChannelIconsRenderer, RendererChannel} from "tc-shared/ui/tree/RendererChannel";
import {ClientIcon} from "svg-sprites/client-icons"; import {ClientIcon} from "svg-sprites/client-icons";
import {UnreadMarkerRenderer} from "tc-shared/ui/tree/RendererTreeEntry"; import {UnreadMarkerRenderer} from "tc-shared/ui/tree/RendererTreeEntry";
import {LogCategory, logError} from "tc-shared/log"; import {LogCategory, logError, logWarn} from "tc-shared/log";
import { import {
ClientIconsRenderer, ClientIconsRenderer,
ClientName, ClientName,
@ -78,12 +78,25 @@ export class RDPTreeSelection {
private readonly documentKeyListener; private readonly documentKeyListener;
private readonly documentBlurListener; private readonly documentBlurListener;
private shiftKeyPressed = false; private shiftKeyPressed = false;
private controlKeyPressed = false;
private rangeStartEntry: RDPEntry;
private rangeMode: "add" | "remove";
constructor(handle: RDPChannelTree) { constructor(handle: RDPChannelTree) {
this.handle = handle; this.handle = handle;
this.documentKeyListener = event => this.shiftKeyPressed = event.shiftKey; this.documentKeyListener = (event: KeyboardEvent) => {
this.documentBlurListener = () => this.shiftKeyPressed = false; this.shiftKeyPressed = event.shiftKey;
this.controlKeyPressed = event.ctrlKey;
};
this.documentBlurListener = (event: MouseEvent | FocusEvent) => {
if(event.relatedTarget === null || event.relatedTarget["nodeName"] === "HTML") {
this.shiftKeyPressed = false;
this.controlKeyPressed = false;
}
};
document.addEventListener("keydown", this.documentKeyListener); document.addEventListener("keydown", this.documentKeyListener);
document.addEventListener("keyup", this.documentKeyListener); document.addEventListener("keyup", this.documentKeyListener);
@ -115,7 +128,7 @@ export class RDPTreeSelection {
this.select([], "exclusive", false); this.select([], "exclusive", false);
} }
select(entries: RDPEntry[], mode: RDPTreeSelectType, selectMaintree: boolean) { select(entries: RDPEntry[], mode: RDPTreeSelectType, selectMainTree: boolean) {
entries = entries.filter(entry => !!entry); entries = entries.filter(entry => !!entry);
let deletedEntries: RDPEntry[] = []; let deletedEntries: RDPEntry[] = [];
@ -124,31 +137,56 @@ export class RDPTreeSelection {
if(mode === "exclusive") { if(mode === "exclusive") {
deletedEntries = this.selectedEntries.slice(); deletedEntries = this.selectedEntries.slice();
newEntries = entries; newEntries = entries;
this.rangeStartEntry = entries.last();
} else if(mode === "append") { } else if(mode === "append") {
newEntries = entries; newEntries = entries;
} else if(mode === "remove") { } else if(mode === "remove") {
deletedEntries = entries; deletedEntries = entries;
} else if(mode === "auto" || mode === "auto-add") { } else if(mode === "auto" || mode === "auto-add") {
if(this.shiftKeyPressed) { if(this.shiftKeyPressed && this.selectedEntries.length === 1) {
for(const entry of entries) { this.rangeStartEntry = this.selectedEntries[0];
const index = this.selectedEntries.findIndex(e => e === entry); this.rangeMode = "add";
if(index === -1) { }
newEntries.push(entry);
} else if(mode === "auto") { if(this.shiftKeyPressed && this.rangeStartEntry) {
deletedEntries.push(entry); const treeEntries = this.handle.getTreeEntries();
}
const targetEntry = entries.last();
if(!targetEntry) { return; }
let targetIndex = treeEntries.indexOf(targetEntry);
let sourceIndex = treeEntries.indexOf(this.rangeStartEntry);
if(sourceIndex === -1 || targetIndex === -1) { return; }
if(targetIndex < sourceIndex) {
const index = targetIndex;
targetIndex = sourceIndex;
sourceIndex = index;
}
const array = this.rangeMode === "add" ? newEntries : deletedEntries;
for(let index = sourceIndex; index <= targetIndex; index++) {
array.push(treeEntries[index]);
}
} else if(this.controlKeyPressed || this.shiftKeyPressed) {
const targetEntry = entries.last();
if(!targetEntry) { return; }
this.rangeStartEntry = targetEntry;
if(this.selectedEntries.indexOf(targetEntry) === -1 || mode === "auto-add") {
this.rangeMode = "add";
newEntries.push(targetEntry);
} else {
this.rangeMode = "remove";
deletedEntries.push(targetEntry);
} }
} else { } else {
this.rangeStartEntry = undefined;
deletedEntries = this.selectedEntries.slice(); deletedEntries = this.selectedEntries.slice();
if(entries.length !== 0) { newEntries = entries;
const entry = entries[entries.length - 1];
if(!deletedEntries.remove(entry)) {
newEntries.push(entry); /* entry wans't selected yet */
}
}
} }
} else { } else {
console.warn("Received entry select event with unknown mode: %s", mode); logWarn(LogCategory.CHANNEL, tr("Received entry select event with unknown mode: %s"), mode);
} }
newEntries.forEach(entry => deletedEntries.remove(entry)); newEntries.forEach(entry => deletedEntries.remove(entry));
@ -161,7 +199,6 @@ export class RDPTreeSelection {
} }
}); });
deletedEntries = deletedEntries.filter(entry => this.selectedEntries.remove(entry)); deletedEntries = deletedEntries.filter(entry => this.selectedEntries.remove(entry));
deletedEntries.forEach(entry => entry.setSelected(false)); deletedEntries.forEach(entry => entry.setSelected(false));
newEntries.forEach(entry => entry.setSelected(true)); newEntries.forEach(entry => entry.setSelected(true));
@ -174,7 +211,7 @@ export class RDPTreeSelection {
this.selectedEntries.sort((a, b) => lookupMap[a.entryId] - lookupMap[b.entryId]); this.selectedEntries.sort((a, b) => lookupMap[a.entryId] - lookupMap[b.entryId]);
} }
if(this.selectedEntries.length === 1 && selectMaintree) { if(this.selectedEntries.length === 1 && selectMainTree) {
this.handle.events.fire("action_select", { treeEntryId: this.selectedEntries[0].entryId }); this.handle.events.fire("action_select", { treeEntryId: this.selectedEntries[0].entryId });
} }
} }
@ -536,7 +573,6 @@ export class RDPChannelTree {
return; return;
} }
console.error("hint: %o", currentDragHint);
if(!currentDragHint || currentDragHint === "none") { if(!currentDragHint || currentDragHint === "none") {
return; return;
} }