Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Z
zeroing-editor
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
劳工
zeroing-editor
Commits
c9a419ca
Commit
c9a419ca
authored
Nov 09, 2019
by
rockyl
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
增加行为解释器
增加项目详情编辑
parent
0a0442d1
Changes
22
Hide whitespace changes
Inline
Side-by-side
Showing
22 changed files
with
676 additions
and
510 deletions
+676
-510
index.js
mock/api/project/query/data/index.js
+160
-2
en.json
src/locales/en.json
+2
-0
behavior.js
src/store/modules/behavior.js
+14
-1
project.js
src/store/modules/project.js
+22
-2
behavior.scss
src/themes/light/behavior.scss
+16
-3
index.scss
src/themes/light/index.scss
+1
-1
inspector.scss
src/themes/light/inspector.scss
+4
-0
common.js
src/utils/common.js
+220
-209
events.js
src/utils/events.js
+1
-1
index.js
src/utils/index.js
+14
-0
properties.js
src/utils/properties.js
+56
-5
PropsTab.vue
src/views/Editor/Inspector/PropsTab.vue
+2
-1
ProcessNode.vue
src/views/Editor/behavior-editor/Board/ProcessNode.vue
+22
-6
MetaEditorDialog.vue
src/views/Editor/behavior-editor/MetaEditorDialog.vue
+9
-3
OptionsEditorDialog.vue
src/views/Editor/behavior-editor/OptionsEditorDialog.vue
+3
-0
PropertiesEditor.vue
src/views/Editor/behavior-editor/PropertiesEditor.vue
+5
-1
AssetEditor.vue
src/views/Editor/behavior-editor/editors/AssetEditor.vue
+45
-0
ColorEditor.vue
src/views/Editor/behavior-editor/editors/ColorEditor.vue
+4
-4
EnumEditor.vue
src/views/Editor/behavior-editor/editors/EnumEditor.vue
+16
-3
EnumSelect.vue
.../Editor/behavior-editor/editors/EnumEditor/EnumSelect.vue
+0
-49
EventEditor.vue
src/views/Editor/behavior-editor/editors/EventEditor.vue
+0
-207
ProjectDetailsDialog.vue
src/views/Editor/dialogs/ProjectDetailsDialog.vue
+60
-12
No files found.
mock/api/project/query/data/index.js
View file @
c9a419ca
...
...
@@ -19,6 +19,7 @@ const data = {
"x"
:
10
,
"y"
:
10
},
"uuid"
:
"f97bbf76-6923-4669-b5a3-e6382753e49a"
,
events
:
{
click
:
{
once
:
false
,
...
...
@@ -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"
:
[],
processes
:
[
{
...
...
@@ -91,6 +247,8 @@ const data = {
num
:
{
alias
:
'数字'
,
type
:
'number'
,
default
:
1
},
type
:
{
alias
:
'类型'
,
type
:
'enum'
,
enum
:
[
'rotate'
,
'jump'
,
'breath'
],
default
:
'rotate'
},
autoPlay
:
{
alias
:
'自动播放'
,
type
:
'boolean'
,
default
:
false
},
color
:
{
alias
:
'颜色'
,
type
:
'color'
,
default
:
'#123456'
},
asset
:
{
alias
:
'素材'
,
type
:
'asset'
,},
},
output
:
[
'success'
,
'failed'
],
script
:
"console.log('test');"
,
...
...
src/locales/en.json
View file @
c9a419ca
...
...
@@ -67,8 +67,10 @@
"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!"
,
"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"
:
{
"save"
:
"Save"
,
"details"
:
"Details"
,
"preview"
:
"Preview"
,
"publish"
:
"Publish"
,
"data-mapping"
:
"DataMapping"
,
...
...
src/store/modules/behavior.js
View file @
c9a419ca
...
...
@@ -69,7 +69,7 @@ export const behaviorStore = {
break
;
}
}
}
}
,
},
getters
:
{
customProcessMap
:
state
=>
{
...
...
@@ -89,6 +89,19 @@ export const behaviorStore = {
}
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
:
{
addCustomProcessMeta
({
commit
,
state
})
{
...
...
src/store/modules/project.js
View file @
c9a419ca
...
...
@@ -9,12 +9,27 @@ import generateUUID from "uuid/v4";
import
{
getCmpProps
,
flattenViews
,
getCmpByUUID
}
from
'../../utils/common'
;
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
=
{
state
:
{
id
:
''
,
name
:
''
,
creator
:
''
,
data
:
{
launchOptions
:
{},
views
:
[],
assets
:
[],
dataMapping
:
[],
...
...
@@ -41,12 +56,14 @@ export const projectStore = {
const
localData
=
state
.
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
,
'assets'
,
assets
||
[]);
Vue
.
set
(
localData
,
'dataMapping'
,
dataMapping
||
[]);
Vue
.
set
(
localData
,
'processes'
,
processes
||
[]);
}
else
{
Vue
.
set
(
localData
,
'launchOptions'
,
getDefaultLaunchOptions
());
Vue
.
set
(
localData
,
'views'
,
[]);
Vue
.
set
(
localData
,
'assets'
,
[]);
Vue
.
set
(
localData
,
'dataMapping'
,
[]);
...
...
@@ -258,6 +275,9 @@ export const projectStore = {
}
return
result
;
},
launchOptions
(
state
){
return
state
.
data
.
launchOptions
;
},
/**
* 当前激活的组件
*/
...
...
@@ -287,7 +307,7 @@ export const projectStore = {
let
result
=
flattenViews
(
_
.
cloneDeep
(
_view
));
// console.log('componentList', result);
return
result
;
}
}
,
},
actions
:
{
saveToLocal
({
getters
,
commit
})
{
...
...
src/themes/light/behavior.scss
View file @
c9a419ca
...
...
@@ -133,12 +133,13 @@ $dock-point-width: 9px;
flex-direction
:
column
;
padding
:
3px
;
font-size
:
12px
;
color
:
$--color-text-
primary
;
color
:
$--color-text-
regular
;
.field-item
{
display
:
flex
;
align-items
:
center
;
span
{
&
>
*
{
flex
:
1
;
white-space
:
nowrap
;
...
...
@@ -149,9 +150,17 @@ $dock-point-width: 9px;
}
.value
{
.
string-
value
{
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;
padding-right
:
5px
;
}
.el-select
{
width
:
100%
;
}
.wrapper
{
padding
:
5px
;
flex
:
1
;
...
...
src/themes/light/index.scss
View file @
c9a419ca
...
...
@@ -44,6 +44,6 @@
}
.el-tabs--border-card
>
.el-tabs__content
{
padding
:
5px
;
padding
:
5px
0
5px
5px
;
}
src/themes/light/inspector.scss
View file @
c9a419ca
...
...
@@ -20,6 +20,10 @@
.zero-inspector-props-form
{
height
:
100%
;
.el-form
{
padding-right
:
10px
;
}
.el-input-number.el-input-number--mini
,
.el-select.el-select--mini
{
width
:
100%
;
}
...
...
src/utils/common.js
View file @
c9a419ca
import
_
from
'lodash'
;
import
properties
from
'./properties'
;
export
const
componentsMap
=
[{
label
:
'文本'
,
value
:
'label'
},
{
label
:
'图片'
,
value
:
'image'
},
{
label
:
'视图'
,
value
:
'node'
},
{
label
:
'形状'
,
value
:
'rect'
}];
export
const
componentsMap
=
[
{
label
:
'文本'
,
value
:
'label'
},
{
label
:
'图片'
,
value
:
'image'
},
{
label
:
'视图'
,
value
:
'node'
},
{
label
:
'矩形'
,
value
:
'rect'
},
/*{
label: '圆形',
value: 'circle'
},*/
];
// 属性的计算方法
const
propsComputeRules
=
{
x
:
'add'
,
y
:
'add'
,
rotate
:
'add'
,
scaleX
:
'multi'
,
scaleY
:
'multi'
,
alpha
:
'multi'
,
visible
:
'visible'
}
x
:
'add'
,
y
:
'add'
,
rotate
:
'add'
,
scaleX
:
'multi'
,
scaleY
:
'multi'
,
alpha
:
'multi'
,
visible
:
'visible'
}
;
const
isClient
=
typeof
window
!==
'undefined'
;
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
)
{
return
!
key
||
typeof
value
===
'undefined'
||
value
===
''
;
return
!
key
||
typeof
value
===
'undefined'
||
value
===
''
;
}
// 属性简称 对照表
const
attrShortMapper
=
{
x
:
'left'
,
y
:
'top'
,
align
:
'text-align'
,
size
:
'font-size'
,
alpha
:
'opacity'
,
'strokeColor'
:
'border-color'
,
'strokeWidth'
:
'border-width'
,
'fillColor'
:
'background-color'
,
'source'
:
'background-image'
x
:
'left'
,
y
:
'top'
,
align
:
'text-align'
,
size
:
'font-size'
,
alpha
:
'opacity'
,
'strokeColor'
:
'border-color'
,
'strokeWidth'
:
'border-width'
,
'fillColor'
:
'background-color'
,
'source'
:
'background-image'
};
// 编辑时想拖拽组件需要生成的css属性
...
...
@@ -53,229 +64,229 @@ const operatProps = ['x', 'y', 'width', 'height', 'rotate'];
// 属性单位 对照表, 如果是数值的时候需要添加单位
const
attrUnitMapper
=
{
x
:
'px'
,
y
:
'px'
,
width
:
'px'
,
height
:
'px'
,
fontSize
:
'px'
,
size
:
'px'
,
letterSpacing
:
'px'
,
borderRadius
:
'px'
,
borderWidth
:
'px'
,
strokeWidth
:
'px'
,
minHeight
:
'px'
x
:
'px'
,
y
:
'px'
,
width
:
'px'
,
height
:
'px'
,
fontSize
:
'px'
,
size
:
'px'
,
letterSpacing
:
'px'
,
borderRadius
:
'px'
,
borderWidth
:
'px'
,
strokeWidth
:
'px'
,
minHeight
:
'px'
};
/**
* 根据uuid,从list中找到所有父组件
* @param {*} uuid
* @param {*} list
* @param {*} uuid
* @param {*} list
*/
function
getParentCmps
(
uuid
,
list
)
{
let
_self
=
list
.
find
(
c
=>
c
.
uuid
===
uuid
);
let
_self
=
list
.
find
(
c
=>
c
.
uuid
===
uuid
);
let
parentLoop
=
(
uuid
,
list
)
=>
{
let
_item
=
list
.
find
(
c
=>
c
.
uuid
===
uuid
);
return
_item
.
parent
?
[
_item
].
concat
(
parentLoop
(
_item
.
parent
,
list
))
:
[
_item
];
}
let
parentLoop
=
(
uuid
,
list
)
=>
{
let
_item
=
list
.
find
(
c
=>
c
.
uuid
===
uuid
);
return
_item
.
parent
?
[
_item
].
concat
(
parentLoop
(
_item
.
parent
,
list
))
:
[
_item
];
}
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
)
{
if
(
!
uuid
)
{
return
null
;
}
let
_node
=
views
.
find
(
v
=>
v
.
uuid
===
uuid
);
if
(
_node
)
{
return
_node
}
else
{
for
(
let
index
=
0
;
index
<
views
.
length
;
index
++
)
{
if
(
views
[
index
].
children
&&
views
[
index
].
children
.
length
)
{
return
getCmpByUUID
(
uuid
,
views
[
index
].
children
)
}
}
}
if
(
!
uuid
)
{
return
null
;
}
let
_node
=
views
.
find
(
v
=>
v
.
uuid
===
uuid
);
if
(
_node
)
{
return
_node
}
else
{
for
(
let
index
=
0
;
index
<
views
.
length
;
index
++
)
{
if
(
views
[
index
].
children
&&
views
[
index
].
children
.
length
)
{
return
getCmpByUUID
(
uuid
,
views
[
index
].
children
)
}
}
}
}
/**
* 扁平化视图数组
* @param {*} views
* @param {*} views
*/
export
const
flattenViews
=
function
(
views
)
{
return
views
.
reduce
((
flat
,
toFlat
)
=>
{
if
(
toFlat
.
children
)
{
let
_children
=
toFlat
.
children
.
map
(
c
=>
{
c
.
parent
=
toFlat
.
uuid
;
return
c
;
});
return
flat
.
concat
([
toFlat
].
concat
(
flattenViews
(
_children
)));
}
else
{
return
flat
.
concat
([
toFlat
]);
}
},
[]);
return
views
.
reduce
((
flat
,
toFlat
)
=>
{
if
(
toFlat
.
children
)
{
let
_children
=
toFlat
.
children
.
map
(
c
=>
{
c
.
parent
=
toFlat
.
uuid
;
return
c
;
});
return
flat
.
concat
([
toFlat
].
concat
(
flattenViews
(
_children
)));
}
else
{
return
flat
.
concat
([
toFlat
]);
}
},
[]);
}
/**
* 根据propsComputeRules的计算规则,继承父级的属性
* @param {*} props
* @param {*} parent
* @param {*} props
* @param {*} parent
*/
function
inheritProps
(
props
,
parent
)
{
_
.
forIn
(
parent
,
(
value
,
key
)
=>
{
let
rule
=
propsComputeRules
[
key
];
// 加法
if
(
rule
===
'add'
)
{
props
[
key
]
+=
parent
[
key
];
}
// 乘法
if
(
rule
===
'multi'
)
{
props
[
key
]
*=
parent
[
key
];
}
// 可见,特殊处理
if
(
rule
===
'visible'
)
{
props
[
key
]
=
!
props
[
key
]
||
!
parent
[
key
]
?
false
:
true
;
}
});
_
.
forIn
(
parent
,
(
value
,
key
)
=>
{
let
rule
=
propsComputeRules
[
key
];
// 加法
if
(
rule
===
'add'
)
{
props
[
key
]
+=
parent
[
key
];
}
// 乘法
if
(
rule
===
'multi'
)
{
props
[
key
]
*=
parent
[
key
];
}
// 可见,特殊处理
if
(
rule
===
'visible'
)
{
props
[
key
]
=
!
props
[
key
]
||
!
parent
[
key
]
?
false
:
true
;
}
});
}
/**
* 根据组件type 依赖properties.js构建组件完整的属性对象
* @param {*} component
* @param {*} component
*/
function
completeSelfProps
(
component
)
{
// 根据组件类型,获取默认属性
let
defaultProps
=
getCmpProps
(
component
.
type
);
// 根据组件类型,获取默认属性
let
defaultProps
=
getCmpProps
(
component
.
type
);
// omit从defaultProps中过滤出组件properties中没有的属性,格式参考properties.js
defaultProps
=
_
.
omit
(
defaultProps
,
_
.
keys
(
component
.
properties
));
// 再把这些属性格式转换成key: value
defaultProps
=
_
.
mapValues
(
defaultProps
,
o
=>
(
o
.
value
));
// omit从defaultProps中过滤出组件properties中没有的属性,格式参考properties.js
defaultProps
=
_
.
omit
(
defaultProps
,
_
.
keys
(
component
.
properties
));
// 再把这些属性格式转换成key: value
defaultProps
=
_
.
mapValues
(
defaultProps
,
o
=>
(
o
.
value
));
// 将组件properties中的属性和默认属性拼装成组件自身的属性
return
{
...
component
.
properties
,
...
defaultProps
}
// 将组件properties中的属性和默认属性拼装成组件自身的属性
return
{
...
component
.
properties
,
...
defaultProps
}
}
export
const
styles
=
{
getStyles
(
value
,
key
)
{
const
attr
=
attrShortMapper
[
key
]
||
changeCamle
(
key
);
const
unit
=
attrUnitMapper
[
key
]
||
''
;
getStyles
(
value
,
key
)
{
const
attr
=
attrShortMapper
[
key
]
||
changeCamle
(
key
);
const
unit
=
attrUnitMapper
[
key
]
||
''
;
if
(
invalidAttr
(
key
,
value
))
return
''
;
if
(
invalidAttr
(
key
,
value
))
return
''
;
switch
(
attr
)
{
case
'rotate'
:
return
[
'transform'
,
[
`rotate(
${
value
}
deg)`
]];
//`transform: rotate(${value}deg);`;
case
'background-image'
:
return
[
'background-image'
,
[
`url(
${
value
}
)`
]];
//`background-image: url(${value});background-position:center;background-size:contain;`;
// case 'scale-x':
// return ['transform', [`scaleX(${value})`]]; //`transform: scaleX(${value});`;
// case 'scale-y':
// return ['transform', [`scaleY(${value})`]]; //`transform: scaleY(${value});`;
case
'visible'
:
return
[
'display'
,
[
value
?
'block'
:
'none'
]];
// `display: ${value ? 'block' : 'none'};`;
default
:
return
[
attr
,
[
`
${
value
}${
Number
.
isNaN
(
value
)
?
''
:
unit
}
`
]];
//`${attr}:${value}${Number.isNaN(value) ? '' : unit};`;
}
},
/**
* 根据Object类型的属性对象,生成dom中style属性可用的数据格式
* @param {*} obj
*/
getStylesFromObj
(
obj
,
project
)
{
let
resultObj
=
{};
switch
(
attr
)
{
case
'rotate'
:
return
[
'transform'
,
[
`rotate(
${
value
}
deg)`
]];
//`transform: rotate(${value}deg);`;
case
'background-image'
:
return
[
'background-image'
,
[
`url(
${
value
}
)`
]];
//`background-image: url(${value});background-position:center;background-size:contain;`;
// case 'scale-x':
// return ['transform', [`scaleX(${value})`]]; //`transform: scaleX(${value});`;
// case 'scale-y':
// return ['transform', [`scaleY(${value})`]]; //`transform: scaleY(${value});`;
case
'visible'
:
return
[
'display'
,
[
value
?
'block'
:
'none'
]];
// `display: ${value ? 'block' : 'none'};`;
default
:
return
[
attr
,
[
`
${
value
}${
Number
.
isNaN
(
value
)
?
''
:
unit
}
`
]];
//`${attr}:${value}${Number.isNaN(value) ? '' : unit};`;
}
},
/**
* 根据Object类型的属性对象,生成dom中style属性可用的数据格式
* @param {*} obj
*/
getStylesFromObj
(
obj
,
project
)
{
let
resultObj
=
{};
_
.
forIn
(
obj
,
(
value
,
key
)
=>
{
if
(
key
===
'source'
&&
value
.
indexOf
(
'asset://'
)
===
0
)
{
let
uuid
=
value
.
split
(
'//'
)[
1
];
let
asset
=
project
.
data
.
assets
.
find
(
a
=>
a
.
uuid
===
uuid
);
value
=
asset
?
asset
.
url
:
''
;
}
let
_style
=
styles
.
getStyles
(
value
,
key
);
if
(
!
_style
)
{
return
;
}
if
(
resultObj
[
_style
[
0
]])
{
resultObj
[
_style
[
0
]]
=
resultObj
[
_style
[
0
]].
concat
(
_style
[
1
]);
}
else
{
resultObj
[
_style
[
0
]]
=
_style
[
1
];
}
});
return
resultObj
;
},
/**
* 根据组件数据,生成完整的style
* @param {*} component
*/
getComponentStyle
(
component
,
project
,
componentList
,
onlyOpera
)
{
if
(
!
component
||
!
component
.
uuid
)
{
return
''
;
}
// debugger;
let
result
=
''
;
let
cmpSelfProps
=
completeSelfProps
(
component
);
_
.
forIn
(
obj
,
(
value
,
key
)
=>
{
if
(
key
===
'source'
&&
value
.
indexOf
(
'asset://'
)
===
0
)
{
let
uuid
=
value
.
split
(
'//'
)[
1
];
let
asset
=
project
.
data
.
assets
.
find
(
a
=>
a
.
uuid
===
uuid
);
value
=
asset
?
asset
.
url
:
''
;
}
let
_style
=
styles
.
getStyles
(
value
,
key
);
if
(
!
_style
)
{
return
;
}
if
(
resultObj
[
_style
[
0
]])
{
resultObj
[
_style
[
0
]]
=
resultObj
[
_style
[
0
]].
concat
(
_style
[
1
]);
}
else
{
resultObj
[
_style
[
0
]]
=
_style
[
1
];
}
});
return
resultObj
;
},
/**
* 根据组件数据,生成完整的style
* @param {*} component
*/
getComponentStyle
(
component
,
project
,
componentList
,
onlyOpera
)
{
if
(
!
component
||
!
component
.
uuid
)
{
return
''
;
}
// debugger;
let
result
=
''
;
let
cmpSelfProps
=
completeSelfProps
(
component
);
// 根据uuid获取节点的所有父节点
let
propsMatrix
=
getParentCmps
(
component
.
uuid
,
componentList
);
propsMatrix
=
propsMatrix
.
map
(
completeSelfProps
);
// console.log('propsMatrix', propsMatrix);
if
(
propsMatrix
.
length
)
{
propsMatrix
.
forEach
(
prop
=>
{
inheritProps
(
cmpSelfProps
,
prop
);
});
}
// 根据uuid获取节点的所有父节点
let
propsMatrix
=
getParentCmps
(
component
.
uuid
,
componentList
);
propsMatrix
=
propsMatrix
.
map
(
completeSelfProps
);
// console.log('propsMatrix', propsMatrix);
if
(
propsMatrix
.
length
)
{
propsMatrix
.
forEach
(
prop
=>
{
inheritProps
(
cmpSelfProps
,
prop
);
});
}
if
(
cmpSelfProps
.
scaleX
)
{
cmpSelfProps
.
width
*=
cmpSelfProps
.
scaleX
;
}
if
(
cmpSelfProps
.
scaleX
)
{
cmpSelfProps
.
width
*=
cmpSelfProps
.
scaleX
;
}
if
(
cmpSelfProps
.
scaleY
)
{
cmpSelfProps
.
height
*=
cmpSelfProps
.
scaleY
;
}
if
(
cmpSelfProps
.
scaleY
)
{
cmpSelfProps
.
height
*=
cmpSelfProps
.
scaleY
;
}
if
(
onlyOpera
)
{
_
.
forIn
(
cmpSelfProps
,
(
val
,
key
)
=>
{
if
(
operatProps
.
indexOf
(
key
)
===
-
1
)
{
delete
cmpSelfProps
[
key
];
}
});
}
if
(
onlyOpera
)
{
_
.
forIn
(
cmpSelfProps
,
(
val
,
key
)
=>
{
if
(
operatProps
.
indexOf
(
key
)
===
-
1
)
{
delete
cmpSelfProps
[
key
];
}
});
}
// console.log('cmpSelfProps after inherit ', cmpSelfProps);
cmpSelfProps
=
styles
.
getStylesFromObj
(
cmpSelfProps
,
project
);
_
.
forIn
(
cmpSelfProps
,
(
value
,
key
)
=>
{
result
+=
`
${
key
}
:
${
value
.
join
(
' '
)}
;`
if
(
key
===
'border-color'
)
{
result
+=
'border-style: solid;'
}
});
result
+=
`background-position: center;background-size: 100% 100%;`
// console.log('cmpSelfProps after inherit ', cmpSelfProps);
cmpSelfProps
=
styles
.
getStylesFromObj
(
cmpSelfProps
,
project
);
_
.
forIn
(
cmpSelfProps
,
(
value
,
key
)
=>
{
result
+=
`
${
key
}
:
${
value
.
join
(
' '
)}
;`
if
(
key
===
'border-color'
)
{
result
+=
'border-style: solid;'
}
});
result
+=
`background-position: center;background-size: 100% 100%;`
// console.log('getComponentStyle', result);
return
result
;
}
// console.log('getComponentStyle', result);
return
result
;
}
}
export
const
getCmpProps
=
function
(
type
)
{
if
(
!
type
)
{
return
{}
}
else
{
let
_nodeProps
=
_
.
cloneDeep
(
properties
.
node
);
let
_typeProps
=
{};
if
(
type
!==
'node'
)
{
_typeProps
=
_
.
cloneDeep
(
properties
[
type
]);
}
let
result
=
{
...
_nodeProps
,
...
_typeProps
};
delete
result
.
groupName
;
if
(
!
type
)
{
return
{}
}
else
{
let
_nodeProps
=
_
.
cloneDeep
(
properties
.
node
);
let
_typeProps
=
{};
if
(
type
!==
'node'
)
{
_typeProps
=
_
.
cloneDeep
(
properties
[
type
]);
}
let
result
=
{
...
_nodeProps
,
...
_typeProps
};
delete
result
.
groupName
;
return
result
}
return
result
}
}
\ No newline at end of file
src/utils/events.js
View file @
c9a419ca
export
default
[
'click'
,
'touchstart'
,
'touchend'
,
'touchmove'
]
\ No newline at end of file
export
default
[
'init'
,
'click'
,
'dataevent'
,
'touchstart'
,
'touchend'
,
'touchmove'
]
\ No newline at end of file
src/utils/index.js
View file @
c9a419ca
...
...
@@ -6,6 +6,20 @@ import {Message, Loading} from "element-ui";
import
i18n
from
'../i18n'
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
)
{
Message
({
dangerouslyUseHTMLString
:
true
,
...
...
src/utils/properties.js
View file @
c9a419ca
...
...
@@ -66,7 +66,27 @@ export default {
width
:
40
},
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
:
{
groupName
:
'文本'
,
...
...
@@ -88,7 +108,7 @@ export default {
},
value
:
12
},
a
lign
:
{
textA
lign
:
{
title
:
'文本对齐'
,
type
:
'select'
,
options
:
[
...
...
@@ -97,7 +117,17 @@ export default {
{
label
:
'靠右'
,
value
:
'right'
}
],
value
:
'left'
}
},
/*verticalAlign: {
title: '纵向对齐',
type: 'select',
options: [
{ label: '靠上', value: 'up' },
{ label: '居中', value: 'middle' },
{ label: '靠下', value: 'down' }
],
value: 'up'
},*/
},
image
:
{
groupName
:
'来源'
,
...
...
@@ -108,7 +138,7 @@ export default {
}
},
rect
:
{
groupName
:
'
形状
'
,
groupName
:
'
矩形
'
,
fillColor
:
{
title
:
'填充色'
,
type
:
'colorPicker'
,
...
...
@@ -127,5 +157,26 @@ export default {
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
}
}
},
}
src/views/Editor/Inspector/PropsTab.vue
View file @
c9a419ca
...
...
@@ -86,7 +86,8 @@ const componentMapper = {
inputNumber
:
{
component
:
'el-input-number'
,
props
:
{
size
:
'mini'
size
:
'mini'
,
'controls-position'
:
'right'
}
},
input
:
{
...
...
src/views/Editor/behavior-editor/Board/ProcessNode.vue
View file @
c9a419ca
...
...
@@ -4,12 +4,16 @@
@mouseleave="onMouseLeave" @click="onClick" @dblclick="onDblclick">
<div
class=
"header"
>
<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
class=
"body"
>
<div
class=
"field-item"
v-for=
"(param, key, index) in meta.options"
:key=
"index"
>
<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
ref=
"inputDock"
class=
"dock input"
>
...
...
@@ -30,7 +34,7 @@
import
DockPoint
from
"./DockPoint"
;
import
{
state
}
from
"./state"
;
import
events
from
"../../../../global-events"
;
//todo 容器坐标改变影响节点坐标
//todo 容器坐标改变影响节点坐标
export
default
{
name
:
"ProcessNode"
,
components
:
{
DockPoint
},
...
...
@@ -69,6 +73,18 @@
},
},
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
()
{
let
{
design
,
options
,
output
}
=
this
.
process
.
data
;
if
(
!
design
)
{
...
...
@@ -94,7 +110,7 @@
onDblclick
(
e
)
{
this
.
$emit
(
'dblclick'
,
e
);
},
setActive
(
active
){
setActive
(
active
)
{
this
.
active
=
active
;
},
onMouseEnter
(
e
)
{
...
...
@@ -135,8 +151,8 @@
this
.
$emit
(
'change-position'
,
this
,
this
);
}
},
updateSize
(){
this
.
$nextTick
(()
=>
{
updateSize
()
{
this
.
$nextTick
(()
=>
{
let
bounds
=
this
.
$refs
.
node
.
getBoundingClientRect
();
this
.
width
=
bounds
.
width
+
18
;
this
.
height
=
bounds
.
height
;
...
...
src/views/Editor/behavior-editor/MetaEditorDialog.vue
View file @
c9a419ca
...
...
@@ -75,10 +75,16 @@
this
.
$refs
.
optionsEditorDialog
.
edit
(
this
.
meta
.
options
);
},
save
()
{
this
.
$emit
(
'input'
,
this
.
meta
);
this
.
visible
=
false
;
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
.
visible
=
false
;
}
},
cancel
(){
cancel
()
{
this
.
visible
=
false
;
}
}
...
...
src/views/Editor/behavior-editor/OptionsEditorDialog.vue
View file @
c9a419ca
...
...
@@ -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-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-color-picker
v-if=
"scope.row.option.type === 'color'"
class=
"default-value"
v-model=
"scope.row.option.default"
size=
"mini"
/>
</
template
>
</el-table-column>
<el-table-column
...
...
@@ -92,6 +93,8 @@
'string'
,
'number'
,
'enum'
,
'color'
,
'asset'
,
],
}
},
...
...
src/views/Editor/behavior-editor/PropertiesEditor.vue
View file @
c9a419ca
...
...
@@ -24,17 +24,21 @@
import
StringEditor
from
"./editors/StringEditor"
;
import
EnumEditor
from
"./editors/EnumEditor"
;
import
BooleanEditor
from
"./editors/BooleanEditor"
;
import
ColorEditor
from
"./editors/ColorEditor"
;
import
AssetEditor
from
"./editors/AssetEditor"
;
const
editorMapping
=
{
number
:
'NumberEditor'
,
string
:
'StringEditor'
,
enum
:
'EnumEditor'
,
boolean
:
'BooleanEditor'
,
color
:
'ColorEditor'
,
asset
:
'AssetEditor'
,
};
export
default
{
name
:
"PropertiesEditor"
,
components
:
{
BooleanEditor
,
EnumEditor
,
NumberEditor
,
StringEditor
},
components
:
{
AssetEditor
,
ColorEditor
,
BooleanEditor
,
EnumEditor
,
NumberEditor
,
StringEditor
},
data
()
{
return
{
process
:
null
,
...
...
src/views/Editor/behavior-editor/editors/AssetEditor.vue
0 → 100644
View file @
c9a419ca
<
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
>
src/views/Editor/behavior-editor/editors/ColorEditor.vue
View file @
c9a419ca
<
template
>
<editor-wrapper
:property=
"property"
class=
"color-editor-container"
>
<editor-wrapper
:property=
"property"
:propertyName=
"propertyName"
class=
"color-editor-container"
>
<el-color-picker
class=
"picker"
:value=
"editValue"
...
...
@@ -16,7 +16,7 @@
export
default
{
name
:
"ColorEditor"
,
components
:
{
EditorWrapper
,},
props
:
[
'
component'
,
'value'
,
'property
'
],
props
:
[
'
value'
,
'container'
,
'property'
,
'propertyName
'
],
data
()
{
return
{
predefineColors
:
[
...
...
@@ -39,13 +39,13 @@
},
computed
:
{
editValue
()
{
return
this
.
value
===
undefined
?
this
.
property
.
default
Value
:
this
.
value
;
return
this
.
value
===
undefined
?
this
.
property
.
default
:
this
.
value
;
},
},
methods
:
{
onInput
(
v
)
{
if
(
v
!==
this
.
value
)
{
this
.
$emit
(
'input'
,
v
,
this
.
co
mponent
,
this
.
property
.
n
ame
,
this
.
value
);
this
.
$emit
(
'input'
,
v
,
this
.
co
ntainer
,
this
.
propertyN
ame
,
this
.
value
);
}
}
},
...
...
src/views/Editor/behavior-editor/editors/EnumEditor.vue
View file @
c9a419ca
<
template
>
<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>
</
template
>
<
script
>
import
EnumSelect
from
"./EnumEditor/EnumSelect"
;
import
EditorWrapper
from
"./EditorWrapper"
;
export
default
{
name
:
"EnumEditor"
,
components
:
{
E
numSelect
,
E
ditorWrapper
,},
components
:
{
EditorWrapper
,},
props
:
[
'value'
,
'container'
,
'property'
,
'propertyName'
],
computed
:
{
editValue
()
{
return
this
.
value
===
undefined
?
this
.
property
.
default
:
this
.
value
;
},
},
methods
:
{
onInput
(
v
,
oldValue
){
if
(
v
!==
this
.
value
){
...
...
src/views/Editor/behavior-editor/editors/EnumEditor/EnumSelect.vue
deleted
100644 → 0
View file @
0a0442d1
<
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
src/views/Editor/behavior-editor/editors/EventEditor.vue
deleted
100644 → 0
View file @
0a0442d1
<
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
src/views/Editor/dialogs/ProjectDetailsDialog.vue
View file @
c9a419ca
<
template
>
<el-dialog
:title=
"$t('Project details')"
width=
"70%"
:visible
.
sync=
"visible"
@
open=
"onOpen"
:close-on-click-modal=
"false"
:append-to-body=
"true"
>
:append-to-body=
"true"
:show-close=
"false"
>
<div
class=
"project-details-dialog"
>
<el-form
v-model=
"project"
>
<el-form-item
prop=
""
>
<el-form
@
submit
.
native
.
prevent
ref=
"form"
:model=
"launchOptions"
size=
"mini"
label-position=
"right"
label-width=
"150px"
>
<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>
</div>
<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>
</div>
</el-dialog>
</
template
>
<
script
>
import
{
mapState
}
from
'vuex'
;
import
{
mapState
,
mapGetters
}
from
'vuex'
;
import
{
RENDERER_TYPES
,
SCALE_MODES
}
from
"../../../utils"
;
export
default
{
name
:
"ProjectDetailsDialog"
,
data
()
{
return
{
visible
:
false
,
SCALE_MODES
,
RENDERER_TYPES
,
}
},
computed
:
{
...
map
State
([
'
project
'
,
...
map
Getters
([
'
launchOptions
'
,
]),
...
mapState
([
'project'
])
},
methods
:
{
show
(){
show
()
{
this
.
visible
=
true
;
},
onConfirm
(){
onCancel
()
{
this
.
$refs
.
form
.
resetFields
();
this
.
visible
=
false
;
},
onConfirm
()
{
this
.
visible
=
false
;
},
onOpen
(){
onOpen
()
{
},
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment