mirror of
https://github.com/tengge1/ShadowEditor.git
synced 2026-02-01 16:08:17 +00:00
新增大量ui类。
This commit is contained in:
parent
6c2ccea448
commit
c6e99dfebd
@ -5,6 +5,7 @@ export * from './event/index';
|
||||
export * from './core/index';
|
||||
export * from './command/index';
|
||||
export * from './ui/index';
|
||||
export * from './ui/index';
|
||||
export * from './menu/index';
|
||||
export * from './panel/index';
|
||||
export * from './editor/index';
|
||||
|
||||
35
src/ui2/Boolean.js
Normal file
35
src/ui2/Boolean.js
Normal file
@ -0,0 +1,35 @@
|
||||
import Control from './Control';
|
||||
import Span from './Span';
|
||||
import Checkbox from './Checkbox';
|
||||
import Text from './Text';
|
||||
|
||||
/**
|
||||
* 布尔值
|
||||
* @param {*} options
|
||||
*/
|
||||
function Boolean(options) {
|
||||
Control.call(this, options);
|
||||
options = options || {};
|
||||
};
|
||||
|
||||
Boolean.prototype = Object.create(Control.prototype);
|
||||
Boolean.prototype.constructor = Boolean;
|
||||
|
||||
Boolean.prototype.render = function () {
|
||||
// this.setMarginRight('10px');
|
||||
|
||||
this.checkbox = new Checkbox(boolean);
|
||||
this.text = new Text(text).setMarginLeft('3px');
|
||||
this.parent.appendChild(this.checkbox);
|
||||
this.parent.appendChild(this.text);
|
||||
};
|
||||
|
||||
Boolean.prototype.getValue = function () {
|
||||
return this.checkbox.getValue();
|
||||
};
|
||||
|
||||
Boolean.prototype.setValue = function (value) {
|
||||
return this.checkbox.setValue(value);
|
||||
};
|
||||
|
||||
export default Boolean;
|
||||
@ -0,0 +1,225 @@
|
||||
import Control from './Control';
|
||||
|
||||
/**
|
||||
* 外形
|
||||
* @param {*} options
|
||||
*/
|
||||
function Outliner(options) {
|
||||
Control.call(this, options);
|
||||
options = options || {};
|
||||
this.editor = options.editor || null;
|
||||
}
|
||||
|
||||
Outliner.prototype = Object.create(Control.prototype);
|
||||
Outliner.prototype.constructor = Outliner;
|
||||
|
||||
Outliner.prototype.render = function () {
|
||||
this.dom = document.createElement('div');
|
||||
this.dom.className = 'Outliner';
|
||||
this.dom.tabIndex = 0; // keyup event is ignored without setting tabIndex
|
||||
|
||||
// hack
|
||||
this.scene = this.editor.scene;
|
||||
|
||||
// Prevent native scroll behavior
|
||||
this.dom.addEventListener('keydown', function (event) {
|
||||
switch (event.keyCode) {
|
||||
case 38: // up
|
||||
case 40: // down
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
break;
|
||||
}
|
||||
|
||||
}, false);
|
||||
|
||||
var _this = this;
|
||||
|
||||
// Keybindings to support arrow navigation
|
||||
this.dom.addEventListener('keyup', function (event) {
|
||||
switch (event.keyCode) {
|
||||
case 38: // up
|
||||
_this.selectIndex(scope.selectedIndex - 1);
|
||||
break;
|
||||
case 40: // down
|
||||
_this.selectIndex(scope.selectedIndex + 1);
|
||||
break;
|
||||
}
|
||||
|
||||
}, false);
|
||||
|
||||
_this.parent.appendChild(this.dom);
|
||||
|
||||
this.options = [];
|
||||
this.selectedIndex = - 1;
|
||||
this.selectedValue = null;
|
||||
};
|
||||
|
||||
|
||||
Outliner.prototype = Object.create(Element.prototype);
|
||||
Outliner.prototype.constructor = Outliner;
|
||||
|
||||
Outliner.prototype.selectIndex = function (index) {
|
||||
if (index >= 0 && index < this.options.length) {
|
||||
|
||||
this.setValue(this.options[index].value);
|
||||
|
||||
var changeEvent = document.createEvent('HTMLEvents');
|
||||
changeEvent.initEvent('change', true, true);
|
||||
this.dom.dispatchEvent(changeEvent);
|
||||
}
|
||||
};
|
||||
|
||||
Outliner.prototype.setOptions = function (options) {
|
||||
var _this = this;
|
||||
|
||||
while (_this.dom.children.length > 0) {
|
||||
_this.dom.removeChild(_this.dom.firstChild);
|
||||
}
|
||||
|
||||
function onClick() {
|
||||
_this.setValue(this.value);
|
||||
|
||||
var changeEvent = document.createEvent('HTMLEvents');
|
||||
changeEvent.initEvent('change', true, true);
|
||||
_this.dom.dispatchEvent(changeEvent);
|
||||
}
|
||||
|
||||
// Drag
|
||||
var currentDrag;
|
||||
|
||||
function onDrag(event) {
|
||||
currentDrag = this;
|
||||
}
|
||||
|
||||
function onDragStart(event) {
|
||||
event.dataTransfer.setData('text', 'foo');
|
||||
}
|
||||
|
||||
function onDragOver(event) {
|
||||
if (this === currentDrag) {
|
||||
return;
|
||||
}
|
||||
|
||||
var area = event.offsetY / this.clientHeight;
|
||||
|
||||
if (area < 0.25) {
|
||||
this.className = 'option dragTop';
|
||||
} else if (area > 0.75) {
|
||||
this.className = 'option dragBottom';
|
||||
} else {
|
||||
this.className = 'option drag';
|
||||
}
|
||||
}
|
||||
|
||||
function onDragLeave() {
|
||||
if (this === currentDrag) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.className = 'option';
|
||||
}
|
||||
|
||||
function onDrop(event) {
|
||||
|
||||
if (this === currentDrag) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.className = 'option';
|
||||
|
||||
var scene = _this.scene;
|
||||
var object = scene.getObjectById(currentDrag.value);
|
||||
|
||||
var area = event.offsetY / this.clientHeight;
|
||||
|
||||
if (area < 0.25) {
|
||||
var nextObject = scene.getObjectById(this.value);
|
||||
moveObject(object, nextObject.parent, nextObject);
|
||||
} else if (area > 0.75) {
|
||||
var nextObject = scene.getObjectById(this.nextSibling.value);
|
||||
moveObject(object, nextObject.parent, nextObject);
|
||||
} else {
|
||||
var parentObject = scene.getObjectById(this.value);
|
||||
moveObject(object, parentObject);
|
||||
}
|
||||
}
|
||||
|
||||
function moveObject(object, newParent, nextObject) {
|
||||
if (nextObject === null) nextObject = undefined;
|
||||
|
||||
var newParentIsChild = false;
|
||||
|
||||
object.traverse(function (child) {
|
||||
if (child === newParent) newParentIsChild = true;
|
||||
});
|
||||
|
||||
if (newParentIsChild) return;
|
||||
|
||||
editor.execute(new MoveObjectCommand(object, newParent, nextObject));
|
||||
|
||||
var changeEvent = document.createEvent('HTMLEvents');
|
||||
changeEvent.initEvent('change', true, true);
|
||||
_this.dom.dispatchEvent(changeEvent);
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
_this.options = [];
|
||||
|
||||
for (var i = 0; i < options.length; i++) {
|
||||
var div = options[i];
|
||||
div.className = 'option';
|
||||
_this.dom.appendChild(div);
|
||||
|
||||
_this.options.push(div);
|
||||
|
||||
div.addEventListener('click', onClick, false);
|
||||
|
||||
if (div.draggable === true) {
|
||||
div.addEventListener('drag', onDrag, false);
|
||||
div.addEventListener('dragstart', onDragStart, false); // Firefox needs this
|
||||
|
||||
div.addEventListener('dragover', onDragOver, false);
|
||||
div.addEventListener('dragleave', onDragLeave, false);
|
||||
div.addEventListener('drop', onDrop, false);
|
||||
}
|
||||
}
|
||||
|
||||
return _this;
|
||||
};
|
||||
|
||||
Outliner.prototype.getValue = function () {
|
||||
return this.selectedValue;
|
||||
};
|
||||
|
||||
Outliner.prototype.setValue = function (value) {
|
||||
for (var i = 0; i < this.options.length; i++) {
|
||||
var element = this.options[i];
|
||||
|
||||
if (element.value === value) {
|
||||
element.classList.add('active');
|
||||
|
||||
// scroll into view
|
||||
var y = element.offsetTop - this.dom.offsetTop;
|
||||
var bottomY = y + element.offsetHeight;
|
||||
var minScroll = bottomY - this.dom.offsetHeight;
|
||||
|
||||
if (this.dom.scrollTop > y) {
|
||||
this.dom.scrollTop = y;
|
||||
} else if (this.dom.scrollTop < minScroll) {
|
||||
this.dom.scrollTop = minScroll;
|
||||
}
|
||||
|
||||
this.selectedIndex = i;
|
||||
} else {
|
||||
element.classList.remove('active');
|
||||
}
|
||||
}
|
||||
|
||||
this.selectedValue = value;
|
||||
|
||||
return this;
|
||||
};
|
||||
|
||||
export default Outliner;
|
||||
@ -0,0 +1,153 @@
|
||||
import Control from './Control';
|
||||
|
||||
/**
|
||||
* 纹理
|
||||
* @param {*} options
|
||||
*/
|
||||
function Texture(options) {
|
||||
Control.call(this, options);
|
||||
}
|
||||
|
||||
Texture.prototype = Object.create(Control.prototype);
|
||||
Texture.prototype.constructor = Texture;
|
||||
|
||||
Texture.prototype.render = function () {
|
||||
this.dom = document.createElement('span');
|
||||
|
||||
this.form = document.createElement('form');
|
||||
|
||||
this.input = document.createElement('input');
|
||||
this.input.type = 'file';
|
||||
|
||||
var _this = this;
|
||||
this.input.addEventListener('change', function (event) {
|
||||
_this.loadFile(event.target.files[0]);
|
||||
});
|
||||
this.form.appendChild(this.input);
|
||||
|
||||
this.canvas = document.createElement('canvas');
|
||||
this.canvas.width = 32;
|
||||
this.canvas.height = 16;
|
||||
this.canvas.style.cursor = 'pointer';
|
||||
this.canvas.style.marginRight = '5px';
|
||||
this.canvas.style.border = '1px solid #888';
|
||||
|
||||
this.canvas.addEventListener('click', function (event) {
|
||||
_this.input.click();
|
||||
}, false);
|
||||
|
||||
this.canvas.addEventListener('drop', function (event) {
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
_this.loadFile(event.dataTransfer.files[0]);
|
||||
}, false);
|
||||
|
||||
this.dom.appendChild(this.canvas);
|
||||
|
||||
this.name = document.createElement('input');
|
||||
this.name.disabled = true;
|
||||
this.name.style.width = '64px';
|
||||
this.name.style.border = '1px solid #ccc';
|
||||
this.dom.appendChild(this.name);
|
||||
|
||||
function loadFile(file) {
|
||||
|
||||
if (file.type.match('image.*')) {
|
||||
|
||||
var reader = new FileReader();
|
||||
if (file.type === 'image/targa') {
|
||||
reader.addEventListener('load', function (event) {
|
||||
var canvas = new THREE.TGALoader().parse(event.target.result);
|
||||
var texture = new THREE.CanvasTexture(canvas, mapping);
|
||||
texture.sourceFile = file.name;
|
||||
|
||||
_this.setValue(texture);
|
||||
|
||||
if (_this.onChangeCallback) {
|
||||
_this.onChangeCallback();
|
||||
}
|
||||
}, false);
|
||||
|
||||
reader.readAsArrayBuffer(file);
|
||||
|
||||
} else {
|
||||
|
||||
reader.addEventListener('load', function (event) {
|
||||
|
||||
var image = document.createElement('img');
|
||||
image.addEventListener('load', function (event) {
|
||||
|
||||
var texture = new THREE.Texture(this, mapping);
|
||||
texture.sourceFile = file.name;
|
||||
texture.format = file.type === 'image/jpeg' ? THREE.RGBFormat : THREE.RGBAFormat;
|
||||
texture.needsUpdate = true;
|
||||
|
||||
_this.setValue(texture);
|
||||
|
||||
if (_this.onChangeCallback) {
|
||||
_this.onChangeCallback();
|
||||
}
|
||||
|
||||
}, false);
|
||||
|
||||
image.src = event.target.result;
|
||||
|
||||
}, false);
|
||||
|
||||
reader.readAsDataURL(file);
|
||||
}
|
||||
}
|
||||
|
||||
_this.form.reset();
|
||||
}
|
||||
|
||||
this.parent.appendChild(this.dom);
|
||||
this.texture = null;
|
||||
this.onChangeCallback = null;
|
||||
};
|
||||
|
||||
Texture.prototype.getValue = function () {
|
||||
return this.texture;
|
||||
};
|
||||
|
||||
Texture.prototype.setValue = function (texture) {
|
||||
|
||||
var canvas = this.dom.children[0];
|
||||
var name = this.dom.children[1];
|
||||
var context = canvas.getContext('2d');
|
||||
|
||||
if (texture !== null) {
|
||||
var image = texture.image;
|
||||
|
||||
if (image !== undefined && image.width > 0) {
|
||||
name.value = texture.sourceFile;
|
||||
|
||||
var scale = canvas.width / image.width;
|
||||
context.drawImage(image, 0, 0, image.width * scale, image.height * scale);
|
||||
} else {
|
||||
name.value = texture.sourceFile + ' (error)';
|
||||
context.clearRect(0, 0, canvas.width, canvas.height);
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
name.value = '';
|
||||
|
||||
if (context !== null) {
|
||||
|
||||
// Seems like context can be null if the canvas is not visible
|
||||
context.clearRect(0, 0, canvas.width, canvas.height);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
this.texture = texture;
|
||||
};
|
||||
|
||||
Texture.prototype.onChange = function (callback) {
|
||||
this.onChangeCallback = callback;
|
||||
|
||||
return this;
|
||||
};
|
||||
|
||||
export default Texture;
|
||||
@ -15,6 +15,9 @@ import Break from './Break';
|
||||
import HorizontalRule from './HorizontalRule';
|
||||
import Button from './Button';
|
||||
import Modal from './Modal';
|
||||
import Texture from './Texture';
|
||||
import Outliner from './Outliner';
|
||||
import Boolean from './Boolean';
|
||||
|
||||
/**
|
||||
* 所有UI控件封装
|
||||
@ -40,6 +43,9 @@ const UI = {
|
||||
Modal: Modal,
|
||||
|
||||
// ui.three.js
|
||||
Texture: Texture,
|
||||
Outliner: Outliner,
|
||||
Boolean: Boolean
|
||||
};
|
||||
|
||||
export default UI;
|
||||
@ -1 +1 @@
|
||||
export { default as UI } from './UI';
|
||||
export { default as UI2 } from './UI';
|
||||
Loading…
x
Reference in New Issue
Block a user