Files
JaredTherriault-ComfyUI-JNodes/web/js/ImageDrawer/BasicOptionManagerButtons/BatchSelectionManager.js
T
JaredTherriault f0338b0c5f Batch selection, batch deletion, classifying some scripts, module manager
-Added new batch selection and batch deletion features. All imageElements now have a checkbox and each selected element is tracked within a context or folder. When you've selected all you want to delete, click the recycle button on the toolbar, then again to confirm. All checked items will be recylced/deleted. You can also click on the selection widget next to the batch delete button to toggle select/deselect all.
-Renamed ImageDrawer.js to ImageDrawerMain.js
-Separated ImageListAndSearch out into separate scripts and classes named ImageDrawerList and ImageDrawerSearch
-Changed order of some initialized functions and variables in imageElements to better accommodate batch selection
-
-Moved some scripts over to a classy architecture. More scripts will be moved over time. This will eventually allow for multiple image drawer instances in the same window.
-Added a new module script that manages all class instances. See ImageDrawerModule.js for an explanation of the new architecture. Basically, it makes cyclical dependencies impossible.
-Updated imports
-Updated various scripts to use class instances where applicable
-Updated some outdated comments
-Added option to prepend or append labels to Labeled widgets
-Parameter optimizations
-
2024-05-07 20:39:40 -07:00

159 lines
4.9 KiB
JavaScript

import { $el } from "/scripts/ui.js";
import { ClassInstanceFactory, imageDrawerComponentManagerInstance } from "../Core/ImageDrawerModule.js";
import { BatchOptionManagerButton } from "./BatchOptionManagerButton.js";
class BatchSelectionManager extends BatchOptionManagerButton {
constructor(args) {
super(args);
this.selectionCheckbox = null;
this.countText = null;
this.lastCheckedItemCount = {};
this.onCheckedItemCountUpdatedMulticastFunctions = [];
}
makeWidget() {
const superWidget = super.makeWidget();
{
this.selectionCheckbox = $el("input.JNodes-image-drawer-menu-selection-manager-checkbox", {
title: "Toggle select/deselect all",
type: "checkbox",
checked: false,
style: {
pointerEvents: "none"
}
});
superWidget.button.appendChild(this.selectionCheckbox);
}
{
this.countText = $el("label", {
textContent: "(0)",
style: {
color: "white",
pointerEvents: "none"
}
});
superWidget.button.appendChild(this.countText)
}
this.updateWidget();
// Subscribe to imageList Changes
const imageDrawerListInstance = imageDrawerComponentManagerInstance.getComponentByName("ImageDrawerList");
imageDrawerListInstance.registerStartChangingImageListMulticastFunction(() => {
this.lastCheckedItemCount = { selectedCount: 0, totalItems: 0 };
this.notifyCheckedItemCountUpdatedMulticastDelegate();
const bUpdateCount = false;
this.updateWidget(bUpdateCount);
});
imageDrawerListInstance.registerFinishChangingImageListMulticastFunction(() => {
this.updateWidget();
});
return superWidget;
}
onClickButton() {
const counts = this.countCheckedItems();
let bNewCheckedState = true; // Default to select all
if (counts.selectedCount == counts.totalItems) {
// Deselect all
bNewCheckedState = false;
}
const imageDrawerListInstance = imageDrawerComponentManagerInstance.getComponentByName("ImageDrawerList");
const listChildren = imageDrawerListInstance.getImageListChildren();
for (const child of listChildren) {
if (child.setSelected) {
child.setSelected(bNewCheckedState, false); // Don't update this widget after each item, update it after all selections are changed
}
}
this.updateWidget();
}
countCheckedItems() {
const imageDrawerListInstance = imageDrawerComponentManagerInstance.getComponentByName("ImageDrawerList");
const listChildren = imageDrawerListInstance.getImageListChildren();
// Count up selected items in the current view
let selectedCount = 0;
for (const child of listChildren) {
if (child.bIsCheckboxSelectorChecked && child.bIsCheckboxSelectorChecked == true) {
selectedCount++;
}
}
this.lastCheckedItemCount = { selectedCount: selectedCount, totalItems: listChildren.length };
this.notifyCheckedItemCountUpdatedMulticastDelegate();
return this.lastCheckedItemCount;
}
registerCheckedItemCountUpdatedMulticastFunction(inFunction) {
if (typeof inFunction == "function") {
this.onCheckedItemCountUpdatedMulticastFunctions.push(inFunction);
}
}
notifyCheckedItemCountUpdatedMulticastDelegate() {
// Filter out invalid delegates
this.onCheckedItemCountUpdatedMulticastFunctions = this.onCheckedItemCountUpdatedMulticastFunctions.filter(func => func !== null && func !== undefined);
for (const func of this.onCheckedItemCountUpdatedMulticastFunctions) {
func(this.lastCheckedItemCount);
}
}
updateWidget(bUpdateCount = true) {
if (bUpdateCount) {
this.countCheckedItems();
}
// Set widget visibilities and text
this.selectionCheckbox.indeterminate = false;
if (this.lastCheckedItemCount.selectedCount == 0) {
this.selectionCheckbox.checked = false;
} else if (this.lastCheckedItemCount.selectedCount == this.lastCheckedItemCount.totalItems) {
this.selectionCheckbox.checked = true;
} else { // selectedCount < listChildren.length or perhaps some kind of computer rogue state
this.selectionCheckbox.indeterminate = true;
}
this.countText.textContent = `(${this.lastCheckedItemCount.selectedCount}/${this.lastCheckedItemCount.totalItems})`;
}
}
const factoryInstance = new ClassInstanceFactory(BatchSelectionManager, {
tooltipText: "Toggle select/deselect all", buttonClass: "JNodes-image-drawer-menu-selection-manager-button"
});