Browse Source

feat(editor): 添加 InOutCenterEditor 组件并更新相关文件

- 新增 InOutCenterEditor 组件,用于编辑输入、输出和中心端口
- 在 PropertyPanelConstant 中注册 InOutCenterEditor 组件
- 更新 TransformEditor 组件,注释掉调试日志
- 新增 flex 布局相关 CSS 类
master
lizw-2015 6 months ago
parent
commit
3d77b7492f
  1. 43
      src/base.css
  2. 282
      src/editor/propEditors/InOutCenterEditor.vue
  3. 11
      src/editor/widgets/property/PropertyPanelConstant.ts

43
src/base.css

@ -382,3 +382,46 @@ body {
opacity: 1; opacity: 1;
} }
} }
/** flex多行容器 */
.flex-column-container {
display: flex;
flex-direction: column;
flex-wrap: nowrap;
}
/** flex多列容器 */
.flex-row-container {
display: flex;
flex-direction: row;
flex-wrap: nowrap;
}
/** flex自动填充 */
.flex-item-fill {
flex-grow: 1;
overflow: hidden;
}
/** flex固定大小 */
.flex-item-fixed {
flex-shrink: 0;
}
/** flex主轴上对齐方式 */
.flex-justify-content-center {
justify-content: center;
}
/** flex交叉轴上对齐方式 */
.flex-align-items-center {
align-items: center;
}
/** 内容居中 */
.content-center {
display: flex;
align-items: center;
justify-content: center;
}

282
src/editor/propEditors/InOutCenterEditor.vue

@ -0,0 +1,282 @@
<script setup lang="ts">
import { computed, reactive } from "vue";
import { ElIcon, ElRadioButton, ElRadioGroup, useFormItem } from "element-plus";
import { ArrowDown, ArrowUp, Delete, EditPen } from "@element-plus/icons-vue";
import { Typeof } from "@ease-forge/shared";
defineOptions({
name: 'InOutCenterEditor',
});
//
const emit = defineEmits<{
/** 更新内联表格数据 */
"update:modelValue": [value: ItemJson["dt"]];
}>();
// Props
interface InOutCenterEditorProps {
modelValue: ItemJson["dt"];
}
// props
const props = withDefaults(defineProps<InOutCenterEditorProps>(), {});
// State
interface InOutCenterEditorState {
portsType: "center" | "in" | "out";
selectCenterIdx?: number;
selectInIdx?: number;
selectOutIdx?: number;
}
// state
const state = reactive<InOutCenterEditorState>({
portsType: "in",
});
// Data
interface InOutCenterEditorData {
}
//
const data: InOutCenterEditorData = {};
const { formItem } = useFormItem();
const list = computed<Array<string>>(() => {
const portsType = state.portsType;
if (portsType === "center") return props.modelValue?.center ?? [];
if (portsType === "in") return props.modelValue?.in ?? [];
if (portsType === "out") return props.modelValue?.out ?? [];
return [];
});
const selectIdx = computed<number | undefined>({
set: newValue => {
const portsType = state.portsType;
if (portsType === "center") state.selectCenterIdx = newValue;
if (portsType === "in") state.selectInIdx = newValue;
if (portsType === "out") state.selectOutIdx = newValue;
},
get: oldValue => {
const portsType = state.portsType;
if (portsType === "center") return state.selectCenterIdx;
if (portsType === "in") return state.selectInIdx;
if (portsType === "out") return state.selectOutIdx;
},
});
const canUpItem = computed(() => selectIdx.value > 0);
const canDownItem = computed(() => selectIdx.value < (list.value.length - 1));
const canDeleteItem = computed(() => selectIdx.value < list.value.length);
function setSelectIdx(idx: number) {
selectIdx.value = idx;
}
function addItem() {
const [list, modelValue] = getListAndModelValue();
list.push(`D_${Date.now()}`);
emit("update:modelValue", modelValue);
}
function upItem() {
if (!canUpItem.value) return;
const idx = selectIdx.value;
if (Typeof.noValue(idx)) return;
if (idx <= 0) return;
const [list, modelValue] = getListAndModelValue();
const idxUp = idx - 1;
const tmp = list[idxUp];
list[idxUp] = list[idx];
list[idx] = tmp;
emit("update:modelValue", modelValue);
selectIdx.value--;
}
function downItem() {
if (!canDownItem.value) return;
const idx = selectIdx.value;
if (Typeof.noValue(idx)) return;
const [list, modelValue] = getListAndModelValue();
if (idx >= (list.length - 1)) return;
const idxDown = idx + 1;
const tmp = list[idxDown];
list[idxDown] = list[idx];
list[idx] = tmp;
emit("update:modelValue", modelValue);
selectIdx.value++;
}
function deleteItem() {
if (!canDeleteItem.value) return;
if (Typeof.noValue(selectIdx.value)) return;
const [list, modelValue] = getListAndModelValue();
list.splice(selectIdx.value, 1);
emit("update:modelValue", modelValue);
if (selectIdx.value >= list.length) {
setSelectIdx(Math.max(0, selectIdx.value - 1));
}
}
function getListAndModelValue() {
const modelValue = props.modelValue ?? {};
const portsType = state.portsType;
let list: Array<string> = [];
if (portsType === "center") {
if (!modelValue.center) modelValue.center = [];
list = modelValue.center;
} else if (portsType === "in") {
if (!modelValue.in) modelValue.in = [];
list = modelValue.in;
} else if (portsType === "out") {
if (!modelValue.out) modelValue.out = [];
list = modelValue.out;
}
return [list, modelValue];
}
interface InOutCenterEditorExpose {
state: InOutCenterEditorState;
data: InOutCenterEditorData;
}
const expose: InOutCenterEditorExpose = {
state,
data,
};
//
defineExpose(expose);
export type {
InOutCenterEditorProps,
InOutCenterEditorState,
}
</script>
<template>
<div class="flex-column-container in-out-center-editor">
<ElRadioGroup class="flex-item-fixed flex-justify-content-center" v-model="state.portsType" size="small">
<ElRadioButton label="Input Ports" value="in"/>
<ElRadioButton label="Central Ports" value="center"/>
<ElRadioButton label="Output Ports" value="out"/>
</ElRadioGroup>
<div class="flex-item-fill flex-row-container in-out-center-editor-data">
<div class="flex-item-fixed in-out-center-editor-tools">
<div class="tools-button-container">
<ElIcon class="tools-button-icon" @click="addItem">
<EditPen/>
</ElIcon>
<ElIcon :class="['tools-button-icon', { 'tools-button-disabled': !canUpItem }]" @click="upItem">
<ArrowUp/>
</ElIcon>
<ElIcon :class="['tools-button-icon', { 'tools-button-disabled': !canDownItem }]" @click="downItem">
<ArrowDown/>
</ElIcon>
<ElIcon :class="['tools-button-icon', { 'tools-button-disabled': !canDeleteItem }]" @click="deleteItem">
<Delete/>
</ElIcon>
</div>
</div>
<div class="flex-item-fill in-out-center-editor-data-list">
<div
v-for="(item, idx) in list"
:class="[
'list-item',
{
'list-item-select': selectIdx === idx,
},
]"
@click="setSelectIdx(idx)"
>
{{ item }}
</div>
</div>
</div>
</div>
</template>
<style scoped>
.in-out-center-editor {
width: 100%;
height: 160px;
}
.in-out-center-editor-data {
margin-top: 6px;
border: 1px solid #dddddd;
}
.in-out-center-editor-tools {
background-color: #f5f5f5;
border-right: 1px solid #dddddd;
width: 28px;
padding: 4px 0;
}
.tools-button-container {
display: flex;
flex-direction: column;
flex-wrap: nowrap;
align-items: center;
justify-content: center;
gap: 4px;
cursor: pointer;
height: 100%;
}
.tools-button-container > .tools-button-icon {
color: #8c8c8c;
padding: 4px;
font-size: 22px;
border-radius: 2px;
}
.tools-button-container > .tools-button-icon:hover {
color: #595959;
background-color: #d9d9d9;
}
.tools-button-container > .tools-button-icon:active {
color: #434343;
background-color: #bfbfbf;
}
.tools-button-container > .tools-button-disabled {
cursor: not-allowed;
}
.tools-button-container > .tools-button-disabled.tools-button-icon,
.tools-button-container > .tools-button-disabled.tools-button-icon:hover,
.tools-button-container > .tools-button-disabled.tools-button-icon:active {
color: #d9d9d9;
background-color: unset;
pointer-events: none;
}
.in-out-center-editor-data-list {
overflow-y: auto;
}
.list-item {
padding: 4px 0 4px 2px;
cursor: pointer;
border-bottom: 1px solid #f0f0f0;
user-select: none;
color: #262626;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.list-item:hover {
background-color: #f0f0f0;
}
.list-item:active {
background-color: #dddddd;
}
.list-item.list-item-select,
.list-item.list-item-select:hover,
.list-item.list-item-select:active {
background-color: #d9d9d9;
}
</style>

