1、undo和redo监听HistoryChanged事件来控制菜单是否可用。

2、删除旧编辑菜单,编辑改造成功。
This commit is contained in:
liteng 2018-06-21 21:58:44 +08:00
parent 808487bd5c
commit 96ea1dab0f
5 changed files with 88 additions and 236 deletions

View File

@ -16,10 +16,14 @@ RedoEvent.prototype.start = function () {
this.app.on('mRedo.' + this.id, function () {
_this.onRedo();
});
this.app.on('historyChanged.' + this.id, function () {
_this.onHistoryChanged();
});
};
RedoEvent.prototype.stop = function () {
this.app.on('mRedo.' + this.id, null);
this.app.on('historyChanged.' + this.id, null);
};
RedoEvent.prototype.onRedo = function () {
@ -28,4 +32,19 @@ RedoEvent.prototype.onRedo = function () {
editor.redo();
};
RedoEvent.prototype.onHistoryChanged = function () {
var history = this.app.editor.history;
var dom = document.getElementById('mRedo');
if (history.redos.length === 0) {
if (!dom.classList.contains('inactive')) {
dom.classList.add('inactive');
}
} else {
if (dom.classList.contains('inactive')) {
dom.classList.remove('inactive');
}
}
};
export default RedoEvent;

View File

@ -16,10 +16,14 @@ UndoEvent.prototype.start = function () {
this.app.on('mUndo.' + this.id, function () {
_this.onUndo();
});
this.app.on('historyChanged.' + this.id, function () {
_this.onHistoryChanged();
});
};
UndoEvent.prototype.stop = function () {
this.app.on('mUndo.' + this.id, null);
this.app.on('historyChanged.' + this.id, null);
};
UndoEvent.prototype.onUndo = function () {
@ -28,4 +32,19 @@ UndoEvent.prototype.onUndo = function () {
editor.undo();
};
UndoEvent.prototype.onHistoryChanged = function () {
var history = this.app.editor.history;
var dom = document.getElementById('mUndo');
if (history.undos.length === 0) {
if (!dom.classList.contains('inactive')) {
dom.classList.add('inactive');
}
} else {
if (dom.classList.contains('inactive')) {
dom.classList.remove('inactive');
}
}
};
export default UndoEvent;

View File

@ -1,213 +0,0 @@
import AddObjectCommand from '../command/AddObjectCommand';
import RemoveObjectCommand from '../command/RemoveObjectCommand';
import SetMaterialValueCommand from '../command/SetMaterialValueCommand';
import MultiCmdsCommand from '../command/MultiCmdsCommand';
import UI from '../ui/UI';
/**
* @author mrdoob / http://mrdoob.com/
*/
function EditMenu(editor) {
var container = new UI.Panel();
container.setClass('menu');
var title = new UI.Panel();
title.setClass('title');
title.setTextContent('编辑');
container.add(title);
var options = new UI.Panel();
options.setClass('options');
container.add(options);
// Undo
var undo = new UI.Row();
undo.setClass('option');
undo.setTextContent('撤销(Ctrl+Z)');
undo.onClick(function () {
editor.undo();
});
options.add(undo);
// Redo
var redo = new UI.Row();
redo.setClass('option');
redo.setTextContent('重做(Ctrl+Shift+Z)');
redo.onClick(function () {
editor.redo();
});
options.add(redo);
// Clear History
var option = new UI.Row();
option.setClass('option');
option.setTextContent('清空历史记录');
option.onClick(function () {
if (confirm('撤销/重做历史纪录将被清空。确定吗?')) {
editor.history.clear();
}
});
options.add(option);
editor.app.on('historyChanged.EditMenu', function () {
var history = editor.history;
undo.setClass('option');
redo.setClass('option');
if (history.undos.length == 0) {
undo.setClass('inactive');
}
if (history.redos.length == 0) {
redo.setClass('inactive');
}
});
// ---
options.add(new UI.HorizontalRule());
// Clone
var option = new UI.Row();
option.setClass('option');
option.setTextContent('复制');
option.onClick(function () {
var object = editor.selected;
if (object.parent === null) return; // avoid cloning the camera or scene
object = object.clone();
editor.execute(new AddObjectCommand(object));
});
options.add(option);
// Delete
var option = new UI.Row();
option.setClass('option');
option.setTextContent('删除(Del)');
option.onClick(function () {
var object = editor.selected;
if (confirm('Delete ' + object.name + '?') === false) return;
var parent = object.parent;
if (parent === undefined) return; // avoid deleting the camera or scene
editor.execute(new RemoveObjectCommand(object));
});
options.add(option);
// Minify shaders
var option = new UI.Row();
option.setClass('option');
option.setTextContent('清除着色');
option.onClick(function () {
var root = editor.selected || editor.scene;
var errors = [];
var nMaterialsChanged = 0;
var path = [];
function getPath(object) {
path.length = 0;
var parent = object.parent;
if (parent !== undefined) getPath(parent);
path.push(object.name || object.uuid);
return path;
}
var cmds = [];
root.traverse(function (object) {
var material = object.material;
if (material instanceof THREE.ShaderMaterial) {
try {
var shader = glslprep.minifyGlsl([
material.vertexShader, material.fragmentShader]);
cmds.push(new SetMaterialValueCommand(object, 'vertexShader', shader[0]));
cmds.push(new SetMaterialValueCommand(object, 'fragmentShader', shader[1]));
++nMaterialsChanged;
} catch (e) {
var path = getPath(object).join("/");
if (e instanceof glslprep.SyntaxError)
errors.push(path + ":" +
e.line + ":" + e.column + ": " + e.message);
else {
errors.push(path +
" 未预料到的错误(详情请见控制台)。");
console.error(e.stack || e);
}
}
}
});
if (nMaterialsChanged > 0) {
editor.execute(new MultiCmdsCommand(cmds), 'Minify Shaders');
}
window.alert(nMaterialsChanged +
"材质已经改变。\n" + errors.join("\n"));
});
options.add(option);
return container;
};
export default EditMenu;

View File

@ -6,7 +6,6 @@ import ExampleMenu from './ExampleMenu';
import HelpMenu from './HelpMenu';
import StatusMenu from './StatusMenu';
import ViewMenu from './ViewMenu';
import UI from '../ui/UI';
import UI2 from '../ui2/UI';
/**
@ -20,16 +19,19 @@ function Menubar(app) {
this.data = [{
text: '场景',
children: [{
id: 'mNewScene',
text: '新建',
onClick: function () {
app.call('mNewScene');
}
}, {
id: 'mLoadScene',
text: '载入',
onClick: function () {
app.call('mLoadScene');
}
}, {
id: 'mSaveScene',
text: '保存',
onClick: function () {
app.call('mSaveScene');
@ -37,6 +39,7 @@ function Menubar(app) {
}, {
text: '-'
}, {
id: 'mPublishScene',
text: '发布',
onClick: function () {
app.call('mPublishScene');
@ -45,16 +48,19 @@ function Menubar(app) {
}, {
text: '编辑',
children: [{
id: 'mUndo',
text: '撤销(Ctrl+Z)',
onClick: function () {
app.call('mUndo');
}
}, {
id: 'mRedo',
text: '重做(Ctrl+Shift+Z)',
onClick: function () {
app.call('mRedo');
}
}, {
id: 'mClearHistory',
text: '清空历史记录',
onClick: function () {
app.call('mClearHistory');
@ -62,16 +68,19 @@ function Menubar(app) {
}, {
text: '-'
}, {
id: 'mClone',
text: '复制',
onClick: function () {
app.call('mClone');
}
}, {
id: 'mDelete',
text: '删除(Del)',
onClick: function () {
app.call('mDelete');
}
}, {
id: 'mMinifyShader',
text: '删除着色器',
onClick: function () {
app.call('mMinifyShader');
@ -80,6 +89,7 @@ function Menubar(app) {
}, {
text: '添加',
children: [{
id: 'mAddGroup',
text: '组',
onClick: function () {
app.call('mAddGroup');
@ -87,56 +97,67 @@ function Menubar(app) {
}, {
text: '-'
}, {
id: 'mAddPlane',
text: '平板',
onClick: function () {
app.call('mAddPlane');
}
}, {
id: 'mAddBox',
text: '正方体',
onClick: function () {
app.call('mAddBox');
}
}, {
id: 'mAddCircle',
text: '圆',
onClick: function () {
app.call('mAddCircle');
}
}, {
id: 'mAddCylinder',
text: '圆柱体',
onClick: function () {
app.call('mAddCylinder');
}
}, {
id: 'mAddSphere',
text: '球体',
onClick: function () {
app.call('mAddSphere');
}
}, {
id: 'mAddIcosahedron',
text: '二十面体',
onClick: function () {
app.call('mAddIcosahedron');
}
}, {
id: 'mAddTorus',
text: '轮胎',
onClick: function () {
app.call('mAddTorus');
}
}, {
id: 'mAddTorusKnot',
text: '扭结',
onClick: function () {
app.call('mAddTorusKnot');
}
}, {
id: 'mAddTeaport',
text: '茶壶',
onClick: function () {
app.call('mAddTeaport');
}
}, {
id: 'mAddLathe',
text: '花瓶',
onClick: function () {
app.call('mAddLathe');
}
}, {
id: 'mAddSprite',
text: '精灵',
onClick: function () {
app.call('mAddSprite');
@ -144,26 +165,31 @@ function Menubar(app) {
}, {
text: '-'
}, {
id: 'mAddPointLight',
text: '点光源',
onClick: function () {
app.call('mAddPointLight');
}
}, {
id: 'mAddSpotLight',
text: '聚光灯',
onClick: function () {
app.call('mAddSpotLight');
}
}, {
id: 'mAddDirectionalLight',
text: '平行光源',
onClick: function () {
app.call('mAddDirectionalLight');
}
}, {
id: 'mAddHemisphereLight',
text: '半球光',
onClick: function () {
app.call('mAddHemisphereLight');
}
}, {
id: 'mAddAmbientLight',
text: '环境光',
onClick: function () {
app.call('mAddAmbientLight');
@ -171,6 +197,7 @@ function Menubar(app) {
}, {
text: '-'
}, {
id: 'mAddPerspectiveCamera',
text: '透视相机',
onClick: function () {
app.call('mAddPerspectiveCamera');
@ -179,39 +206,46 @@ function Menubar(app) {
}, {
text: '资源',
children: [{
id: 'mImportAsset',
text: '导入',
onClick: function () {
app.call('mNewScene');
app.call('mImportAsset');
}
}, {
text: '-'
}, {
id: 'mExportGeometry',
text: '导出Geometry',
onClick: function () {
app.call('mExportGeometry');
}
}, {
id: 'mExportObject',
text: '导出Object',
onClick: function () {
app.call('mExportObject');
}
}, {
id: 'mExportScene',
text: '导出场景',
onClick: function () {
app.call('mExportScene');
}
}, {
id: 'mExportOBJ',
text: '导出OBJ',
onClick: function () {
app.call('mExportOBJ');
}
}, {
id: 'mExportSTL',
text: '导出STL',
onClick: function () {
app.call('mExportSTL');
}
}]
}, {
id: 'mPlay',
text: '启动',
onClick: function () {
app.call('mPlay');
@ -219,6 +253,7 @@ function Menubar(app) {
}, {
text: '视图',
children: [{
id: 'mVRMode',
text: 'VR模式',
onClick: function () {
app.call('mVRMode');
@ -227,21 +262,25 @@ function Menubar(app) {
}, {
text: '示例',
children: [{
id: 'mArkanoid',
text: '打砖块',
onClick: function () {
app.call('mArkanoid');
}
}, {
id: 'mCamera',
text: '相机',
onClick: function () {
app.call('mCamera');
}
}, {
id: 'mParticles',
text: '粒子',
onClick: function () {
app.call('mParticles');
}
}, {
id: 'mPong',
text: '乒乓球',
onClick: function () {
app.call('mPong');
@ -250,11 +289,13 @@ function Menubar(app) {
}, {
text: '帮助',
children: [{
id: 'mSourceCode',
text: '源码',
onClick: function () {
app.call('mSourceCode');
}
}, {
id: 'mAbout',
text: '关于',
onClick: function () {
app.call('mAbout');
@ -277,6 +318,7 @@ function Menubar(app) {
// 菜单标题
var title = new UI2.Panel({
id: n.id,
cls: 'title',
html: n.text
});
@ -295,6 +337,7 @@ function Menubar(app) {
options.add(hr);
} else { // 其他文字
var option = new UI2.Panel({
id: m.id,
cls: 'option',
html: m.text
});
@ -302,7 +345,7 @@ function Menubar(app) {
// 菜单子项click事件
if (typeof (m.onClick) === 'function') {
option.onClick = m.onClick.bind(_this);
option.onClick = m.onClick; // this是具体菜单对应的Panel
}
}
});
@ -310,31 +353,13 @@ function Menubar(app) {
// 主菜单click事件
if (typeof (n.onClick) === 'function') {
menu.onClick = n.onClick.bind(_this);
menu.onClick = n.onClick; // this是具体菜单对应的Panel
}
_this.dom.add(menu);
});
this.dom.render();
// var editor = this.app.editor;
// var container = new UI.Panel();
// container.setId('menubar');
// container.add(new FileMenu(editor));
// container.add(new EditMenu(editor));
// container.add(new AddMenu(editor));
// container.add(new AssetMenu(editor));
// container.add(new PlayMenu(editor));
// container.add(new ViewMenu(editor));
// container.add(new ExampleMenu(editor));
// container.add(new HelpMenu(editor));
// container.add(new StatusMenu(editor));
// return container;
};
export default Menubar;

View File

@ -1,6 +1,8 @@
import Control from './Control';
import Container from './Container';
var ID = -1;
/**
* 面板
* @param {*} options
@ -8,7 +10,7 @@ import Container from './Container';
function Panel(options) {
Container.call(this, options);
this.cls = options.cls || 'Panel';
this.id = options.id || null;
this.id = options.id || 'Panel' + ID--;
this.html = options.html || null;
this.onClick = options.onClick || null;
};