// vim: et:ts=4:sw=4:sts=4:ft=javascript 'use strict'; /*@ Ox.AnnotationFolder AnnotationFolder Object () -> AnnotationFolder Object (options) -> AnnotationFolder Object (options, self) -> AnnotationFolder Object options Options object editable If true, annotations can be added id id items items title title type panel type width self shared private variable @*/ Ox.AnnotationFolder = function(options, self) { self = self || {}; var that = Ox.Element({}, self) .defaults({ collapsed: false, editable: false, id: '', 'in': 0, item: '', items: [], out: 0, position: 0, range: 'all', selected: '', showWidget: false, sort: 'position', title: '', type: 'text', users: 'all', widgetSize: 256, width: 0 }) .options(options || {}); self.sort = getSort(); self.widget = self.options.type == 'event' ? 'Calendar' : self.options.type == 'place' ? 'Map' : ''; if (self.widget) { self.$defineButton = Ox.Button({ disabled: !self.options.selected, id: 'define', style: 'symbol', title: 'click', tooltip: 'Define ' + Ox.toTitleCase(self.options.type), type: 'image' }) .bindEvent({ click: function() { } }); } self.$addButton = Ox.Button({ disabled: !self.options.editable, id: 'add', style: 'symbol', title: 'add', tooltip: 'Add ' + self.options.item, type: 'image' }).bindEvent({ click: function() { that.triggerEvent('add', {value: ''}); } }); that.setElement( Ox.CollapsePanel({ collapsed: self.options.collapsed, extras: Ox.merge( self.widget ? [self.$defineButton] : [], [self.$addButton] ), size: 16, title: self.options.title }) .addClass('OxAnnotationFolder') .bindEvent({ toggle: toggleLayer }) ); that.$content = that.$element.$content; if (self.widget) { self.widgetSize = self.options.showWidget * self.options.widgetSize; Ox.print('FOO', self.widgetSize, self.options.showWidget, self.options.widgetSize) self.$outer = Ox.Element() .css({ display: 'table-cell', width: self.options.width + 'px' }) .appendTo(that.$content); self.$inner = Ox.Element() .css({ height: self.widgetSize + 'px', overflow: 'hidden' }) .appendTo(self.$outer); if (options.type == 'event') { self.$widget = self.$calendar = Ox.Calendar({ events: getEvents(), height: self.widgetSize, showZoombar: true, width: self.options.width }) .css({ width: self.options.width + 'px', height: self.widgetSize + 'px' }) .bindEvent({ select: function(data) { selectAnnotation({id: data.annotationId}); } }) .appendTo(self.$inner); } else { // place self.$widget = self.$map = Ox.Map({ places: getPlaces(), // FIXME: should be showZoombar zoombar: true // showLabels: true }) .css({ width: self.options.width + 'px', height: self.widgetSize + 'px' }) .bindEvent({ // FIXME: should be select, not selectplace selectplace: function(data) { self.$annotations.options({selected: data.annotationId}); // selectAnnotation({id: data.annotationId}); } }) .appendTo(self.$inner); } self.$resizebar = Ox.Element({ tooltip: 'Drag to resize or click to toggle map' // fixme: update as w/ splitpanels }) .addClass('OxResizebar OxHorizontal') .css({ position: 'absolute', top: self.widgetSize + 'px', cursor: 'ns-resize' }) .append($('
').addClass('OxSpace')) .append($('
').addClass('OxLine')) .append($('
').addClass('OxSpace')) .bindEvent({ anyclick: toggleWidget, dragstart: dragstart, drag: drag, dragend: dragend }) .appendTo(self.$outer); } self.$annotations = Ox.ArrayEditable({ editable: self.options.editable, items: getAnnotations(), selected: self.options.selected, sort: self.sort, submitOnBlur: false, width: self.options.type == 'text' ? self.options.width + 8 : self.options.width, type: self.options.type == 'text' ? 'textarea' : 'input' }) //.css({marginTop: '256px'}) .bindEvent({ add: function(data) { that.triggerEvent('add', {value: data.value || ''}); }, blur: function() { that.triggerEvent('blur'); }, 'delete': function(data) { that.triggerEvent('remove', {id: data.id}); }, edit: function() { self.editing = true; that.triggerEvent('edit'); }, select: selectAnnotation, submit: submitAnnotation, key_space: function() { that.triggerEvent('paused'); } }) .appendTo( ['event', 'place'].indexOf(self.options.type) > -1 ? self.$outer : that.$content ); Ox.print('SAH', self.$annotations.height()) self.options.selected && setTimeout(function() { selectAnnotation({id: self.options.selected}); }, 0); showWarnings(); function dragstart() { if (self.options.showWidget) { self.drag = { startSize: self.options.widgetSize }; } } function drag(e) { if (self.options.showWidget) { self.options.widgetSize = Ox.limit( self.drag.startSize + e.clientDY, 128, 384 ); if (self.options.widgetSize >= 248 && self.options.widgetSize <= 264) { self.options.widgetSize = 256; } self.$resizebar.css({top: self.options.widgetSize + 'px'}); self.$inner.css({height: self.options.widgetSize + 'px'}); self.$widget.css({ height: self.options.widgetSize + 'px' }); } //self.options.type == 'place' && self.$map.resizeMap(); } function dragend(e) { if (self.options.showWidget) { that.triggerEvent('resizewidget', {size: self.options.widgetSize}); } } function getAnnotations() { return self.options.items.filter(function(item) { return self.editing && item.id == self.options.selected || ( ( self.options.range == 'all' || ( self.options.range == 'selection' && item['in'] < self.options.out && item.out > self.options['in'] ) || ( self.options.range == 'position' && item['in'] <= self.options.position && item.out >= self.options.position ) ) && ( self.options.users == 'all' || self.options.users.indexOf(item.user) > -1 ) ); }); } function getEvents() { var events = []; getAnnotations().forEach(function(item) { if (item.event && Ox.getIndexById(events, item.event.id) == -1) { events.push(Ox.extend({ annotationId: item.id }, item.event)); } }); if (!events.length) { events = [{id: 'FOO', name: '20th Century', type: 'date', start: '1900', end: '2000'}] } return events; } function getPlaces() { var places = []; getAnnotations().forEach(function(item) { if (item.place && Ox.getIndexById(places, item.place.id) == -1) { places.push(Ox.extend({ annotationId: item.id }, item.place)); } }); return places; } function getSort() { return ({ duration: ['-duration', '+in', '+value'], position: ['+in', '-duration', '+value'], text: ['+value', '+in', '-duration'] })[self.options.sort]; } function selectAnnotation(data) { var item = Ox.getObjectById(self.options.items, data.id); self.options.selected = item ? data.id : ''; self.$defineButton.options({disabled: !self.options.selected}); ///* if (self.options.type == 'place') { self.$map.options({ selected: item && item.place ? item.place.id : null }) .panToPlace(); } //*/ that.triggerEvent('select', Ox.extend(data, item ? { 'in': item['in'], out: item.out, layer: self.options.id } : {})); } function showWarnings() { if (self.widget) { self.$annotations.find('.OxValue').each(function() { var $element = $(this); if (!Ox.getObject( self.options.items, 'value', $element.html() )[self.options.type]) { $element.css({color: 'rgb(192, 64, 64)'}); } }); } } function submitAnnotation(data) { var item = Ox.getObjectById(self.options.items, data.id); item.value = data.value; self.editing = false; Ox.print('??:', self.options.items[0], self.$annotations.options('items')[0]) //self.$annotations.options({items: self.options.items}); self.options.sort == 'text' && self.$annotations.reloadItems(); that.triggerEvent('submit', item); } function toggleLayer() { self.options.collapsed = !self.options.collapsed; that.triggerEvent('togglelayer', {collapsed: self.options.collapsed}); } function toggleWidget() { self.options.showWidget = !self.options.showWidget; self.widgetSize = self.options.showWidget * self.options.widgetSize; self.$resizebar.animate({top: self.widgetSize + 'px'}, 250); self.$inner.animate({height: self.widgetSize + 'px'}, 250); self.$widget.animate({height: self.widgetSize + 'px'}, 250, function() { self.$widget.options({height: self.widgetSize}); }); that.triggerEvent('togglewidget', {collapsed: !self.options.showWidget}); } self.setOption = function(key, value) { if (['in', 'out'].indexOf(key) > -1 && self.editing) { var index = Ox.getIndexById(self.options.items, self.options.selected); self.options.items[index][key] = value; self.options.items[index].duration = self.options.out - self.options['in']; } if (key == 'in') { //fixme: array editable should support item updates while editing if (self.editing || self.options.range == 'selection') { self.options.type == 'place' ? self.$map.options({places: getPlaces()}) : self.$annotations.options({items: getAnnotations()}); } } else if (key == 'out') { if (self.editing || self.options.range == 'selection') { self.options.type == 'place' ? self.$map.options({places: getPlaces()}) : self.$annotations.options({items: getAnnotations()}); } } else if (key == 'position') { if (self.editing || self.options.range == 'position') { self.options.type == 'place' ? self.$map.options({places: getPlaces()}) : self.$annotations.options({items: getAnnotations()}); } } else if (key == 'range') { self.$annotations.options({items: getAnnotations()}); } else if (key == 'selected') { if (value === '') { self.editing = false; } self.$annotations.options({selected: value}); } else if (key == 'sort') { self.sort = getSort(); self.$annotations.options({sort: self.sort}); showWarnings(); } else if (key == 'users') { self.$annotations.options({items: getAnnotations()}); showWarnings(); } else if (key == 'width') { Ox.print('RESIZE!!!!') if (self.widget) { self.$outer.options({width: self.options.width}); self.$inner.options({width: self.options.width}); self.$widget.options({width: self.options.width}); } self.$annotations.options({ width: self.options.type == 'text' ? self.options.width + 8 : self.options.width }); } }; /*@ addItem addItem @*/ that.addItem = function(item) { var pos = 0; self.options.items.splice(pos, 0, item); self.$annotations.addItem(pos, item); self.$annotations.editItem(item.id); }; that.blurItem = function() { self.$annotations.blurItem(); }; that.editItem = function() { self.$annotations.editItem(); }; /*@ removeItems removeItems @*/ /* that.removeItem = function(id) { var pos = Ox.getIndexById(self.options.items, id); self.options.items.splice(pos, 1); self.$annotations.removeItems && self.$annotations.removeItems([id]); }; */ return that; };