Skip to content

Commit 1b29f82

Browse files
committed
Merge branch 'master' into dev
2 parents 63dc460 + 6c66314 commit 1b29f82

File tree

5 files changed

+166
-55
lines changed

5 files changed

+166
-55
lines changed

editor/css/light.css

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
}
1818

1919
.Outliner .option.active {
20-
background-color: #f8f8f8;
20+
background-color: rgba(0,0,0,0.02);
2121
}
2222

2323
input.Number {

editor/css/main.css

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,29 @@ textarea, input { outline: none; } /* osx */
9494

9595
/* outliner */
9696

97+
#outliner .option {
98+
99+
border: 1px solid transparent;
100+
}
101+
102+
#outliner .option.drag {
103+
104+
border: 1px dashed #999;
105+
106+
}
107+
108+
#outliner .option.dragTop {
109+
110+
border-top: 1px dashed #999;
111+
112+
}
113+
114+
#outliner .option.dragBottom {
115+
116+
border-bottom: 1px dashed #999;
117+
118+
}
119+
97120
#outliner .type {
98121
position:relative;
99122
top:-2px;

editor/index.html

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,6 @@
7373
<script src="js/libs/ternjs/doc_comment.js"></script>
7474
<script src="js/libs/tern-threejs/threejs.js"></script>
7575

76-
<script src="js/libs/sortable.min.js"></script>
7776
<script src="js/libs/signals.min.js"></script>
7877
<script src="js/libs/ui.js"></script>
7978
<script src="js/libs/ui.three.js"></script>

editor/js/libs/sortable.min.js

Lines changed: 0 additions & 2 deletions
This file was deleted.

editor/js/libs/ui.three.js

