({
- type: "fixed",
- key: key.value,
- value:
- modelEntries.find(([k]) => k === key.value)?.[1] ||
- newVarInputVal("str"),
- }));
-
- const editableEntries = modelEntries.filter(
- ([key]) => !fixedKeys.some((k) => k.value === key)
- );
-
return {
- fixedItems: fixedKeyValues,
- localItems: editableEntries.length
- ? editableEntries.map(([key, value]) => ({
- type: "editable",
- key,
- value,
- }))
- : [{ type: "editable", key: "", value: newVarInputVal("str") }],
- filterOptions: this.normalizeKeys(this.options?.optionKeys || []),
inputValue: "",
};
},
@@ -232,11 +213,49 @@ export default defineComponent({
this.updateModelValue();
},
},
+ normalizedOptionKeys() {
+ return this.filterOptions;
+ },
+ // 规范化的固定键列表
+ normalizedFixedKeys() {
+ return this.normalizeKeys(this.options?.fixedKeys || []);
+ },
+ // 从 modelValue 中提取的所有条目
+ modelEntries() {
+ return Object.entries(this.modelValue || {});
+ },
+ // 固定键项
+ fixedItems() {
+ return this.normalizedFixedKeys.map((key) => ({
+ type: "fixed",
+ key: key.value,
+ value:
+ this.modelEntries.find(([k]) => k === key.value)?.[1] ||
+ newVarInputVal("str"),
+ }));
+ },
+ // 可编辑项
+ localItems() {
+ // 过滤出不在固定键中的条目
+ const editableEntries = this.modelEntries.filter(
+ ([key]) => !this.normalizedFixedKeys.some((k) => k.value === key)
+ );
+
+ return editableEntries.length || this.options?.disableAdd
+ ? editableEntries.map(([key, value]) => ({
+ type: "editable",
+ key,
+ value,
+ }))
+ : [{ type: "editable", key: "", value: newVarInputVal("str") }];
+ },
+ // 所有项目的组合
allItems() {
return [...this.fixedItems, ...this.localItems];
},
- normalizedOptionKeys() {
- return this.filterOptions;
+ // 过滤选项
+ filterOptions() {
+ return this.normalizeKeys(this.options?.optionKeys || []);
},
},
methods: {
@@ -251,10 +270,7 @@ export default defineComponent({
getKeyLabel(key) {
if (typeof key === "object") return key.label;
- const allKeys = [
- ...this.normalizeKeys(this.options?.fixedKeys || []),
- ...this.normalizeKeys(this.options?.optionKeys || []),
- ];
+ const allKeys = [...this.normalizedFixedKeys, ...this.filterOptions];
return allKeys.find((k) => k.value === key)?.label || key;
},
@@ -280,62 +296,57 @@ export default defineComponent({
},
updateItemValue(val, index, isFixed = false) {
- if (isFixed) {
- const newItems = [...this.fixedItems];
- newItems[index].value = val;
- this.fixedItems = newItems;
- } else {
- const newItems = [...this.localItems];
- newItems[index].value = val;
- this.localItems = newItems;
+ const dict = { ...this.modelValue };
+ const item = this.allItems[index];
+ if (item.key) {
+ dict[item.key] = val;
+ this.$emit("update:modelValue", dict);
}
- this.updateModelValue();
},
addItem() {
- this.localItems = [
- ...this.localItems,
- {
- key: "",
- value: newVarInputVal("str"),
- },
- ];
+ if (this.options?.disableAdd) return;
+ const dict = { ...this.modelValue };
+ dict[""] = newVarInputVal("str");
+ this.$emit("update:modelValue", dict);
},
+
removeItem(index) {
- const newItems = [...this.localItems];
- newItems.splice(index, 1);
- if (newItems.length === 0) {
- newItems.push({
- key: "",
- value: newVarInputVal("str"),
- });
+ if (this.options?.disableAdd) return;
+ const dict = { ...this.modelValue };
+ const item = this.localItems[index];
+ if (item.key) {
+ delete dict[item.key];
+ this.$emit("update:modelValue", dict);
}
- this.localItems = newItems;
},
+
updateItemKey(val, index) {
- const newItems = [...this.localItems];
- newItems[index].key = val;
- this.localItems = newItems;
+ const dict = { ...this.modelValue };
+ const oldItem = this.localItems[index];
+ if (oldItem.key) {
+ delete dict[oldItem.key];
+ }
+ dict[val] = oldItem.value;
+ this.$emit("update:modelValue", dict);
},
+
handleInput(val, index) {
this.inputValue = val;
if (val) {
- const newItems = [...this.localItems];
- newItems[index].key = val;
- this.localItems = newItems;
- this.updateModelValue();
+ this.updateItemKey(val, index);
}
},
+
handleSelect(val, index) {
this.inputValue = "";
- const newItems = [...this.localItems];
- newItems[index].key = val.value || val;
- this.localItems = newItems;
- this.updateModelValue();
+ this.updateItemKey(val.value || val, index);
},
+
handleBlur() {
this.inputValue = "";
},
+
filterFn(val, update) {
if (!this.options?.optionKeys) return;
diff --git a/src/js/composer/commands/index.js b/src/js/composer/commands/index.js
index 41d362d..bf7c44c 100644
--- a/src/js/composer/commands/index.js
+++ b/src/js/composer/commands/index.js
@@ -11,6 +11,7 @@ import { codingCommands } from "./codingCommand";
import { mathCommands } from "./mathCommands";
import { userdataCommands } from "./userdataCommands";
import { utoolsCommands } from "./utoolsCommand";
+import { screenCommands } from "./screenCommands";
export const commandCategories = [
fileCommands,
@@ -25,5 +26,6 @@ export const commandCategories = [
simulateCommands,
mathCommands,
userdataCommands,
+ screenCommands,
otherCommands,
];
diff --git a/src/js/composer/commands/screenCommands.js b/src/js/composer/commands/screenCommands.js
new file mode 100644
index 0000000..8e0c9d5
--- /dev/null
+++ b/src/js/composer/commands/screenCommands.js
@@ -0,0 +1,126 @@
+import { newVarInputVal } from "js/composer/varInputValManager";
+
+const XY_DICT_EDITOR = {
+ label: "坐标",
+ type: "dictEditor",
+ icon: "transform",
+ isCollapse: false,
+ width: 12,
+ defaultValue: {
+ x: newVarInputVal("var", "0"),
+ y: newVarInputVal("var", "0"),
+ },
+ options: {
+ fixedKeys: [
+ { value: "x", label: "X坐标" },
+ { value: "y", label: "Y坐标" },
+ ],
+ disableAdd: true,
+ },
+};
+
+const RECT_DICT_EDITOR = {
+ label: "区域",
+ type: "dictEditor",
+ icon: "transform",
+ isCollapse: false,
+ width: 12,
+ defaultValue: {
+ x: newVarInputVal("var", "0"),
+ y: newVarInputVal("var", "0"),
+ width: newVarInputVal("var", "100"),
+ height: newVarInputVal("var", "100"),
+ },
+ options: {
+ fixedKeys: [
+ { value: "x", label: "X坐标" },
+ { value: "y", label: "Y坐标" },
+ { value: "width", label: "宽度" },
+ { value: "height", label: "高度" },
+ ],
+ disableAdd: true,
+ },
+};
+
+export const screenCommands = {
+ label: "显示器",
+ icon: "screenshot_monitor",
+ commands: [
+ {
+ value: "utools.getPrimaryDisplay",
+ label: "获取显示器信息",
+ desc: "获取显示器信息",
+ icon: "monitor",
+ outputVariable: "display",
+ saveOutput: true,
+ subCommands: [
+ {
+ value: "utools.getPrimaryDisplay",
+ label: "获取主显示器",
+ icon: "monitor",
+ },
+ {
+ value: "utools.getAllDisplays",
+ label: "获取所有显示器",
+ icon: "desktop_windows",
+ },
+ {
+ value: "utools.getDisplayNearestPoint",
+ label: "获取位置所在显示器",
+ icon: "gps_fixed",
+ config: [XY_DICT_EDITOR],
+ },
+ {
+ value: "utools.getDisplayMatching",
+ label: "获取矩形所在显示器",
+ icon: "crop_square",
+ config: [RECT_DICT_EDITOR],
+ },
+ ],
+ },
+ {
+ value: "utools.screenToDipPoint",
+ label: "物理/DIP坐标转换",
+ desc: "屏幕物理坐标和 DIP 坐标转换",
+ icon: "transform",
+ outputVariable: "{x,y}",
+ saveOutput: true,
+ config: [XY_DICT_EDITOR],
+ subCommands: [
+ {
+ value: "utools.screenToDipPoint",
+ label: "物理坐标转DIP坐标",
+ icon: "transform",
+ },
+ {
+ value: "utools.dipToScreenPoint",
+ label: "DIP坐标转物理坐标",
+ icon: "transform",
+ },
+ ],
+ },
+ {
+ value: "utools.screenToDipRect",
+ label: "物理/DIP区域转换",
+ desc: "屏幕物理区域和 DIP 区域转换",
+ icon: "transform",
+ outputVariable: "{x,y,width,height}",
+ saveOutput: true,
+ config: [RECT_DICT_EDITOR],
+ subCommands: [
+ {
+ value: "utools.screenToDipRect",
+ label: "物理区域转DIP区域",
+ desc: "屏幕物理区域转 DIP 区域",
+ icon: "transform",
+ },
+ {
+ value: "utools.dipToScreenRect",
+ label: "DIP区域转物理区域",
+ desc: "DIP 区域转屏幕物理区域",
+ icon: "transform",
+ },
+ ],
+ },
+ ],
+};
diff --git a/src/js/composer/commands/simulateCommands.js b/src/js/composer/commands/simulateCommands.js
index fa2a4ff..2057ea6 100644
--- a/src/js/composer/commands/simulateCommands.js
+++ b/src/js/composer/commands/simulateCommands.js
@@ -1,3 +1,5 @@
+import { newVarInputVal } from "js/composer/varInputValManager";
+
export const simulateCommands = {
label: "模拟操作",
icon: "ads_click",
@@ -185,5 +187,89 @@ export const simulateCommands = {
config: [],
isAsync: true,
},
+ {
+ value: "quickcomposer.simulate.screenColorPick",
+ label: "屏幕取色",
+ desc: "获取用户选择的颜色,会弹出一个系统取色器",
+ icon: "colorize",
+ isAsync: true,
+ outputVariable: "{hex,rgb}",
+ saveOutput: true,
+ },
+ {
+ value: "quickcomposer.simulate.captureScreen",
+ label: "屏幕截图",
+ desc: "屏幕截图,进行区域截图或全屏截图",
+ icon: "screenshot_monitor",
+ isAsync: true,
+ outputVariable: "base64Data",
+ saveOutput: true,
+ config: [
+ {
+ key: "range",
+ label: "截图范围",
+ type: "buttonGroup",
+ options: [
+ {
+ label: "全屏截图",
+ value: "fullscreen",
+ },
+ {
+ label: "区域截图",
+ value: "area",
+ },
+ ],
+ defaultValue: "fullscreen",
+ width: 12,
+ },
+ ],
+ subCommands: [
+ {
+ label: "保存到dataUrl",
+ value: "quickcomposer.simulate.captureScreen",
+ icon: "link",
+ },
+ {
+ label: "保存到文件",
+ value: "quickcomposer.simulate.captureScreenToFile",
+ icon: "file_copy",
+ config: [
+ {
+ key: "path",
+ label: "截图保存路径",
+ type: "varInput",
+ defaultValue: newVarInputVal(
+ "str",
+ `${window.utools.getPath("desktop")}${
+ utools.isWindows() ? "\\" : "/"
+ }quickcommand_screenshot.png`
+ ),
+ options: {
+ dialog: {
+ type: "save",
+ options: {
+ title: "选择保存路径",
+ properties: ["openFile", "showHiddenFiles"],
+ filters: [
+ {
+ name: "PNG",
+ extensions: ["png"],
+ },
+ ],
+ },
+ },
+ },
+ icon: "description",
+ width: 12,
+ },
+ ],
+ },
+ {
+ label: "复制到剪贴板",
+ value: "quickcomposer.simulate.captureScreenToClipboard",
+ icon: "content_copy",
+ },
+ ],
+ },
],
};
diff --git a/src/js/composer/commands/systemCommands.js b/src/js/composer/commands/systemCommands.js
index 138fa21..de2ba11 100644
--- a/src/js/composer/commands/systemCommands.js
+++ b/src/js/composer/commands/systemCommands.js
@@ -6,20 +6,75 @@ export const systemCommands = {
defaultOpened: false,
commands: [
{
- value: "electron.clipboard.writeText",
- label: "将内容写入剪贴板",
- config: [
+ value: "utools.copyText",
+ label: "写入剪贴板",
+ subCommands: [
{
- key: "content",
- label: "要写入剪切板的内容",
- type: "varInput",
+ value: "utools.copyText",
+ label: "写入文本",
icon: "content_copy",
+ config: [
+ {
+ key: "content",
+ label: "要写入剪切板的内容",
+ type: "varInput",
+ icon: "content_copy",
+ },
+ ],
+ },
+ {
+ value: "utools.copyImage",
+ label: "写入图片",
+ icon: "image",
+ config: [
+ {
+ key: "image",
+ label: "图片路径/base64",
+ type: "varInput",
+ icon: "image",
+ options: {
+ dialog: {
+ type: "open",
+ options: {
+ title: "选择图片",
+ properties: ["openFile", "showHiddenFiles"],
+ },
+ },
+ },
+ },
+ ],
+ },
+ {
+ value: "utools.copyFile",
+ label: "写入文件",
+ icon: "file_copy",
+ config: [
+ {
+ key: "file",
+ label: "文件路径",
+ type: "varInput",
+ icon: "file_copy",
+ options: {
+ dialog: {
+ type: "open",
+ options: {
+ title: "选择文件",
+ properties: [
+ "openFile",
+ "showHiddenFiles",
+ "multiSelections",
+ ],
+ },
+ },
+ },
+ },
+ ],
},
],
},
{
value: "electron.clipboard.readText",
- label: "获取剪贴板内容",
+ label: "读取剪贴板",
outputVariable: "clipboardContent",
saveOutput: true,
subCommands: [
@@ -33,6 +88,11 @@ export const systemCommands = {
label: "剪贴板图片",
icon: "image",
},
+ {
+ value: "utools.getCopyedFiles",
+ label: "剪贴板文件",
+ icon: "file_copy",
+ },
{
value: "electron.clipboard.readRTF",
label: "剪贴板RTF",
diff --git a/src/js/composer/commands/utoolsCommand.js b/src/js/composer/commands/utoolsCommand.js
index b7cc89d..a7d0267 100644
--- a/src/js/composer/commands/utoolsCommand.js
+++ b/src/js/composer/commands/utoolsCommand.js
@@ -110,6 +110,7 @@ export const utoolsCommands = {
type: "dictEditor",
icon: "settings",
options: {
+ disableAdd: true,
fixedKeys: [
{
value: "forward",