11
src/editor/widgets/property/PropertyPanelConstant.ts

@ -3,6 +3,7 @@ import type { DataFormProps } from "@/components/data-form/DataFormTypes.ts";
import type { PropertyFieldSetter } from "@/core/base/PropertyTypes.ts"; import type { PropertyFieldSetter } from "@/core/base/PropertyTypes.ts";
import { dataFormInputComponents } from "@/components/data-form/DataFormConstant.ts"; import { dataFormInputComponents } from "@/components/data-form/DataFormConstant.ts";
import TransformEditor from "@/editor/propEditors/TransformEditor.vue"; import TransformEditor from "@/editor/propEditors/TransformEditor.vue";
import InOutCenterEditor from "@/editor/propEditors/InOutCenterEditor.vue";
const defDataFormProps: DataFormProps = { const defDataFormProps: DataFormProps = {
columnCount: 1, columnCount: 1,
@ -12,6 +13,7 @@ const defDataFormProps: DataFormProps = {
}; };
dataFormInputComponents.TransformEditor = markRaw<any>(TransformEditor); dataFormInputComponents.TransformEditor = markRaw<any>(TransformEditor);
dataFormInputComponents.InOutCenterEditor = markRaw<any>(InOutCenterEditor);
const basicFieldsSetter: Array<PropertyFieldSetter> = [ const basicFieldsSetter: Array<PropertyFieldSetter> = [
{ {
@ -48,11 +50,10 @@ const basicFieldsSetter: Array<PropertyFieldSetter> = [
dataPath: 'tf', input: 'TransformEditor', dataPath: 'tf', input: 'TransformEditor',
inputProps: {}, inputProps: {},
}, },
// { {
// dataPath: 'dt', input: 'InOutCenterEditor', dataPath: 'dt', input: 'InOutCenterEditor',
// inputProps: { inputProps: {},
// }, },
// },
]; ];

Loading…
Cancel
Save