Lines changed: 142 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -146,33 +146,8 @@ UI.Outliner = function ( editor ) {
146146
dom.className = 'Outliner';
147147
dom.tabIndex = 0; // keyup event is ignored without setting tabIndex
148148

149-
var scene = editor.scene;
150-
151-
var sortable = Sortable.create( dom, {
152-
draggable: '.draggable',
153-
onUpdate: function ( event ) {
154-
155-
var item = event.item;
156-
157-
var object = scene.getObjectById( item.value );
158-
159-
if ( item.nextSibling === null ) {
160-
161-
editor.execute( new MoveObjectCommand( object, editor.scene ) );
162-
163-
} else {
164-
165-
var nextObject = scene.getObjectById( item.nextSibling.value );
166-
editor.execute( new MoveObjectCommand( object, nextObject.parent, nextObject ) );
167-
168-
}
169-
170-
}
171-
} );
172-
173-
// Broadcast for object selection after arrow navigation
174-
var changeEvent = document.createEvent( 'HTMLEvents' );
175-
changeEvent.initEvent( 'change', true, true );
149+
// hack
150+
this.scene = editor.scene;
176151

177152
// Prevent native scroll behavior
178153
dom.addEventListener( 'keydown', function ( event ) {
@@ -190,26 +165,12 @@ UI.Outliner = function ( editor ) {
190165
// Keybindings to support arrow navigation
191166
dom.addEventListener( 'keyup', function ( event ) {
192167

193-
function select( index ) {
194-
195-
if ( index >= 0 && index < scope.options.length ) {
196-
197-
scope.selectedIndex = index;
198-
199-
// Highlight selected dom elem and scroll parent if needed
200-
scope.setValue( scope.options[ index ].value );
201-
scope.dom.dispatchEvent( changeEvent );
202-
203-
}
204-
205-
}
206-
207168
switch ( event.keyCode ) {
208169
case 38: // up
209-
select( scope.selectedIndex - 1 );
170+
scope.selectIndex( scope.selectedIndex - 1 );
210171
break;
211172
case 40: // down
212-
select( scope.selectedIndex + 1 );
173+
scope.selectIndex( scope.selectedIndex + 1 );
213174
break;
214175
}
215176

@@ -228,39 +189,169 @@ UI.Outliner = function ( editor ) {
228189
UI.Outliner.prototype = Object.create( UI.Element.prototype );
229190
UI.Outliner.prototype.constructor = UI.Outliner;
230191

192+
UI.Outliner.prototype.selectIndex = function ( index ) {
193+
194+
if ( index >= 0 && index < this.options.length ) {
195+
196+
this.setValue( this.options[ index ].value );
197+
198+
var changeEvent = document.createEvent( 'HTMLEvents' );
199+
changeEvent.initEvent( 'change', true, true );
200+
this.dom.dispatchEvent( changeEvent );
201+
202+
}
203+
204+
};
205+
231206
UI.Outliner.prototype.setOptions = function ( options ) {
232207

233208
var scope = this;
234209

235-
var changeEvent = document.createEvent( 'HTMLEvents' );
236-
changeEvent.initEvent( 'change', true, true );
237-
238210
while ( scope.dom.children.length > 0 ) {
239211

240212
scope.dom.removeChild( scope.dom.firstChild );
241213

242214
}
243215

216+
function onClick() {
217+
218+
scope.setValue( this.value );
219+
220+
var changeEvent = document.createEvent( 'HTMLEvents' );
221+
changeEvent.initEvent( 'change', true, true );
222+
scope.dom.dispatchEvent( changeEvent );
223+
224+
}
225+
226+
// Drag
227+
228+
var currentDrag;
229+
230+
function onDrag( event ) {
231+
232+
currentDrag = this;
233+
234+
}
235+
236+
function onDragStart( event ) {
237+
238+
event.dataTransfer.setData( 'text', 'foo' );
239+
240+
}
241+
242+
function onDragOver( event ) {
243+
244+
if ( this === currentDrag ) return;
245+
246+
var area = event.offsetY / this.clientHeight;
247+
248+
if ( area < 0.25 ) {
249+
250+
this.className = 'option dragTop';
251+
252+
} else if ( area > 0.75 ) {
253+
254+
this.className = 'option dragBottom';
255+
256+
} else {
257+
258+
this.className = 'option drag';
259+
260+
}
261+
262+
}
263+
264+
function onDragLeave() {
265+
266+
if ( this === currentDrag ) return;
267+
268+
this.className = 'option';
269+
270+
}
271+
272+
function onDrop( event ) {
273+
274+
if ( this === currentDrag ) return;
275+
276+
this.className = 'option';
277+
278+
var scene = scope.scene;
279+
var object = scene.getObjectById( currentDrag.value );
280+
281+
var area = event.offsetY / this.clientHeight;
282+
283+
if ( area < 0.25 ) {
284+
285+
var nextObject = scene.getObjectById( this.value );
286+
moveObject( object, nextObject.parent, nextObject );
287+
288+
} else if ( area > 0.75 ) {
289+
290+
var nextObject = scene.getObjectById( this.nextSibling.value );
291+
moveObject( object, nextObject.parent, nextObject );
292+
293+
} else {
294+
295+
var parentObject = scene.getObjectById( this.value );
296+
moveObject( object, parentObject );
297+
298+
}
299+
300+
}
301+
302+
function moveObject( object, newParent, nextObject ) {
303+
304+
if ( nextObject === null ) nextObject = undefined;
305+
306+
var newParentIsChild = false;
307+
308+
object.traverse( function ( child ) {
309+
310+
if ( child === newParent ) newParentIsChild = true;
311+
312+
} );
313+
314+
if ( newParentIsChild ) return;
315+
316+
editor.execute( new MoveObjectCommand( object, newParent, nextObject ) );
317+
318+
var changeEvent = document.createEvent( 'HTMLEvents' );
319+
changeEvent.initEvent( 'change', true, true );
320+
scope.dom.dispatchEvent( changeEvent );
321+
322+
}
323+
324+
//
325+
244326
scope.options = [];
245327

246328
for ( var i = 0; i < options.length; i ++ ) {
247329

248330
var option = options[ i ];
249331

250332
var div = document.createElement( 'div' );
251-
div.className = 'option ' + ( option.static === true ? '' : 'draggable' );
333+
div.className = 'option';
252334
div.innerHTML = option.html;
253335
div.value = option.value;
254336
scope.dom.appendChild( div );
255337

256338
scope.options.push( div );
257339

258-
div.addEventListener( 'click', function ( event ) {
340+
div.addEventListener( 'click', onClick, false );
341+
342+
if ( option.static !== true ) {
343+
344+
div.draggable = true;
259345

260-
scope.setValue( this.value );
261-
scope.dom.dispatchEvent( changeEvent );
346+
div.addEventListener( 'drag', onDrag, false );
347+
div.addEventListener( 'dragstart', onDragStart, false ); // Firefox needs this
348+
349+
div.addEventListener( 'dragover', onDragOver, false );
350+
div.addEventListener( 'dragleave', onDragLeave, false );
351+
div.addEventListener( 'drop', onDrop, false );
352+
353+
}
262354

263-
}, false );
264355

265356
}
266357

0 commit comments

Comments
 (0)