mirror of
https://github.com/tidys/cc-inspector-chrome
synced 2025-04-19 16:38:41 +00:00
终于把属性对接完了
This commit is contained in:
parent
004b8f8241
commit
b7dbec512a
@ -4,7 +4,8 @@ export enum BusMsg {
|
|||||||
ShowPlace = "ShowPlace",
|
ShowPlace = "ShowPlace",
|
||||||
RequestObjectData = "RequestObjectData",
|
RequestObjectData = "RequestObjectData",
|
||||||
LogData = "LogData",
|
LogData = "LogData",
|
||||||
FoldAllGroup = "FoldAllGroup"
|
FoldAllGroup = "FoldAllGroup",
|
||||||
|
UpdateSettings = "UpdateSettings",
|
||||||
}
|
}
|
||||||
|
|
||||||
export default new TinyEmitter();
|
export default new TinyEmitter();
|
||||||
|
@ -47,13 +47,17 @@ class ConnectBackground implements TestClient {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
postMessageToBackground(msg: Msg, data?: any) {
|
postMessageToBackground(msg: Msg, data?: any) {
|
||||||
if (this.connect) {
|
if (CCP.Adaptation.Env.isChromeDevtools) {
|
||||||
let sendData = new PluginEvent(Page.Devtools, Page.Background, msg, data)
|
if (this.connect) {
|
||||||
this.connect.postMessage(sendData)
|
let sendData = new PluginEvent(Page.Devtools, Page.Background, msg, data)
|
||||||
|
this.connect.postMessage(sendData)
|
||||||
|
} else {
|
||||||
|
console.warn("重新和background建立链接")
|
||||||
|
this._initConnect();
|
||||||
|
this.postMessageToBackground(msg, data)
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
console.warn("重新和background建立链接")
|
testServer.recv(msg, data);
|
||||||
this._initConnect();
|
|
||||||
this.postMessageToBackground(msg, data)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6,6 +6,7 @@ export enum DataType {
|
|||||||
Text = 'Text',
|
Text = 'Text',
|
||||||
Vec2 = 'Vec2',
|
Vec2 = 'Vec2',
|
||||||
Vec3 = 'Vec3',
|
Vec3 = 'Vec3',
|
||||||
|
Vec4 = 'Vec4',
|
||||||
Enum = 'Enum',
|
Enum = 'Enum',
|
||||||
Bool = 'Bool',
|
Bool = 'Bool',
|
||||||
Color = 'Color',
|
Color = 'Color',
|
||||||
@ -29,6 +30,7 @@ export class Info {
|
|||||||
public isEnum(): boolean { return false; }
|
public isEnum(): boolean { return false; }
|
||||||
public isVec2(): boolean { return false; }
|
public isVec2(): boolean { return false; }
|
||||||
public isVec3(): boolean { return false; }
|
public isVec3(): boolean { return false; }
|
||||||
|
public isVec4(): boolean { return false; }
|
||||||
public isBool(): boolean { return false; }
|
public isBool(): boolean { return false; }
|
||||||
public isText(): boolean { return false; }
|
public isText(): boolean { return false; }
|
||||||
public isString(): boolean { return false; }
|
public isString(): boolean { return false; }
|
||||||
@ -43,15 +45,19 @@ export class Info {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export class TextData extends Info {
|
export class TextData extends Info {
|
||||||
constructor() {
|
constructor(data: string = "") {
|
||||||
super();
|
super();
|
||||||
this.type = DataType.Text;
|
this.type = DataType.Text;
|
||||||
|
this.data = data;
|
||||||
}
|
}
|
||||||
public isText(): boolean { return true; }
|
public isText(): boolean { return true; }
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ObjectItemRequestData {
|
export interface ObjectItemRequestData {
|
||||||
id: string | null;
|
id: string | null;
|
||||||
|
/**
|
||||||
|
* 该对象拥有的所有属性
|
||||||
|
*/
|
||||||
data: Property[];
|
data: Property[];
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -60,6 +66,9 @@ export interface FrameDetails {
|
|||||||
url: string;
|
url: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 组件里面定义了引擎类型的数据,比如 `@property(cc.Label)`
|
||||||
|
*/
|
||||||
export class EngineData extends Info {
|
export class EngineData extends Info {
|
||||||
public engineType: string = "";
|
public engineType: string = "";
|
||||||
public engineUUID: string = "";
|
public engineUUID: string = "";
|
||||||
@ -85,6 +94,7 @@ export class ArrayData extends Info {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
public isArray(): boolean { return true; }
|
public isArray(): boolean { return true; }
|
||||||
|
public isArrayOrObject(): boolean { return true; }
|
||||||
}
|
}
|
||||||
|
|
||||||
export class ObjectDataItem extends Info {
|
export class ObjectDataItem extends Info {
|
||||||
@ -98,6 +108,7 @@ export class ObjectData extends Info {
|
|||||||
this.type = DataType.Object;
|
this.type = DataType.Object;
|
||||||
}
|
}
|
||||||
public isObject(): boolean { return true; }
|
public isObject(): boolean { return true; }
|
||||||
|
public isArrayOrObject(): boolean { return true; }
|
||||||
}
|
}
|
||||||
|
|
||||||
export class InvalidData extends Info {
|
export class InvalidData extends Info {
|
||||||
@ -184,7 +195,24 @@ export class Vec3Data extends Info {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
export class Vec4Data extends Vec2Data {
|
||||||
|
data: Array<Property> = [];
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
super();
|
||||||
|
this.type = DataType.Vec4;
|
||||||
|
this.data = [];
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
add(info: Property) {
|
||||||
|
this.data.push(info);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
public isVec4(): boolean {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
export class ImageData extends Info {
|
export class ImageData extends Info {
|
||||||
data: string | null = null;
|
data: string | null = null;
|
||||||
|
|
||||||
@ -226,6 +254,9 @@ export class Property {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export class Group {
|
export class Group {
|
||||||
|
/**
|
||||||
|
* 节点的UUID
|
||||||
|
*/
|
||||||
public id: string = "";
|
public id: string = "";
|
||||||
public name: string = "group";
|
public name: string = "group";
|
||||||
public data: Array<Property> = [];
|
public data: Array<Property> = [];
|
||||||
|
@ -137,7 +137,7 @@ export default defineComponent({
|
|||||||
if (item.id === targetUUID) {
|
if (item.id === targetUUID) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (circle(item.children)) {
|
if (circle(item.children || [])) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -147,6 +147,9 @@ export default defineComponent({
|
|||||||
return circle(data);
|
return circle(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 请求属性的列表,如果一个属性请求失败,会阻断后续的相同请求,因为都已经失败了,就没必要再响应请求了
|
||||||
|
*/
|
||||||
const requestList: Array<{ id: string; cb: Function }> = [];
|
const requestList: Array<{ id: string; cb: Function }> = [];
|
||||||
|
|
||||||
function _expand(uuid: string) {
|
function _expand(uuid: string) {
|
||||||
@ -205,7 +208,6 @@ export default defineComponent({
|
|||||||
if (!Array.isArray(data)) {
|
if (!Array.isArray(data)) {
|
||||||
data = [data];
|
data = [data];
|
||||||
}
|
}
|
||||||
console.log(data);
|
|
||||||
treeData.value = data;
|
treeData.value = data;
|
||||||
if (_checkSelectedUUID()) {
|
if (_checkSelectedUUID()) {
|
||||||
updateNodeInfo();
|
updateNodeInfo();
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import { Msg, Page, PluginEvent } from "../../../core/types";
|
import { Msg, Page, PluginEvent } from "../../../core/types";
|
||||||
import { NodeInfoData, TreeData } from "../data";
|
import { ArrayData, BoolData, ColorData, EngineData, EnumData, Group, Info, NodeInfoData, NumberData, ObjectData, ObjectItemRequestData, Property, StringData, TextData, TreeData, Vec2Data, Vec3Data, Vec4Data } from "../data";
|
||||||
export class TestClient {
|
export class TestClient {
|
||||||
recv(event: PluginEvent) {
|
recv(event: PluginEvent) {
|
||||||
|
|
||||||
@ -13,26 +13,134 @@ export class TestServer {
|
|||||||
recv(msg: string, data: any) {
|
recv(msg: string, data: any) {
|
||||||
switch (msg) {
|
switch (msg) {
|
||||||
case Msg.NodeInfo: {
|
case Msg.NodeInfo: {
|
||||||
console.log(data);
|
const id: string = data as string;
|
||||||
|
|
||||||
|
const group = new Group("test");
|
||||||
|
{
|
||||||
|
const text = new TextData("text1");
|
||||||
|
group.addProperty(new Property("text", text))
|
||||||
|
}
|
||||||
|
{
|
||||||
|
const number = new NumberData(100);
|
||||||
|
group.addProperty(new Property("number", number))
|
||||||
|
}
|
||||||
|
{
|
||||||
|
const str = new StringData("str");
|
||||||
|
group.addProperty(new Property("str", str))
|
||||||
|
}
|
||||||
|
{
|
||||||
|
const v2 = new Vec2Data();
|
||||||
|
v2.add(new Property("x", new NumberData(100)));
|
||||||
|
v2.add(new Property("y", new NumberData(200)));
|
||||||
|
group.addProperty(new Property("v2", v2))
|
||||||
|
}
|
||||||
|
{
|
||||||
|
const v3 = new Vec3Data();
|
||||||
|
v3.add(new Property("x", new NumberData(100)));
|
||||||
|
v3.add(new Property("y", new NumberData(200)));
|
||||||
|
v3.add(new Property("z", new NumberData(300)));
|
||||||
|
group.addProperty(new Property("v3", v3))
|
||||||
|
}
|
||||||
|
{
|
||||||
|
const v4 = new Vec4Data();
|
||||||
|
v4.add(new Property("x", new NumberData(100)));
|
||||||
|
v4.add(new Property("y", new NumberData(200)));
|
||||||
|
v4.add(new Property("z", new NumberData(300)));
|
||||||
|
v4.add(new Property("w", new NumberData(400)));
|
||||||
|
group.addProperty(new Property("v4", v4))
|
||||||
|
}
|
||||||
|
{
|
||||||
|
const b = new BoolData(true);
|
||||||
|
group.addProperty(new Property("bool", b))
|
||||||
|
}
|
||||||
|
{
|
||||||
|
const e = new EnumData();
|
||||||
|
e.values.push({ name: "a", value: 1 });
|
||||||
|
e.values.push({ name: "b", value: 2 });
|
||||||
|
group.addProperty(new Property("enum", e))
|
||||||
|
}
|
||||||
|
{
|
||||||
|
const c = new ColorData('#f00');
|
||||||
|
group.addProperty(new Property("color", c))
|
||||||
|
}
|
||||||
|
{
|
||||||
|
const arr = new ArrayData();
|
||||||
|
arr.add(new Property("item1", new TextData("text")));
|
||||||
|
arr.add(new Property("item2", new BoolData(true)));
|
||||||
|
group.addProperty(new Property("arr", arr))
|
||||||
|
}
|
||||||
|
{
|
||||||
|
const obj = new ObjectData();
|
||||||
|
obj.data = JSON.stringify({ fack: 'test' });
|
||||||
|
group.addProperty(new Property("obj", obj));
|
||||||
|
}
|
||||||
|
{
|
||||||
|
const engine = new EngineData();
|
||||||
|
engine.engineName = "engineName";
|
||||||
|
engine.engineType = "engineType";
|
||||||
|
engine.engineUUID = "engineUUID";
|
||||||
|
group.addProperty(new Property("engine", engine))
|
||||||
|
}
|
||||||
|
{
|
||||||
|
const engine = new EngineData();
|
||||||
|
engine.engineName = "engineName";
|
||||||
|
engine.engineType = "cc_Node";
|
||||||
|
engine.engineUUID = "engineUUID";
|
||||||
|
group.addProperty(new Property("engine", engine))
|
||||||
|
}
|
||||||
|
{
|
||||||
|
const engine = new EngineData();
|
||||||
|
engine.engineName = "engineName";
|
||||||
|
engine.engineType = "cc_Srpite";
|
||||||
|
engine.engineUUID = "engineUUID";
|
||||||
|
group.addProperty(new Property("engine", engine))
|
||||||
|
}
|
||||||
|
{
|
||||||
|
const engine = new EngineData();
|
||||||
|
engine.engineName = "engineName";
|
||||||
|
engine.engineType = "cc_Label";
|
||||||
|
engine.engineUUID = "engineUUID";
|
||||||
|
group.addProperty(new Property("engine", engine))
|
||||||
|
}
|
||||||
const ret: NodeInfoData = {
|
const ret: NodeInfoData = {
|
||||||
uuid: "1",
|
uuid: id,
|
||||||
group: []
|
group: [group,]
|
||||||
};
|
};
|
||||||
const event = new PluginEvent(Page.Background, Page.Devtools, Msg.NodeInfo, ret);
|
const event = new PluginEvent(Page.Background, Page.Devtools, Msg.NodeInfo, ret);
|
||||||
this.send(event);
|
this.send(event);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case Msg.TreeInfo: {
|
case Msg.TreeInfo: {
|
||||||
const data: TreeData = {
|
const ret: TreeData = {
|
||||||
id: "1",
|
id: "root",
|
||||||
text: "root",
|
text: "root",
|
||||||
active: true,
|
active: true,
|
||||||
children: [],
|
children: [],
|
||||||
};
|
};
|
||||||
const event = new PluginEvent(Page.Inject, Page.Devtools, Msg.TreeInfo, data);
|
const event = new PluginEvent(Page.Inject, Page.Devtools, Msg.TreeInfo, ret);
|
||||||
this.send(event);
|
this.send(event);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case Msg.SetProperty: {
|
||||||
|
console.log(data);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case Msg.GetObjectItemData: {
|
||||||
|
const d = data as ObjectData;
|
||||||
|
const property = [];
|
||||||
|
property.push(new Property("fake", new TextData('test')));
|
||||||
|
const ret: ObjectItemRequestData = {
|
||||||
|
id: d.id,
|
||||||
|
data: property,
|
||||||
|
}
|
||||||
|
const event = new PluginEvent(Page.Inject, Page.Devtools, Msg.GetObjectItemData, ret);
|
||||||
|
this.send(event)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case Msg.LogData: {
|
||||||
|
console.log(data);
|
||||||
|
break;
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
111
cc-inspector/src/views/devtools/ui/property-engine.vue
Normal file
111
cc-inspector/src/views/devtools/ui/property-engine.vue
Normal file
@ -0,0 +1,111 @@
|
|||||||
|
<template>
|
||||||
|
<div class="property-engine">
|
||||||
|
<i class="icon iconfont" :class="getEngineTypeIcon()"></i>
|
||||||
|
<div class="type">{{ data.engineType }}</div>
|
||||||
|
<div class="name">{{ data.engineName }}</div>
|
||||||
|
<div class="place" @click="onPlaceInTree">
|
||||||
|
<i class="iconfont icon_place"></i>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts">
|
||||||
|
import ccui from "@xuyanfeng/cc-ui";
|
||||||
|
import { defineComponent, PropType, ref } from "vue";
|
||||||
|
import Bus, { BusMsg } from "../bus";
|
||||||
|
import { EngineData, NumberData, Property } from "../data";
|
||||||
|
export default defineComponent({
|
||||||
|
name: "property-engine",
|
||||||
|
components: {},
|
||||||
|
props: {
|
||||||
|
data: {
|
||||||
|
type: Object as PropType<EngineData>,
|
||||||
|
default: () => new EngineData(),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
setup(props, context) {
|
||||||
|
return {
|
||||||
|
onPlaceInTree() {
|
||||||
|
Bus.emit(BusMsg.ShowPlace, props.data);
|
||||||
|
},
|
||||||
|
getEngineTypeIcon() {
|
||||||
|
console.log(props.data.engineType);
|
||||||
|
switch (props.data.engineType) {
|
||||||
|
case "cc_Sprite": {
|
||||||
|
return "icon_picture";
|
||||||
|
}
|
||||||
|
case "cc_Label": {
|
||||||
|
return "icon_text";
|
||||||
|
}
|
||||||
|
case "cc_Node": {
|
||||||
|
return "icon_node";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return "icon_unknown";
|
||||||
|
},
|
||||||
|
};
|
||||||
|
},
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped lang="less">
|
||||||
|
@my-height: 20px;
|
||||||
|
.property-engine {
|
||||||
|
height: @my-height;
|
||||||
|
box-sizing: border-box;
|
||||||
|
flex: 1;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
border: solid #409eff 1px;
|
||||||
|
border-radius: 3px;
|
||||||
|
align-items: center;
|
||||||
|
align-content: center;
|
||||||
|
background-color: cornflowerblue;
|
||||||
|
height: @my-height;
|
||||||
|
align-items: center;
|
||||||
|
align-content: center;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
|
||||||
|
.icon {
|
||||||
|
font-size: 14px;
|
||||||
|
width: @my-height;
|
||||||
|
margin: 0 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.type {
|
||||||
|
text-align: left;
|
||||||
|
flex: 1;
|
||||||
|
color: white;
|
||||||
|
font-size: 12px;
|
||||||
|
display: flex;
|
||||||
|
align-content: center;
|
||||||
|
height: @my-height;
|
||||||
|
padding: 0 5px;
|
||||||
|
background-color: rgb(48, 158, 0);
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.name {
|
||||||
|
font-size: 12px;
|
||||||
|
color: white;
|
||||||
|
flex: 1;
|
||||||
|
height: @my-height;
|
||||||
|
background-color: rgb(184, 157, 5);
|
||||||
|
display: flex;
|
||||||
|
padding: 0 5px;
|
||||||
|
align-items: center;
|
||||||
|
align-content: center;
|
||||||
|
}
|
||||||
|
.place {
|
||||||
|
padding: 0 5px;
|
||||||
|
cursor: pointer;
|
||||||
|
&:hover {
|
||||||
|
color: #6d6d6d;
|
||||||
|
}
|
||||||
|
&:active {
|
||||||
|
color: #000000;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
@ -1,48 +1,19 @@
|
|||||||
<template>
|
<template>
|
||||||
<div id="ui-prop">
|
<div class="ui-prop">
|
||||||
<div class="normal-data" style="display: flex; flex-direction: row; align-items: center; min-height: 30px; margin: 0">
|
<CCProp :name="name" :icon="icon" :head-width="headWidth" v-model:expand="expand" :arrow="value.isArrayOrObject()" :slide="value.isNumber()" :indent="indent * 10" @change-expand="onClickFold">
|
||||||
<div @mousedown="onPropNameMouseDown" class="key" @click="onClickFold" :style="{ cursor: isArrayOrObject() ? 'pointer' : '' }">
|
<div class="prop-value">
|
||||||
<i
|
|
||||||
class="data-arrow"
|
|
||||||
v-if="arrow"
|
|
||||||
:class="fold ? 'iconfont icon_arrow_right' : 'iconfont icon_arrow_down'"
|
|
||||||
:style="{
|
|
||||||
visibility: isArrayOrObject() ? 'visible' : 'hidden',
|
|
||||||
'margin-left': indent * 10 + 'px',
|
|
||||||
}"
|
|
||||||
>
|
|
||||||
</i>
|
|
||||||
<div class="text" ref="propText">
|
|
||||||
<!-- 使用CCProp -->
|
|
||||||
<!-- <el-popover
|
|
||||||
placement="top"
|
|
||||||
trigger="hover"
|
|
||||||
:disabled="!isShowTooltip()"
|
|
||||||
>
|
|
||||||
<div>{{ name }}</div>
|
|
||||||
<span>{{ name }}</span>
|
|
||||||
</el-popover> -->
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="value">
|
|
||||||
<div v-if="value.isInvalid()" class="invalid">
|
<div v-if="value.isInvalid()" class="invalid">
|
||||||
{{ value.data }}
|
{{ value.data }}
|
||||||
</div>
|
</div>
|
||||||
<CCInput v-if="value.isString()" v-model="value.data" :disabled="value.readonly" @change="onChangeValue"> </CCInput>
|
<CCInput v-if="value.isString()" v-model:value="value.data" :disabled="value.readonly" @change="onChangeValue"> </CCInput>
|
||||||
<CCInput v-if="value.isText()" type="textarea" :autosize="{ minRows: 3, maxRows: 5 }" placeholder="请输入内容" :disabled="value.readonly" @change="onChangeValue" v-model="value.data"> </CCInput>
|
<CCTextarea v-if="value.isText()" v-model:value="value.data" :disabled="value.readonly" @change="onChangeValue"> </CCTextarea>
|
||||||
<CCInputNumber v-if="value.isNumber()" style="width: 100%; text-align: left" v-model="value.data" :step="step" :disabled="value.readonly" @change="onChangeValue" controls-position="right"></CCInputNumber>
|
<CCInputNumber v-if="value.isNumber()" v-model:value="value.data" :step="step" :disabled="value.readonly" @change="onChangeValue"></CCInputNumber>
|
||||||
|
<div v-if="value.isVec2() || value.isVec3() || value.isVec4()" class="vec">
|
||||||
<div v-if="value.isVec2() || value.isVec3()" class="vec">
|
<UiProp v-for="(vec, index) in value.data" :icon="!!index" head-width="auto" :key="index" :arrow="false" :value="vec.value" :name="vec.name"> </UiProp>
|
||||||
<ui-prop v-for="(vec, index) in value.data" :key="index" :arrow="false" :value="vec.value" :name="vec.name"> </ui-prop>
|
|
||||||
</div>
|
|
||||||
<CCSelect v-model="value.data" :disabled="value.readonly" :data="getEnumValues(value)" v-if="value.isEnum()" style="width: 100%" @change="onChangeValue"> </CCSelect>
|
|
||||||
<CCCheckBox v-model="value.data" v-if="value.isBool()" :disabled="value.readonly" @change="onChangeValue"> </CCCheckBox>
|
|
||||||
<div class="color" v-if="value.isColor()">
|
|
||||||
<CCColor style="position: absolute" :disabled="value.readonly" v-model="value.data" @change="onChangeValue"> </CCColor>
|
|
||||||
<div class="hex" :style="{ color: colorReverse(value.data) }">
|
|
||||||
{{ value.data }}
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
<CCSelect v-if="value.isEnum()" v-model:value="value.data" :disabled="value.readonly" :data="getEnumValues(value)" @change="onChangeValue"> </CCSelect>
|
||||||
|
<CCCheckBox v-if="value.isBool()" v-model:value="value.data" :disabled="value.readonly" @change="onChangeValue"> </CCCheckBox>
|
||||||
|
<CCColor v-if="value.isColor()" :show-color-text="true" :disabled="value.readonly" v-model:color="value.data" @change="onChangeValue"> </CCColor>
|
||||||
<div v-if="value.isImage()" class="image-property">
|
<div v-if="value.isImage()" class="image-property">
|
||||||
<!-- TODO: 适配 -->
|
<!-- TODO: 适配 -->
|
||||||
<div v-if="value.isImage() || true" placement="top" trigger="hover">
|
<div v-if="value.isImage() || true" placement="top" trigger="hover">
|
||||||
@ -55,28 +26,14 @@
|
|||||||
<CCButton @click="onShowValueInConsole">log</CCButton>
|
<CCButton @click="onShowValueInConsole">log</CCButton>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div v-if="value.isEngine()" class="engine">
|
<Engine v-if="value.isEngine()" v-model:data="(value as EngineData)"> </Engine>
|
||||||
<div class="head">
|
<div v-if="value.isObject() && !expand" class="objectDesc">{{ value.data }}</div>
|
||||||
<i class="icon" :class="getEngineTypeIcon()"></i>
|
<div v-if="value.isArray()" class="array">Array[{{ value.data.length }}]</div>
|
||||||
<div class="type">{{ value["engineType"] }}</div>
|
|
||||||
</div>
|
|
||||||
<div class="name">{{ value["engineName"] }}</div>
|
|
||||||
<CCButton @click="onPlaceInTree" type="primary">
|
|
||||||
<i class="iconfont icon_place"></i>
|
|
||||||
</CCButton>
|
|
||||||
</div>
|
|
||||||
<div v-if="value.isObject() && fold" class="objectDesc">
|
|
||||||
{{ value.data }}
|
|
||||||
</div>
|
|
||||||
<div v-if="value.isArray()" class="array">Array({{ value.data.length }})</div>
|
|
||||||
<div class="slot" v-if="false">
|
|
||||||
<slot></slot>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</CCProp>
|
||||||
<div v-if="isArrayOrObject()">
|
<div v-if="value.isArrayOrObject()">
|
||||||
<div v-show="!fold && subData" style="display: flex; flex-direction: column">
|
<div v-show="expand && subData">
|
||||||
<ui-prop v-for="(arr, index) in subData" :key="index" :indent="indent + 1" :value="arr.value" :name="getName(value.isArray(), arr)"> </ui-prop>
|
<UiProp v-for="(arr, index) in subData" :key="index" :indent="indent + 1" :value="arr.value" :name="getName(value.isArray(), arr)"> </UiProp>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -89,38 +46,33 @@ import { defineComponent, onMounted, onUnmounted, PropType, ref, toRaw, watch }
|
|||||||
import { Msg } from "../../../core/types";
|
import { Msg } from "../../../core/types";
|
||||||
import Bus, { BusMsg } from "../bus";
|
import Bus, { BusMsg } from "../bus";
|
||||||
import { connectBackground } from "../connectBackground";
|
import { connectBackground } from "../connectBackground";
|
||||||
import { DataType, EngineData, EnumData, Info, Property } from "../data";
|
import { DataType, EngineData, EnumData, Info, NumberData, Property, StringData, TextData, Vec2Data, Vec3Data } from "../data";
|
||||||
const { CCInput, CCButton, CCInputNumber, CCSelect, CCCheckBox, CCColor } = ccui.components;
|
import Engine from "./property-engine.vue";
|
||||||
|
const { CCInput, CCTextarea, CCProp, CCButton, CCInputNumber, CCSelect, CCCheckBox, CCColor } = ccui.components;
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
name: "UiProp",
|
name: "ui-prop",
|
||||||
components: {
|
components: { CCProp, Engine, CCTextarea, CCInput, CCButton, CCInputNumber, CCSelect, CCCheckBox, CCColor },
|
||||||
CCInput,
|
|
||||||
CCButton,
|
|
||||||
CCInputNumber,
|
|
||||||
CCSelect,
|
|
||||||
CCCheckBox,
|
|
||||||
CCColor,
|
|
||||||
},
|
|
||||||
props: {
|
props: {
|
||||||
name: { type: String, default: "" },
|
name: { type: String, default: "" },
|
||||||
indent: { type: Number, default: 0 },
|
indent: { type: Number, default: 0 },
|
||||||
arrow: { type: Boolean, default: true },
|
icon: { type: Boolean, default: true },
|
||||||
|
headWidth: { type: String, default: "120px" },
|
||||||
|
arrow: { type: Boolean, default: false },
|
||||||
step: { type: Number, default: 1 },
|
step: { type: Number, default: 1 },
|
||||||
value: {
|
value: {
|
||||||
type: Object as PropType<Info | EngineData | EnumData>,
|
type: Object as PropType<Info | EngineData | EnumData | NumberData | StringData | TextData | Vec2Data | Vec3Data>,
|
||||||
default: () => {},
|
default: () => {},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
setup(props, { emit }) {
|
setup(props, { emit }) {
|
||||||
const { value, step } = props;
|
const { value, step } = props;
|
||||||
const fold = ref(true);
|
const expand = ref(false);
|
||||||
let clientX: number = 0;
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
watchValue();
|
watchValue();
|
||||||
});
|
});
|
||||||
function watchValue() {
|
function watchValue() {
|
||||||
fold.value = true;
|
// fold.value = true;
|
||||||
if (value.isArray()) {
|
if (value.isArray()) {
|
||||||
subData.value = value.data;
|
subData.value = value.data;
|
||||||
} else {
|
} else {
|
||||||
@ -130,32 +82,10 @@ export default defineComponent({
|
|||||||
watch(props.value, () => {
|
watch(props.value, () => {
|
||||||
watchValue();
|
watchValue();
|
||||||
});
|
});
|
||||||
const subData = ref<Property[]>([]);
|
const subData = ref<Array<Property> | null>(null);
|
||||||
const propText = ref<HTMLDivElement>();
|
|
||||||
|
|
||||||
function _onMouseMove(event: MouseEvent) {
|
|
||||||
let x = event.clientX;
|
|
||||||
let calcStep = step || 0;
|
|
||||||
if (x > clientX) {
|
|
||||||
calcStep = Math.abs(calcStep);
|
|
||||||
} else {
|
|
||||||
calcStep = -Math.abs(calcStep);
|
|
||||||
}
|
|
||||||
emit("movestep", calcStep);
|
|
||||||
clientX = x;
|
|
||||||
}
|
|
||||||
|
|
||||||
function _onMouseUp(event: MouseEvent) {
|
|
||||||
document.removeEventListener("mousemove", _onMouseMove);
|
|
||||||
document.removeEventListener("mouseup", _onMouseUp);
|
|
||||||
document.removeEventListener("onselectstart", _onSelect);
|
|
||||||
}
|
|
||||||
function _onSelect() {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return {
|
return {
|
||||||
fold,
|
expand,
|
||||||
propText,
|
|
||||||
subData,
|
subData,
|
||||||
getEnumValues(data: any): Option[] {
|
getEnumValues(data: any): Option[] {
|
||||||
const value: EnumData = data;
|
const value: EnumData = data;
|
||||||
@ -168,56 +98,30 @@ export default defineComponent({
|
|||||||
});
|
});
|
||||||
return ret;
|
return ret;
|
||||||
},
|
},
|
||||||
isArrayOrObject() {
|
|
||||||
return value && (value.isArray() || value.isObject());
|
|
||||||
},
|
|
||||||
isImageValid() {
|
isImageValid() {
|
||||||
return !!value.data;
|
return !!value.data;
|
||||||
},
|
},
|
||||||
onPlaceInTree() {
|
|
||||||
Bus.emit(BusMsg.ShowPlace, value);
|
|
||||||
},
|
|
||||||
isShowTooltip() {
|
|
||||||
const el: HTMLDivElement = propText.value as HTMLDivElement;
|
|
||||||
if (el) {
|
|
||||||
if (el.scrollWidth > el.offsetWidth) {
|
|
||||||
// 出现了省略号
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
},
|
|
||||||
getEngineTypeIcon() {
|
|
||||||
switch ((value as EngineData).engineType) {
|
|
||||||
case "cc_Sprite": {
|
|
||||||
return "icon_picture";
|
|
||||||
}
|
|
||||||
case "cc_Label": {
|
|
||||||
return "icon_text";
|
|
||||||
}
|
|
||||||
case "cc_Node": {
|
|
||||||
return "icon_node";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return "icon_unknown";
|
|
||||||
},
|
|
||||||
getName(isArray: boolean, arr: Property) {
|
getName(isArray: boolean, arr: Property) {
|
||||||
const type = arr.value.type;
|
const type = arr.value.type;
|
||||||
if (isArray) {
|
if (isArray) {
|
||||||
return `[${arr.name}]`;
|
return arr.name;
|
||||||
} else {
|
} else {
|
||||||
return arr.name;
|
return arr.name;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
onClickFold() {
|
onClickFold(v: boolean) {
|
||||||
if (value.isObject() && fold && !subData) {
|
if (value.isArray()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const s = toRaw(subData.value);
|
||||||
|
const e = toRaw(expand.value);
|
||||||
|
if (value.isObject() && s === null && e === true) {
|
||||||
// 请求object的item数据
|
// 请求object的item数据
|
||||||
Bus.emit(BusMsg.RequestObjectData, value, (info: Property[]) => {
|
Bus.emit(BusMsg.RequestObjectData, toRaw(value), (info: Property[]) => {
|
||||||
fold.value = false;
|
|
||||||
subData.value = info;
|
subData.value = info;
|
||||||
});
|
});
|
||||||
} else {
|
|
||||||
fold.value = !fold.value;
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
onShowValueInConsole() {
|
onShowValueInConsole() {
|
||||||
@ -231,35 +135,93 @@ export default defineComponent({
|
|||||||
},
|
},
|
||||||
onChangeValue() {
|
onChangeValue() {
|
||||||
if (!value.readonly) {
|
if (!value.readonly) {
|
||||||
connectBackground.postMessageToBackground(Msg.SetProperty, value);
|
connectBackground.postMessageToBackground(Msg.SetProperty, toRaw(value));
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
onPropNameMouseDown(event: MouseEvent) {
|
|
||||||
document.addEventListener("mousemove", _onMouseMove);
|
|
||||||
document.addEventListener("mouseup", _onMouseUp);
|
|
||||||
document.addEventListener("onselectstart", _onSelect);
|
|
||||||
},
|
|
||||||
colorReverse(OldColorValue: string) {
|
|
||||||
OldColorValue = "0x" + OldColorValue.replace(/#/g, "");
|
|
||||||
var str = "000000" + (0xffffff - parseInt(OldColorValue)).toString(16);
|
|
||||||
return "#" + str.substring(str.length - 6, str.length);
|
|
||||||
},
|
|
||||||
_onMouseMove,
|
|
||||||
_onMouseUp,
|
|
||||||
_onSelect,
|
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="less">
|
<style scoped lang="less">
|
||||||
#ui-prop {
|
.ui-prop {
|
||||||
min-height: 30px;
|
min-height: 30px;
|
||||||
margin: 1px 0;
|
margin: 1px 0;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
|
.prop-value {
|
||||||
|
flex: 3;
|
||||||
|
text-align: left;
|
||||||
|
overflow: hidden;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
align-items: flex-start;
|
||||||
|
|
||||||
|
.invalid {
|
||||||
|
color: grey;
|
||||||
|
}
|
||||||
|
|
||||||
|
.objectDesc {
|
||||||
|
white-space: nowrap;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
user-select: none;
|
||||||
|
font-size: 12px;
|
||||||
|
color: #d2d2d2;
|
||||||
|
}
|
||||||
|
|
||||||
|
.array {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
color: #d2d2d2;
|
||||||
|
font-size: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.vec {
|
||||||
|
width: 100%;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
.ui-prop {
|
||||||
|
flex: 1;
|
||||||
|
.cc-prop {
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// #ui-prop:first-child {
|
||||||
|
// margin-left: 0;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// #ui-prop:last-child {
|
||||||
|
// margin-right: 0;
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
|
||||||
|
.array-object {
|
||||||
|
flex: 1;
|
||||||
|
max-width: 100%;
|
||||||
|
overflow: hidden;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.image-property {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
align-content: center;
|
||||||
|
align-items: center;
|
||||||
|
height: 36px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.slot {
|
||||||
|
display: flex;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
.normal-data {
|
.normal-data {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
min-height: 30px;
|
min-height: 30px;
|
||||||
@ -278,13 +240,6 @@ export default defineComponent({
|
|||||||
align-items: center;
|
align-items: center;
|
||||||
min-width: 90px;
|
min-width: 90px;
|
||||||
|
|
||||||
.data-arrow {
|
|
||||||
width: 20px;
|
|
||||||
height: 16px;
|
|
||||||
font-size: 16px;
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
|
|
||||||
.text {
|
.text {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
@ -301,147 +256,6 @@ export default defineComponent({
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.value {
|
|
||||||
flex: 3;
|
|
||||||
text-align: left;
|
|
||||||
height: 100%;
|
|
||||||
overflow: hidden;
|
|
||||||
min-width: 400px;
|
|
||||||
|
|
||||||
.color {
|
|
||||||
position: relative;
|
|
||||||
height: 30px;
|
|
||||||
|
|
||||||
.hex {
|
|
||||||
line-height: 30px;
|
|
||||||
position: relative;
|
|
||||||
text-align: center;
|
|
||||||
user-select: none;
|
|
||||||
pointer-events: none;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.invalid {
|
|
||||||
color: grey;
|
|
||||||
}
|
|
||||||
|
|
||||||
.objectDesc {
|
|
||||||
white-space: nowrap;
|
|
||||||
overflow: hidden;
|
|
||||||
text-overflow: ellipsis;
|
|
||||||
user-select: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.array {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
color: red;
|
|
||||||
}
|
|
||||||
|
|
||||||
.engine {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: row;
|
|
||||||
border: solid #409eff 1px;
|
|
||||||
border-radius: 5px;
|
|
||||||
align-items: center;
|
|
||||||
align-content: center;
|
|
||||||
|
|
||||||
.head {
|
|
||||||
background-color: cornflowerblue;
|
|
||||||
height: 28px;
|
|
||||||
align-items: center;
|
|
||||||
align-content: center;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: row;
|
|
||||||
|
|
||||||
.icon {
|
|
||||||
font-size: 20px;
|
|
||||||
width: 20px;
|
|
||||||
margin-left: 5px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.type {
|
|
||||||
display: flex;
|
|
||||||
align-content: center;
|
|
||||||
align-items: center;
|
|
||||||
margin: 0 5px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.name {
|
|
||||||
flex: 1;
|
|
||||||
height: 28px;
|
|
||||||
padding-left: 5px;
|
|
||||||
background-color: gold;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
align-content: center;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.vec {
|
|
||||||
width: 100%;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: row;
|
|
||||||
align-items: center;
|
|
||||||
|
|
||||||
#ui-prop {
|
|
||||||
margin: 0 10px;
|
|
||||||
flex: 1;
|
|
||||||
|
|
||||||
.normal-data {
|
|
||||||
.value {
|
|
||||||
min-width: 50px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.key {
|
|
||||||
min-width: unset;
|
|
||||||
display: block;
|
|
||||||
margin-right: 5px;
|
|
||||||
flex: unset;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#ui-prop:first-child {
|
|
||||||
margin-left: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ui-prop:last-child {
|
|
||||||
margin-right: 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.array-object {
|
|
||||||
flex: 1;
|
|
||||||
max-width: 100%;
|
|
||||||
overflow: hidden;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: row;
|
|
||||||
align-items: center;
|
|
||||||
|
|
||||||
.text {
|
|
||||||
flex: 1;
|
|
||||||
overflow: hidden;
|
|
||||||
white-space: nowrap;
|
|
||||||
text-overflow: ellipsis;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.image-property {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: row;
|
|
||||||
align-content: center;
|
|
||||||
align-items: center;
|
|
||||||
height: 36px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.slot {
|
|
||||||
display: flex;
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user