234 lines
6.1 KiB
JavaScript
234 lines
6.1 KiB
JavaScript
|
cdb.admin.SlideTransition = cdb.core.Model.extend({
|
||
|
defaults: {
|
||
|
time: 0
|
||
|
}
|
||
|
});
|
||
|
|
||
|
/**
|
||
|
* contains and manages the state for an slide
|
||
|
*/
|
||
|
cdb.admin.Slide = cdb.core.Model.extend({
|
||
|
|
||
|
initialize: function() {
|
||
|
var self = this;
|
||
|
this._tracked = [];
|
||
|
this.visualization = null;
|
||
|
this.bind('change:active', function _active() {
|
||
|
if (self.isActive() && self.master && self.visualization) {
|
||
|
self.master.changeTo(this.visualization);
|
||
|
}
|
||
|
});
|
||
|
},
|
||
|
|
||
|
// unload the visualization from memory and deattach all the stuff
|
||
|
unload: function() {
|
||
|
var self = this;
|
||
|
this.unbind(null, null, this);
|
||
|
this.visualization.unbind(null, null, this);
|
||
|
this.visualization = null;
|
||
|
this.master.map.unbind(null, null, this);
|
||
|
this.master.unbind(null, null, this);
|
||
|
_.each(this._tracked, function(o) {
|
||
|
o.unbind(null, null, self);
|
||
|
});
|
||
|
this._tracked = [];
|
||
|
this.loaded = false;
|
||
|
},
|
||
|
|
||
|
// track object state using restore and serialize
|
||
|
_trackObject: function(obj, properties, serialize) {
|
||
|
|
||
|
this._tracked.push(obj);
|
||
|
|
||
|
// build list of properties to listen
|
||
|
var listen = 'change';
|
||
|
if (properties && properties.length) {
|
||
|
listen = properties.map(function(p) {
|
||
|
return 'change:' + p;
|
||
|
}).join(' ');
|
||
|
}
|
||
|
|
||
|
// serialize object state to slide
|
||
|
obj.bind(listen, function() {
|
||
|
if (this.isActive()) {
|
||
|
serialize.call(this, obj, properties ? _.pick(obj.attributes, properties): obj.attributes);
|
||
|
}
|
||
|
}, this);
|
||
|
|
||
|
},
|
||
|
|
||
|
setMaster: function(vis) {
|
||
|
var self = this;
|
||
|
this.master = vis;
|
||
|
if (!this.visualization) {
|
||
|
this.visualization = new cdb.admin.Visualization(
|
||
|
_.extend(
|
||
|
_.pick(this.attributes, 'id', 'map_id', 'next_id', 'prev_id', 'transition_options', 'type'), { bindMap: false, parent_id: vis.id }
|
||
|
));
|
||
|
}
|
||
|
},
|
||
|
|
||
|
isActive: function() {
|
||
|
return !!this.get('active');
|
||
|
},
|
||
|
|
||
|
destroy: function() {
|
||
|
this.visualization.destroy.apply(this.visualization, arguments);
|
||
|
this.trigger('destroy', this, this.collection);
|
||
|
return this;
|
||
|
},
|
||
|
|
||
|
setNext: function(next_visualization_id, opt) {
|
||
|
var v = new cdb.admin.Visualization({ id: this.id });
|
||
|
v.order.save('next_id', next_visualization_id, opt);
|
||
|
this._reorder(next_visualization_id);
|
||
|
this.trigger('change:next_id', this, next_visualization_id);
|
||
|
return this;
|
||
|
},
|
||
|
|
||
|
_reorder: function(next_visualization_id) {
|
||
|
var s, insertIndex;
|
||
|
// look for the slide in collection
|
||
|
if (this.collection) {
|
||
|
var col = this.collection;
|
||
|
if (next_visualization_id !== null) {
|
||
|
s = col.get(next_visualization_id);
|
||
|
insertIndex = col.indexOf(s);
|
||
|
} else {
|
||
|
insertIndex = col.length;
|
||
|
}
|
||
|
if (insertIndex >= 0) {
|
||
|
var currentIndex = col.indexOf(this);
|
||
|
// insert just before the
|
||
|
col.models.splice(insertIndex, 0, this);
|
||
|
if (currentIndex >= insertIndex) currentIndex += 1;
|
||
|
// remove previous one
|
||
|
col.models.splice(currentIndex, 1);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
});
|
||
|
|
||
|
|
||
|
/**
|
||
|
* slide collection
|
||
|
*/
|
||
|
cdb.admin.Slides = Backbone.Collection.extend({
|
||
|
|
||
|
model: cdb.admin.Slide,
|
||
|
|
||
|
initialize: function(models, options) {
|
||
|
if (!options || !options.visualization) {
|
||
|
throw new Error("visualization is undefined");
|
||
|
}
|
||
|
|
||
|
// master visualization
|
||
|
this.visualization = options.visualization;
|
||
|
// save the master visualization id so when a new visualization is created
|
||
|
// we set this as parent, see create method
|
||
|
this.master_visualization_id = this.visualization.id;
|
||
|
|
||
|
|
||
|
var self = this;
|
||
|
|
||
|
var _setMaster = function(m) {
|
||
|
m.setMaster(self.visualization);
|
||
|
};
|
||
|
|
||
|
this.bind('add', _setMaster, this);
|
||
|
this.bind('add', function(slide) {
|
||
|
this.setActive(slide);
|
||
|
}, this);
|
||
|
|
||
|
this.bind('reset', function() {
|
||
|
this.each(_setMaster);
|
||
|
this.setActive(this.at(0));
|
||
|
}, this);
|
||
|
|
||
|
this.bind('remove', this._onRemoveSlide, this);
|
||
|
},
|
||
|
|
||
|
_onRemoveSlide: function(slide, collection, options) {
|
||
|
if (slide.isActive() && this.length > 0) {
|
||
|
if (options.index !== this.length) {
|
||
|
this.setActive(this.at(options.index));
|
||
|
} else if (options.index == this.length) {
|
||
|
this.setActive(this.at(options.index - 1));
|
||
|
}
|
||
|
}
|
||
|
},
|
||
|
|
||
|
// https://github.com/jashkenas/backbone/issues/962
|
||
|
initializeModels: function() {
|
||
|
var self = this;
|
||
|
var _setMaster = function(m) {
|
||
|
m.setMaster(self.visualization);
|
||
|
};
|
||
|
this.each(_setMaster);
|
||
|
},
|
||
|
|
||
|
// creates a new slide
|
||
|
// there is an special case when there is no slides: two slides are actually created, one to clone the master one and the new one the user is actually adding
|
||
|
create: function(done) {
|
||
|
var self = this;
|
||
|
if (this.length === 0) {
|
||
|
this._createSlide(function(slide) {
|
||
|
self._createSlide(function(slide2) {
|
||
|
self.add(slide)
|
||
|
self.add(slide2);
|
||
|
done && done(slide2);
|
||
|
}, { no_add: true, prev_id: slide.id });
|
||
|
}, { no_add: true });
|
||
|
} else {
|
||
|
this._createSlide(done);
|
||
|
}
|
||
|
},
|
||
|
|
||
|
_createSlide: function(done, options) {
|
||
|
options = options || {}
|
||
|
var self = this;
|
||
|
var prev_id = options.prev_id || null;
|
||
|
if (!prev_id && this.length) {
|
||
|
prev_id = this.last().visualization.id
|
||
|
}
|
||
|
return this.visualization.copy({
|
||
|
copy_overlays: true,
|
||
|
type: 'slide',
|
||
|
parent_id: this.master_visualization_id,
|
||
|
prev_id: prev_id
|
||
|
}, {
|
||
|
success: function(vis) {
|
||
|
vis.map.layers.bind('reset', function() {
|
||
|
// on create assign the track id
|
||
|
var slide = new cdb.admin.Slide({ id: vis.id });
|
||
|
slide.visualization = vis;
|
||
|
if (!options.no_add) self.add(slide);
|
||
|
done && done(slide);
|
||
|
});
|
||
|
}
|
||
|
});
|
||
|
},
|
||
|
|
||
|
setActive: function(slide) {
|
||
|
var active = this.find(function (s) {
|
||
|
return s.get('active');
|
||
|
});
|
||
|
if (active) {
|
||
|
active.set('active', false);
|
||
|
}
|
||
|
if (slide) slide.set('active', true);
|
||
|
},
|
||
|
|
||
|
/*
|
||
|
* return true if some layer inside any of the visualization contain a torque layer
|
||
|
*/
|
||
|
existsTorqueLayer: function() {
|
||
|
return this.any(function(s) {
|
||
|
return s.visualization.map.layers.getTorqueLayers().length !== 0;
|
||
|
});
|
||
|
}
|
||
|
|
||
|
});
|