/** @constructor */
hui.ui.Gallery = function(options) {
this.options = options || {};
this.name = options.name;
this.element = hui.get(options.element);
this.body = hui.get.firstByClass(this.element,'hui_gallery_body');
this.objects = [];
this.nodes = [];
this.selected = [];
this.width = 100;
this.height = 100;
this.revealing = false;
hui.ui.extend(this);
if (options.dropFiles) {
this._addDrop();
}
if (this.options.source) {
this.options.source.listen(this);
}
if (this.element.parentNode && hui.cls.has(this.element.parentNode,'hui_overflow')) {
this.revealing = true;
hui.listen(this.element.parentNode,'scroll',this._reveal.bind(this));
}
};
hui.ui.Gallery.create = function(options) {
options = options || {};
options.element = hui.build('div',{'class':'hui_gallery',html:'<div class="hui_gallery_progress"></div><div class="hui_gallery_body"></div>'});
return new hui.ui.Gallery(options);
};
hui.ui.Gallery.prototype = {
_addDrop : function() {
hui.drag.listen({
element : this.element,
hoverClass : 'hui_gallery_drop',
$dropFiles : function(files) {
this.fire('filesDropped',files);
}.bind(this),
$dropURL : function(url) {
this.fire('urlDropped',url);
}.bind(this)
});
},
hide : function() {
this.element.style.display='none';
},
show : function() {
this.element.style.display='';
if (this.options.source) {
this.options.source.refresh();
}
},
setSize : function(size) {
this.width = size;
this.height = size;
for (var i=0; i < this.nodes.length; i++) {
var node = this.nodes[i];
node.style.width = size+'px';
node.style.height = size+'px';
}
this.maxRevealed = 0;
clearTimeout(this._timer);
this._timer = setTimeout(function() {
for (var i = 0; i < this.nodes.length; i++) {
this.nodes[i].revealed = false;
}
this._reveal();
}.bind(this),500);
},
reRender : function() {
this._render();
},
setObjects : function(objects) {
this.selected = [];
this.objects = objects;
this._render();
this.fire('selectionReset');
},
getObjects : function() {
return this.objects;
},
/** @private */
$sourceShouldRefresh : function() {
return hui.dom.isVisible(this.element);
},
/** @private */
$objectsLoaded : function(objects) {
this.setObjects(objects);
},
/** @private */
$optionsLoaded : function(objects) {
this.setObjects(objects);
},
/** @private */
_render : function() {
this.nodes = [];
this.maxRevealed = 0;
this.body.innerHTML = '';
hui.each(this.objects,function(object,i) {
var top = 0;
if (!this.revealing && object.height < object.width) {
top = (this.height-(this.height*object.height/object.width))/2;
}
var img = hui.build('img',{style:'margin:'+top+'px auto 0px'});
var item = hui.build('div',{'class' : 'hui_gallery_item',style:'width:'+this.width+'px; height:'+this.height+'px'});
if (!this.revealing) {
item.style.backgroundImage = 'url(' + this._resolveImageUrl(object) + ')';
}
//item.appendChild(img);
hui.listen(item,'click',function(e) {
this._itemClicked(i,e);
}.bind(this));
item.dragDropInfo = {kind:'image',icon:'common/image',id:object.id,title:object.name || object.title};
item.onmousedown = function(e) {
hui.ui.startDrag(e,item);
return false;
};
hui.listen(item,'dblclick',function() {
this._onItemDoubleClick(i);
}.bind(this));
this.body.appendChild(item);
this.nodes.push(item);
}.bind(this));
this._reveal();
this.fireSizeChange();
},
_reveal : function() {
if (!this.revealing) {
return;
}
var container = this.element.parentNode;
var limit = container.scrollTop + container.clientHeight;
if (limit <= this.maxRevealed) {
return;
}
this.maxRevealed = limit;
var self = this;
for (var i=0,l=this.nodes.length; i < l; i++) {
var item = this.nodes[i];
if (item.revealed) {
continue;
}
if (item.offsetTop < limit) {
this._load(item, this.objects[i]);
} else {
hui.cls.add(item,'hui_is_pending');
}
}
},
_load : function(item, object) {
hui.cls.add(item,'hui_is_loading');
var url = this._resolveImageUrl(object);
var img = new Image();
img.onload = function() {
item.className = 'hui_gallery_item';
hui.cls.remove(item,'hui_is_pending');
hui.cls.remove(item,'hui_is_loading');
item.style.backgroundImage = 'url(' + url + ')';
};
img.onerror = function() {
hui.cls.remove(item,'hui_is_loading');
hui.cls.add(item,'hui_is_error');
};
img.src = url;
item.revealed = true;
},
_updateUI : function() {
var s = this.selected;
for (var i=0; i < this.nodes.length; i++) {
hui.cls.set(this.nodes[i],'hui_gallery_item_selected',hui.array.contains(s,i));
}
},
_resolveImageUrl : function(img) {
var url = hui.ui.callDelegates(this,'buildImageUrl',{item: img, width: this.width, height: this.height});
return url || hui.ui.resolveImageUrl(this,img,this.width,this.height);
},
_itemClicked : function(index,e) {
if (this.busy) {
return;
}
e = hui.event(e);
if (e.metaKey) {
hui.array.flip(this.selected,index);
} else {
this.selected = [index];
}
this.fire('select',this.selected);
this._updateUI();
},
isOneSelection : function() {
return this.selected.length==1;
},
getSelectionSize : function() {
return this.selected.length;
},
getSelection : function() {
var selection = [];
for (var i=0; i < this.selected.length; i++) {
var obj = this.objects[this.selected[i]];
if (obj) {
selection.push(obj);
}
}
return selection;
},
getSelectionIds : function() {
var selection = [];
for (var i=0; i < this.selected.length; i++) {
var obj = this.objects[this.selected[i]];
if (obj) {
selection.push(obj.id);
}
}
return selection;
},
getFirstSelection : function() {
if (this.selected.length>0) {
return this.objects[this.selected[0]];
}
return null;
},
_onItemDoubleClick : function(index) {
if (this.busy) {
return;
}
this.fire('itemOpened',this.objects[index]);
this.fire('open',this.objects[index]);
},
/**
* Sets the lists data source and refreshes it if it is new
* @param {hui.ui.Source} source The source
*/
setSource : function(source) {
if (this.options.source!=source) {
if (this.options.source) {
this.options.source.unListen(this);
}
source.listen(this);
this.options.source = source;
source.refresh();
}
},
/** @private */
$sourceIsBusy : function() {
this._setBusy(true);
},
/** @private */
$sourceIsNotBusy : function() {
this._setBusy(false);
},
/** @private */
$visibilityChanged : function() {
if (hui.dom.isVisible(this.element)) {
if (this.options.source) {
this.options.source.refreshFirst();
}
this._reveal();
}
},
/** @private */
$$layout : function() {
if (this.nodes.length > 0) {
this._reveal();
}
},
_setBusy : function(busy) {
this.busy = busy;
window.clearTimeout(this.busytimer);
if (busy) {
var e = this.element;
this.busytimer = window.setTimeout(function() {
hui.cls.add(e,'hui_gallery_busy');
},300);
} else {
hui.cls.remove(this.element,'hui_gallery_busy');
}
}
};