From 2e645418ddcf2851aa0bae7b2108e88ef139e5b8 Mon Sep 17 00:00:00 2001
From: rlx <0x0073@0x2620.org>
Date: Fri, 25 Feb 2011 10:23:33 +0000
Subject: [PATCH] improvements to map
---
build/js/ox.js | 140 +++-
build/js/ox.load.js | 2 +-
build/js/ox.map.js | 76 ++-
build/js/ox.ui.js | 1041 ++++++++++++++++++++++--------
build/json/ox.ui.images.json | 6 +-
build/png/ox.ui/markerBlue.png | Bin 3239 -> 0 bytes
build/png/ox.ui/markerGreen.png | Bin 3234 -> 0 bytes
build/png/ox.ui/markerRed.png | Bin 3233 -> 0 bytes
build/png/ox.ui/markerYellow.png | Bin 3207 -> 0 bytes
9 files changed, 980 insertions(+), 285 deletions(-)
delete mode 100644 build/png/ox.ui/markerBlue.png
delete mode 100644 build/png/ox.ui/markerGreen.png
delete mode 100644 build/png/ox.ui/markerRed.png
delete mode 100644 build/png/ox.ui/markerYellow.png
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 = $('
T5{S8#kDF?g)o&p&l
z0(OAcz&6l6b*i1YuD&tW@v+uw+HBgbHT7nP>3}!XFRFWcHm9ep3=jJ;o%Ve;>xZc+
z%R4(pallvgRyVw=y1MG`WYTSL9V~*I@w=W#xV60OK^(BIhJpGFDDLj^XJUd+QN#%l
z^1s@N1i|JeqvPYGfaf9b0$^^AA5lc>0uUf