245 lines
6.6 KiB
JavaScript
245 lines
6.6 KiB
JavaScript
import { app } from "../../scripts/app.js";
|
|
|
|
const D2_QUEUE_DEFAULT_COUNT = "1,10";
|
|
|
|
/**
|
|
* Queue Button を作るクラス
|
|
*/
|
|
class D2_QueueButton {
|
|
static CSS_FILEPATH = "./extensions/D2-nodes-ComfyUI/css/D2_QueueButton.css";
|
|
static COOKIE_NAME = "D2_QueueButton_Pos";
|
|
static DEFAULT_LEFT = 50;
|
|
static DEFAULT_TOP = 50;
|
|
|
|
container = undefined;
|
|
buttonContainer = undefined;
|
|
|
|
constructor() {
|
|
D2_QueueButton._loadStyles();
|
|
this._createContainer();
|
|
this._createButtons();
|
|
|
|
// 表示切り替え
|
|
const visible = app.ui.settings.getSettingValue("D2.QueueButton.Visible", true);
|
|
this.changeVisible(visible);
|
|
|
|
// 初期位置
|
|
const pos = D2_QueueButton._getPosition();
|
|
this.container.style.left = pos[0] + "px";
|
|
this.container.style.top = pos[1] + "px";
|
|
|
|
// ウィンドウリサイズ対策
|
|
window.addEventListener("resize", () => {
|
|
this.resizeSetting();
|
|
});
|
|
this.resizeSetting();
|
|
}
|
|
|
|
/**
|
|
* ボタンリセット
|
|
*/
|
|
resetButton() {
|
|
this.buttonContainer.innerHTML = "";
|
|
this._createButtons();
|
|
}
|
|
|
|
/**
|
|
* 表示切り替え
|
|
*/
|
|
changeVisible(bool) {
|
|
this.container.style.display = bool ? "block" : "none";
|
|
}
|
|
|
|
///////////////////////////////////////////////
|
|
// private method
|
|
///////////////////////////////////////////////
|
|
/**
|
|
* ベース作成
|
|
*/
|
|
_createContainer() {
|
|
this.container = document.createElement("div");
|
|
this.container.classList.add("p-panel", "d2-queue-button");
|
|
document.querySelector("body").appendChild(this.container);
|
|
|
|
const content = document.createElement("div");
|
|
content.classList.add("p-panel-content", "flex", "flex-nowrap", "items-center", "d2-queue-button__content");
|
|
this.container.appendChild(content);
|
|
|
|
const dragHandle = document.createElement("span");
|
|
dragHandle.classList.add("drag-handle", "cursor-move", "mr-2");
|
|
content.appendChild(dragHandle);
|
|
|
|
this.buttonContainer = document.createElement("div");
|
|
this.buttonContainer.classList.add("flex", "flex-nowrap", "items-center", "d2-queue-button__button-container");
|
|
content.appendChild(this.buttonContainer);
|
|
|
|
// ドラッグ設定
|
|
this._dragSetting(dragHandle, this.container);
|
|
}
|
|
|
|
/**
|
|
* ボタン作成
|
|
*/
|
|
_createButtons() {
|
|
const counts = D2_QueueButton._getCounts();
|
|
|
|
counts.forEach((count) => {
|
|
const button = document.createElement("button");
|
|
button.classList.add("p-button");
|
|
button.textContent = count;
|
|
this.buttonContainer.appendChild(button);
|
|
|
|
button.addEventListener("click", function (event) {
|
|
app.queuePrompt(event.shiftKey ? -1 : 0, count);
|
|
});
|
|
});
|
|
}
|
|
|
|
/**
|
|
* 設定からボタン設定を読む
|
|
*/
|
|
static _getCounts(string) {
|
|
const setting = app.ui.settings.getSettingValue("D2.QueueButton.BatchCount", D2_QUEUE_DEFAULT_COUNT);
|
|
if (setting.trim() === "") return [];
|
|
|
|
return setting
|
|
.split(",")
|
|
.map((item) => item.trim())
|
|
.filter((item) => item !== "")
|
|
.map((item) => Number(item));
|
|
}
|
|
|
|
/**
|
|
* CSSを動的に読み込む
|
|
*/
|
|
static _loadStyles() {
|
|
const link = document.createElement("link");
|
|
link.rel = "stylesheet";
|
|
link.href = D2_QueueButton.CSS_FILEPATH;
|
|
document.head.appendChild(link);
|
|
}
|
|
|
|
/**
|
|
* 座標をcookieに記録
|
|
*/
|
|
static _savePosition(x, y) {
|
|
const jsonString = JSON.stringify([x, y]);
|
|
const encodedJsonString = encodeURIComponent(jsonString);
|
|
|
|
const farFuture = new Date();
|
|
farFuture.setFullYear(farFuture.getFullYear() + 100);
|
|
|
|
document.cookie = `${D2_QueueButton.COOKIE_NAME}=${encodedJsonString}; expires=${farFuture.toUTCString()}; path=/`;
|
|
}
|
|
|
|
/**
|
|
* 座標をcookieから取得
|
|
*/
|
|
static _getPosition() {
|
|
const cookies = document.cookie.split(";");
|
|
for (let cookie of cookies) {
|
|
cookie = cookie.trim();
|
|
if (cookie.startsWith(D2_QueueButton.COOKIE_NAME + "=")) {
|
|
const encodedJsonString = cookie.substring(D2_QueueButton.COOKIE_NAME.length + 1);
|
|
const jsonString = decodeURIComponent(encodedJsonString);
|
|
return JSON.parse(jsonString);
|
|
}
|
|
}
|
|
// Cookieが見つからない場合
|
|
return [D2_QueueButton.DEFAULT_LEFT, D2_QueueButton.DEFAULT_TOP];
|
|
}
|
|
|
|
/**
|
|
* ドラッグ設定
|
|
*/
|
|
_dragSetting(handle, container) {
|
|
let isDragging = false;
|
|
let startX, startY, initialLeft, initialTop;
|
|
|
|
// マウスダウンイベントリスナー
|
|
handle.addEventListener("mousedown", (e) => {
|
|
isDragging = true;
|
|
startX = e.clientX;
|
|
startY = e.clientY;
|
|
initialLeft = container.offsetLeft;
|
|
initialTop = container.offsetTop;
|
|
|
|
// テキスト選択を防止
|
|
e.preventDefault();
|
|
});
|
|
|
|
// マウスムーブイベントリスナー
|
|
document.addEventListener("mousemove", (e) => {
|
|
if (!isDragging) return;
|
|
|
|
const x = e.clientX - startX + initialLeft;
|
|
const y = e.clientY - startY + initialTop;
|
|
|
|
container.style.left = `${x}px`;
|
|
container.style.top = `${y}px`;
|
|
|
|
D2_QueueButton._savePosition(x, y);
|
|
});
|
|
|
|
// マウスアップイベントリスナー
|
|
document.addEventListener("mouseup", () => {
|
|
isDragging = false;
|
|
});
|
|
|
|
// マウスリーブイベントリスナー(ブラウザ外にマウスが出た場合)
|
|
document.addEventListener("mouseleave", () => {
|
|
isDragging = false;
|
|
});
|
|
}
|
|
|
|
/**
|
|
* ウィンドウリサイズ対策
|
|
*/
|
|
resizeSetting() {
|
|
const container = this.container;
|
|
const rect = container.getBoundingClientRect();
|
|
const viewportWidth = window.innerWidth || document.documentElement.clientWidth;
|
|
const viewportHeight = window.innerHeight || document.documentElement.clientHeight;
|
|
|
|
// 右端の調整
|
|
if (rect.right > viewportWidth) {
|
|
const newLeft = Math.max(0, viewportWidth - rect.width);
|
|
container.style.left = `${newLeft}px`;
|
|
} else if (rect.left < 0) {
|
|
container.style.left = '0px';
|
|
}
|
|
|
|
// 下端の調整
|
|
if (rect.bottom > viewportHeight) {
|
|
const newTop = Math.max(0, viewportHeight - rect.height);
|
|
container.style.top = `${newTop}px`;
|
|
} else if (rect.top < 0) {
|
|
container.style.top = '0px';
|
|
}
|
|
}
|
|
}
|
|
|
|
(function () {
|
|
const queueButton = new D2_QueueButton();
|
|
|
|
app.ui.settings.addSetting({
|
|
id: "D2.QueueButton.BatchCount",
|
|
name: "Batch count list",
|
|
type: "string",
|
|
defaultValue: D2_QUEUE_DEFAULT_COUNT,
|
|
onChange(value) {
|
|
queueButton.resetButton();
|
|
},
|
|
});
|
|
|
|
app.ui.settings.addSetting({
|
|
id: "D2.QueueButton.Visible",
|
|
name: "Show queue button",
|
|
type: "boolean",
|
|
defaultValue: true,
|
|
onChange(value) {
|
|
queueButton.changeVisible(value);
|
|
},
|
|
});
|
|
})();
|