You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
180 lines
7.7 KiB
180 lines
7.7 KiB
(function (global) {
|
|
'use strict';
|
|
|
|
/**
|
|
* 属性面板(壳侧):通过 Bridge 读写节点属性。
|
|
* @constructor
|
|
*/
|
|
function InspectorPanel() {
|
|
this.el = null;
|
|
this.body = null;
|
|
this._bridge = null;
|
|
this._uuid = '';
|
|
this._props = null;
|
|
}
|
|
|
|
InspectorPanel.prototype.setBridge = function (bridge) {
|
|
this._bridge = bridge;
|
|
};
|
|
|
|
InspectorPanel.prototype.mount = function () {
|
|
var root = document.createElement('div');
|
|
root.className = 'pw-panel-inner pw-inspector';
|
|
root.style.height = '100%';
|
|
root.style.display = 'flex';
|
|
root.style.flexDirection = 'column';
|
|
root.innerHTML =
|
|
'<div class="pw-panel-body pw-inspector-body" id="pw-inspector-body">' +
|
|
'<div class="pw-inspector-empty">未选中节点</div></div>';
|
|
this.el = root;
|
|
this.body = root.querySelector('#pw-inspector-body');
|
|
return root;
|
|
};
|
|
|
|
InspectorPanel.prototype.loadUuid = function (uuid) {
|
|
var self = this;
|
|
this._uuid = uuid || '';
|
|
if (!this._uuid || !this._bridge) {
|
|
this._props = null;
|
|
if (this.body) this.body.innerHTML = '<div class="pw-inspector-empty">未选中节点</div>';
|
|
return;
|
|
}
|
|
this._bridge.call('node.get', { uuid: this._uuid }).then(function (props) {
|
|
self._props = props;
|
|
self.render();
|
|
}).catch(function () {
|
|
if (self.body) self.body.innerHTML = '<div class="pw-inspector-empty">读取失败</div>';
|
|
});
|
|
};
|
|
|
|
InspectorPanel.prototype.render = function () {
|
|
var body = this.body;
|
|
var p = this._props;
|
|
if (!body) return;
|
|
if (!p) {
|
|
body.innerHTML = '<div class="pw-inspector-empty">未选中节点</div>';
|
|
return;
|
|
}
|
|
var html = [];
|
|
html.push('<section class="pw-insp-section open">');
|
|
html.push('<header class="pw-insp-sec-head" data-toggle="1"><span class="pw-insp-caret"></span><span>节点</span></header>');
|
|
html.push('<div class="pw-insp-sec-body">');
|
|
html.push(rowText('名称', 'name', p.name));
|
|
html.push(rowCheck('激活', 'active', !!p.active));
|
|
html.push(rowNum('Layer', 'layer', p.layer));
|
|
html.push(rowVec3('位置', ['px', 'py', 'pz'], [p.pos.x, p.pos.y, p.pos.z]));
|
|
html.push(rowVec3('旋转', ['rx', 'ry', 'rz'], [p.euler.x, p.euler.y, p.euler.z]));
|
|
html.push(rowVec3('缩放', ['sx', 'sy', 'sz'], [p.scale.x, p.scale.y, p.scale.z]));
|
|
html.push('</div></section>');
|
|
|
|
if (p.ui) {
|
|
html.push('<section class="pw-insp-section open">');
|
|
html.push('<header class="pw-insp-sec-head" data-toggle="1"><span class="pw-insp-caret"></span><span>UITransform</span></header>');
|
|
html.push('<div class="pw-insp-sec-body">');
|
|
html.push(rowVec2('尺寸', ['uiw', 'uih'], [p.ui.width, p.ui.height], ['W', 'H']));
|
|
html.push(rowVec2('锚点', ['uax', 'uay'], [p.ui.anchorX, p.ui.anchorY], ['X', 'Y']));
|
|
html.push('</div></section>');
|
|
}
|
|
|
|
var comps = p.comps || [];
|
|
for (var i = 0; i < comps.length; i++) {
|
|
var c = comps[i];
|
|
html.push('<section class="pw-insp-section open">');
|
|
html.push('<header class="pw-insp-sec-head" data-toggle="1"><span class="pw-insp-caret"></span><span>' +
|
|
escapeHtml(c.name) + '</span></header>');
|
|
html.push('<div class="pw-insp-sec-body">');
|
|
var fields = c.fields || [];
|
|
if (!fields.length) html.push('<div class="pw-insp-muted">无可编辑公开字段</div>');
|
|
for (var f = 0; f < fields.length; f++) {
|
|
var field = fields[f];
|
|
var fid = 'c' + c.index + '_' + field.key;
|
|
if (field.type === 'number') html.push(rowNum(field.key, fid, field.value));
|
|
else if (field.type === 'boolean') html.push(rowCheck(field.key, fid, field.value));
|
|
else html.push(rowText(field.key, fid, field.value));
|
|
}
|
|
html.push('</div></section>');
|
|
}
|
|
|
|
body.innerHTML = html.join('');
|
|
this._bindFields();
|
|
this._bindSections();
|
|
};
|
|
|
|
InspectorPanel.prototype._bindSections = function () {
|
|
var heads = this.body.querySelectorAll('.pw-insp-sec-head[data-toggle]');
|
|
for (var i = 0; i < heads.length; i++) {
|
|
heads[i].addEventListener('click', function (ev) {
|
|
var sec = ev.currentTarget.parentNode;
|
|
if (sec) sec.classList.toggle('open');
|
|
});
|
|
}
|
|
};
|
|
|
|
InspectorPanel.prototype._bindFields = function () {
|
|
var self = this;
|
|
var body = this.body;
|
|
if (!body || !this._bridge || !this._uuid) return;
|
|
var inputs = body.querySelectorAll('[data-fid]');
|
|
for (var i = 0; i < inputs.length; i++) {
|
|
(function (el) {
|
|
var run = function () {
|
|
var fid = el.getAttribute('data-fid');
|
|
var value;
|
|
if (el.type === 'checkbox') value = !!el.checked;
|
|
else if (el.type === 'number') value = parseFloat(el.value);
|
|
else value = el.value;
|
|
self._bridge.call('node.set', { uuid: self._uuid, fid: fid, value: value });
|
|
};
|
|
el.addEventListener('change', run);
|
|
el.addEventListener('input', run);
|
|
})(inputs[i]);
|
|
}
|
|
};
|
|
|
|
function rowText(label, id, value) {
|
|
return '<div class="pw-insp-row"><label class="pw-insp-label">' + escapeHtml(label) +
|
|
'</label><input class="pw-insp-input" data-fid="' + id + '" type="text" value="' +
|
|
escapeAttr(value == null ? '' : String(value)) + '" /></div>';
|
|
}
|
|
function rowNum(label, id, value) {
|
|
return '<div class="pw-insp-row"><label class="pw-insp-label">' + escapeHtml(label) +
|
|
'</label><input class="pw-insp-input pw-insp-num" data-fid="' + id +
|
|
'" type="number" step="any" value="' + (value != null ? value : 0) + '" /></div>';
|
|
}
|
|
function rowCheck(label, id, value) {
|
|
return '<div class="pw-insp-row"><label class="pw-insp-label">' + escapeHtml(label) +
|
|
'</label><label class="pw-insp-check"><input data-fid="' + id + '" type="checkbox"' +
|
|
(value ? ' checked' : '') + ' /><span></span></label></div>';
|
|
}
|
|
function rowVec3(label, ids, values) {
|
|
return '<div class="pw-insp-row pw-insp-vec">' +
|
|
'<label class="pw-insp-label">' + escapeHtml(label) + '</label>' +
|
|
'<div class="pw-insp-xyz">' +
|
|
axis('X', ids[0], values[0]) +
|
|
axis('Y', ids[1], values[1]) +
|
|
axis('Z', ids[2], values[2]) +
|
|
'</div></div>';
|
|
}
|
|
function rowVec2(label, ids, values, axisNames) {
|
|
return '<div class="pw-insp-row pw-insp-vec">' +
|
|
'<label class="pw-insp-label">' + escapeHtml(label) + '</label>' +
|
|
'<div class="pw-insp-xyz">' +
|
|
axis(axisNames[0], ids[0], values[0]) +
|
|
axis(axisNames[1], ids[1], values[1]) +
|
|
'</div></div>';
|
|
}
|
|
function axis(name, id, value) {
|
|
return '<div class="pw-insp-axis"><span class="pw-insp-axis-tag">' + name +
|
|
'</span><input class="pw-insp-input pw-insp-num" data-fid="' + id +
|
|
'" type="number" step="any" value="' + (value != null ? value : 0) + '" /></div>';
|
|
}
|
|
|
|
function escapeHtml(s) {
|
|
return String(s).replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>');
|
|
}
|
|
function escapeAttr(s) {
|
|
return escapeHtml(s).replace(/"/g, '"');
|
|
}
|
|
|
|
global.PWInspectorPanel = InspectorPanel;
|
|
})(window);
|
|
|