mirror of
https://github.com/fofolee/uTools-quickcommand.git
synced 2025-06-29 12:22:44 +08:00
355 lines
8.5 KiB
Vue
355 lines
8.5 KiB
Vue
<template>
|
|
<q-btn-dropdown
|
|
flat
|
|
dense
|
|
stretch
|
|
size="sm"
|
|
:dropdown-icon="icon"
|
|
:no-icon-animation="icon !== 'arrow_drop_down'"
|
|
@click="({ variables, functions } = getAvailableVariablesAndFunctions())"
|
|
>
|
|
<q-list class="variable-list">
|
|
<template v-if="variables.length || functions.length">
|
|
<div v-if="variables.length && showVariableList">
|
|
<q-item-label header class="variable-label">
|
|
<q-separator class="separator-left" />
|
|
<div class="label-content">
|
|
<span>变量</span>
|
|
</div>
|
|
<q-separator class="separator-right" />
|
|
</q-item-label>
|
|
<q-item
|
|
v-for="variable in variables"
|
|
:key="variable.name"
|
|
clickable
|
|
v-close-popup
|
|
@click="insertValue(variable.name)"
|
|
class="variable-item"
|
|
>
|
|
<q-item-section>
|
|
<q-item-label class="variable-name">
|
|
{{ variable.name }}
|
|
</q-item-label>
|
|
<q-item-label
|
|
caption
|
|
class="variable-source"
|
|
v-if="variable.sourceCommand"
|
|
>
|
|
<span>
|
|
{{ variable.type === "global" ? "全局变量:" : "来自:" }}
|
|
</span>
|
|
<span>{{ variable.sourceCommand.label }}</span>
|
|
</q-item-label>
|
|
</q-item-section>
|
|
<q-tooltip
|
|
anchor="center left"
|
|
self="center end"
|
|
v-if="variable.description"
|
|
>
|
|
<div
|
|
v-text="variable.description"
|
|
class="variable-description"
|
|
></div>
|
|
</q-tooltip>
|
|
</q-item>
|
|
</div>
|
|
<div v-if="functions.length && showFunctionList">
|
|
<q-item-label header class="variable-label">
|
|
<q-separator class="separator-left" />
|
|
<div class="label-content">
|
|
<span>函数</span>
|
|
</div>
|
|
<q-separator class="separator-right" />
|
|
</q-item-label>
|
|
<q-item
|
|
v-for="func in functions"
|
|
:key="func.id"
|
|
clickable
|
|
v-close-popup
|
|
@click="insertValue(func.name + getInsertFunctionParams(func.id))"
|
|
class="variable-item"
|
|
>
|
|
<q-item-section>
|
|
<q-item-label class="variable-name">
|
|
{{ func.name }}
|
|
</q-item-label>
|
|
<q-item-label caption class="row item">
|
|
{{ func.label }}
|
|
</q-item-label>
|
|
</q-item-section>
|
|
</q-item>
|
|
</div>
|
|
</template>
|
|
<template v-else>
|
|
<q-item dense>
|
|
<q-item-section>
|
|
<div class="empty-tip">
|
|
<!-- 主要提示 -->
|
|
<div class="tip-header">
|
|
<q-icon name="info" size="16px" class="text-grey-6" />
|
|
<span>当前没有可用的变量或函数</span>
|
|
</div>
|
|
|
|
<q-separator spaced />
|
|
|
|
<!-- 添加方法提示 -->
|
|
<div class="tip-content">
|
|
<!-- 变量添加方法 -->
|
|
<div class="tip-section">
|
|
<div class="section-title">
|
|
<q-icon
|
|
name="data_object"
|
|
size="16px"
|
|
class="text-primary"
|
|
/>
|
|
<span>添加变量</span>
|
|
</div>
|
|
<div class="section-items">
|
|
<div class="item">
|
|
<span>命令右上角</span>
|
|
<q-badge color="primary">
|
|
<q-icon name="output" size="10px" />
|
|
</q-badge>
|
|
<span>按钮</span>
|
|
</div>
|
|
<div class="item">
|
|
<span>标签栏右侧</span>
|
|
<q-badge color="primary">
|
|
<q-icon name="settings" size="10px" />
|
|
</q-badge>
|
|
<span>按钮</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<q-separator vertical spaced />
|
|
|
|
<!-- 函数添加方法 -->
|
|
<div class="tip-section">
|
|
<div class="section-title">
|
|
<q-icon name="functions" size="16px" class="text-primary" />
|
|
<span>添加函数</span>
|
|
</div>
|
|
<div class="section-items">
|
|
<div class="item">
|
|
<span>主流程右侧</span>
|
|
<q-badge color="primary">
|
|
<q-icon name="add" size="10px" />
|
|
</q-badge>
|
|
<span>按钮</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</q-item-section>
|
|
</q-item>
|
|
</template>
|
|
</q-list>
|
|
</q-btn-dropdown>
|
|
</template>
|
|
|
|
<script>
|
|
import { defineComponent, inject } from "vue";
|
|
|
|
export default defineComponent({
|
|
name: "VariableList",
|
|
emits: ["emitValue"],
|
|
setup(props) {
|
|
const getCurrentVariables = inject("getCurrentVariables");
|
|
const commandIndex = inject("commandIndex", null);
|
|
|
|
const getAvailableVariables = () => {
|
|
let variables = getCurrentVariables();
|
|
if (!props.showGlobalVariables) {
|
|
variables = variables.filter((variable) => variable.type !== "global");
|
|
}
|
|
const usableVariables = variables.filter((variable) =>
|
|
// 输出变量只显示在当前命令之前的
|
|
variable.type === "output"
|
|
? variable.sourceCommand.index < commandIndex.value
|
|
: // 参数和局部变量显示所有
|
|
true
|
|
);
|
|
// 去除名称重复的变量,只保留最新的
|
|
return [...new Map(usableVariables.map((v) => [v.name, v])).values()];
|
|
};
|
|
|
|
const getCurrentFunctions = inject("getCurrentFunctions");
|
|
|
|
const getAvailableVariablesAndFunctions = () => {
|
|
return {
|
|
variables: getAvailableVariables(),
|
|
functions: getCurrentFunctions(),
|
|
};
|
|
};
|
|
|
|
const getFunctionParams = inject("getFunctionParams");
|
|
|
|
return {
|
|
getAvailableVariablesAndFunctions,
|
|
getFunctionParams,
|
|
};
|
|
},
|
|
data() {
|
|
return {
|
|
variables: [],
|
|
functions: [],
|
|
};
|
|
},
|
|
methods: {
|
|
insertValue(value) {
|
|
this.$emit("emitValue", "var", value);
|
|
},
|
|
getInsertFunctionParams(funcId) {
|
|
return (
|
|
"(" +
|
|
this.getFunctionParams(funcId)
|
|
.map((p) => p.name)
|
|
.join(", ") +
|
|
")"
|
|
);
|
|
},
|
|
},
|
|
props: {
|
|
showGlobalVariables: {
|
|
type: Boolean,
|
|
default: true,
|
|
},
|
|
showVariableList: {
|
|
type: Boolean,
|
|
default: true,
|
|
},
|
|
showFunctionList: {
|
|
type: Boolean,
|
|
default: true,
|
|
},
|
|
icon: {
|
|
type: String,
|
|
default: "arrow_drop_down",
|
|
},
|
|
},
|
|
});
|
|
</script>
|
|
|
|
<style scoped>
|
|
/* 基础样式 */
|
|
.variable-list {
|
|
padding: 4px;
|
|
}
|
|
|
|
/* 变量列表项 */
|
|
.variable-item {
|
|
border-radius: 4px;
|
|
padding: 0 16px;
|
|
min-height: 32px;
|
|
text-align: center;
|
|
transition: all 0.3s ease;
|
|
}
|
|
|
|
.variable-item:hover {
|
|
background: var(--q-primary-opacity-10);
|
|
}
|
|
|
|
/* 变量标签 */
|
|
.variable-label {
|
|
padding: 4px 8px;
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 4px;
|
|
font-size: 13px;
|
|
}
|
|
|
|
.label-content {
|
|
padding: 0 8px;
|
|
white-space: nowrap;
|
|
}
|
|
|
|
.separator-left,
|
|
.separator-right {
|
|
min-width: 32px;
|
|
flex: 1;
|
|
}
|
|
|
|
/* 变量名称和来源 */
|
|
.variable-name {
|
|
font-size: 12px;
|
|
font-weight: 500;
|
|
}
|
|
|
|
.variable-source {
|
|
font-size: 11px;
|
|
opacity: 0.7;
|
|
margin-top: 0;
|
|
}
|
|
|
|
/* 空状态提示 */
|
|
.empty-tip {
|
|
padding: 6px;
|
|
min-width: 260px;
|
|
font-size: 12px;
|
|
}
|
|
|
|
.tip-header {
|
|
padding: 2px 6px;
|
|
color: var(--q-grey-7);
|
|
}
|
|
|
|
.tip-content {
|
|
padding: 0 6px;
|
|
gap: 12px;
|
|
}
|
|
|
|
.tip-section {
|
|
flex: 1;
|
|
}
|
|
|
|
/* 通用布局 */
|
|
.tip-header,
|
|
.tip-content,
|
|
.section-title,
|
|
.item {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 4px;
|
|
justify-content: center;
|
|
}
|
|
|
|
.tip-content {
|
|
align-items: flex-start;
|
|
}
|
|
|
|
.section-title {
|
|
padding: 4px;
|
|
color: var(--q-primary);
|
|
font-weight: 500;
|
|
}
|
|
|
|
.section-items {
|
|
padding-left: 4px;
|
|
}
|
|
|
|
.item {
|
|
padding: 2px 0;
|
|
color: var(--q-grey-7);
|
|
}
|
|
|
|
.body--dark .variable-item:hover {
|
|
background: rgba(255, 255, 255, 0.1);
|
|
}
|
|
|
|
.body--dark .item {
|
|
color: var(--q-grey-5);
|
|
}
|
|
|
|
.empty-tip .q-separator {
|
|
opacity: 0.2;
|
|
}
|
|
|
|
.variable-description {
|
|
word-break: break-all;
|
|
white-space: pre-wrap;
|
|
font-size: 11px;
|
|
}
|
|
</style>
|