diff --git a/index.js b/index.js index 0b73603..c1a5f7c 100644 --- a/index.js +++ b/index.js @@ -4,6 +4,7 @@ // let g_sdapi_path = 'sdapi' let g_version = 'v1.1.9' let g_sd_url = 'http://127.0.0.1:7860' +const Enum = require('./enum') const helper = require('./helper') // let g_sdapi_path = 'sdapi_py_re' // const sdapi = require(`./${g_sdapi_path}`) @@ -3222,7 +3223,7 @@ async function silentImagesToLayersExe(images_info) { images_info.images_paths ) // Returns a Promise that resolves after "ms" Milliseconds - const timer = (ms) => new Promise((res) => setTimeout(res, ms)) + const timer = (ms) => new Promise((res) => setTimeout(res, ms)) //Todo: move this line to it's own utilit function for (image_info of images_info) { console.log(gCurrentImagePath) @@ -3342,113 +3343,30 @@ document.getElementById('collapsible').addEventListener('click', function () { function removeInitImageFromViewer() {} function removeMaskFromViewer() {} -async function NewViewerImageClickHandler(img, viewer_obj_owner) { - try { - img.addEventListener('click', async (e) => { - if (g_isViewerMenuDisabled) { - return g_isViewerMenuDisabled - } - - // e.target.classList.add("viewerImgSelected") - // viewer_obj_owner.isAccepted = true - // console.log("viewer_obj_owner: viewer_obj_owner.layer.name: ",viewer_obj_owner.layerName()) - // e.target.classList.toggle("viewerImgSelected") - // e.target.style.border="3px solid #6db579" - //turn off all layers - //select the layer this image represent and turn it on - - await executeAsModal(async () => { - // const img = e.target - // const layer_id = parseInt(img.dataset.image_id) - // console.log("the layer id = ",layer_id) - - // let selectedViewerImageObj - // Array.isArray(layer) - - //turn off all layers linked the viewer tab - - for (const [path, viewer_object] of Object.entries( - g_viewer_manager.pathToViewerImage - )) { - try { - if (viewer_object.getHighlight()) { - // viewer_object.state = viewer.ViewerObjState["Unlink"] - } else { - // viewer_object.state = viewer.ViewerObjState["Delete"] - } - viewer_object.visible(false) - viewer_object.active(false) - - // console.log("viewer_object.path: ",viewer_object.path) - // console.log("viewer_object.info(): ") - // viewer_object.info() - } catch (e) { - console.error('cannot hide a layer: ', e) - } - } - - // for(viewerImageObj of viewer_layers){ - // try{ - // //viewerImageObj.visible(false) - - // //make all layers of that entry invisible - // viewerImageObj.visible(false) - - // //if the layer id of the first layer in the group container - // //viewerImageObj.isSameLayer(layer_id) - // // if (viewerImageObj.isSameLayer(layer_id)){ - // // selectedViewerImageObj = viewerImageObj - // // } - // } catch (e){ - // console.error("cannot hide a layer: ",e) - // } - // } - - // selectedViewerImageObj.visible(true) - // selectedViewerImageObj.select(true) - // viewer_obj_owner.state = viewer.ViewerObjState['Unlink'] - viewer_obj_owner.visible(true) - await viewer_obj_owner.select(true) //select() does take arguments - viewer_obj_owner.active(true) - // console.log("viewer_obj_owner.path: ",viewer_obj_owner.path) - // console.log("viewer_obj_owner.info(): ") - // viewer_obj_owner.info() - if (e.shiftKey) { - try { - if (g_viewer_manager.last_selected_viewer_obj) { - //if the last selected layer is valid then converted last selected layer into highlight layer - g_viewer_manager.last_selected_viewer_obj.setHighlight( - true - ) - } - } catch (e) { - console.warn(e) - } - - viewer_obj_owner.setHighlight(true) - // e.target.classList.add("viewerImgSelected") - } else if (e.altKey) { - g_viewer_manager.last_selected_viewer_obj = null - viewer_obj_owner.setHighlight(false) - viewer_obj_owner.visible(false) - viewer_obj_owner.active(false) - - // await viewer_obj_owner.select(false) - await psapi.unselectActiveLayersExe() - // e.target.classList.remove("viewerImgSelected") - } - - if (viewer_obj_owner.isActive()) { - // will not store current viewer_obj if we click "alt" click if we hit alt click - - g_viewer_manager.last_selected_viewer_obj = viewer_obj_owner //store the current selection as last selection for the next click attempt . - } - }) - }) - } catch (e) { - console.warn(e) +async function viewerThumbnailclickHandler(e, viewer_obj_owner) { + if (g_isViewerMenuDisabled) { + return g_isViewerMenuDisabled } + + let click_type = Enum.clickTypeEnum['Click'] + if (e.shiftKey) { + click_type = Enum.clickTypeEnum['ShiftClick'] + } else if (e.altKey) { + click_type = Enum.clickTypeEnum['AltClick'] + } + await executeAsModal(async () => { + //get type of click + + await viewer_obj_owner.click(click_type) + }) } +// async function NewViewerImageClickHandler(img, viewer_obj_owner) { +// try { + +// } catch (e) { +// console.warn(e) +// } +// } function createViewerImgHtml(output_dir_relative, image_path, base64_image) { const img = document.createElement('img') // img.src = `${output_dir_relative}/${image_path}` @@ -3549,7 +3467,10 @@ async function loadViewerImages() { init_image_container.appendChild(init_img_html) initImage.setImgHtml(init_img_html) - await NewViewerImageClickHandler(init_img_html, initImage) // create click handler for each images + init_img_html.addEventListener('click', async (e) => { + await viewerThumbnailclickHandler(e, initImage) + }) + // await NewViewerImageClickHandler(init_img_html, initImage) // create click handler for each images } } } @@ -3583,7 +3504,12 @@ async function loadViewerImages() { mask_container.appendChild(mask_img_html) mask_obj.setImgHtml(mask_img_html) - await NewViewerImageClickHandler(mask_img_html, mask_obj) // create click handler for each images ,viewer_layers)// create click handler for each images + // await NewViewerImageClickHandler(mask_img_html, mask_obj) // create click handler for each images ,viewer_layers)// create click handler for each images + + mask_img_html.addEventListener('click', async (e) => { + await viewerThumbnailclickHandler(e, mask_obj) + }) + // await viewerImageClickHandler(mask_img_html,viewer_layers)// create click handler for each images } } @@ -3616,14 +3542,20 @@ async function loadViewerImages() { } output_image_container.appendChild(output_image_obj.img_html) //add on click event handler to the html img - await NewViewerImageClickHandler(img, output_image_obj) + // await NewViewerImageClickHandler(img, output_image_obj) + img.addEventListener('click', async (e) => { + await viewerThumbnailclickHandler(e, output_image_obj) + }) } // i++ } if (lastOutputImage) { //select the last generate/output image - lastOutputImage.img_html.click() + // lastOutputImage.img_html.click() + executeAsModal(async () => { + await lastOutputImage.click(Enum.clickTypeEnum['Click']) + }) } } catch (e) { console.error(`loadViewer images: `, e) diff --git a/viewer.js b/viewer.js index 73b1be7..c6b13a2 100644 --- a/viewer.js +++ b/viewer.js @@ -3,13 +3,13 @@ // * image layer // * viewer() // * select() -// * isLayerValid() + // * init image class: has three layers // * path : // * init image group layer // * init image layer // * background layer -// * isLayerValid() + // * mask class: // * path // * mask group @@ -17,10 +17,9 @@ // * balck layer // * select() // * viewe() -// * isLayerValid() - +const Enum = require('./enum') const psapi = require('./psapi') - +const layer_util = require('./utility/layer') const ViewerObjState = { Delete: 'delete', Unlink: 'unlink', @@ -31,12 +30,13 @@ class ViewerImage { this.img_html = null this.is_highlighted = false this.can_highlight = true - this.is_active = false // active is a temporary highlight + this.is_active = false // active is a temporary highlight , the yellow/orang highlight this.state = ViewerObjState['Unlink'] // true will delete the layers from the layer stacks when the session ends, // false mean use this.state to determine whither you delete the layer or not this.autoDelete = false + this.viewerManager = null // store link to the viewer manager of this document } info() { console.log('state: ', this.state) @@ -66,7 +66,7 @@ class ViewerImage { setAutoDelete(auto_delete) { this.autoDelete = auto_delete } - isLayerValid() {} + isSameLayer(layer_id) {} setHighlight(is_highlighted) { if (this.can_highlight) { @@ -179,13 +179,56 @@ class ViewerImage { } class OutputImage extends ViewerImage { - constructor(layer, path) { + constructor(layer, path, viewer_manager) { super() this.layer = layer this.path = path this.img_html = null + this.viewerManager = viewer_manager + } + async click(click_type) { + console.log('click_type: ', click_type) + if (this.isActive() && click_type === Enum.clickTypeEnum['Click']) { + //convert consecutive clicks to AltClick + click_type = Enum.clickTypeEnum['SecondClick'] + console.log('converted click_type: ', click_type) + } + + if (click_type === Enum.clickTypeEnum['Click']) { + //select layer + //turn the layer visible + //set the layer to active + this.visible(true) + await this.select(true) //select() does take arguments + this.active(true) + } else if (click_type === Enum.clickTypeEnum['ShiftClick']) { + this.visible(true) + await this.select(true) //select() does take arguments + this.setHighlight(true) + this.active(true) + // if (this.viewerManager.last_selected_viewer_obj) { + // //if the last selected layer is valid then converted last selected layer into highlight layer + // this.viewerManager.last_selected_viewer_obj.setHighlight(true) + // } + } else if (click_type === Enum.clickTypeEnum['AltClick']) { + // this.viewerManager.last_selected_viewer_obj = null + this.setHighlight(false) + this.visible(false) + this.active(false) + + await psapi.unselectActiveLayersExe() //Note:can we move to ViewerManager.click() + } else if (click_type === Enum.clickTypeEnum['SecondClick']) { + //select layer + //turn the layer visible + //set the layer to active + this.visible(false) + await this.select(false) //select() does take arguments + this.active(false) + } + this.viewerManager.replaceLastSelection(click_type, this) //pass the click_type and this object } visible(visibleOn) { + //turn the visibility for the layer try { super.visible(visibleOn) if (layer_util.Layer.doesLayerExist(this.layer)) { @@ -196,28 +239,28 @@ class OutputImage extends ViewerImage { } } async select() { + //select the layer super.select() if (layer_util.Layer.doesLayerExist(this.layer)) { await psapi.selectLayersExe([this.layer]) // console.log(`${this.layer.id} got selected`); } } - isLayerValid() { - super.isLayerValid() - //check if layer is defined or not - //true if the layer is defined - //false otherwise - let isValid = false - if (typeof this.layer !== 'undefined' && this.layer) { - isValid = true - } - return isValid - } + isSameLayer(layer_id) { super.isSameLayer(layer_id) const is_same = this.layer.id == layer_id return is_same } + isSameObject(object) { + if ( + layer_util.Layer.doesLayerExist(this.layer) && + layer_util.Layer.doesLayerExist(object.layer) + ) { + return this.layer.id === object.layer.id + } + return false + } setImgHtml(img_html) { super.setImgHtml() @@ -251,7 +294,7 @@ class OutputImage extends ViewerImage { } class InitImage extends ViewerImage { - constructor(init_group, init_snapshot, solid_layer, path) { + constructor(init_group, init_snapshot, solid_layer, path, viewer_manager) { super() this.init_group = init_group this.init_snapshot = init_snapshot @@ -259,15 +302,46 @@ class InitImage extends ViewerImage { this.path = path this.can_highlight = false - + this.viewerManager = viewer_manager // if (this.autoDelete === false){ // this.state = ViewerObjState['Unlink'] // } } + async click(click_type) { + if (click_type === Enum.clickTypeEnum['Click']) { + //select layer + //turn the layer visible + //set the layer to active + this.visible(true) + await this.select(true) //select() does take arguments + this.active(true) + click_type = Enum.clickTypeEnum['Click'] // convert all click to Click + this.viewerManager.replaceLastSelection(click_type, this) //pass the click_type and this object + } else if (click_type === Enum.clickTypeEnum['ShiftClick']) { + this.visible(true) + await this.select(true) //select() does take arguments + this.active(true) + // if (this.viewerManager.last_selected_viewer_obj) { + // //if the last selected layer is valid then converted last selected layer into highlight layer + // this.viewerManager.last_selected_viewer_obj.setHighlight(true) + // } + click_type = Enum.clickTypeEnum['Click'] // convert all click to Click + this.viewerManager.replaceLastSelection(click_type, this) //pass the click_type and this object + } + // else if (click_type === Enum.clickTypeEnum['AltClick']) { + // // this.viewerManager.last_selected_viewer_obj = null + // this.setHighlight(false) + // this.visible(false) + // this.active(false) + + // await psapi.unselectActiveLayersExe() //Note:can we move to ViewerManager.click() + // } + // this.viewerManager.replaceLastSelection(click_type, this) //pass the click_type and this object + } visible(visibleOn) { try { super.visible(visibleOn) - // const isValid = this.isLayerValid() + let visibleValues = [] if (visibleOn) { visibleValues = [true, true, true] @@ -302,38 +376,18 @@ class InitImage extends ViewerImage { super.select() const selectLayers = [] - if (this.isLayerValid(this.init_group)) { + if (layer_util.Layer.doesLayerExist(this.init_group)) { selectLayers.push(this.init_group) } - // if (this.isLayerValid(this.init_snapshot)) { - - // selectLayers.push(this.init_snapshot) - // } - // if (this.isLayerValid(this.solid_layer)) { - // selectLayers.push(this.solid_layer) - // } await psapi.selectLayersExe(selectLayers) // console.log(`${this.layer.id} got selected`); } - isLayerValid(layer) { - super.isLayerValid() - //check if layer is defined or not - //true if the layer is defined - //false otherwise - // let isValid = [false,false,false] - let isValid = false - if (typeof layer !== 'undefined' && layer) { - isValid = true - } - - return isValid - } isSameLayer(layer_id) { super.isSameLayer(layer_id) let is_same = false - if (this.isLayerValid(this.init_group)) { + if (layer_util.Layer.doesLayerExist(this.init_group)) { is_same = this.init_group.id == layer_id } return is_same @@ -367,7 +421,7 @@ class InitImage extends ViewerImage { } class InitMaskImage extends ViewerImage { - constructor(mask_group, white_mark, solid_black, path) { + constructor(mask_group, white_mark, solid_black, path, viewer_manager) { super() this.mask_group = mask_group this.white_mark = white_mark @@ -375,11 +429,34 @@ class InitMaskImage extends ViewerImage { this.path = path this.can_highlight = false + this.viewerManager = viewer_manager + } + async click(click_type) { + if (click_type === Enum.clickTypeEnum['Click']) { + //select layer + //turn the layer visible + //set the layer to active + this.visible(true) + await this.select(true) //select() does take arguments + this.active(true) + click_type = Enum.clickTypeEnum['Click'] // convert all click to Click + this.viewerManager.replaceLastSelection(click_type, this) //pass the click_type and this object + } else if (click_type === Enum.clickTypeEnum['ShiftClick']) { + this.visible(true) + await this.select(true) //select() does take arguments + this.active(true) + // if (this.viewerManager.last_selected_viewer_obj) { + // //if the last selected layer is valid then converted last selected layer into highlight layer + // this.viewerManager.last_selected_viewer_obj.setHighlight(true) + // } + click_type = Enum.clickTypeEnum['Click'] // convert all click to Click + this.viewerManager.replaceLastSelection(click_type, this) //pass the click_type and this object + } } visible(visibleOn) { try { super.visible(visibleOn) - // const isValid = this.isLayerValid() + let visibleValues = [] if (visibleOn) { visibleValues = [true, true, false] @@ -414,23 +491,10 @@ class InitMaskImage extends ViewerImage { // console.log(`${this.layer.id} got selected`); } - isLayerValid(layer) { - super.isLayerValid() - //check if layer is defined or not - //true if the layer is defined - //false otherwise - // let isValid = [false,false,false] - let isValid = false - if (typeof layer !== 'undefined' && layer) { - isValid = true - } - - return isValid - } isSameLayer(layer_id) { super.isSameLayer(layer_id) let is_same = false - if (this.isLayerValid(this.mask_group)) { + if (layer_util.Layer.doesLayerExist(this.mask_group)) { is_same = this.mask_group.id == layer_id } return is_same @@ -484,6 +548,8 @@ class ViewerManager { this.pathToViewerImage = {} // quick way to check if an link image path on disk to ViewerImage object. this.initImageLayersJson = {} //{path: initImageLayers} + this.selectedOutputImages = {} //store the selected output images {path: outputImage} + this.mask_layer this.maskLayersJson = {} //{path: MaskLayers} @@ -496,6 +562,32 @@ class ViewerManager { //last_selected_obj this.last_selected_viewer_obj } + + replaceLastSelection(click_type, clicked_object) { + if ( + this.last_selected_viewer_obj + // clicked_object instanceof OutputImage && + // !clicked_object.isSameObject(this.last_selected_viewer_obj) + ) { + //if the current selection and the last selection are different + + this.last_selected_viewer_obj.visible(false) + this.last_selected_viewer_obj.active(false) + } + if (click_type === Enum.clickTypeEnum['Click']) { + this.last_selected_viewer_obj = clicked_object + } else if (click_type === Enum.clickTypeEnum['ShiftClick']) { + if (this.last_selected_viewer_obj) { + //if the last selected layer is valid then converted last selected layer into highlight layer + this.last_selected_viewer_obj.setHighlight(true) + } + this.last_selected_viewer_obj = clicked_object + } else if (click_type === Enum.clickTypeEnum['AltClick']) { + this.last_selected_viewer_obj = null + } else if (click_type === Enum.clickTypeEnum['SecondClick']) { + this.last_selected_viewer_obj = null + } + } initializeInitImage(group, snapshot, solid_background, path) { this.initGroup = group this.init_solid_background = solid_background @@ -559,14 +651,20 @@ class ViewerManager { return false } addOutputImage(layer, path) { - const outputImage = new OutputImage(layer, path) + const outputImage = new OutputImage(layer, path, this) this.outputImages.push(outputImage) this.pathToViewerImage[path] = outputImage // return outputImage } addInitImage(group, snapshot, solid_background, path, auto_delete) { - const initImage = new InitImage(group, snapshot, solid_background, path) + const initImage = new InitImage( + group, + snapshot, + solid_background, + path, + this + ) initImage.setAutoDelete(auto_delete) this.initImages.push(initImage) this.pathToViewerImage[path] = initImage @@ -577,7 +675,8 @@ class ViewerManager { group, white_mark, solid_background, - path + path, + this ) this.initMaskImage = mask