feat: selectie met toetsen toegevoegd
This commit is contained in:
+104
-3
@@ -7,6 +7,7 @@ let state = {
|
||||
selectedItems: [],
|
||||
visibleItems: [],
|
||||
currentRowIndex: -1,
|
||||
selectionAnchorIndex: null,
|
||||
},
|
||||
right: {
|
||||
currentPath: "/Volumes",
|
||||
@@ -15,6 +16,7 @@ let state = {
|
||||
selectedItems: [],
|
||||
visibleItems: [],
|
||||
currentRowIndex: -1,
|
||||
selectionAnchorIndex: null,
|
||||
},
|
||||
},
|
||||
activePane: "left",
|
||||
@@ -198,6 +200,14 @@ function setSelectedItem(pane, item) {
|
||||
updateActionButtons();
|
||||
}
|
||||
|
||||
function clearSelectionAnchor(pane) {
|
||||
paneState(pane).selectionAnchorIndex = null;
|
||||
}
|
||||
|
||||
function setSelectionAnchor(pane, index) {
|
||||
paneState(pane).selectionAnchorIndex = Number.isInteger(index) ? index : null;
|
||||
}
|
||||
|
||||
function selectedPaths(pane) {
|
||||
return paneState(pane).selectedItems.map((item) => item.path);
|
||||
}
|
||||
@@ -206,6 +216,11 @@ function setSingleSelection(pane, item) {
|
||||
setSelectedItem(pane, item);
|
||||
}
|
||||
|
||||
function setSingleSelectionAtIndex(pane, item, index) {
|
||||
setSingleSelection(pane, item);
|
||||
setSelectionAnchor(pane, index);
|
||||
}
|
||||
|
||||
function toggleSelection(pane, item) {
|
||||
const model = paneState(pane);
|
||||
const index = model.selectedItems.findIndex((selected) => selected.path === item.path);
|
||||
@@ -222,6 +237,43 @@ function toggleSelection(pane, item) {
|
||||
updateActionButtons();
|
||||
}
|
||||
|
||||
function toggleSelectionAtIndex(pane, item, index) {
|
||||
toggleSelection(pane, item);
|
||||
setSelectionAnchor(pane, index);
|
||||
}
|
||||
|
||||
function selectedEntryFromItem(entry) {
|
||||
return { path: entry.path, name: entry.name, kind: entry.kind };
|
||||
}
|
||||
|
||||
function setRangeSelection(pane, anchorIndex, currentIndex) {
|
||||
const model = paneState(pane);
|
||||
if (!Array.isArray(model.visibleItems) || model.visibleItems.length === 0) {
|
||||
return;
|
||||
}
|
||||
const start = Math.max(0, Math.min(anchorIndex, currentIndex));
|
||||
const end = Math.min(model.visibleItems.length - 1, Math.max(anchorIndex, currentIndex));
|
||||
model.selectedItems = model.visibleItems
|
||||
.slice(start, end + 1)
|
||||
.filter((entry) => !entry.isParent)
|
||||
.map((entry) => selectedEntryFromItem(entry));
|
||||
const current = model.visibleItems[currentIndex];
|
||||
model.selectedItem = current && !current.isParent ? selectedEntryFromItem(current) : (model.selectedItems[model.selectedItems.length - 1] || null);
|
||||
updateActionButtons();
|
||||
}
|
||||
|
||||
function isMacLike() {
|
||||
const platform = navigator.platform || navigator.userAgent || "";
|
||||
return /Mac|iPhone|iPad|iPod/i.test(platform);
|
||||
}
|
||||
|
||||
function isToggleModifierClick(event) {
|
||||
if (isMacLike()) {
|
||||
return !!event.metaKey && !event.ctrlKey && !event.shiftKey && !event.altKey;
|
||||
}
|
||||
return !!event.ctrlKey && !event.metaKey && !event.shiftKey && !event.altKey;
|
||||
}
|
||||
|
||||
function currentRowItem(pane) {
|
||||
const model = paneState(pane);
|
||||
if (!Array.isArray(model.visibleItems) || model.visibleItems.length === 0) {
|
||||
@@ -490,6 +542,7 @@ function renderPaneItems(pane) {
|
||||
up.onclick = () => {
|
||||
setActivePane(pane);
|
||||
model.currentRowIndex = index;
|
||||
clearSelectionAnchor(pane);
|
||||
renderPaneItems(pane);
|
||||
};
|
||||
up.append(document.createElement("span"));
|
||||
@@ -526,7 +579,7 @@ function renderPaneItems(pane) {
|
||||
row.onclick = () => {
|
||||
setActivePane(pane);
|
||||
model.currentRowIndex = index;
|
||||
setSingleSelection(pane, { path: entry.path, name: entry.name, kind: entry.kind });
|
||||
setSingleSelectionAtIndex(pane, { path: entry.path, name: entry.name, kind: entry.kind }, index);
|
||||
renderPaneItems(pane);
|
||||
};
|
||||
const checkbox = row.querySelector(".select-marker");
|
||||
@@ -535,7 +588,7 @@ function renderPaneItems(pane) {
|
||||
ev.stopPropagation();
|
||||
setActivePane(pane);
|
||||
model.currentRowIndex = index;
|
||||
toggleSelection(pane, { path: entry.path, name: entry.name, kind: entry.kind });
|
||||
toggleSelectionAtIndex(pane, { path: entry.path, name: entry.name, kind: entry.kind }, index);
|
||||
renderPaneItems(pane);
|
||||
};
|
||||
}
|
||||
@@ -553,10 +606,24 @@ function renderPaneItems(pane) {
|
||||
ev.stopPropagation();
|
||||
setActivePane(pane);
|
||||
model.currentRowIndex = index;
|
||||
setSingleSelection(pane, { path: entry.path, name: entry.name, kind: entry.kind });
|
||||
if (isToggleModifierClick(ev)) {
|
||||
toggleSelectionAtIndex(pane, { path: entry.path, name: entry.name, kind: entry.kind }, index);
|
||||
} else {
|
||||
setSingleSelectionAtIndex(pane, { path: entry.path, name: entry.name, kind: entry.kind }, index);
|
||||
}
|
||||
renderPaneItems(pane);
|
||||
};
|
||||
}
|
||||
row.onclick = (ev) => {
|
||||
setActivePane(pane);
|
||||
model.currentRowIndex = index;
|
||||
if (isToggleModifierClick(ev)) {
|
||||
toggleSelectionAtIndex(pane, { path: entry.path, name: entry.name, kind: entry.kind }, index);
|
||||
} else {
|
||||
setSingleSelectionAtIndex(pane, { path: entry.path, name: entry.name, kind: entry.kind }, index);
|
||||
}
|
||||
renderPaneItems(pane);
|
||||
};
|
||||
items.append(row);
|
||||
});
|
||||
updateActionButtons();
|
||||
@@ -606,6 +673,7 @@ function navigateTo(pane, path) {
|
||||
const model = paneState(pane);
|
||||
model.currentPath = path;
|
||||
model.currentRowIndex = 0;
|
||||
clearSelectionAnchor(pane);
|
||||
setSelectedItem(pane, null);
|
||||
loadBrowsePane(pane);
|
||||
}
|
||||
@@ -1290,6 +1358,27 @@ function moveCurrentRow(delta) {
|
||||
scrollCurrentRowIntoView(pane);
|
||||
}
|
||||
|
||||
function extendSelectionByRow(delta) {
|
||||
const pane = state.activePane;
|
||||
const model = paneState(pane);
|
||||
if (!Array.isArray(model.visibleItems) || model.visibleItems.length === 0) {
|
||||
model.currentRowIndex = -1;
|
||||
return;
|
||||
}
|
||||
const originalIndex = model.currentRowIndex < 0 ? 0 : model.currentRowIndex;
|
||||
if (model.currentRowIndex < 0) {
|
||||
model.currentRowIndex = 0;
|
||||
}
|
||||
if (!Number.isInteger(model.selectionAnchorIndex)) {
|
||||
model.selectionAnchorIndex = originalIndex;
|
||||
}
|
||||
const maxIndex = model.visibleItems.length - 1;
|
||||
model.currentRowIndex = Math.max(0, Math.min(maxIndex, model.currentRowIndex + delta));
|
||||
setRangeSelection(pane, model.selectionAnchorIndex, model.currentRowIndex);
|
||||
renderPaneItems(pane);
|
||||
scrollCurrentRowIntoView(pane);
|
||||
}
|
||||
|
||||
function jumpCurrentRow(edge) {
|
||||
const pane = state.activePane;
|
||||
const model = paneState(pane);
|
||||
@@ -1317,12 +1406,14 @@ function toggleCurrentSelection() {
|
||||
if (!item || item.isParent) {
|
||||
return;
|
||||
}
|
||||
setSelectionAnchor(pane, paneState(pane).currentRowIndex);
|
||||
toggleSelection(pane, { path: item.path, name: item.name, kind: item.kind });
|
||||
renderPaneItems(pane);
|
||||
}
|
||||
|
||||
function clearSelectionForActivePane() {
|
||||
const pane = state.activePane;
|
||||
clearSelectionAnchor(pane);
|
||||
setSelectedItem(pane, null);
|
||||
renderPaneItems(pane);
|
||||
}
|
||||
@@ -1415,11 +1506,21 @@ function handleKeyboardShortcuts(event) {
|
||||
return;
|
||||
}
|
||||
if (event.key === "ArrowUp") {
|
||||
if (event.shiftKey) {
|
||||
event.preventDefault();
|
||||
extendSelectionByRow(-1);
|
||||
return;
|
||||
}
|
||||
event.preventDefault();
|
||||
moveCurrentRow(-1);
|
||||
return;
|
||||
}
|
||||
if (event.key === "ArrowDown") {
|
||||
if (event.shiftKey) {
|
||||
event.preventDefault();
|
||||
extendSelectionByRow(1);
|
||||
return;
|
||||
}
|
||||
event.preventDefault();
|
||||
moveCurrentRow(1);
|
||||
return;
|
||||
|
||||
Reference in New Issue
Block a user