Commit c9a419ca authored by rockyl's avatar rockyl

增加行为解释器

增加项目详情编辑
parent 0a0442d1
...@@ -19,6 +19,7 @@ const data = { ...@@ -19,6 +19,7 @@ const data = {
"x": 10, "x": 10,
"y": 10 "y": 10
}, },
"uuid": "f97bbf76-6923-4669-b5a3-e6382753e49a",
events: { events: {
click: { click: {
once: false, once: false,
...@@ -41,10 +42,165 @@ const data = { ...@@ -41,10 +42,165 @@ const data = {
} }
} }
], ],
"uuid": "f97bbf76-6923-4669-b5a3-e6382753e49a"
}] }]
}], }],
"assets": [], "assets": [
{
"name": "face",
"ext": ".png",
"url": "//yun.duiba.com.cn/aurora/58323a0469a7467c99b34f8933ea65b507a0c655.png",
"uuid": "3e496939-5fe6-42f2-b8fa-42c7a742e880"
}, {
"name": "还以是bug",
"ext": ".jpg",
"url": "//yun.duiba.com.cn/aurora/094832ace87c94bdb9e4a7821b3a3ebca0df2cd7.jpg",
"uuid": "ec67a8a0-8708-43a4-888e-efb0fe7c2bd6"
}, {
"name": "嘿嘿",
"ext": ".gif",
"url": "//yun.duiba.com.cn/aurora/1ad10a4cf3488ef1400af1d6f353d9c577fe1049.gif",
"uuid": "429803eb-0f68-4071-b68c-468980883ac4"
}, {
"name": "1643017",
"ext": ".jpg",
"url": "//yun.duiba.com.cn/aurora/2e4adf3d8646ffbd027038cb2c6627a6bca44e44.jpg",
"uuid": "cc1ad757-ff4c-4cb9-b629-be355119d018"
}, {
"name": "0",
"ext": ".gif",
"url": "//yun.duiba.com.cn/aurora/616a413facbd406b81daac809a52bd0b648a7f4c.gif",
"uuid": "0a5f2064-f5b4-41a9-8a54-2085e208d20f"
}, {
"name": "3",
"ext": ".gif",
"url": "//yun.duiba.com.cn/aurora/e052cb4a88d63330c37ecaf55ae8e7eb2246c433.gif",
"uuid": "e4dacdd2-064f-413e-a8f0-6425ce6dcf12"
}, {
"name": "5",
"ext": ".gif",
"url": "//yun.duiba.com.cn/aurora/881193ea1bd975c8a59f38f2d1f0d0094db6ec7a.gif",
"uuid": "bf822d51-a1b1-4ab6-8f49-a821863731d0"
}, {
"name": "4",
"ext": ".gif",
"url": "//yun.duiba.com.cn/aurora/2df4a5c5238f86704388517d2ba0faa6782fea1e.gif",
"uuid": "9c1d46b4-d2f1-4733-8b93-39b2bb4db9d1"
}, {
"name": "1",
"ext": ".gif",
"url": "//yun.duiba.com.cn/aurora/0bc24c7bb68e3691bad89c8ae096b253af874a73.gif",
"uuid": "db076340-e1db-4e2d-8bb2-7cc32ccdee43"
}, {
"name": "7",
"ext": ".gif",
"url": "//yun.duiba.com.cn/aurora/3e218541244d1ed1192274ad49ea70588b6cd0dc.gif",
"uuid": "02aa47c3-dbdf-43d2-8cdc-869cab544bcc"
}, {
"name": "2",
"ext": ".gif",
"url": "//yun.duiba.com.cn/aurora/1e1344fabf25cf2ea6f1407cd42afc1f1de0bb07.gif",
"uuid": "264f7a8d-475e-4fd0-ac83-96e13a7702f3"
}, {
"name": "8",
"ext": ".gif",
"url": "//yun.duiba.com.cn/aurora/90080b186e0507b70f64c2020880dd1ddd3b7cd8.gif",
"uuid": "ec63930b-8aff-4108-9ceb-ddf9353d4412"
}, {
"name": "0",
"ext": ".gif",
"url": "//yun.duiba.com.cn/aurora/616a413facbd406b81daac809a52bd0b648a7f4c.gif",
"uuid": "7c475d4d-0ae2-4b9a-81ff-76fb8264721f"
}, {
"name": "9",
"ext": ".gif",
"url": "//yun.duiba.com.cn/aurora/f41b70c1003ff703386a5a80ed7092db5fdc11f4.gif",
"uuid": "473b82ec-c9b9-43d7-b2e5-b5399a55d239"
}, {
"name": "12",
"ext": ".gif",
"url": "//yun.duiba.com.cn/aurora/99660ca0a9a578cd6c5eb38b1f35aee9a77849b3.gif",
"uuid": "84f549d3-9bb1-4066-9668-3705e94b5891"
}, {
"name": "11",
"ext": ".gif",
"url": "//yun.duiba.com.cn/aurora/f88c5de6bb6ab80f24cc56978e92cedf4af201f0.gif",
"uuid": "a4470420-60bd-4578-a2dc-100663ba6256"
}, {
"name": "13",
"ext": ".gif",
"url": "//yun.duiba.com.cn/aurora/c5c446eba840899d364bcdb010a2aea8d2ae02ab.gif",
"uuid": "7383d2db-43dd-408a-aa69-261bd39865ac"
}, {
"name": "6",
"ext": ".gif",
"url": "//yun.duiba.com.cn/aurora/881193ea1bd975c8a59f38f2d1f0d0094db6ec7a.gif",
"uuid": "894a28f8-a814-4c8c-a5d9-619194b3073d"
}, {
"name": "btn-join",
"ext": ".png",
"url": "//yun.duiba.com.cn/aurora/e50e0fe70f4b2c96d2deee1d93a0a2444732be6a.png",
"uuid": "e3301bc4-7b51-4868-a613-26298f87988b"
}, {
"name": "bg",
"ext": ".jpg",
"url": "//yun.duiba.com.cn/aurora/7dbe10dba2a92d830f0f9ff72f3d82e07a4c4649.jpg",
"uuid": "bab58ec1-24b1-4d5d-9c95-7014b9915cb3"
}, {
"name": "1643017",
"ext": ".png",
"uuid": "54f7916f-dc10-49f7-b3b1-0bda9d4f5bcd",
"url": "//yun.duiba.com.cn/aurora/4090d0acf7dbf29cd6ab0690795e0b00b715280c.png"
}, {
"name": "bg",
"ext": ".png",
"uuid": "5fe14ca0-5b86-405e-98a6-54ca733f2180",
"url": "//yun.duiba.com.cn/aurora/070159098034ae2cd8c8e4bf4f47b1d45b87024a.png"
}, {
"name": "rule_button",
"ext": ".png",
"uuid": "82a9d493-078a-4b7c-8352-616abc99f24a",
"url": "//yun.duiba.com.cn/aurora/d0c3ed2bf9abc5748c01eb88abb7e0830669b1c5.png"
}, {
"name": "wheel_items",
"ext": ".png",
"uuid": "b899e2f0-36da-42dc-a9ac-c8f4093e4457",
"url": "//yun.duiba.com.cn/aurora/897ee802eb89999c2019c683c084f4b7e2d7f554.png"
}, {
"name": "wheel_bg",
"ext": ".png",
"uuid": "8f531f60-b48e-4a7a-bd7a-9488a3c3dd2d",
"url": "//yun.duiba.com.cn/aurora/479cbb31bfdaee48893bf34f7d0c8fc702b1459a.png"
}, {
"name": "start_bg",
"ext": ".png",
"uuid": "62fe5f9b-47ec-4c1e-b508-f566501caa72",
"url": "//yun.duiba.com.cn/aurora/3191ba684512b9e9391ab4a9d2a2df31cad4825d.png"
}, {
"name": "0",
"ext": ".png",
"uuid": "562af6d0-6b73-4de8-bed0-ed3a4507962c",
"url": "//yun.duiba.com.cn/aurora/be2fa0d9e91b58d9aafcd18f7934784742069cb6.png"
}, {
"name": "1",
"ext": ".png",
"uuid": "6cf1bc08-bcc8-4cec-88d8-3e979b35dd0f",
"url": "//yun.duiba.com.cn/aurora/3f64f753e272d17a1f5807ddf1a8965a0e2de9d5.png"
}, {
"name": "0",
"ext": ".png",
"uuid": "378851d3-6664-4b0e-8407-342f4ffaf334",
"url": "//yun.duiba.com.cn/aurora/3c292a9c6c5b1a3dab684e95d1f7b7cb4f369a8a.png"
}, {
"name": "1",
"ext": ".png",
"uuid": "dee35c49-db44-4722-a412-a8b7123d20b7",
"url": "//yun.duiba.com.cn/aurora/b22420f2322326359e2b3e1dae66dc7e34ce6978.png"
}, {
"name": "bg",
"ext": ".png",
"uuid": "2b0cc6bd-fc10-43ee-a217-aaf1c40a0ad3",
"url": "//yun.duiba.com.cn/aurora/93fbb49529a3b4617f4cdc41dba7c297989baa5e.png"
}],
"dataMapping": [], "dataMapping": [],
processes: [ processes: [
{ {
...@@ -91,6 +247,8 @@ const data = { ...@@ -91,6 +247,8 @@ const data = {
num: {alias: '数字', type: 'number', default: 1}, num: {alias: '数字', type: 'number', default: 1},
type: {alias: '类型', type: 'enum', enum: ['rotate', 'jump', 'breath'], default: 'rotate'}, type: {alias: '类型', type: 'enum', enum: ['rotate', 'jump', 'breath'], default: 'rotate'},
autoPlay: {alias: '自动播放', type: 'boolean', default: false}, autoPlay: {alias: '自动播放', type: 'boolean', default: false},
color: {alias: '颜色', type: 'color', default: '#123456'},
asset: {alias: '素材', type: 'asset',},
}, },
output: ['success', 'failed'], output: ['success', 'failed'],
script: "console.log('test');", script: "console.log('test');",
......
...@@ -67,8 +67,10 @@ ...@@ -67,8 +67,10 @@
"Unsaved Alert": "You are leaving, but the project is not saved. Do you want to save it?", "Unsaved Alert": "You are leaving, but the project is not saved. Do you want to save it?",
"Meta is in use, can not delete": "Meta is in use, can not delete!", "Meta is in use, can not delete": "Meta is in use, can not delete!",
"Are you sure to delete this meta": "Are you sure to delete this meta?", "Are you sure to delete this meta": "Are you sure to delete this meta?",
"This Meta ID is in use, can not save": "This Meta ID is in use, can not save!",
"menu": { "menu": {
"save": "Save", "save": "Save",
"details": "Details",
"preview": "Preview", "preview": "Preview",
"publish": "Publish", "publish": "Publish",
"data-mapping": "DataMapping", "data-mapping": "DataMapping",
......
...@@ -69,7 +69,7 @@ export const behaviorStore = { ...@@ -69,7 +69,7 @@ export const behaviorStore = {
break; break;
} }
} }
} },
}, },
getters: { getters: {
customProcessMap: state => { customProcessMap: state => {
...@@ -89,6 +89,19 @@ export const behaviorStore = { ...@@ -89,6 +89,19 @@ export const behaviorStore = {
} }
return result; return result;
}, },
metaIDExists: state => id => {
let result = false;
for (let process of state.data.processes) {
if (process.id === id) {
result = true;
break;
}
}
return result;
},
behavior_getAssetByUUID: state=>uuid=>{
return state.data.assets.find(item=>item.uuid === uuid);
},
}, },
actions: { actions: {
addCustomProcessMeta({commit, state}) { addCustomProcessMeta({commit, state}) {
......
...@@ -9,12 +9,27 @@ import generateUUID from "uuid/v4"; ...@@ -9,12 +9,27 @@ import generateUUID from "uuid/v4";
import { getCmpProps, flattenViews, getCmpByUUID } from '../../utils/common'; import { getCmpProps, flattenViews, getCmpByUUID } from '../../utils/common';
import { saveAs } from "../../utils"; import { saveAs } from "../../utils";
const defaultLaunchOptions = {
entrySceneView: '',
containerID: 'game-container',
designWidth: 750,
designHeight: 1334,
frameRate: 60,
scaleMode: 'fixedWidth',
rendererType: 'webgl',
};
function getDefaultLaunchOptions(){
return JSON.parse(JSON.stringify(defaultLaunchOptions));
}
export const projectStore = { export const projectStore = {
state: { state: {
id: '', id: '',
name: '', name: '',
creator: '', creator: '',
data: { data: {
launchOptions: {},
views: [], views: [],
assets: [], assets: [],
dataMapping: [], dataMapping: [],
...@@ -41,12 +56,14 @@ export const projectStore = { ...@@ -41,12 +56,14 @@ export const projectStore = {
const localData = state.data; const localData = state.data;
if (data) { if (data) {
const { views, assets, dataMapping, processes } = JSON.parse(data); const { views, assets, dataMapping, processes, launchOptions, } = JSON.parse(data);
Vue.set(localData, 'launchOptions', launchOptions || getDefaultLaunchOptions());
Vue.set(localData, 'views', views || []); Vue.set(localData, 'views', views || []);
Vue.set(localData, 'assets', assets || []); Vue.set(localData, 'assets', assets || []);
Vue.set(localData, 'dataMapping', dataMapping || []); Vue.set(localData, 'dataMapping', dataMapping || []);
Vue.set(localData, 'processes', processes || []); Vue.set(localData, 'processes', processes || []);
} else { } else {
Vue.set(localData, 'launchOptions', getDefaultLaunchOptions());
Vue.set(localData, 'views', []); Vue.set(localData, 'views', []);
Vue.set(localData, 'assets', []); Vue.set(localData, 'assets', []);
Vue.set(localData, 'dataMapping', []); Vue.set(localData, 'dataMapping', []);
...@@ -258,6 +275,9 @@ export const projectStore = { ...@@ -258,6 +275,9 @@ export const projectStore = {
} }
return result; return result;
}, },
launchOptions(state){
return state.data.launchOptions;
},
/** /**
* 当前激活的组件 * 当前激活的组件
*/ */
...@@ -287,7 +307,7 @@ export const projectStore = { ...@@ -287,7 +307,7 @@ export const projectStore = {
let result = flattenViews(_.cloneDeep(_view)); let result = flattenViews(_.cloneDeep(_view));
// console.log('componentList', result); // console.log('componentList', result);
return result; return result;
} },
}, },
actions: { actions: {
saveToLocal({ getters, commit }) { saveToLocal({ getters, commit }) {
......
...@@ -133,12 +133,13 @@ $dock-point-width: 9px; ...@@ -133,12 +133,13 @@ $dock-point-width: 9px;
flex-direction: column; flex-direction: column;
padding: 3px; padding: 3px;
font-size: 12px; font-size: 12px;
color: $--color-text-primary; color: $--color-text-regular;
.field-item { .field-item {
display: flex; display: flex;
align-items: center;
span { & > * {
flex: 1; flex: 1;
white-space: nowrap; white-space: nowrap;
...@@ -149,9 +150,17 @@ $dock-point-width: 9px; ...@@ -149,9 +150,17 @@ $dock-point-width: 9px;
} }
.value { .string-value {
text-align: right; text-align: right;
} }
.color-value {
width: 15px;
height: 15px;
border-radius: 3px;
float: right;
border: 1px solid $--border-color-base;
}
} }
} }
...@@ -224,6 +233,10 @@ $dock-point-width: 9px; ...@@ -224,6 +233,10 @@ $dock-point-width: 9px;
padding-right: 5px; padding-right: 5px;
} }
.el-select {
width: 100%;
}
.wrapper { .wrapper {
padding: 5px; padding: 5px;
flex: 1; flex: 1;
......
...@@ -44,6 +44,6 @@ ...@@ -44,6 +44,6 @@
} }
.el-tabs--border-card > .el-tabs__content{ .el-tabs--border-card > .el-tabs__content{
padding: 5px; padding: 5px 0 5px 5px;
} }
...@@ -20,6 +20,10 @@ ...@@ -20,6 +20,10 @@
.zero-inspector-props-form { .zero-inspector-props-form {
height: 100%; height: 100%;
.el-form{
padding-right: 10px;
}
.el-input-number.el-input-number--mini, .el-select.el-select--mini { .el-input-number.el-input-number--mini, .el-select.el-select--mini {
width: 100%; width: 100%;
} }
......
import _ from 'lodash'; import _ from 'lodash';
import properties from './properties'; import properties from './properties';
export const componentsMap = [{ export const componentsMap = [
{
label: '文本', label: '文本',
value: 'label' value: 'label'
}, { },
{
label: '图片', label: '图片',
value: 'image' value: 'image'
}, { },
{
label: '视图', label: '视图',
value: 'node' value: 'node'
}, { },
label: '形状', {
label: '矩形',
value: 'rect' value: 'rect'
}]; },
/*{
label: '圆形',
value: 'circle'
},*/
];
// 属性的计算方法 // 属性的计算方法
const propsComputeRules = { const propsComputeRules = {
...@@ -24,16 +33,18 @@ const propsComputeRules = { ...@@ -24,16 +33,18 @@ const propsComputeRules = {
scaleY: 'multi', scaleY: 'multi',
alpha: 'multi', alpha: 'multi',
visible: 'visible' visible: 'visible'
} };
const isClient = typeof window !== 'undefined'; const isClient = typeof window !== 'undefined';
function changeCamle(s) { function changeCamle(s) {
return s ? s.replace(/([A-Z])/g, '-$1').toLowerCase() : ''; return s ? s.replace(/([A-Z])/g, '-$1').toLowerCase() : '';
} }
function invalidAttr(key, value) { function invalidAttr(key, value) {
return !key || typeof value === 'undefined' || value === ''; return !key || typeof value === 'undefined' || value === '';
} }
// 属性简称 对照表 // 属性简称 对照表
const attrShortMapper = { const attrShortMapper = {
x: 'left', x: 'left',
...@@ -82,7 +93,7 @@ function getParentCmps(uuid, list) { ...@@ -82,7 +93,7 @@ function getParentCmps(uuid, list) {
return _self.parent ? parentLoop(_self.parent, list) : []; return _self.parent ? parentLoop(_self.parent, list) : [];
} }
export { getParentCmps, completeSelfProps }; export {getParentCmps, completeSelfProps};
export const getCmpByUUID = function (uuid, views) { export const getCmpByUUID = function (uuid, views) {
if (!uuid) { if (!uuid) {
......
export default ['click', 'touchstart', 'touchend', 'touchmove'] export default ['init', 'click', 'dataevent', 'touchstart', 'touchend', 'touchmove']
\ No newline at end of file \ No newline at end of file
...@@ -6,6 +6,20 @@ import {Message, Loading} from "element-ui"; ...@@ -6,6 +6,20 @@ import {Message, Loading} from "element-ui";
import i18n from '../i18n' import i18n from '../i18n'
import generateUUID from "uuid/v4"; import generateUUID from "uuid/v4";
export const SCALE_MODES = {
EXACT_FIT: "exactFit",
NO_BORDER: "noBorder",
NO_SCALE: "noScale",
SHOW_ALL: "showAll",
FIXED_WIDTH: "fixedWidth",
FIXED_HEIGHT: "fixedHeight",
};
export const RENDERER_TYPES= {
WEBGL: 'webgl',
CANVAS: 'canvas',
};
export function messageError(e) { export function messageError(e) {
Message({ Message({
dangerouslyUseHTMLString: true, dangerouslyUseHTMLString: true,
......
...@@ -66,7 +66,27 @@ export default { ...@@ -66,7 +66,27 @@ export default {
width: 40 width: 40
}, },
value: true value: true
} },
left: {
title: '左边距',
type: 'inputNumber',
value: undefined,
},
top: {
title: '上边距',
type: 'inputNumber',
value: undefined,
},
right: {
title: '右边距',
type: 'inputNumber',
value: undefined,
},
bottom: {
title: '下边距',
type: 'inputNumber',
value: undefined,
},
}, },
label: { label: {
groupName: '文本', groupName: '文本',
...@@ -88,7 +108,7 @@ export default { ...@@ -88,7 +108,7 @@ export default {
}, },
value: 12 value: 12
}, },
align: { textAlign: {
title: '文本对齐', title: '文本对齐',
type: 'select', type: 'select',
options: [ options: [
...@@ -97,7 +117,17 @@ export default { ...@@ -97,7 +117,17 @@ export default {
{ label: '靠右', value: 'right' } { label: '靠右', value: 'right' }
], ],
value: 'left' value: 'left'
} },
/*verticalAlign: {
title: '纵向对齐',
type: 'select',
options: [
{ label: '靠上', value: 'up' },
{ label: '居中', value: 'middle' },
{ label: '靠下', value: 'down' }
],
value: 'up'
},*/
}, },
image: { image: {
groupName: '来源', groupName: '来源',
...@@ -108,7 +138,7 @@ export default { ...@@ -108,7 +138,7 @@ export default {
} }
}, },
rect: { rect: {
groupName: '形状', groupName: '矩形',
fillColor: { fillColor: {
title: '填充色', title: '填充色',
type: 'colorPicker', type: 'colorPicker',
...@@ -127,5 +157,26 @@ export default { ...@@ -127,5 +157,26 @@ export default {
min: 0 min: 0
} }
} }
},
circle: {
groupName: '圆形',
fillColor: {
title: '填充色',
type: 'colorPicker',
value: '#fff'
},
strokeColor: {
title: '边框颜色',
type: 'colorPicker',
value: '#000'
},
strokeWidth: {
title: '边框宽度',
type: 'inputNumber',
value: 1,
props: {
min: 0
}
} }
},
} }
...@@ -86,7 +86,8 @@ const componentMapper = { ...@@ -86,7 +86,8 @@ const componentMapper = {
inputNumber: { inputNumber: {
component: 'el-input-number', component: 'el-input-number',
props: { props: {
size: 'mini' size: 'mini',
'controls-position': 'right'
} }
}, },
input: { input: {
......
...@@ -4,12 +4,16 @@ ...@@ -4,12 +4,16 @@
@mouseleave="onMouseLeave" @click="onClick" @dblclick="onDblclick"> @mouseleave="onMouseLeave" @click="onClick" @dblclick="onDblclick">
<div class="header"> <div class="header">
<span class="title">{{data.alias || meta.name}}</span> <span class="title">{{data.alias || meta.name}}</span>
<i v-if="meta.id !== 'entry'" class="delete-button el-icon-delete" @click.stop="onClickDelete" @mousedown.stop.prevent></i> <i v-if="meta.id !== 'entry'" class="delete-button el-icon-delete" @click.stop="onClickDelete"
@mousedown.stop.prevent></i>
</div> </div>
<div class="body"> <div class="body">
<div class="field-item" v-for="(param, key, index) in meta.options" :key="index"> <div class="field-item" v-for="(param, key, index) in meta.options" :key="index">
<span class="key">{{param.alias || key}}</span>: <span class="key">{{param.alias || key}}</span>:
<span class="value">{{data.options[key] || meta.options[key].default}}</span> <div v-if="param.type === 'color'">
<div class="color-value" :style="{'background-color': valueToString(param, data, key)}"></div>
</div>
<span v-else class="string-value">{{valueToString(param, data, key)}}</span>
</div> </div>
</div> </div>
<div ref="inputDock" class="dock input"> <div ref="inputDock" class="dock input">
...@@ -30,7 +34,7 @@ ...@@ -30,7 +34,7 @@
import DockPoint from "./DockPoint"; import DockPoint from "./DockPoint";
import {state} from "./state"; import {state} from "./state";
import events from "../../../../global-events"; import events from "../../../../global-events";
//todo 容器坐标改变影响节点坐标 //todo 容器坐标改变影响节点坐标
export default { export default {
name: "ProcessNode", name: "ProcessNode",
components: {DockPoint}, components: {DockPoint},
...@@ -69,6 +73,18 @@ ...@@ -69,6 +73,18 @@
}, },
}, },
methods: { methods: {
valueToString(param, data, key) {
if (param.type === 'asset') {
if(data.options.hasOwnProperty(key)){
let asset = this.$store.getters.behavior_getAssetByUUID(data.options[key]);
return asset.name;
}
} else {
return data.options[key] || param.default;
}
return '';
},
prepare() { prepare() {
let {design, options, output} = this.process.data; let {design, options, output} = this.process.data;
if (!design) { if (!design) {
...@@ -94,7 +110,7 @@ ...@@ -94,7 +110,7 @@
onDblclick(e) { onDblclick(e) {
this.$emit('dblclick', e); this.$emit('dblclick', e);
}, },
setActive(active){ setActive(active) {
this.active = active; this.active = active;
}, },
onMouseEnter(e) { onMouseEnter(e) {
...@@ -135,8 +151,8 @@ ...@@ -135,8 +151,8 @@
this.$emit('change-position', this, this); this.$emit('change-position', this, this);
} }
}, },
updateSize(){ updateSize() {
this.$nextTick(()=>{ this.$nextTick(() => {
let bounds = this.$refs.node.getBoundingClientRect(); let bounds = this.$refs.node.getBoundingClientRect();
this.width = bounds.width + 18; this.width = bounds.width + 18;
this.height = bounds.height; this.height = bounds.height;
......
...@@ -75,10 +75,16 @@ ...@@ -75,10 +75,16 @@
this.$refs.optionsEditorDialog.edit(this.meta.options); this.$refs.optionsEditorDialog.edit(this.meta.options);
}, },
save() { save() {
if (this.$store.getters.metaIDExists(this.meta.id)) {
this.$alert(this.$t('This Meta ID is in use, can not save'), this.$t('Alert'))
.catch((e) => {
});
} else {
this.$emit('input', this.meta); this.$emit('input', this.meta);
this.visible = false; this.visible = false;
}
}, },
cancel(){ cancel() {
this.visible = false; this.visible = false;
} }
} }
......
...@@ -44,6 +44,7 @@ ...@@ -44,6 +44,7 @@
<el-input v-if="scope.row.option.type === 'string' || scope.row.option.type === 'enum'" class="default-value" v-model="scope.row.option.default" size="mini" placeholder="Default"/> <el-input v-if="scope.row.option.type === 'string' || scope.row.option.type === 'enum'" class="default-value" v-model="scope.row.option.default" size="mini" placeholder="Default"/>
<el-input-number v-if="scope.row.option.type === 'number'" controls-position="right" class="default-value" v-model="scope.row.option.default" size="mini" placeholder="Default"/> <el-input-number v-if="scope.row.option.type === 'number'" controls-position="right" class="default-value" v-model="scope.row.option.default" size="mini" placeholder="Default"/>
<el-switch v-if="scope.row.option.type === 'boolean'" class="default-value" v-model="scope.row.option.default" size="mini"/> <el-switch v-if="scope.row.option.type === 'boolean'" class="default-value" v-model="scope.row.option.default" size="mini"/>
<el-color-picker v-if="scope.row.option.type === 'color'" class="default-value" v-model="scope.row.option.default" size="mini"/>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column <el-table-column
...@@ -92,6 +93,8 @@ ...@@ -92,6 +93,8 @@
'string', 'string',
'number', 'number',
'enum', 'enum',
'color',
'asset',
], ],
} }
}, },
......
...@@ -24,17 +24,21 @@ ...@@ -24,17 +24,21 @@
import StringEditor from "./editors/StringEditor"; import StringEditor from "./editors/StringEditor";
import EnumEditor from "./editors/EnumEditor"; import EnumEditor from "./editors/EnumEditor";
import BooleanEditor from "./editors/BooleanEditor"; import BooleanEditor from "./editors/BooleanEditor";
import ColorEditor from "./editors/ColorEditor";
import AssetEditor from "./editors/AssetEditor";
const editorMapping = { const editorMapping = {
number: 'NumberEditor', number: 'NumberEditor',
string: 'StringEditor', string: 'StringEditor',
enum: 'EnumEditor', enum: 'EnumEditor',
boolean: 'BooleanEditor', boolean: 'BooleanEditor',
color: 'ColorEditor',
asset: 'AssetEditor',
}; };
export default { export default {
name: "PropertiesEditor", name: "PropertiesEditor",
components: {BooleanEditor, EnumEditor, NumberEditor, StringEditor}, components: {AssetEditor, ColorEditor, BooleanEditor, EnumEditor, NumberEditor, StringEditor},
data() { data() {
return { return {
process: null, process: null,
......
<template>
<editor-wrapper :property="property" :propertyName="propertyName">
<el-select :value="editValue" @input="onInput" :placeholder="property.default" class="el-select">
<el-option
v-for="(item, key) in assets"
:key="key"
:label="item.name"
:value="item.uuid">
<span>{{item.name}}</span>
</el-option>
</el-select>
</editor-wrapper>
</template>
<script>
import {mapMutations} from 'vuex'
import EditorWrapper from "./EditorWrapper";
export default {
name: "AssetEditor",
components: {EditorWrapper,},
props: ['value', 'container', 'property', 'propertyName'],
computed: {
editValue() {
return this.value === undefined ? this.property.default : this.value;
},
...mapMutations({
assets(){
return this.$store.state.behavior.data.assets;
}
}),
},
methods: {
onInput(v, oldValue){
if(v !== this.value){
this.$emit('input', v, this.container, this.propertyName, oldValue);
}
}
},
}
</script>
<style scoped>
</style>
<template> <template>
<editor-wrapper :property="property" class="color-editor-container"> <editor-wrapper :property="property" :propertyName="propertyName" class="color-editor-container">
<el-color-picker <el-color-picker
class="picker" class="picker"
:value="editValue" :value="editValue"
...@@ -16,7 +16,7 @@ ...@@ -16,7 +16,7 @@
export default { export default {
name: "ColorEditor", name: "ColorEditor",
components: {EditorWrapper,}, components: {EditorWrapper,},
props: ['component', 'value', 'property'], props: ['value', 'container', 'property', 'propertyName'],
data() { data() {
return { return {
predefineColors: [ predefineColors: [
...@@ -39,13 +39,13 @@ ...@@ -39,13 +39,13 @@
}, },
computed: { computed: {
editValue() { editValue() {
return this.value === undefined ? this.property.defaultValue : this.value; return this.value === undefined ? this.property.default : this.value;
}, },
}, },
methods: { methods: {
onInput(v) { onInput(v) {
if (v !== this.value) { if (v !== this.value) {
this.$emit('input', v, this.component, this.property.name, this.value); this.$emit('input', v, this.container, this.propertyName, this.value);
} }
} }
}, },
......
<template> <template>
<editor-wrapper :property="property" :propertyName="propertyName"> <editor-wrapper :property="property" :propertyName="propertyName">
<enum-select :value="value" @input="onInput" :property="property"></enum-select> <el-select :value="editValue" @input="onInput" :placeholder="property.default" class="el-select">
<el-option
v-for="(item, key) in property.enum"
:key="item"
:label="item"
:value="item">
<span>{{item}}</span>
<span class="comment"></span>
</el-option>
</el-select>
</editor-wrapper> </editor-wrapper>
</template> </template>
<script> <script>
import EnumSelect from "./EnumEditor/EnumSelect";
import EditorWrapper from "./EditorWrapper"; import EditorWrapper from "./EditorWrapper";
export default { export default {
name: "EnumEditor", name: "EnumEditor",
components: {EnumSelect, EditorWrapper,}, components: {EditorWrapper,},
props: ['value', 'container', 'property', 'propertyName'], props: ['value', 'container', 'property', 'propertyName'],
computed: {
editValue() {
return this.value === undefined ? this.property.default : this.value;
},
},
methods: { methods: {
onInput(v, oldValue){ onInput(v, oldValue){
if(v !== this.value){ if(v !== this.value){
......
<template>
<el-select :value="editValue" @input="onInput" :placeholder="property.default" class="el-select">
<el-option
v-for="(item, key) in property.enum"
:key="item"
:label="item"
:value="item">
<span>{{item}}</span>
<span class="comment"></span>
</el-option>
</el-select>
</template>
<script>
export default {
name: "EnumSelect",
props: ['value', 'property'],
data(){
return {
}
},
computed: {
editValue(){
return this.value || this.property.default;
},
},
methods: {
onInput(v){
if(v !== this.value){
this.$emit('input', v, this.value);
}
}
},
}
</script>
<style scoped>
.el-select {
width: 100%;
}
.comment {
float: right;
color: darkgray;
font-size: 12px;
}
</style>
\ No newline at end of file
<template>
<el-form-item class="wrapper editor-event-wrapper" label-width="0">
<div class="header">
<span class="event-name">{{property.name}}</span>
<el-button icon="el-icon-plus" circle plain type="primary" class="mini-button" @click="onClickAdd"></el-button>
</div>
<div class="list" v-if="editValue">
<div class="event-item" v-for="(item, index) in editValue">
<div class="method-path">
<entity-linker class="entity-linker" v-model="item.entity" @input="onEntityChange(item, index)"></entity-linker>
<el-popover
popper-class="tooltip-popover"
class="method-name-container"
placement="top"
trigger="hover"
:disabled="getMethodName(item, index).length === 0"
:open-delay="400"
:content="getMethodName(item, index)">
<div slot="reference" class="method-menu editor-event-method-menu" @click="onShowMethodMenu(item, index)">{{getMethodName(item, index)}}
</div>
</el-popover>
</div>
<div class="params-box">
<el-form-item class="param-input" label="param" label-width="45px">
<el-input v-model="item.param"></el-input>
</el-form-item>
<el-button icon="el-icon-close" @click="onClickDelete(item, index)" circle plain class="mini-button"
type="danger"></el-button>
</div>
</div>
</div>
</el-form-item>
</template>
<script>
import ElFormItem from "./form-item";
import EntityLinker from "./EntityEditor/EntityLinker";
import {getUUIDFromLink} from "../../../../../utils";
import {getCurrentProject, getCurrentScene} from "../../../../../editor";
import {showMethodMenu} from "../../../../../menus/index";
import {getClassDeclare} from "../../../../../components-manager";
export default {
name: "EventEditor",
components: {EntityLinker, ElFormItem},
props: ['component', 'value', 'property'],
data() {
this.storeOldValue(this.value);
return {
methodName: '',
editValue: this.value,
}
},
watch: {
value() {
this.editValue = this.value;
this.storeOldValue();
},
},
methods: {
storeOldValue(v){
let value = v || this.editValue;
this.oldValue = value === undefined ? undefined : JSON.parse(JSON.stringify(value));
},
onShowMethodMenu(item, index) {
let entity = this.getEntity(item.entity);
showMethodMenu(entity, event.x, event.y, index, this.onSelectMethod);
},
onSelectMethod(index, componentIndex, method) {
let item = this.editValue[index];
if(componentIndex < 0){
item.component = null;
item.method = null;
}else{
item.component = componentIndex;
item.method = method;
}
this.emitInput();
},
onEntityChange(item, index) {
item.component = null;
item.method = null;
this.emitInput();
},
onClickAdd() {
if (this.editValue === undefined) {
this.editValue = [];
}
this.editValue.push({
entity: null,
component: null,
method: null,
});
this.emitInput();
},
onClickDelete(item, index) {
this.editValue.splice(index, 1);
this.emitInput();
},
emitInput() {
this.$emit('input', this.editValue.length > 0 ? this.editValue : undefined, this.component, this.property.name, this.oldValue);
},
getEntity(link) {
if (link) {
let {type, uuid} = getUUIDFromLink(link);
if (type === 'entity') {
let _entity = getCurrentScene().findEntityByUUID(uuid);
if (_entity) {
return _entity;
}
}
}
},
getMethodName({entity: entityLink, component, method}, index) {
let entity = this.getEntity(entityLink);
if (entity) {
let comp = entity.components[component];
if (comp) {
let declare = getClassDeclare(comp.script);
return declare.className + '.' + method;
}
return '';
} else {
return '';
}
}
}
}
</script>
<style scoped>
.wrapper {
border-radius: 3px;
width: 100%;
height: 100%;
padding: 5px;
}
.header {
display: flex;
align-items: center;
justify-content: space-between;
}
.event-name {
}
.list {
}
.event-item {
display: flex;
flex-direction: column;
margin: 3px 0;
}
.method-path {
display: flex;
align-items: flex-end;
margin-bottom: 5px;
}
.params-box{
display: flex;
align-items: center;
}
.param-input{
flex: 1;
margin-right: 5px;
}
.entity-linker {
flex: 1;
}
.method-menu {
height: 28px;
padding: 0 3px;
border-radius: 3px;
text-overflow: ellipsis;
white-space: nowrap;
overflow: hidden;
}
.method-menu:focus {
outline: none;
}
.method-name-container {
width: 120px;
margin: 0 5px;
}
.mini-button {
padding: 3px !important;
}
</style>
\ No newline at end of file
<template> <template>
<el-dialog :title="$t('Project details')" width="70%" :visible.sync="visible" @open="onOpen" <el-dialog :title="$t('Project details')" width="70%" :visible.sync="visible" @open="onOpen"
:close-on-click-modal="false" :close-on-click-modal="false"
:append-to-body="true"> :append-to-body="true"
:show-close="false"
>
<div class="project-details-dialog"> <div class="project-details-dialog">
<el-form v-model="project"> <el-form @submit.native.prevent ref="form" :model="launchOptions" size="mini" label-position="right" label-width="150px">
<el-form-item prop=""> <el-form-item prop="entrySceneView" label="Entry scene view">
<el-select v-model="launchOptions.entrySceneView">
<el-option v-for="(view, index) in project.data.views"
:key="index"
:value="view.name"
:label="view.name"
></el-option>
</el-select>
</el-form-item>
<el-form-item prop="containerID" label="Container ID">
<el-input v-model="launchOptions.containerID"/>
</el-form-item>
<el-form-item prop="designWidth" label="Design width">
<el-input-number v-model="launchOptions.designWidth" controls-position="right"/>
</el-form-item>
<el-form-item prop="designHeight" label="Design height">
<el-input-number v-model="launchOptions.designHeight" controls-position="right"/>
</el-form-item>
<el-form-item prop="frameRate" label="Frame Rate">
<el-input-number v-model="launchOptions.frameRate" :max="60" :min="0" controls-position="right"/>
</el-form-item>
<el-form-item prop="scaleMode" label="Scale Mode">
<el-select v-model="launchOptions.scaleMode">
<el-option v-for="(value, key) in SCALE_MODES"
:key="key"
:value="value"
:label="key"
></el-option>
</el-select>
</el-form-item>
<el-form-item prop="rendererType" label="Renderer Type">
<el-select v-model="launchOptions.rendererType">
<el-option v-for="(value, key) in RENDERER_TYPES"
:key="key"
:value="value"
:label="key"
></el-option>
</el-select>
</el-form-item> </el-form-item>
</el-form> </el-form>
</div> </div>
<div slot="footer" class="dialog-footer"> <div slot="footer" class="dialog-footer">
<el-button size="mini" @click="visible=false">{{$t('Cancel')}}</el-button> <el-button size="mini" @click="onCancel">{{$t('Cancel')}}</el-button>
<el-button size="mini" type="primary" @click="onConfirm">{{$t('Save')}}</el-button> <el-button size="mini" type="primary" @click="onConfirm">{{$t('Save')}}</el-button>
</div> </div>
</el-dialog> </el-dialog>
</template> </template>
<script> <script>
import {mapState} from 'vuex'; import {mapState, mapGetters} from 'vuex';
import {RENDERER_TYPES, SCALE_MODES} from "../../../utils";
export default { export default {
name: "ProjectDetailsDialog", name: "ProjectDetailsDialog",
data() { data() {
return { return {
visible: false, visible: false,
SCALE_MODES,
RENDERER_TYPES,
} }
}, },
computed: { computed: {
...mapState([ ...mapGetters([
'project', 'launchOptions',
]), ]),
...mapState([
'project'
])
}, },
methods: { methods: {
show(){ show() {
this.visible = true; this.visible = true;
}, },
onConfirm(){ onCancel() {
this.$refs.form.resetFields();
this.visible = false;
},
onConfirm() {
this.visible = false;
}, },
onOpen(){ onOpen() {
}, },
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment