mirror of
https://github.com/fofolee/uTools-quickcommand.git
synced 2025-12-20 19:20:37 +08:00
可视化编排添加命令配置功能
This commit is contained in:
@@ -1,66 +0,0 @@
|
||||
const winScpt = `Add-Type -TypeDefinition @"
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
public class Win32 {
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct RECT {
|
||||
public int Left;
|
||||
public int Top;
|
||||
public int Right;
|
||||
public int Bottom;
|
||||
}
|
||||
[DllImport("user32.dll", SetLastError=true)]
|
||||
public static extern IntPtr GetForegroundWindow();
|
||||
[DllImport("user32.dll", SetLastError=true)]
|
||||
public static extern bool GetWindowRect(IntPtr hwnd, out RECT lpRect);
|
||||
}
|
||||
"@
|
||||
$foregroundWindow = [Win32]::GetForegroundWindow()
|
||||
$windowRect = New-Object Win32+RECT
|
||||
$_ = [Win32]::GetWindowRect($foregroundWindow, [ref]$windowRect)
|
||||
$result = New-Object PSObject
|
||||
$result | Add-Member -Type NoteProperty -Name Left -Value $windowRect.Left
|
||||
$result | Add-Member -Type NoteProperty -Name Top -Value $windowRect.Top
|
||||
$result | Add-Member -Type NoteProperty -Name Right -Value $windowRect.Right
|
||||
$result | Add-Member -Type NoteProperty -Name Bottom -Value $windowRect.Bottom
|
||||
$result | ConvertTo-Json`;
|
||||
|
||||
const macScpt = `tell application "System Events"
|
||||
set frontmostProcess to first application process where it is frontmost
|
||||
set frontmostWindow to first window of frontmostProcess
|
||||
set {windowLeft, windowTop} to position of frontmostWindow
|
||||
set {windowWidth, windowHeight} to size of frontmostWindow
|
||||
set windowRight to windowLeft + windowWidth
|
||||
set windowBottom to windowTop + windowHeight
|
||||
end tell
|
||||
return "{ \\"Left\\": " & windowLeft & ", \\"Top\\": " & windowTop & ", \\"Right\\": " & windowRight & ", \\"Bottom\\": " &windowBottom & " }"`;
|
||||
|
||||
const getForegroundWindowPos = async () => {
|
||||
let foregroundWindowPos;
|
||||
try {
|
||||
if (window.utools.isWindows()) {
|
||||
foregroundWindowPos = await window.quickcommand.runPowerShell(winScpt);
|
||||
} else if (window.utools.isMacOS()) {
|
||||
foregroundWindowPos = await window.quickcommand.runAppleScript(macScpt);
|
||||
}
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
}
|
||||
if (!foregroundWindowPos) return;
|
||||
return JSON.parse(foregroundWindowPos);
|
||||
};
|
||||
|
||||
let autoDetach = async () => {
|
||||
const foregroundWindowPos = await getForegroundWindowPos();
|
||||
console.log(foregroundWindowPos);
|
||||
if (foregroundWindowPos) {
|
||||
const { Left, Top, Right, Bottom } = foregroundWindowPos;
|
||||
let { x, y } = window.utools.getCursorScreenPoint();
|
||||
window.utools.simulateMouseDoubleClick(Left + 200, Top + 30);
|
||||
window.utools.simulateMouseMove(x, y);
|
||||
}
|
||||
};
|
||||
|
||||
export default {
|
||||
autoDetach,
|
||||
};
|
||||
@@ -2,6 +2,8 @@ import { reactive } from "vue";
|
||||
import quickcommandParser from "js/common/quickcommandParser.js";
|
||||
import importAll from "js/common/importAll.js";
|
||||
import utoolsFull from "js/utools.js";
|
||||
import { getUniqueId } from "js/common/uuid.js";
|
||||
import outputTypes from "js/options/outputTypes.js";
|
||||
|
||||
// 默认命令
|
||||
const defaultCommands = importAll(
|
||||
@@ -16,6 +18,50 @@ const state = reactive({
|
||||
activatedQuickPanels: [],
|
||||
});
|
||||
|
||||
const getCmdType = (cmds) => {
|
||||
const firstCmdType = cmds[0].type || "key";
|
||||
if (!cmds.find((x) => typeof x !== "string")) return "key";
|
||||
if (!cmds.find((x) => x.type !== firstCmdType)) return firstCmdType;
|
||||
return "professional";
|
||||
};
|
||||
|
||||
const getFeatureCode = (cmds) => {
|
||||
return `${getCmdType(cmds)}_${getUniqueId({ short: true })}`;
|
||||
};
|
||||
|
||||
const getLabeledCmds = (cmds, explain) => {
|
||||
return cmds.map((cmd) => {
|
||||
if (typeof cmd === "string") {
|
||||
return cmd || explain;
|
||||
}
|
||||
return {
|
||||
...cmd,
|
||||
label: cmd.label || explain,
|
||||
};
|
||||
});
|
||||
};
|
||||
|
||||
export const getValidCommand = (command) => {
|
||||
const { cmds, explain } = command.features;
|
||||
if (!explain) throw "名称不能为空";
|
||||
if (!Array.isArray(cmds)) throw "匹配规则格式错误";
|
||||
|
||||
// 未配置label或关键字时,直接使用名称
|
||||
command.features.cmds = getLabeledCmds(cmds, explain);
|
||||
|
||||
// 不需要显示输入框的输入类型,添加mainHide属性
|
||||
if (outputTypes[command.output].outPlugin) {
|
||||
command.features.mainHide = true;
|
||||
}
|
||||
|
||||
// 生成唯一code
|
||||
if (!command.features.code) {
|
||||
command.features.code = getFeatureCode(cmds);
|
||||
}
|
||||
|
||||
return window.lodashM.cloneDeep(command);
|
||||
};
|
||||
|
||||
// 使用函数工厂模式,确保每个组件获取自己的状态副本
|
||||
export function useCommandManager() {
|
||||
// 获取已启用的命令
|
||||
@@ -59,6 +105,11 @@ export function useCommandManager() {
|
||||
|
||||
// 保存命令
|
||||
const saveCommand = (command) => {
|
||||
try {
|
||||
command = getValidCommand(command);
|
||||
} catch (e) {
|
||||
return quickcommand.showMessageBox(e.toString(), "error");
|
||||
}
|
||||
const code = command.features.code;
|
||||
state.allQuickCommands[code] = command;
|
||||
|
||||
@@ -70,7 +121,7 @@ export function useCommandManager() {
|
||||
utoolsFull.whole.setFeature(command.features);
|
||||
|
||||
if (!isDefaultCommand(code)) {
|
||||
utoolsFull.putDB(window.lodashM.cloneDeep(command), "qc_" + code);
|
||||
utoolsFull.putDB(command, "qc_" + code);
|
||||
}
|
||||
|
||||
getAllQuickCommandTags();
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
export const getUniqueId = () => {
|
||||
return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, (c) => {
|
||||
export const getUniqueId = (options = {}) => {
|
||||
const { short = false } = options;
|
||||
const uuid = "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, (c) => {
|
||||
const r = (Math.random() * 16) | 0;
|
||||
const v = c === "x" ? r : (r & 0x3) | 0x8;
|
||||
return v.toString(16);
|
||||
});
|
||||
return short ? uuid.substring(0, 8) : uuid;
|
||||
};
|
||||
|
||||
@@ -133,3 +133,10 @@ export function generateCode(flow) {
|
||||
|
||||
return finalCode;
|
||||
}
|
||||
|
||||
export function generateFlowsCode(flows) {
|
||||
const [mainFlow, ...subFlows] = flows;
|
||||
return [...subFlows, mainFlow]
|
||||
.map((flow) => generateCode(flow))
|
||||
.join("\n\n");
|
||||
}
|
||||
|
||||
@@ -3,7 +3,8 @@
|
||||
*/
|
||||
|
||||
const jsonSample = [
|
||||
"关键词",
|
||||
"关键词1",
|
||||
"关键词2",
|
||||
{
|
||||
type: "img",
|
||||
label: "图片匹配",
|
||||
@@ -41,12 +42,12 @@ const jsonSample = [
|
||||
},
|
||||
];
|
||||
|
||||
const commandTypes = {
|
||||
export default {
|
||||
key: {
|
||||
name: "key",
|
||||
label: "关键词",
|
||||
icon: "font_download",
|
||||
color: "teal",
|
||||
color: "blue",
|
||||
matchLabel: "关键词",
|
||||
desc: "直接在主输入框输入对应关键字,最通用的一种模式,关键字可以设置多个",
|
||||
valueType: "array",
|
||||
@@ -57,7 +58,7 @@ const commandTypes = {
|
||||
},
|
||||
regex: {
|
||||
name: "regex",
|
||||
label: "正则/划词",
|
||||
label: "正则",
|
||||
icon: "rule",
|
||||
color: "cyan",
|
||||
matchLabel: "正则",
|
||||
@@ -82,7 +83,7 @@ const commandTypes = {
|
||||
over: {
|
||||
name: "over",
|
||||
label: "所有文本",
|
||||
matchLabel: "无需设置",
|
||||
matchLabel: "无需配置",
|
||||
icon: "emergency",
|
||||
color: "light-green",
|
||||
desc: "匹配主输入框的所有文本,但只有在该文本未设置对应的插件或功能时才生效",
|
||||
@@ -104,7 +105,7 @@ const commandTypes = {
|
||||
},
|
||||
window: {
|
||||
name: "window",
|
||||
label: "窗口/进程",
|
||||
label: "窗口",
|
||||
matchLabel: "进程名",
|
||||
icon: "widgets",
|
||||
color: "indigo",
|
||||
@@ -154,7 +155,7 @@ const commandTypes = {
|
||||
},
|
||||
files: {
|
||||
name: "files",
|
||||
label: "复制/选中文件",
|
||||
label: "文件",
|
||||
matchLabel: "正则",
|
||||
icon: "description",
|
||||
color: "light-blue",
|
||||
@@ -200,5 +201,3 @@ const commandTypes = {
|
||||
jsonSample: jsonSample,
|
||||
},
|
||||
};
|
||||
|
||||
export default commandTypes;
|
||||
|
||||
Reference in New Issue
Block a user