@@ -146,33 +146,8 @@ UI.Outliner = function ( editor ) {
146
146
dom . className = 'Outliner' ;
147
147
dom . tabIndex = 0 ; // keyup event is ignored without setting tabIndex
148
148
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 ;
176
151
177
152
// Prevent native scroll behavior
178
153
dom . addEventListener ( 'keydown' , function ( event ) {
@@ -190,26 +165,12 @@ UI.Outliner = function ( editor ) {
190
165
// Keybindings to support arrow navigation
191
166
dom . addEventListener ( 'keyup' , function ( event ) {
192
167
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
-
207
168
switch ( event . keyCode ) {
208
169
case 38 : // up
209
- select ( scope . selectedIndex - 1 ) ;
170
+ scope . selectIndex ( scope . selectedIndex - 1 ) ;
210
171
break ;
211
172
case 40 : // down
212
- select ( scope . selectedIndex + 1 ) ;
173
+ scope . selectIndex ( scope . selectedIndex + 1 ) ;
213
174
break ;
214
175
}
215
176
@@ -228,39 +189,169 @@ UI.Outliner = function ( editor ) {
228
189
UI . Outliner . prototype = Object . create ( UI . Element . prototype ) ;
229
190
UI . Outliner . prototype . constructor = UI . Outliner ;
230
191
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
+
231
206
UI . Outliner . prototype . setOptions = function ( options ) {
232
207
233
208
var scope = this ;
234
209
235
- var changeEvent = document . createEvent ( 'HTMLEvents' ) ;
236
- changeEvent . initEvent ( 'change' , true , true ) ;
237
-
238
210
while ( scope . dom . children . length > 0 ) {
239
211
240
212
scope . dom . removeChild ( scope . dom . firstChild ) ;
241
213
242
214
}
243
215
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
+
244
326
scope . options = [ ] ;
245
327
246
328
for ( var i = 0 ; i < options . length ; i ++ ) {
247
329
248
330
var option = options [ i ] ;
249
331
250
332
var div = document . createElement ( 'div' ) ;
251
- div . className = 'option ' + ( option . static === true ? '' : 'draggable' ) ;
333
+ div . className = 'option' ;
252
334
div . innerHTML = option . html ;
253
335
div . value = option . value ;
254
336
scope . dom . appendChild ( div ) ;
255
337
256
338
scope . options . push ( div ) ;
257
339
258
- div . addEventListener ( 'click' , function ( event ) {
340
+ div . addEventListener ( 'click' , onClick , false ) ;
341
+
342
+ if ( option . static !== true ) {
343
+
344
+ div . draggable = true ;
259
345
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
+ }
262
354
263
- } , false ) ;
264
355
265
356
}
266
357
0 commit comments