2014-09-15 20:15:34 +00:00
|
|
|
/* globals Polymer, Path, Gui */
|
2014-09-04 04:14:36 +00:00
|
|
|
|
2014-09-03 16:16:11 +00:00
|
|
|
// [ ] scrolling when docked
|
|
|
|
// [ ] scrolling when window short and not docked
|
2014-08-27 00:01:15 +00:00
|
|
|
|
2014-09-09 19:53:30 +00:00
|
|
|
Polymer( 'dat-gui', {
|
2014-08-27 00:01:15 +00:00
|
|
|
|
2014-09-08 01:31:51 +00:00
|
|
|
docked: false,
|
|
|
|
open: true,
|
2014-09-16 03:44:07 +00:00
|
|
|
localStorage: false,
|
2014-09-08 03:36:20 +00:00
|
|
|
touch: ( 'ontouchstart' in window ) || ( !!window.DocumentTouch && document instanceof window.DocumentTouch ),
|
2014-08-27 00:01:15 +00:00
|
|
|
|
2014-09-15 20:15:34 +00:00
|
|
|
ready: function() {
|
|
|
|
|
|
|
|
this.vars = {};
|
2014-09-16 03:44:07 +00:00
|
|
|
|
|
|
|
this._controllersByObject = {};
|
|
|
|
|
2014-09-15 22:39:43 +00:00
|
|
|
this.domElement = this; // legacy
|
2014-09-15 20:15:34 +00:00
|
|
|
|
2014-09-18 18:50:55 +00:00
|
|
|
|
|
|
|
// this winds up triggering like all the time?
|
|
|
|
|
|
|
|
// var _this = this;
|
|
|
|
// window.addEventListener( 'resize', function() {
|
|
|
|
// _this.asyncFire( 'resize' );
|
|
|
|
// }, false );
|
|
|
|
|
2014-09-15 20:15:34 +00:00
|
|
|
},
|
|
|
|
|
2014-09-16 03:44:07 +00:00
|
|
|
//
|
2014-09-15 20:15:34 +00:00
|
|
|
// -------------------------------
|
|
|
|
|
|
|
|
add: function( object, path ) {
|
|
|
|
|
|
|
|
// Make controller
|
|
|
|
|
|
|
|
var value = Path.get( path ).getValueFrom( object );
|
|
|
|
|
|
|
|
if ( value === null || value === undefined ) {
|
2014-09-27 19:02:21 +00:00
|
|
|
return Gui.error( 'Object doesn\'t have a value for path "' + path + '".', object );
|
2014-09-15 20:15:34 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
var args = Array.prototype.slice.call( arguments, 2 );
|
|
|
|
var controller;
|
|
|
|
|
|
|
|
if ( args[ 0 ] instanceof Array || typeof args[ 0 ] == 'object' ) {
|
|
|
|
controller = document.createElement( 'dat-gui-option' );
|
|
|
|
} else {
|
|
|
|
controller = Gui.getController( value );
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( !controller ) {
|
|
|
|
return Gui.error( 'Unrecognized type:', value );
|
|
|
|
}
|
|
|
|
|
|
|
|
controller.watch( object, path );
|
|
|
|
controller.init.apply( controller, args );
|
|
|
|
|
2014-09-16 03:44:07 +00:00
|
|
|
// Make row ( todo: put row in controllers )
|
2014-09-15 20:15:34 +00:00
|
|
|
|
|
|
|
var row = document.createElement( 'gui-row' );
|
|
|
|
row.name = path;
|
|
|
|
|
|
|
|
controller.row = row;
|
|
|
|
|
|
|
|
controller.name = function( name ) {
|
|
|
|
row.name = name;
|
2014-10-11 19:39:16 +00:00
|
|
|
return controller;
|
2014-09-15 20:15:34 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
controller.comment = function( comment ) {
|
|
|
|
row.comment = comment;
|
2014-10-11 19:39:16 +00:00
|
|
|
return controller;
|
2014-09-15 20:15:34 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
row.appendChild( controller );
|
|
|
|
this.appendChild( row );
|
|
|
|
|
2014-09-16 03:44:07 +00:00
|
|
|
// Remember
|
2014-09-15 20:15:34 +00:00
|
|
|
|
2014-09-27 19:02:21 +00:00
|
|
|
var objectKey = this._hash( object );
|
|
|
|
var objectControllers = this._controllersByObject[ objectKey ];
|
2014-09-15 20:15:34 +00:00
|
|
|
|
2014-09-27 19:02:21 +00:00
|
|
|
if ( !objectControllers ) {
|
|
|
|
objectControllers = {};
|
|
|
|
this._controllersByObject[ objectKey ] = objectControllers;
|
|
|
|
}
|
2014-09-16 03:44:07 +00:00
|
|
|
|
2014-09-27 19:02:21 +00:00
|
|
|
objectControllers[ controller.path ] = controller;
|
2014-09-15 20:15:34 +00:00
|
|
|
|
2014-09-16 03:44:07 +00:00
|
|
|
return controller;
|
2014-09-15 20:15:34 +00:00
|
|
|
|
2014-09-16 03:44:07 +00:00
|
|
|
},
|
2014-09-15 20:15:34 +00:00
|
|
|
|
2014-10-11 19:39:16 +00:00
|
|
|
folder: function( name, open ) {
|
|
|
|
|
|
|
|
var folder = document.createElement( 'dat-gui-folder' );
|
|
|
|
|
|
|
|
folder.name = name;
|
|
|
|
folder.open = open === undefined ? true : open;
|
|
|
|
folder.parent = this;
|
|
|
|
|
|
|
|
this.appendChild( folder );
|
|
|
|
|
|
|
|
return folder;
|
|
|
|
|
|
|
|
},
|
|
|
|
|
2014-09-16 03:44:07 +00:00
|
|
|
remove: function( controller ) {
|
2014-09-15 20:15:34 +00:00
|
|
|
|
2014-09-16 03:44:07 +00:00
|
|
|
this.removeChild( controller );
|
2014-09-15 20:15:34 +00:00
|
|
|
|
2014-09-16 03:44:07 +00:00
|
|
|
// Forget
|
2014-09-15 20:15:34 +00:00
|
|
|
|
2014-09-27 19:02:21 +00:00
|
|
|
var objectKey = this._hash( object );
|
2014-09-16 03:44:07 +00:00
|
|
|
controller.objectKey = objectKey;
|
2014-09-15 20:15:34 +00:00
|
|
|
|
2014-09-16 03:44:07 +00:00
|
|
|
var objectControllers = this._controllersByObject[ objectKey ];
|
|
|
|
objectControllers.splice( objectControllers.indexOf( controller ), 1 );
|
2014-09-15 20:15:34 +00:00
|
|
|
|
|
|
|
},
|
|
|
|
|
2014-09-16 03:44:07 +00:00
|
|
|
var: function( name, initialValue ) {
|
2014-09-15 20:15:34 +00:00
|
|
|
|
2014-09-16 03:44:07 +00:00
|
|
|
var args = [ this.vars, name ];
|
|
|
|
args = args.concat( Array.prototype.slice.call( arguments, 2 ) );
|
2014-09-15 20:15:34 +00:00
|
|
|
|
2014-09-16 03:44:07 +00:00
|
|
|
this.vars[ name ] = initialValue;
|
2014-09-15 20:15:34 +00:00
|
|
|
|
2014-09-16 03:44:07 +00:00
|
|
|
return this.add.apply( this, args );
|
2014-09-15 20:15:34 +00:00
|
|
|
|
|
|
|
},
|
|
|
|
|
2014-09-16 03:44:07 +00:00
|
|
|
save: function() {
|
2014-09-15 02:48:00 +00:00
|
|
|
|
2014-09-16 03:44:07 +00:00
|
|
|
if ( this.localStorage && window.localStorage ) {
|
2014-08-27 00:01:15 +00:00
|
|
|
|
2014-09-16 03:44:07 +00:00
|
|
|
var data = JSON.stringify( this.serialize() );
|
|
|
|
localStorage.setItem( Gui.LOCAL_STORAGE_KEY, data );
|
2014-08-27 00:01:15 +00:00
|
|
|
|
2014-09-08 01:31:51 +00:00
|
|
|
} else {
|
2014-08-27 00:01:15 +00:00
|
|
|
|
2014-09-16 03:44:07 +00:00
|
|
|
// todo: success
|
2014-09-18 18:50:55 +00:00
|
|
|
Gui.postJSON( this.savePath, this.serialize(), this.saveSuccess, this.saveError, this );
|
2014-08-27 00:01:15 +00:00
|
|
|
|
2014-09-08 01:31:51 +00:00
|
|
|
}
|
2014-08-27 00:01:15 +00:00
|
|
|
|
2014-09-08 01:31:51 +00:00
|
|
|
},
|
2014-08-27 00:01:15 +00:00
|
|
|
|
2014-09-27 19:02:21 +00:00
|
|
|
_hash: function( object ) {
|
|
|
|
|
|
|
|
if ( object == this.vars ) {
|
|
|
|
return 'vars';
|
|
|
|
}
|
|
|
|
|
|
|
|
return this.hash( object );
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
hash: function( object ) {
|
|
|
|
|
|
|
|
// "shallow" stringify
|
|
|
|
var data = {};
|
|
|
|
|
|
|
|
for ( var i in object ) {
|
|
|
|
|
|
|
|
var val;
|
|
|
|
|
|
|
|
try {
|
|
|
|
val = JSON.stringify( object[ i ] );
|
|
|
|
val = object[ i ];
|
|
|
|
} catch (e) {}
|
|
|
|
|
|
|
|
if ( val !== undefined ) {
|
|
|
|
|
|
|
|
data[ i ] = val;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
return JSON.stringify( data );
|
|
|
|
|
|
|
|
},
|
|
|
|
|
2014-09-18 18:50:55 +00:00
|
|
|
saveSuccess: function() {
|
|
|
|
|
|
|
|
Gui.log( 'Saved data to ' + this.savePath );
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
saveError: function( error ) {
|
|
|
|
|
2014-09-19 00:21:59 +00:00
|
|
|
Gui.warn( 'Failed to post data to ' + this.savePath + '. Disabling save.' );
|
2014-09-18 18:50:55 +00:00
|
|
|
this.removeEventListener( 'change', this._debouncedSave, false );
|
|
|
|
|
|
|
|
},
|
|
|
|
|
2014-09-16 03:44:07 +00:00
|
|
|
unserialize: function( data ) {
|
2014-08-27 00:01:15 +00:00
|
|
|
|
2014-09-16 03:44:07 +00:00
|
|
|
for ( var objectKey in this._controllersByObject ) {
|
2014-08-27 00:01:15 +00:00
|
|
|
|
2014-09-16 03:44:07 +00:00
|
|
|
for ( var path in data.values[ objectKey ] ) {
|
2014-08-27 00:01:15 +00:00
|
|
|
|
2014-09-16 03:44:07 +00:00
|
|
|
var value = data.values[ objectKey ][ path ];
|
|
|
|
this._controllersByObject[ objectKey ][ path ].unserialize( value );
|
2014-09-08 03:36:20 +00:00
|
|
|
|
2014-09-16 03:44:07 +00:00
|
|
|
}
|
2014-08-27 00:01:15 +00:00
|
|
|
|
2014-09-16 03:44:07 +00:00
|
|
|
}
|
2014-09-15 20:15:34 +00:00
|
|
|
|
2014-09-16 03:44:07 +00:00
|
|
|
},
|
2014-09-15 20:15:34 +00:00
|
|
|
|
2014-09-16 03:44:07 +00:00
|
|
|
serialize: function() {
|
2014-09-15 20:15:34 +00:00
|
|
|
|
2014-09-16 03:44:07 +00:00
|
|
|
var data = {
|
2014-09-27 20:25:12 +00:00
|
|
|
values: {}
|
2014-09-16 03:44:07 +00:00
|
|
|
};
|
2014-09-15 20:15:34 +00:00
|
|
|
|
2014-09-16 03:44:07 +00:00
|
|
|
for ( var objectKey in this._controllersByObject ) {
|
2014-09-15 20:15:34 +00:00
|
|
|
|
2014-09-16 03:44:07 +00:00
|
|
|
data.values[ objectKey ] = {};
|
2014-09-15 20:15:34 +00:00
|
|
|
|
2014-09-16 03:44:07 +00:00
|
|
|
var controllers = this._controllersByObject[ objectKey ];
|
2014-09-15 20:15:34 +00:00
|
|
|
|
2014-09-16 03:44:07 +00:00
|
|
|
for ( var path in controllers ) {
|
|
|
|
data.values[ objectKey ][ path ] = controllers[ path ].serialize();
|
|
|
|
}
|
2014-09-15 20:15:34 +00:00
|
|
|
|
2014-09-16 03:44:07 +00:00
|
|
|
}
|
2014-09-15 20:15:34 +00:00
|
|
|
|
2014-09-16 03:44:07 +00:00
|
|
|
return data;
|
2014-09-15 20:15:34 +00:00
|
|
|
|
2014-09-16 03:44:07 +00:00
|
|
|
},
|
2014-09-15 20:15:34 +00:00
|
|
|
|
2014-09-16 03:44:07 +00:00
|
|
|
// Legacy
|
|
|
|
// -------------------------------
|
2014-09-15 20:15:34 +00:00
|
|
|
|
2014-09-16 03:44:07 +00:00
|
|
|
remember: function( object ) {
|
2014-09-15 20:15:34 +00:00
|
|
|
|
2014-09-16 03:44:07 +00:00
|
|
|
Gui.warn( 'gui.remember() is deprecated. You don\'t need to do it anymore. See Gui.serialize.' );
|
2014-09-15 20:15:34 +00:00
|
|
|
|
2014-09-16 03:44:07 +00:00
|
|
|
},
|
2014-09-15 20:15:34 +00:00
|
|
|
|
2014-09-16 03:44:07 +00:00
|
|
|
listenAll: function() {
|
2014-09-15 20:15:34 +00:00
|
|
|
|
2014-09-16 03:44:07 +00:00
|
|
|
Gui.warn( 'gui.listenAll() is deprecated. All controllers are listened for free.' );
|
2014-09-15 20:15:34 +00:00
|
|
|
|
2014-09-16 03:44:07 +00:00
|
|
|
},
|
2014-09-15 20:15:34 +00:00
|
|
|
|
|
|
|
|
2014-09-16 03:44:07 +00:00
|
|
|
// Observers
|
|
|
|
// -------------------------------
|
2014-09-15 20:15:34 +00:00
|
|
|
|
2014-09-16 03:44:07 +00:00
|
|
|
openChanged: function() {
|
2014-09-15 20:15:34 +00:00
|
|
|
|
2014-09-16 03:44:07 +00:00
|
|
|
if ( this.open || this.docked ) {
|
2014-09-15 20:15:34 +00:00
|
|
|
|
2014-09-16 03:44:07 +00:00
|
|
|
// let the style sheet take care of things
|
|
|
|
this.$.container.style.transform = '';
|
|
|
|
this.$.panel.style.transform = '';
|
2014-09-15 20:15:34 +00:00
|
|
|
|
2014-09-16 03:44:07 +00:00
|
|
|
} else {
|
2014-09-15 20:15:34 +00:00
|
|
|
|
2014-09-16 03:44:07 +00:00
|
|
|
// todo: need the rest of the vendor prefixes ...
|
|
|
|
// wish i could pipe javascript variables into styl.
|
|
|
|
var y = -this.$.controllers.offsetHeight + 'px';
|
|
|
|
this.$.container.style.transform = 'translate3d( 0, ' + y + ', 0 )';
|
2014-09-15 20:15:34 +00:00
|
|
|
|
|
|
|
}
|
|
|
|
|
2014-09-16 03:44:07 +00:00
|
|
|
this.asyncFire( 'resize' );
|
2014-09-15 20:15:34 +00:00
|
|
|
|
2014-09-16 03:44:07 +00:00
|
|
|
},
|
2014-09-15 20:15:34 +00:00
|
|
|
|
2014-09-16 03:44:07 +00:00
|
|
|
dockedChanged: function() {
|
2014-09-15 20:15:34 +00:00
|
|
|
|
2014-09-16 03:44:07 +00:00
|
|
|
this.openChanged();
|
2014-09-15 20:15:34 +00:00
|
|
|
|
2014-09-16 03:44:07 +00:00
|
|
|
},
|
2014-09-15 22:39:43 +00:00
|
|
|
|
|
|
|
|
2014-09-16 03:44:07 +00:00
|
|
|
// Events
|
|
|
|
// -------------------------------
|
2014-09-15 22:39:43 +00:00
|
|
|
|
2014-09-16 03:44:07 +00:00
|
|
|
tapClose: function() {
|
|
|
|
this.open = !this.open;
|
|
|
|
},
|
2014-09-15 22:39:43 +00:00
|
|
|
|
2014-09-16 03:44:07 +00:00
|
|
|
toggleOpen: function() {
|
|
|
|
this.open = !this.open;
|
2014-09-15 22:39:43 +00:00
|
|
|
}
|
|
|
|
|
2014-09-15 20:15:34 +00:00
|
|
|
} );
|