|
@@ -146,33 +146,8 @@ UI.Outliner = function ( editor ) {
|
|
dom.className = 'Outliner';
|
|
dom.className = 'Outliner';
|
|
dom.tabIndex = 0; // keyup event is ignored without setting tabIndex
|
|
dom.tabIndex = 0; // keyup event is ignored without setting tabIndex
|
|
|
|
|
|
- var scene = editor.scene;
|
|
|
|
-
|
|
|
|
- var sortable = Sortable.create( dom, {
|
|
|
|
- draggable: '.draggable',
|
|
|
|
- onUpdate: function ( event ) {
|
|
|
|
-
|
|
|
|
- var item = event.item;
|
|
|
|
-
|
|
|
|
- var object = scene.getObjectById( item.value );
|
|
|
|
-
|
|
|
|
- if ( item.nextSibling === null ) {
|
|
|
|
-
|
|
|
|
- editor.execute( new MoveObjectCommand( object, editor.scene ) );
|
|
|
|
-
|
|
|
|
- } else {
|
|
|
|
-
|
|
|
|
- var nextObject = scene.getObjectById( item.nextSibling.value );
|
|
|
|
- editor.execute( new MoveObjectCommand( object, nextObject.parent, nextObject ) );
|
|
|
|
-
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- }
|
|
|
|
- } );
|
|
|
|
-
|
|
|
|
- // Broadcast for object selection after arrow navigation
|
|
|
|
- var changeEvent = document.createEvent( 'HTMLEvents' );
|
|
|
|
- changeEvent.initEvent( 'change', true, true );
|
|
|
|
|
|
+ // hack
|
|
|
|
+ this.scene = editor.scene;
|
|
|
|
|
|
// Prevent native scroll behavior
|
|
// Prevent native scroll behavior
|
|
dom.addEventListener( 'keydown', function ( event ) {
|
|
dom.addEventListener( 'keydown', function ( event ) {
|
|
@@ -190,26 +165,12 @@ UI.Outliner = function ( editor ) {
|
|
// Keybindings to support arrow navigation
|
|
// Keybindings to support arrow navigation
|
|
dom.addEventListener( 'keyup', function ( event ) {
|
|
dom.addEventListener( 'keyup', function ( event ) {
|
|
|
|
|
|
- function select( index ) {
|
|
|
|
-
|
|
|
|
- if ( index >= 0 && index < scope.options.length ) {
|
|
|
|
-
|
|
|
|
- scope.selectedIndex = index;
|
|
|
|
-
|
|
|
|
- // Highlight selected dom elem and scroll parent if needed
|
|
|
|
- scope.setValue( scope.options[ index ].value );
|
|
|
|
- scope.dom.dispatchEvent( changeEvent );
|
|
|
|
-
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
switch ( event.keyCode ) {
|
|
switch ( event.keyCode ) {
|
|
case 38: // up
|
|
case 38: // up
|
|
- select( scope.selectedIndex - 1 );
|
|
|
|
|
|
+ scope.selectIndex( scope.selectedIndex - 1 );
|
|
break;
|
|
break;
|
|
case 40: // down
|
|
case 40: // down
|
|
- select( scope.selectedIndex + 1 );
|
|
|
|
|
|
+ scope.selectIndex( scope.selectedIndex + 1 );
|
|
break;
|
|
break;
|
|
}
|
|
}
|
|
|
|
|
|
@@ -228,19 +189,140 @@ UI.Outliner = function ( editor ) {
|
|
UI.Outliner.prototype = Object.create( UI.Element.prototype );
|
|
UI.Outliner.prototype = Object.create( UI.Element.prototype );
|
|
UI.Outliner.prototype.constructor = UI.Outliner;
|
|
UI.Outliner.prototype.constructor = UI.Outliner;
|
|
|
|
|
|
|
|
+UI.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 );
|
|
|
|
+
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+};
|
|
|
|
+
|
|
UI.Outliner.prototype.setOptions = function ( options ) {
|
|
UI.Outliner.prototype.setOptions = function ( options ) {
|
|
|
|
|
|
var scope = this;
|
|
var scope = this;
|
|
|
|
|
|
- var changeEvent = document.createEvent( 'HTMLEvents' );
|
|
|
|
- changeEvent.initEvent( 'change', true, true );
|
|
|
|
-
|
|
|
|
while ( scope.dom.children.length > 0 ) {
|
|
while ( scope.dom.children.length > 0 ) {
|
|
|
|
|
|
scope.dom.removeChild( scope.dom.firstChild );
|
|
scope.dom.removeChild( scope.dom.firstChild );
|
|
|
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ function onClick() {
|
|
|
|
+
|
|
|
|
+ scope.setValue( this.value );
|
|
|
|
+
|
|
|
|
+ var changeEvent = document.createEvent( 'HTMLEvents' );
|
|
|
|
+ changeEvent.initEvent( 'change', true, true );
|
|
|
|
+ scope.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 = scope.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 );
|
|
|
|
+ scope.dom.dispatchEvent( changeEvent );
|
|
|
|
+
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ //
|
|
|
|
+
|
|
scope.options = [];
|
|
scope.options = [];
|
|
|
|
|
|
for ( var i = 0; i < options.length; i ++ ) {
|
|
for ( var i = 0; i < options.length; i ++ ) {
|
|
@@ -248,19 +330,28 @@ UI.Outliner.prototype.setOptions = function ( options ) {
|
|
var option = options[ i ];
|
|
var option = options[ i ];
|
|
|
|
|
|
var div = document.createElement( 'div' );
|
|
var div = document.createElement( 'div' );
|
|
- div.className = 'option ' + ( option.static === true ? '' : 'draggable' );
|
|
|
|
|
|
+ div.className = 'option';
|
|
div.innerHTML = option.html;
|
|
div.innerHTML = option.html;
|
|
div.value = option.value;
|
|
div.value = option.value;
|
|
scope.dom.appendChild( div );
|
|
scope.dom.appendChild( div );
|
|
|
|
|
|
scope.options.push( div );
|
|
scope.options.push( div );
|
|
|
|
|
|
- div.addEventListener( 'click', function ( event ) {
|
|
|
|
|
|
+ div.addEventListener( 'click', onClick, false );
|
|
|
|
+
|
|
|
|
+ if ( option.static !== true ) {
|
|
|
|
+
|
|
|
|
+ div.draggable = true;
|
|
|
|
|
|
- scope.setValue( this.value );
|
|
|
|
- scope.dom.dispatchEvent( changeEvent );
|
|
|
|
|
|
+ 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 );
|
|
|
|
+
|
|
|
|
+ }
|
|
|
|
|
|
- }, false );
|
|
|
|
|
|
|
|
}
|
|
}
|
|
|
|
|