diff --git a/build/js/ox.js b/build/js/ox.js index ae06dd70..b8a88fa7 100644 --- a/build/js/ox.js +++ b/build/js/ox.js @@ -415,6 +415,7 @@ Ox.isEqual = function(obj0, obj1) { if (obj0 == obj1) { ret = true; } else if (Ox.isArray(obj0) && obj0.length == obj1.length) { + ret = true; Ox.forEach(obj0, function(v, i) { ret = Ox.isEqual(v, obj1[i]); return ret; @@ -1331,7 +1332,7 @@ Encoding functions >>> Ox.encodeUTF8('¥€$') '\u00C2\u00A5\u00E2\u0082\u00AC\u0024' */ - return Ox.map(Array.prototype.slice.call(str), function(chr) { + return Ox.map(str, function(chr) { var code = chr.charCodeAt(0), str = ''; if (code < 128) { @@ -1399,6 +1400,10 @@ Format functions ================================================================================ */ +Ox.formatArea = function(num, dec) { + return Ox.formatNumber(Ox.round(num / 1000000, dec)) + ' km²'; +} + Ox.formatColor = function() { }; @@ -1713,6 +1718,132 @@ Geo functions ================================================================================ */ +(function() { + + function rad(point) { + return { + lat: Ox.rad(point.lat), + lng: Ox.rad(point.lng) + }; + } + + Ox.crossesDateline = function(point0, point1) { + return point0.lng > point1.lng; + } + + Ox.getArea = function(point0, point1) { + /* + area of a ring between two latitudes: + 2 * PI * r^2 * abs(sin(lat0) - sin(lat1)) + see http://mathforum.org/library/drmath/view/63767.html + */ + /* + 2 * Math.PI * + Math.pow(Ox.EARTH_RADIUS, 2) * + Math.abs(Math.sin(Ox.rad(0)) - Math.sin(Ox.rad(1))) * + Math.abs(Ox.rad(0) - Ox.rad(1)) / + (2 * Math.PI) + */ + if (Ox.crossesDateline(point0, point1)) { + point1.lng += 360; + } + var point0 = rad(point0), + point1 = rad(point1); + return Math.pow(Ox.EARTH_RADIUS, 2) * + Math.abs(Math.sin(point0.lat) - Math.sin(point1.lat)) * + Math.abs(point0.lng - point1.lng); + }; + + Ox.getBearing = function(point0, point1) { + /* + >>> Ox.getBearing({lat: -45, lng: 0}, {lat: 45, lng: 0}) + 0 + */ + var point0 = rad(point0), + point1 = rad(point1), + x = Math.cos(point0.lat) * Math.sin(point1.lat) - + Math.sin(point0.lat) * Math.cos(point1.lat) * + Math.cos(point1.lng - point0.lng), + y = Math.sin(point1.lng - point0.lng) * + Math.cos(point1.lat); + return (Ox.deg(Math.atan2(y, x)) + 360) % 360; + }; + + Ox.getCenter = function(point0, point1) { + /* + >>> Ox.values(Ox.getCenter({lat: -45, lng: -90}, {lat: 45, lng: 90})) + [0, 0] + */ + var point0 = rad(point0), + point1 = rad(point1), + x = Math.cos(point1.lat) * + Math.cos(point1.lng - point0.lng), + y = Math.cos(point1.lat) * + Math.sin(point1.lng - point0.lng), + d = Math.sqrt( + Math.pow(Math.cos(point0.lat) + x, 2) + Math.pow(y, 2) + ), + lat = Ox.deg( + Math.atan2(Math.sin(point0.lat) + Math.sin(point1.lat), d) + ), + lng = Ox.deg( + point0.lng + Math.atan2(y, Math.cos(point0.lat) + x) + ); + return {lat: lat, lng: lng}; + }; + + Ox.getDistance = function(point0, point1) { + /* + >>> Ox.EARTH_CIRCUMFERENCE == Ox.getDistance({lat: -45, lng: -90}, {lat: 45, lng: 90}) * 2 + true + */ + var point0 = rad(point0), + point1 = rad(point1); + return Math.acos( + Math.sin(point0.lat) * Math.sin(point1.lat) + + Math.cos(point0.lat) * Math.cos(point1.lat) * + Math.cos(point1.lng - point0.lng) + ) * Ox.EARTH_RADIUS; + }; + + Ox.getLatLngByXY = function(xy) { + /* + >>> Ox.values(Ox.getLatLngByXY({x: 0.5, y: 0.5})) + [0, 0] + */ + function getVal(val) { + return (val - 0.5) * 2 * Math.PI; + } + return { + lat: -Ox.deg(Math.atan(Ox.sinh(getVal(xy.y)))), + lng: Ox.deg(getVal(xy.x)) + } + }; + + Ox.getMetersPerDegree = function(lat) { + /* + >>> Ox.EARTH_CIRCUMFERENCE == Ox.getMetersPerDegree(0) * 360 + true + */ + return Math.cos(lat * Math.PI / 180) * Ox.EARTH_CIRCUMFERENCE / 360; + }; + + Ox.getXYByLatLng = function(latlng) { + /* + >>> Ox.values(Ox.getXYByLatLng({lat: 0, lng: 0})) + [0.5, 0.5] + */ + function getVal(val) { + return (val / (2 * Math.PI) + 0.5) + } + return { + x: getVal(Ox.rad(latlng.lng)), + y: getVal(Ox.asinh(Math.tan(Ox.rad(-latlng.lat)))) + }; + }; + +}()); + Ox.Line = function(point0, point1) { var self = { @@ -1734,13 +1865,6 @@ Ox.Line = function(point0, point1) { }; that.getBearing = function() { - var points = rad(), - x = Math.cos(point[0].lat) * Math.sin(point[1].lat) - - Math.sin(point[0].lat) * Math.cos(point[1].lat) * - Math.cos(point[1].lng - point[0].lng), - y = Math.sin(point[1].lng - point[0].lng) * - Math.cos(point[1].lat); - return (Ox.deg(math.atan2(y, x)) + 360) % 360; }; that.getDistance = function() { diff --git a/build/js/ox.load.js b/build/js/ox.load.js index 43c05b53..daa58964 100644 --- a/build/js/ox.load.js +++ b/build/js/ox.load.js @@ -24,7 +24,7 @@ $(function() { WebkitUserSelect: 'none' }, file = 'js/ox.load.js', - path = $('script[src*=' + file + ']').attr('src').replace(file, ''), + path = $('script[src*="' + file + '"]').attr('src').replace(file, ''), userAgent, userAgents = { 'Chrome': 'http://www.google.com/chrome/', diff --git a/build/js/ox.map.js b/build/js/ox.map.js index 29c72482..c8d90fbb 100644 --- a/build/js/ox.map.js +++ b/build/js/ox.map.js @@ -215,7 +215,7 @@ Ox.COUNTRIES = [ {code: 'MD-TR', continent: 'Europe', name: 'Transnistria', region: 'Eastern Europe', type: 'unrecognized'}, {code: 'AQ', continent: 'Antarctica', country: ['Argentina', 'Australia', 'Chile', 'France', 'New Zealand', 'Norway', 'United Kingdom'], name: 'Antarctica'}, {code: 'CX', continent: 'Asia', country: 'Australia', name: 'Christmas Island', region: 'South-Eastern Asia', type: 'dependent'}, - {code: 'CC', continent: 'Asia', country: 'Australia', name: 'Cocos Island', region: 'South-Eastern Asia', type: 'dependent'}, + {code: 'CC', continent: 'Asia', country: 'Australia', name: 'Cocos Islands', region: 'South-Eastern Asia', type: 'dependent'}, {code: 'HM', continent: 'Antarctica', country: 'Australia', name: 'Heard Island and McDonald Islands', type: 'dependent'}, {code: 'NF', continent: 'Oceania', country: 'Australia', name: 'Norfolk Island', region: 'Australia and New Zealand', type: 'dependent'}, {code: 'HK', continent: 'Asia', country: 'China', name: 'Hong Kong', region: 'Eastern Asia', type: 'dependent'}, @@ -311,4 +311,76 @@ Ox.COUNTRIES = [ {code: 'WKUM', continent: 'Oceania', country: 'United States', name: 'Wake Island', region: 'Micronesia', type: 'former'}, {code: 'EU', continent: 'Europe', name: 'European Union', type: 'other'}, {code: 'UK', continent: 'Europe', name: 'United Kingdom', region: 'Northern Europe', type: 'other'} -]; \ No newline at end of file +]; + +Ox.COUNTRY_CODES = Ox.map(Ox.COUNTRIES, function(country) { + return country.code.length == 2 && ['EU', 'UK'].indexOf(country.code) == -1 ? country.code : null; +}).sort(); + +Ox.getCountryCode = (function() { + var aliases = { + 'The Bahamas': 'Bahamas', + 'The Netherlands': 'Netherlands', + 'UK': 'United Kingdom', + 'US Virgin Islands': 'United States Virgin Islands', + 'USA': 'United States' + }; + return function(geoname) { + var countryCode = '', + countryName = geoname.split(', ').pop(); + Ox.forEach(aliases, function(val, key) { + if (countryName == key) { + countryName = val; + return false; + } + }); + Ox.forEach(Ox.COUNTRIES, function(country) { + if (country.name == countryName) { + countryCode = country.code; + return false; + } + }); + return countryCode; + }; +}()); + +Ox.Place = function(options) { + + /* + in: geoname, name, south, west, north, east + out: country, countryCode, geonameReverse, lat, lng + */ + + var self = {}, + that = Ox.extend(this, options); + + ['south', 'west', 'north', 'east'].forEach(function(v) { + self[v + 'Rad'] = Ox.rad(that[v]); + }); + + self.geonames = that.geoname.split(', ').reverse(); + that.geonameReverse = self.geonames.join(', '); + + Ox.forEach(Ox.COUNTRIES, function(country) { + if (country.name == self.geonames[0]) { + that.country = country.name; + that.countryCode = country.code; + return false; + } + }); + + function getArea() { + + } + + function getCenter() { + + } + + function getRad(points) { + + } + + return that; + +}; \ No newline at end of file diff --git a/build/js/ox.ui.js b/build/js/ox.ui.js index 9542637d..0ec43be7 100644 --- a/build/js/ox.ui.js +++ b/build/js/ox.ui.js @@ -955,6 +955,7 @@ requires // self.onChange(key, value) // is called when an option changes // (to be implemented by widget) + // fixme: rename to self.setOption }; that._leakSelf = function() { // fixme: remove @@ -2892,7 +2893,12 @@ requires width: 128 }) .options(options) - .addClass('OxInput OxMedium Ox' + Ox.toTitleCase(self.options.style)) + .addClass( + 'OxInput OxMedium Ox' + Ox.toTitleCase(self.options.style) /*+ ( + self.options.overlap != 'none' ? + ' OxOverlap' + Ox.toTitleCase(self.options.overlap) : '' + )*/ + ) .bindEvent($.extend(self.options.type == 'textarea' ? {} : { key_enter: submit }, { @@ -2935,7 +2941,8 @@ requires float: 'left', // fixme: use css rule }) .click(function() { - that.focus(); + // fixme: ??? + // that.focus(); }) .appendTo(that); } @@ -3307,7 +3314,7 @@ requires */ function blur() { - //Ox.print('blur') + Ox.print('blur!!!!!') that.loseFocus(); //that.removeClass('OxFocus'); self.options.value = self.$input.val(); @@ -3459,7 +3466,7 @@ requires if (self.options.value === '') { if (self.options.type == 'password') { self.$placeholder.hide(); - self.$input.show().focus(); + self.$input.show().focusInput(); } else { self.$input .removeClass('OxPlaceholder') @@ -3530,7 +3537,7 @@ requires } }; - that.focus = function() { + that.focusInput = function() { self.$input.focus(); cursor(0, self.$input.val().length); return that; @@ -3644,7 +3651,7 @@ requires function click(event) { if ($(event.target).hasClass('OxSeparator')) { - self.options.inputs[0].focus(); + self.options.inputs[0].focusInput(); } } @@ -4421,19 +4428,10 @@ requires $.extend(self, { trackColors: self.options.trackColors.length, trackImages: self.options.trackImages.length, - trackSize: self.options.size - self.options.arrows * 32, values: (self.options.max - self.options.min + self.options.step) / self.options.step }); - $.extend(self, { - thumbSize: Math.max(self.trackSize / self.values, self.options.thumbSize), - trackImageWidths: self.trackImages == 1 ? [self.trackSize - 16] : - Ox.divideInt(self.trackSize - 2, self.trackImages) - }); - $.extend(self, { - trackColorsStart: self.thumbSize / 2 / self.options.size, - trackColorsStep: (self.options.size - self.thumbSize) / (self.trackColors - 1) / self.options.size - }); + setSizes(); if (self.options.arrows) { self.$arrows = []; @@ -4555,6 +4553,22 @@ requires self.options.min, self.options.max); } + function setSizes() { + self.trackSize = self.options.size - self.options.arrows * 32; + self.thumbSize = Math.max(self.trackSize / self.values, self.options.thumbSize); + self.trackImageWidths = self.trackImages == 1 ? [self.trackSize - 16] : + Ox.divideInt(self.trackSize - 2, self.trackImages); + self.trackColorsStart = self.thumbSize / 2 / self.options.size; + self.trackColorsStep = (self.options.size - self.thumbSize) / + (self.trackColors - 1) / self.options.size; + self.$track && self.$track.css({ + width: (self.trackSize - 2) + 'px' + }); + self.$thumb && self.$thumb.options({ + width: self.thumbSize + }); + } + function setThumb(animate) { self.$thumb.stop().animate({ marginLeft: (getPx(self.options.value) - 1) + 'px', @@ -4597,7 +4611,9 @@ requires } self.onChange = function(key, value) { - if (key == 'trackColors') { + if (key == 'size') { + setSizes(); + } else if (key == 'trackColors') { setTrackColors(); } else if (key == 'value') { setThumb(); @@ -5375,7 +5391,7 @@ requires float: 'left' }) .click(function() { - that.$input[0].focus(); + that.$input[0].focusInput(); }) .appendTo(that); } else if (key.label.length > 1) { @@ -5429,7 +5445,7 @@ requires float: 'right' }) .click(function() { - that.$input[0].focus(); + that.$input[0].focusInput(); }) .appendTo(that); } else if (self.options.unit.length > 1) { @@ -5469,7 +5485,7 @@ requires marginLeft: (v.width - (i == 0 ? 16 : 32)) + 'px' }) .click(function() { - that.$input[0].focus(); + that.$input[0].focusInput(); }) .appendTo(that); } @@ -5544,7 +5560,7 @@ requires } if (self.options.label) { //that.$label.html(self.option.title); - that.$input[0].focus(); + that.$input[0].focusInput(); //autocompleteCall(); } else { that.$input[0].options({ @@ -5563,14 +5579,14 @@ requires } function changeUnit() { - that.$input[0].focus(); + that.$input[0].focusInput(); } function clear() { $.each(that.$input, function(i, v) { v.val(''); }); - that.$input[0].focus(); + that.$input[0].focusInput(); } function height(value) { @@ -6175,12 +6191,12 @@ requires centerSelection: false, draggable: true, id: '', - item: function() {}, + item: null, + items: null, keys: [], max: -1, min: 0, orientation: 'both', - request: function() {}, selected: [], size: 128, sort: [], @@ -6198,13 +6214,13 @@ requires draggable: self.options.draggable, id: self.options.id, itemHeight: self.itemHeight, + items: self.options.items, itemWidth: self.itemWidth, keys: self.options.keys, orientation: self.options.orientation, keys: self.options.keys, max: self.options.max, min: self.options.min, - request: self.options.request, selected: self.options.selected, size: self.options.size, sort: self.options.sort, @@ -6250,7 +6266,7 @@ requires } self.onChange = function(key, value) { - if (key == 'request') { + if (key == 'items') { that.$element.options(key, value); } else if (key == 'paste') { that.$element.options(key, value); @@ -6470,14 +6486,13 @@ requires centered boolean if true, and orientation is 'horizontal', then keep the selected item centered construct function function(data), returns the list item HTML - request function function(callback) returns {items, size, ...} + items function function(callback) returns {items, size, ...} function(data, callback) returns [items] + or array of items Methods Events ***/ - // fixme: items and request should be the same option - var self = self || {}, that = new Ox.Container({}, self) .defaults({ @@ -6493,7 +6508,6 @@ requires min: 0, orientation: 'vertical', pageLength: 100, - request: null, selected: [], sort: [], sortable: false, @@ -6599,6 +6613,7 @@ requires } if (Ox.isArray(self.options.items)) { + self.listLength = self.options.items.length; loadItems(); } else { updateQuery(self.options.selected); @@ -6698,7 +6713,7 @@ requires Ox.Request.cancel(v); }); $.extend(self, { - $items: [], + //$items: [], $pages: [], page: 0, requests: [] @@ -6708,8 +6723,7 @@ requires function constructEmptyPage(page) { //Ox.print('cEP', page) var i, $page = new Ox.ListPage().css(getPageCSS(page)); - for (i = 0; i < (page < self.pages - 1 ? - self.pageLength : self.listLength % self.pageLength); i++ + for (i = 0; i < getPageLength(page); i++ ) { // fixme: why does chainging fail here? new Ox.ListItem({ @@ -6856,6 +6870,7 @@ requires } function fillFirstPage() { + Ox.print('fillFirstPage') if (self.$pages[0]) { var height = getHeight(), lastItemHeight = height % self.options.itemHeight || self.options.itemHeight, @@ -6966,8 +6981,7 @@ requires left: (page * self.pageWidth + self.listMargin / 2) + 'px', top: (self.listMargin / 2) + 'px', width: (page < self.pages - 1 ? self.pageWidth : - self.listLength % self.pageLength * - (self.options.itemWidth + self.itemMargin)) + 'px' + getPageLength(page) * (self.options.itemWidth + self.itemMargin)) + 'px' } : { top: (page * self.pageHeight + self.listMargin / 2) + 'px', width: self.pageWidth + 'px' @@ -6991,14 +7005,16 @@ requires } function getPositions(ids) { + Ox.print('getPositions', ids) ids = ids || getSelectedIds(); + Ox.print('getPositions', ids) // fixme: optimize: send non-selected ids if more than half of the items are selected if (ids.length /*&& ids.length < self.listLength*/) { /*Ox.print('-------- request', { ids: ids, sort: self.options.sort });*/ - self.requests.push(self.options.request({ + self.requests.push(self.options.items({ ids: ids, sort: self.options.sort }, getPositionsCallback)); @@ -7008,7 +7024,7 @@ requires } function getPositionsCallback(result) { - //Ox.print('getPositionsCallback', result) + Ox.print('getPositionsCallback', result) var pos = 0; if (result) { $.extend(self, { @@ -7059,8 +7075,9 @@ requires } function getSelectedIds() { - Ox.print('gSI', self.selected) + Ox.print('gSI', self.selected, self.$items) return $.map(self.selected, function(pos) { + Ox.print('....', pos, self.options.unique, self.$items[pos].options('data')[self.options.unique]) return self.$items[pos].options('data')[self.options.unique]; }); } @@ -7080,6 +7097,7 @@ requires } function loadItems() { + that.$content.empty(); self.options.items.forEach(function(item, pos) { // fixme: duplicated self.$items[pos] = new Ox.ListItem({ @@ -7094,6 +7112,11 @@ requires }); } + function getPageLength(page) { + var mod = self.listLength % self.pageLength; + return page < self.pages - 1 || mod == 0 ? self.pageLength : mod; + } + function loadPage(page, callback) { if (page < 0 || page >= self.pages) { !Ox.isUndefined(callback) && callback(); @@ -7102,18 +7125,17 @@ requires //Ox.print('loadPage', page); var keys = $.merge(self.options.keys.indexOf(self.options.unique) == -1 ? [self.options.unique] : [], self.options.keys), offset = page * self.pageLength, - range = [offset, offset + (page < self.pages - 1 ? - self.pageLength : self.listLength % self.pageLength)]; + range = [offset, offset + getPageLength(page)]; if (Ox.isUndefined(self.$pages[page])) { // fixme: unload will have made this undefined already self.$pages[page] = constructEmptyPage(page); self.options.type == 'text' && page == 0 && fillFirstPage(); self.$pages[page].appendTo(that.$content); - self.requests.push(self.options.request({ + self.requests.push(self.options.items({ keys: keys, range: range, sort: self.options.sort }, function(result) { - var $emptyPage = $.extend({}, self.$pages[page]); + var $emptyPage = Ox.clone(self.$pages[page]); self.$pages[page] = new Ox.ListPage().css(getPageCSS(page)); $.each(result.data.items, function(i, v) { var pos = offset + i; @@ -7140,10 +7162,8 @@ requires } function loadPages(page, callback) { - //Ox.print('loadPages', page, self.pages) var counter = 0, fn = function() { - //Ox.print('---- self.$pages', self.$pages) if (++counter == 3) { !Ox.isUndefined(callback) && callback(); that.triggerEvent('load'); @@ -7539,8 +7559,8 @@ requires var ids = self.options.selected = getSelectedIds(); setTimeout(function() { var ids_ = getSelectedIds(); - Ox.print('ids', ids, 'ids after 100 msec', ids_) - if (ids.length == ids_.length && (ids.length == 0 || ids[0] == ids_[0])) { + Ox.print('ids', ids, 'ids after 100 msec', ids_, Ox.isEqual(ids, ids_)) + if (Ox.isEqual(ids, ids_)) { that.triggerEvent('select', { ids: ids }); @@ -7609,9 +7629,9 @@ requires function updateQuery(ids) { // fixme: shouldn't this be setQuery? // ids are the selcected ids // (in case list is loaded with selection) - Ox.print('####', self.options) + Ox.print('updateQuery', self.options) clear(); - self.requests.push(self.options.request({}, function(result) { + self.requests.push(self.options.items({}, function(result) { var keys = {}; that.triggerEvent('init', result.data); self.rowLength = getRowLength(); @@ -7639,17 +7659,33 @@ requires } function updateSort() { + var key = self.options.sort[0].key, + operator = self.options.sort[0].operator; if (self.listLength > 1) { - clear(); - getPositions(); + if (Ox.isArray(self.options.items)) { + self.options.items.sort(function(a, b) { + var ret = 0 + if (a[key] < b[key]) { + return operator == '+' ? -1 : 1 + } else if (a[key] > b[key]) { + return operator == '+' ? 1 : -1; + } + return ret; + }); + loadItems(); + } else { + clear(); // fixme: bad function name + getPositions(); + } } } self.onChange = function(key, value) { //Ox.print('list onChange', key, value); - if (key == 'request') { + if (key == 'items') { updateQuery(); } else if (key == 'selected') { + Ox.print('onChange selected', value) setSelected(value); } }; @@ -7689,9 +7725,8 @@ requires that.editItem = function(pos) { var $input, item = self.options.items[pos], - $item = self.$items[pos]; - Ox.print('****', item, $item) - var width = $item.width(), // fixme: don't lookup in DOM + $item = self.$items[pos], + width = $item.width(), // fixme: don't lookup in DOM height = $item.height(); $item .height(height + 8 + 16) @@ -7824,13 +7859,11 @@ requires } that.sortList = function(key, operator) { + Ox.print('sortList', key, operator) if (key != self.options.sort[0].key || operator != self.options.sort[0].operator) { - self.options.sort[0] = { - key: key, - operator: operator - } - that.triggerEvent('sort', self.options.sort[0]); + self.options.sort[0] = {key: key, operator: operator}; updateSort(); + that.triggerEvent('sort', self.options.sort[0]); } return that; } @@ -7869,7 +7902,8 @@ requires .options(options || {}), $input; - that.append($input = new Ox.Input({ + that.append( + $input = new Ox.Input({ height: self.options.height, style: 'square', type: self.options.type, @@ -7881,7 +7915,8 @@ requires // keep mousedown from reaching list e.stopPropagation(); } - })) + }) + ) .append(new Ox.Element() .append(new Ox.Button({type: 'text', title: 'Cancel'}) .css('width', '42%') @@ -7960,6 +7995,8 @@ requires Ox.TextList = function(options, self) { + // fixme: rename to TableList + var self = self || {}, that = new Ox.Element({}, self) .defaults({ @@ -7970,13 +8007,12 @@ requires columnsVisible: false, columnWidth: [40, 800], id: '', - items: null, + items: null, // function() {} {sort, range, keys, callback} or array max: -1, min: 0, pageLength: 100, scrollbarVisible: false, selected: [], - request: null, // function() {} {sort, range, keys, callback} sort: [] }) .options(options || {}) @@ -8082,6 +8118,7 @@ requires id: self.options.id, items: self.options.items, itemHeight: 16, + items: self.options.items, itemWidth: getItemWidth(), format: self.format, // fixme: not needed, happens in TextList keys: $.map(self.visibleColumns, function(v) { @@ -8092,7 +8129,6 @@ requires pageLength: self.options.pageLength, paste: self.options.paste, orientation: 'vertical', - request: self.options.request, selected: self.options.selected, sort: self.options.sort, sortable: self.options.sortable, @@ -8175,7 +8211,7 @@ requires } function clickColumn(id) { - //Ox.print('clickColumn', id); + Ox.print('clickColumn', id); var i = getColumnIndexById(id), isSelected = self.options.sort[0].key == self.options.columns[i].id; that.sortList( @@ -8543,7 +8579,7 @@ requires } self.onChange = function(key, value) { - if (key == 'request') { + if (key == 'items') { //alert('request set!!') that.$body.options(key, value); } else if (key == 'paste') { @@ -8557,21 +8593,21 @@ requires that.closePreview = that.$body.closePreview; that.editCell = function(id, key) { - //Ox.print('editCell') + Ox.print('editCell', id, key) var $item = getItem(id), $cell = getCell(id, key), $input, html = $cell.html(), index = getColumnIndexById(key), column = self.options.columns[index], - width = column.width; + width = column.width - self.options.columnsVisible; $cell.empty() .addClass('OxEdit') .css({ width: width + 'px' }); $input = new Ox.Input({ - autovalidate: column.input.autovalidate, + autovalidate: column.input ? column.input.autovalidate : null, style: 'square', value: html, width: width @@ -8585,8 +8621,9 @@ requires .bindEvent({ blur: submit, }) - .appendTo($cell) - .focus(); + .appendTo($cell); + //.focusInput(); + setTimeout($input.focusInput, 0); // fixme: strange function submit() { var value = $input.value(); //$input.loseFocus().remove(); @@ -8636,12 +8673,7 @@ requires that.sortList = function(key, operator) { var isSelected = key == self.options.sort[0].key; - self.options.sort = [ - { - key: key, - operator: operator - } - ]; + self.options.sort = [{key: key, operator: operator}]; if (self.options.columnsVisible) { if (isSelected) { updateOrder(self.options.columns[self.selectedColumn].id); @@ -8840,6 +8872,346 @@ requires ============================================================================ */ + Ox.ListMap = function(options, self) { + + var self = self || {}, + that = new Ox.Element('div', self) + .defaults({ + addPlace: null, + height: 256, + labels: false, + places: null, + selected: [], + width: 256 + }) + .options(options || {}) + .css({ + width: self.options.width + 'px', + height: self.options.height + 'px' + }); + + self.columns = [ + { + addable: false, // fixme: implement + id: 'id', + unique: true, + visible: false + }, + { + editable: true, + id: 'name', + operator: '+', + removable: false, + title: 'Name', + visible: true, + width: 144 + }, + { + editable: true, + id: 'geoname', + removable: false, + operator: '+', + title: 'Geoname', + visible: true, + width: 192 + }, + { + format: function(value) { + return $('') + .attr({ + // fixme: not the right place to do these + src: '/static/oxjs/build/svg/' + (value || 'NTHH') + '.' + (value == 'RE' ? 'png' : 'svg') + }) + .load(function() { + $(this).css({ + width: '21px', + height: '14px', + padding: '1px 0 0 1px' + }) + }); + }, + id: 'countryCode', + operator: '+', + title: 'Flag', + visible: true, + width: 48 + }, + { + align: 'right', + format: toFixed, + id: 'lat', + operator: '+', + title: 'Latitude', + visible: true, + width: 96 + }, + { + align: 'right', + format: toFixed, + id: 'lng', + operator: '+', + title: 'Longitude', + visible: true, + width: 96 + }, + { + align: 'right', + format: toFixed, + id: 'south', + operator: '+', + title: 'South', + visible: true, + width: 96 + }, + { + align: 'right', + id: 'west', + operator: '+', + title: 'West', + visible: true, + width: 96 + }, + { + align: 'right', + format: toFixed, + id: 'north', + operator: '+', + title: 'North', + visible: true, + width: 96 + }, + { + align: 'right', + format: toFixed, + id: 'east', + operator: '+', + title: 'East', + visible: true, + width: 96 + }, + { + align: 'right', + format: {type: 'area', args: [0]}, + id: 'size', + operator: '-', + title: 'Size', + visible: true, + width: 128 + }, + { + id: 'user', + operator: '+', + title: 'User', + visible: false, + width: 96 + }, + { + format: 'date', + id: 'created', + operator: '+', + title: 'Date Created', + visible: false, + width: 96, + }, + { + format: 'date', + id: 'modified', + operator: '+', + title: 'Date Modified', + visible: false, + width: 96, + } + ]; + + self.$toolbar = new Ox.Bar({ + size: 24 + }); + + self.$findElement = new Ox.FormElementGroup({ + elements: [ + self.$findSelect = new Ox.Select({ + items: [ + {id: 'all', title: 'Find: All'}, + {id: 'name', title: 'Find: Name'}, + {id: 'geoname', title: 'Find: Geoname'}, + {id: 'country', title: 'Find: Country'} + ], + overlap: 'right', + width: 128 + }), + self.$findInput = new Ox.Input({ + clear: true, + width: 192 + }) + ] + }) + .css({float: 'right', margin: '4px'}) + .appendTo(self.$toolbar) + + self.$list = new Ox.TextList({ + columns: self.columns, + columnsRemovable: true, + columnsVisible: true, + items: self.options.places, + pageLength: 100, + scrollbarVisible: true, + sort: [ + {key: 'name', operator: '+'} + ] + }) + .bindEvent({ + 'delete': function(event, data) { + that.triggerEvent('removeplace', {id: data.ids[0]}); + }, + init: initList, + load: function() { + that.triggerEvent('loadlist'); + }, + open: openItem, + select: selectItem + }); + + self.$statusbar = new Ox.Bar({ + size: 24 + }); + + self.$status = new Ox.Element() + .css({paddingTop: '4px', margin: 'auto', textAlign: 'center'}) + .appendTo(self.$statusbar); + + self.mapResize = [ + Math.round(self.options.width * 0.25), + Math.round(self.options.width * 0.5), + Math.round(self.options.width * 0.75) + ]; + + if (Ox.isArray(self.options.places)) { + init(self.options.places) + } else { + self.options.places({}, function(result) { + Ox.print('$$$$', result.data.items) + self.options.places({ + keys: self.columns.map(function(column) { + return column.id + }), + range: [0, result.data.items] + }, function(result) { + Ox.print('DATA', result) + init(result.data.items); + }); + }); + } + + function init(places) { + Ox.print('PLACES', places) + self.$map = new Ox.Map({ + clickable: true, + height: self.options.height, + // fixme: place can still be string, and maybe shouldn't be array at all + places: places.map(function(place) { + return Ox.extend({}, place, { + name: place.name.length == 0 ? '' : place.name[0] + }); + }), + statusbar: true, + toolbar: true, + width: self.mapResize[1], + zoombar: true + }) + .bindEvent({ + addplace: function(event, data) { + that.triggerEvent('addplace', data); + }, + resize: function() { + self.$map.resizeMap(); + }, + select: selectPlace + }); + + that.$element.replaceWith( + that.$element = new Ox.SplitPanel({ + elements: [ + { + element: new Ox.SplitPanel({ + elements: [ + { + element: self.$toolbar, + size: 24 + }, + { + element: self.$list + }, + { + element: self.$statusbar, + size: 24 + } + ], + orientation: 'vertical' + }) + }, + { + element: self.$map, + resizable: true, + resize: self.mapResize, + size: self.mapResize[1] + } + ], + orientation: 'horizontal' + }).$element + ); + } + + function initList(event, data) { + self.$status.html(data.items + ' place' + (data.items == 1 ? '' : 's')) + } + + function openItem(event, data) { + selectItem(event, data); + self.$map.zoomToPlace(data.ids[0]); + } + + function selectItem(event, data) { + Ox.print('selectItem', data.ids[0]) + self.$map.options({selected: data.ids.length ? data.ids[0] : ''}); + } + + function selectPlace(event, data) { + Ox.print('selectPlace', data.id) + data.id[0] != '_' && self.$list.options({ + selected: data.id ? [data.id] : [] + }); + } + + function toFixed(val) { + return val.toFixed(8); + } + + self.onChange = function(key, value) { + if (key == 'selected') { + self.$list.options({selected: value}); + } + } + + that.focusList = function() { + self.$list.gainFocus(); + return that; + } + + that.reloadList = function() { + self.$list.reloadList(); + return that; + } + + that.resizeMap = function() { + Ox.print('Ox.ListMap.resizeMap()') + self.$map.resizeMap(); + return that; + }; + + return that; + + }; + Ox.Map = function(options, self) { var self = self || {} @@ -8849,6 +9221,7 @@ requires height: 256, labels: false, places: [], + selected: null, statusbar: false, toolbar: false, width: 256, @@ -8881,9 +9254,13 @@ requires }, key_enter: focusOnPlace, key_shift_enter: zoomToPlace, - key_escape: deselectPlace + key_escape: function() { + selectPlace(''); + } }); + self.resultPlace = null; + if (self.options.toolbar) { self.$toolbar = new Ox.Bar({ size: 24 @@ -8909,17 +9286,14 @@ requires }) .appendTo(self.$toolbar) } + self.$map = new Ox.Element('div') .css({ width: self.options.width + 'px', - height: ( - self.options.height - - self.options.statusbar * 16 - - self.options.toolbar * 24 - - self.options.zoombar * 16 - ) + 'px' + height: getMapHeight() }) .appendTo(that); + if (self.options.zoombar) { self.$zoombar = new Ox.Bar({ size: 16 @@ -8937,13 +9311,33 @@ requires }) .appendTo(self.$zoombar) } + if (self.options.statusbar) { self.$statusbar = new Ox.Bar({ - size: 16 + size: 24 }) + .css({padding: '2px'}) .appendTo(that); - self.$status = new Ox.Element() - .css({float: 'right', margin: '2px 4px'}) + self.$placeNameInput = new Ox.Input({ + placeholder: 'Name', + width: Math.floor((self.options.width - 96) / 2) + }) + .css({float: 'left', margin: '2px'}) + .appendTo(self.$statusbar); + self.$placeGeonameInput = new Ox.Input({ + placeholder: 'Geoname', + width: Math.ceil((self.options.width - 96) / 2) + }) + .css({float: 'left', margin: '2px'}) + .appendTo(self.$statusbar) + self.$placeButton = new Ox.Button({ + title: 'New Place', + width: 80 + }) + .css({float: 'left', margin: '2px'}) + .bindEvent({ + click: clickPlaceButton + }) .appendTo(self.$statusbar); } @@ -8958,72 +9352,37 @@ requires initMap(); } - function initMap() { - $.extend(self, { - geocoder: new google.maps.Geocoder(), - selected: -1 - }); - loadPlaces(loadMap); + function addNewPlace() { + var bounds = self.map.getBounds(), + center = self.map.getCenter(), + southwest = new google.maps.LatLngBounds( + bounds.getSouthWest(), center + ).getCenter(), + northeast = new google.maps.LatLngBounds( + center, bounds.getNorthEast() + ).getCenter(), + place = new Place({ + countryCode: '', + geoname: '', + id: '_' + Ox.uid(), // fixme: stupid + name: '', + south: southwest.lat(), + west: southwest.lng(), + north: northeast.lat(), + east: northeast.lng() + }); + addPlace(place); + selectPlace(place.name); } - function loadMap() { - self.center = self.bounds ? self.bounds.getCenter() : new google.maps.LatLng(0, 0); - self.zoom = 1; - $.extend(self, { - map: new google.maps.Map(self.$map.$element[0], { - center: self.center, - disableDefaultUI: true, - mapTypeId: google.maps.MapTypeId[getMapType()], - zoom: self.zoom - }) - }); - if (self.bounds) { - self.map.fitBounds(self.bounds); - // self.center = self.map.getCenter(); - self.zoom = self.map.getZoom(); - } - google.maps.event.addListener(self.map, 'click', click); - google.maps.event.addListener(self.map, 'zoom_changed', zoomChanged); - $.each(self.options.places, function(i, place) { - place.marker.add(); - }); - resize(); - that.gainFocus(); - that.triggerEvent('loaded'); - } - - function loadPlaces(callback) { - if (self.options.places.length == 0 || Ox.isObject(self.options.places[0])) { - $.each(self.options.places, function(i, place) { - place.bounds = getBounds(), - place.center = place.bounds.getCenter(); - $.extend(place, { - marker: new Marker(place), - polygon: new Polygon(place) - }); - self.bounds = i == 0 ? getBounds() : self.bounds.union(place.bounds); - self.options.places[i] = place; - function getBounds() { - return new google.maps.LatLngBounds( - new google.maps.LatLng(place.points.southwest[0], place.points.southwest[1]), - new google.maps.LatLng(place.points.northeast[0], place.points.northeast[1]) - ); - } - }); - callback && callback(); - } else { - self.counter = 0; - $.each(self.options.places, function(i, place) { - getLocationByName(place, function(place) { - //Ox.print(self.counter, i, place); - self.options.places[i] = place; - if (self.counter++ == self.options.places.length - 1) { - callback && callback(); - } - }); - }); - } - + function addPlace(place) { + Ox.print('addPlace', place) + Ox.print('self.resultPlace', self.resultPlace) + self.resultPlace && self.resultPlace.remove(); + if (place.id[0] == '_') { + self.resultPlace = place; + } + place.add(); } function canContain(outerBounds, innerBounds) { @@ -9037,47 +9396,62 @@ requires self.map.setZoom(data.value); } - function click(event) { - //Ox.print('event', event); + function clickMap(event) { + Ox.print('Ox.Map clickMap') that.gainFocus(); if (self.options.clickable) { - getLocationByLatLng(event.latLng, self.map.getBounds(), function(location) { - self.marker && self.marker.remove(); - self.polygon && self.polygon.remove(); - if (location) { - self.marker = location.marker.add(); - self.polygon && self.polygon.remove(); - self.polygon = location.polygon.add(); - that.triggerEvent('select', location); + getPlaceByLatLng(event.latLng, self.map.getBounds(), function(place) { + if (place) { + addPlace(place); + selectPlace(place.id); } }); } } - function deselectPlace() { - - } - - function submitFind(event, data) { - that.find(data.value, function(data) { - self.options.statusbar && self.$status.html(data.geoname); - }); + function clickPlaceButton() { + if (self.$placeButton.options('title') == 'New Place') { + addNewPlace(); + } else { + var place = getPlaceById(self.selected), + data = { + place: {} + }; + data.place.name = self.$placeNameInput.value(); + data.place.geoname = self.$placeGeonameInput.value(); + data.place.countryCode = Ox.getCountryCode(data.place.geoname); + [ + 'lat', 'lng', 'south', 'west', 'north', 'east', 'size' + ].forEach(function(key) { + data.place[key] = place[key]; + }); + that.triggerEvent('addplace', data) + } } function focusOnPlace() { - if (self.selected > -1) { - self.map.panTo(self.options.places[self.selected].center); + if (self.options.selected > -1) { + self.map.panTo(self.options.places[self.options.selected].center); } } - function getLocationByLatLng(latlng, bounds, callback) { + function getPlaceById(id) { + var place = Ox.getObjectById(self.places, id); + if (!place && self.resultPlace && self.resultPlace.id == id) { + place = self.resultPlace; + } + Ox.print('getPlaceById', id, place) + return place; + } + + function getPlaceByLatLng(latlng, bounds, callback) { //Ox.print('ll b', latlng, bounds) var callback = arguments.length == 3 ? callback : bounds, bounds = arguments.length == 3 ? bounds : null; self.geocoder.geocode({ latLng: latlng }, function(results, status) { - //Ox.print('results', results) + Ox.print('results', results) var length = results.length; if (status == google.maps.GeocoderStatus.OK) { if (status != google.maps.GeocoderStatus.ZERO_RESULTS) { @@ -9087,12 +9461,12 @@ requires i == length - 1 || canContain(bounds, result.geometry.bounds || result.geometry.viewport) ) { - callback(new Location(results[i])); + callback(Place(results[i])); return false; } }); } else { - callback(new Location(results[0])); + callback(Place(results[0])); } } else { callback(null); @@ -9104,13 +9478,13 @@ requires }); } - function getLocationByName(name, callback) { + function getPlaceByName(name, callback) { self.geocoder.geocode({ address: name }, function(results, status) { if (status == google.maps.GeocoderStatus.OK) { if (status != google.maps.GeocoderStatus.ZERO_RESULTS) { - callback(new Location(results[0])) + callback(Place(results[0])); } else { callback(null); } @@ -9121,6 +9495,15 @@ requires }); } + function getMapHeight() { + return ( + self.options.height - + self.options.statusbar * 24 - + self.options.toolbar * 24 - + self.options.zoombar * 16 + ) + 'px'; + } + function getMapType() { return self.options.labels ? 'HYBRID' : 'SATELLITE' } @@ -9136,21 +9519,96 @@ requires return position; } + function initMap() { + self.geocoder = new google.maps.Geocoder(); + self.places = []; + self.options.places.forEach(function(place, i) { + self.places[i] = Place(Ox.clone(place)); + Ox.print('BOUNDS', self.places.map(function(v) {return v.bounds})) + Ox.print('self.places', i, self.places[i]) + self.bounds = i == 0 ? + Ox.clone(self.places[i].bounds) : + self.bounds.union(self.places[i].bounds); + }); + self.center = self.bounds ? self.bounds.getCenter() : new google.maps.LatLng(0, 0); + self.zoom = 1; // fixme: should depend on height + self.map = new google.maps.Map(self.$map.$element[0], { + center: self.center, + disableDefaultUI: true, + mapTypeId: google.maps.MapTypeId[getMapType()], + zoom: self.zoom + }); + if (self.bounds) { + self.map.fitBounds(self.bounds); + self.zoom = self.map.getZoom(); + } + self.places.forEach(function(place) { + place.add(self.map); + }); + google.maps.event.addListener(self.map, 'click', clickMap); + google.maps.event.addListener(self.map, 'zoom_changed', zoomChanged); + google.maps.event.trigger(self.map, 'resize'); + that.gainFocus(); + that.triggerEvent('load'); + } + function pan(x, y) { self.map.panBy(x * 256, y * 256); }; - function resize() { - google.maps.event.trigger(self.map, 'resize'); + function removePlace(id) { + } function reset() { //Ox.print(self.map.getZoom(), self.zoom); self.map.getZoom() == self.zoom ? - self.map.panTo(self.center) : - self.map.fitBounds(self.bounds); + self.map.panTo(self.center) : + self.map.fitBounds(self.bounds); } + function selectPlace(id) { + Ox.print('Ox.Map selectPlace()', id, self.selected) + var place; + if (id != self.selected) { + place = getPlaceById(self.selected); + place && place.deselect(); + place = getPlaceById(id); + place && place.select(); + } + self.options.selected = id; + self.selected = id; + setStatus(); + that.triggerEvent('select', { + id: self.options.selected + }); + }; + + function setStatus() { + Ox.print('setStatus()', self.options.selected) + var place; + if (self.options.statusbar) { + if (self.options.selected) { + place = getPlaceById(self.options.selected); + } + self.$placeNameInput.options({ + value: self.options.selected ? place.name : '' + }); + self.$placeGeonameInput.options({ + value: self.options.selected ? place.geoname : '' + }); + self.$placeButton.options({ + title: self.options.selected ? 'Add Place' : 'New Place' + }); + } + } + + function submitFind(event, data) { + that.findPlace(data.value, function(place) { + setStatus(place); + }); + } + function toggleLabels() { self.options.labels = !self.options.labels self.map.setMapTypeId(google.maps.MapTypeId[getMapType()]); @@ -9173,117 +9631,141 @@ requires } function zoomToPlace() { - if (self.selected > -1) { - self.map.fitBounds(self.options.places[self.selected].bounds); + if (self.options.selected > -1) { + self.map.fitBounds(self.options.places[self.options.selected].bounds); } } - function Location(geodata) { - //Ox.print('geodata', geodata); - var bounds = geodata.geometry.bounds || geodata.geometry.viewport, - center = bounds.getCenter(), - location = { - bounds: bounds, - center: center, - geoname: geodata.formatted_address, - points: { - 'center': [center.lat(), center.lng()], - 'southwest': [bounds.getSouthWest().lat(), bounds.getSouthWest().lng()], - 'northeast': [bounds.getNorthEast().lat(), bounds.getNorthEast().lng()] - }, - name: geodata.formatted_address.split(', ')[0], - size: 0, - type: geodata.address_components[0].types.join(', ') - }; - return $.extend(location, { - marker: new Marker(location), - polygon: new Polygon(location) - }); - } - function Marker(place) { - //Ox.print(place.center) var listeners = {}, marker = new google.maps.Marker({ - icon: icon('red'), position: place.center, title: place.name }), selected = false; - function click() { - //Ox.print('click', self.selected, selected) - selected = !selected; - selected && self.selected > -1 && self.options.places[self.selected].marker.deselect(); - self.selected = selected ? getPositionByName(place.name) : -1; - marker.setOptions({ - icon: icon(selected ? 'blue' : 'red') - }); - place.polygon[selected ? 'add' : 'remove'](); - that.triggerEvent(selected ? 'select' : 'deselect', place); + setOptions(); + function click(event) { + Ox.print('click metaKey', event.metaKey, selected) + if (event.metaKey == selected) { + selected = !event.metaKey; + selectPlace(selected ? place.id : ''); + } } - function deselect() { - - } function dblclick() { - //Ox.print('dblclick', place.bounds) + Ox.print('####', place.bounds) self.map.fitBounds(place.bounds); } - function select() { - - } - function icon(color) { - return oxui.path + 'png/ox.ui/marker' + Ox.toTitleCase(color) + '.png' + function setOptions() { + marker.setOptions({ + icon: oxui.path + 'png/ox.ui/marker' + + (place.id[0] == '_' ? 'Result' : '') + + (selected ? 'Selected' : '') + '.png' + }); } return { add: function() { - //Ox.print('add Marker') - marker.setMap(self.map); + Ox.print('Marker.add()') + marker.setMap(self.map); listeners = { click: google.maps.event.addListener(marker, 'click', click), dblclick: google.maps.event.addListener(marker, 'dblclick', dblclick), }; - return this; }, deselect: function() { - self.selected = -1; - selected = false; - marker.setOptions({ - icon: icon('red') - }); - place.polygon.remove(); + selected = false; + setOptions(); }, remove: function() { marker.setMap(null); $.each(listeners, function(i, listener) { google.maps.event.removeListener(listener); }); - return this; }, select: function() { - if (self.selected > -1) { - self.options.places[self.selected].marker.deselect(); - } - self.selected = getPositionByName(place.name); - selected = true; - marker.setOptions({ - icon: icon('blue') - }); - place.polygon.add(); + selected = true; + setOptions(); } }; - } + }; - function Polygon(location) { + function Place(place) { + var marker, polygon, selected; + if ('name' in place) { + // place object + //Ox.extend(place, place); + place.bounds = new google.maps.LatLngBounds( + new google.maps.LatLng(place.south, place.west), + new google.maps.LatLng(place.north, place.east) + ); + } else { + // geodata object + if (!place.geometry.bounds) { + Ox.print('NO BOUNDS, ONLY VIEWPORT') + } + Ox.extend(place, { + bounds: place.geometry.bounds || place.geometry.viewport, + countryCode: Ox.getCountryCode(place.formatted_address), + geoname: place.formatted_address, + id: '_' + Ox.uid(), + name: place.formatted_address.split(', ')[0] + }); + Ox.extend(place, { + south: Ox.round(place.bounds.getSouthWest().lat(), 8), + west: Ox.round(place.bounds.getSouthWest().lng(), 8), + north: Ox.round(place.bounds.getNorthEast().lat(), 8), + east: Ox.round(place.bounds.getNorthEast().lng(), 8) + }); + } + place.center = place.bounds.getCenter(); + Ox.extend(place, { + lat: Ox.round(place.center.lat(), 8), + lng: Ox.round(place.center.lng(), 8), + size: Ox.getArea( + {lat: place.south, lng: place.west}, + {lat: place.north, lng: place.east} + ) + }); + Ox.print('PLACE', place) + marker = Marker(place); + polygon = Polygon(place); + selected = false; + return Ox.extend(place, { + add: function() { + Ox.print('Place.add()', self.resultPlace) + marker.add(); + }, + deselect: function() { + selected = false; + marker.deselect(); + polygon.remove(); + }, + remove: function() { + Ox.print('REMOVE!!!', selected) + if (place.id[0] == '_') { + self.resultPlace = null; + } + selected && polygon.remove(); + marker.remove(); + }, + select: function() { + Ox.print('Place.select()') + selected = true; + marker.select(); + polygon.add(); + } + }); + }; + + function Polygon(place) { var listeners = {}, - paths = [ - new google.maps.LatLng(location.points.southwest[0], location.points.southwest[1]), - new google.maps.LatLng(location.points.northeast[0], location.points.southwest[1]), - new google.maps.LatLng(location.points.northeast[0], location.points.northeast[1]), - new google.maps.LatLng(location.points.southwest[0], location.points.northeast[1]), - new google.maps.LatLng(location.points.southwest[0], location.points.southwest[1]) - ], polygon = new google.maps.Polygon({ - paths: paths + paths: [ + new google.maps.LatLng(place.south, place.west), + new google.maps.LatLng(place.north, place.west), + new google.maps.LatLng(place.north, place.east), + new google.maps.LatLng(place.south, place.east), + new google.maps.LatLng(place.south, place.west) + ] }), selected = false; setOptions(); @@ -9304,9 +9786,9 @@ requires } return { add: function() { + Ox.print('Polygon.add()') polygon.setMap(self.map); listeners.click = google.maps.event.addListener(polygon, 'click', click); - return this; }, deselect: function() { selected = false; @@ -9315,12 +9797,11 @@ requires remove: function() { polygon.setMap(null); google.maps.event.removeListener(listeners.click); - return this; }, select: function() { selected = true; setOptions(); - } + } }; } @@ -9365,18 +9846,25 @@ requires self.onChange = function(key, value) { if (key == 'places') { - loadPlaces(loadMap); + loadPlaces(); + } else if (key == 'selected') { + selectPlace(value); } else if (key == 'type') { } }; - that.find = function(name, callback) { - getLocationByName(name, function(place) { + that.findPlace = function(name, callback) { + getPlaceByName(name, function(place) { if (place) { - //self.marker = location.marker.add(); + /* + self.marker = place.marker.add('yellow'); self.polygon && self.polygon.remove(); self.polygon = place.polygon.add(); + */ + addPlace(place); + self.resultPlace = place; + selectPlace(place.id); self.bounds = place.bounds; self.map.fitBounds(self.bounds); } @@ -9384,13 +9872,30 @@ requires }); }; - that.triggerResize = function() { - //Ox.print('---- triggerResize'); + that.resizeMap = function() { + Ox.print('Ox.Map.resizeMap()'); var center = self.map.getCenter(); + self.options.height = that.$element.height(); + self.options.width = that.$element.width(); + Ox.print(self.options.width, self.options.height) + self.$map.css({ + height: getMapHeight() + 'px', + width: self.options.width + 'px' + }); google.maps.event.trigger(self.map, 'resize'); self.map.setCenter(center); + self.options.zoombar && self.$zoomInput.options({ + size: self.options.width + }); } + that.zoomToPlace = function(id) { + Ox.print('zoomToPlace', id) + var place = getPlaceById(id); + self.bounds = place.bounds; + self.map.fitBounds(self.bounds); + }; + that.zoom = function(value) { self.map.setZoom(value); }; @@ -9409,7 +9914,6 @@ requires */ Ox.MapImage = function(options, self) { - var self = self || {}, that = new Ox.Element('img', self) .defaults({ @@ -10377,7 +10881,6 @@ requires } // construct - Ox.print('@@@@', self.options.title[0]) that.append( that.$status = $('', { 'class': 'OxCell OxStatus', @@ -13622,7 +14125,7 @@ requires columnsResizable: true, columnsVisible: true, id: 'files', - request: function(data, callback) { + items: function(data, callback) { pandora.api.findFiles($.extend(data, { query: { conditions: [{ diff --git a/build/json/ox.ui.images.json b/build/json/ox.ui.images.json index ee56a969..8fa9fc88 100644 --- a/build/json/ox.ui.images.json +++ b/build/json/ox.ui.images.json @@ -4,11 +4,7 @@ "png/ox.ui/browserInternetExplorer128.png", "png/ox.ui/browserOpera128.png", "png/ox.ui/browserSafari128.png", - "png/ox.ui/icon16.png", - "png/ox.ui/markerBlue.png", - "png/ox.ui/markerGreen.png", - "png/ox.ui/markerRed.png", - "png/ox.ui/markerYellow.png", + "png/ox.ui/icon16.png", "png/ox.ui/transparent.png", "png/ox.ui/videoMarkerCut.png", "png/ox.ui/videoMarkerIn.png", diff --git a/build/png/ox.ui/markerBlue.png b/build/png/ox.ui/markerBlue.png deleted file mode 100644 index 27873e77..00000000 Binary files a/build/png/ox.ui/markerBlue.png and /dev/null differ diff --git a/build/png/ox.ui/markerGreen.png b/build/png/ox.ui/markerGreen.png deleted file mode 100644 index 5d614b64..00000000 Binary files a/build/png/ox.ui/markerGreen.png and /dev/null differ diff --git a/build/png/ox.ui/markerRed.png b/build/png/ox.ui/markerRed.png deleted file mode 100644 index dac82304..00000000 Binary files a/build/png/ox.ui/markerRed.png and /dev/null differ diff --git a/build/png/ox.ui/markerYellow.png b/build/png/ox.ui/markerYellow.png deleted file mode 100644 index 6d129a3d..00000000 Binary files a/build/png/ox.ui/markerYellow.png and /dev/null differ