Files
uTools-quickcommand/src/components/editor/CommandLanguageBar.vue

365 lines
9.7 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<template>
<div class="command-language-bar">
<q-select
class="q-pl-xs"
dense
options-dense
borderless
square
hide-bottom-space
color="primary"
transition-show="jump-down"
transition-hide="jump-up"
:model-value="currentCommand.program"
@update:model-value="handleProgramChange"
:options="Object.keys(programs)"
>
<template v-slot:prepend>
<q-badge
label="环境"
color="primary"
text-color="white"
class="q-ml-sm"
style="height: 20px"
/>
</template>
<template v-slot:append>
<q-avatar size="20px" square v-if="isRunCodePage">
<img :src="programs[currentCommand.program].icon" />
</q-avatar>
</template>
<template v-slot:option="scope">
<q-item v-bind="scope.itemProps">
<q-item-section avatar>
<img width="32" :src="programs[scope.opt].icon" />
</q-item-section>
<q-item-section>
<q-item-label v-html="scope.opt" />
</q-item-section>
</q-item>
</template>
</q-select>
<q-btn-group unelevated class="button-group">
<q-btn-dropdown
class="special-var-btn"
dense
flat
label="变量"
color="primary"
icon="data_object"
>
<q-list>
<q-item
v-for="(item, index) in Object.values(specialVars)"
:key="index"
clickable
v-close-popup
@click="handleSpecialVarClick(item)"
>
<q-item-section>
<q-item-label class="row items-center justify-between">
<div v-text="item.label" />
<div v-if="item.onlyCmdTypes" class="row">
<q-badge color="grey-9" class="q-ml-xs"> </q-badge>
<q-badge
v-for="type in item.onlyCmdTypes"
:key="type"
class="q-ml-xs"
v-text="commandTypes[type].label"
color="grey-9"
/>
</div>
</q-item-label>
<q-tooltip v-if="item.tooltip">
{{ item.tooltip }}
</q-tooltip>
<q-item-label caption>{{ item.desc }}</q-item-label>
</q-item-section>
</q-item>
</q-list>
</q-btn-dropdown>
<template v-if="currentCommand.program === 'quickcommand'">
<q-btn
v-for="(item, index) in ['help_center', 'view_timeline']"
:key="index"
dense
flat
color="primary"
class="settings-btn"
:label="['文档', '可视化'][index]"
:icon="item"
@click="handleQuickCommandAction(index)"
>
</q-btn>
</template>
<q-btn-dropdown
v-model="isSettingsVisible"
v-else-if="currentCommand.program !== 'html'"
class="settings-btn"
dense
flat
label="设置"
color="primary"
icon="settings"
>
<q-list>
<!-- 自定义解释器 -->
<q-item
v-for="(item, index) in Object.keys(currentCommand.customOptions)"
:key="index"
v-show="currentCommand.program === 'custom'"
>
<q-input
stack-label
autofocus
dense
outlined
class="full-width"
:label="
[
'解释器路径,如:/opt/python',
'运行参数,如:-u',
'脚本后缀不含点py',
][index]
"
:model-value="currentCommand.customOptions[item]"
@update:model-value="
(val) => updateModelValue(`customOptions.${item}`, val)
"
>
<template v-slot:prepend>
<q-icon name="code" />
</template>
</q-input>
</q-item>
<!-- 脚本参数 -->
<q-item v-show="currentCommand.program !== 'quickcommand'">
<q-input
dense
stack-label
outlined
label="脚本参数"
class="full-width"
:model-value="currentCommand.scptarg"
@update:model-value="updateModelValue('scptarg', $event)"
>
<template v-slot:prepend>
<q-icon name="input" />
</template>
</q-input>
</q-item>
<!-- 编码设置 -->
<q-item
v-for="(item, index) in Object.keys(currentCommand.charset)"
:key="index"
v-show="currentCommand.program !== 'quickcommand'"
>
<q-select
dense
outlined
stack-label
clearable
class="full-width"
:label="['脚本编码', '输出编码'][index]"
:model-value="currentCommand.charset[item]"
@update:model-value="
(val) => updateModelValue(`charset.${item}`, val)
"
:options="['GBK', 'utf8', 'Big5']"
type="text"
>
<template v-slot:prepend>
<q-icon :name="['format_size', 'output'][index]" />
</template>
</q-select>
</q-item>
</q-list>
</q-btn-dropdown>
<q-separator vertical inset />
<q-btn
v-if="!isRunCodePage"
class="action-btn run-btn"
dense
flat
color="primary"
icon="arrow_back"
label="退出"
@click="$emit('action', 'back')"
></q-btn>
<q-btn
class="action-btn run-btn"
dense
flat
color="primary"
icon="play_arrow"
:label="`运行(${ctrlKey}B)`"
@click="$emit('action', 'run')"
></q-btn>
<q-btn
v-if="!isRunCodePage"
:disable="!canCommandSave"
:color="canCommandSave ? 'primary' : 'grey'"
class="action-btn save-btn"
flat
dense
icon="save"
:label="`保存(${ctrlKey}S)`"
@click="$emit('action', 'save')"
></q-btn>
</q-btn-group>
<q-dialog v-model="showUserData">
<UserData
@insertText="
insertSpecialVar($event);
showUserData = false;
"
:showInsertBtn="true"
/>
</q-dialog>
</div>
</template>
<script>
import programs from "js/options/programs.js";
import specialVars from "js/options/specialVars.js";
import commandTypes from "js/options/commandTypes.js";
import UserData from "components/popup/UserData.vue";
export default {
name: "CommandLanguageBar",
props: {
modelValue: {
type: Object,
required: true,
},
canCommandSave: {
type: Boolean,
default: true,
},
isRunCodePage: {
type: Boolean,
default: false,
},
},
emits: ["update:modelValue", "action"],
components: {
UserData,
},
data() {
return {
programs,
specialVars,
commandTypes,
isSettingsVisible: false,
showUserData: false,
ctrlKey: utools.isMacOs ? "" : "",
};
},
computed: {
currentCommand() {
return this.modelValue;
},
},
methods: {
handleProgramChange(newProgram) {
const newCommand = { ...this.currentCommand };
newCommand.program = newProgram;
if (newProgram === "custom") {
this.isSettingsVisible = true;
}
if (newProgram === "html") {
newCommand.output = "html";
}
const featuresIcon = this.currentCommand.features.icon || "";
if (featuresIcon.slice(0, 10) !== "data:image") {
newCommand.features.icon = this.programs[newProgram].icon;
}
this.$emit("update:modelValue", newCommand);
},
updateModelValue(keyPath, value) {
const newModelValue = { ...this.modelValue };
const keys = keyPath.split(".");
const lastKey = keys.pop();
const target = keys.reduce((obj, key) => obj[key], newModelValue);
target[lastKey] = value;
this.$emit("update:modelValue", newModelValue);
},
handleQuickCommandAction(index) {
const actions = [
() => this.showHelp(),
() => this.$emit("action", "show-composer"),
];
actions[index]();
},
showHelp() {
window.showUb.docs();
},
handleSpecialVarClick(item) {
if (item.label === "{{usr:}}") this.showUserData = true;
else this.insertSpecialVar(item.label);
},
insertSpecialVar(text) {
if (!text) return;
this.$emit("action", "insert-text", `"${text}"`);
},
},
};
</script>
<style scoped>
.button-group {
padding: 0 5px;
}
.button-group :deep(.q-focus-helper) {
display: none;
}
.button-group :deep(.q-btn__content) {
font-size: 12px;
}
.button-group :deep(.q-btn-dropdown__arrow) {
margin-left: 0;
}
.button-group .q-btn:hover {
filter: brightness(1.2);
transition: all 0.2s ease;
}
/* 运行按钮动画 */
.run-btn:hover :deep(.q-icon) {
display: inline-block;
animation: leftRight 1.5s infinite;
}
/* 保存按钮动画 */
.save-btn:not([disabled]):hover :deep(.q-icon) {
display: inline-block;
animation: upDown 1.2s infinite;
}
.command-language-bar {
background-color: #fffffe;
height: 30px;
margin-bottom: 2px;
display: flex;
align-items: center;
justify-content: space-between;
}
.body--dark .command-language-bar {
background-color: #1e1e1e;
}
.command-language-bar :deep(.q-field__control),
.command-language-bar :deep(.q-field__control > *),
.command-language-bar :deep(.q-field__native) {
max-height: 30px;
min-height: 30px;
}
</style>