diff --git a/build/js/ox.ui.js b/build/js/ox.ui.js index 5936b3f6..4ca3b70e 100644 --- a/build/js/ox.ui.js +++ b/build/js/ox.ui.js @@ -9223,7 +9223,6 @@ requires }, select: selectPlace }); - that.$element.replaceWith( that.$element = new Ox.SplitPanel({ elements: [ @@ -9289,7 +9288,14 @@ requires } self.onChange = function(key, value) { - if (key == 'selected') { + Ox.print('ONCHANGE') + if (key == 'height' || key == 'width') { + Ox.print('ONCHANGE...') + self.$map.options({ + height: self.options.height, + width: self.options.width + }) + } else if (key == 'selected') { self.$list.options({selected: value}); } } @@ -9363,15 +9369,30 @@ requires key_equal: function() { zoom(1); }, - key_enter: panToPlace, - key_shift_enter: zoomToPlace, + key_enter: function() { + that.panToPlace(); + }, + key_shift: function() { + self.shiftKey = true; + $(document).one({ + keyup: function() { + self.shiftKey = false; + } + }); + }, + key_shift_enter: function() { + that.zoomToPlace(); + }, key_escape: function() { selectPlace(''); } }); - self.metaKey = false; - self.resultPlace = null; + Ox.extend(self, { + metaKey: false, + resultPlace: null, + shiftKey: false + }); if (self.options.toolbar) { self.$toolbar = new Ox.Bar({ @@ -9501,7 +9522,7 @@ requires var outerSpan = outerBounds.toSpan(), innerSpan = innerBounds.toSpan(); return outerSpan.lat() > innerSpan.lat() && - outerSpan.lng() > innerSpan.lng(); + outerSpan.lng() > innerSpan.lng(); } function changeZoom(event, data) { @@ -9567,12 +9588,12 @@ requires i == length - 1 || canContain(bounds, result.geometry.bounds || result.geometry.viewport) ) { - callback(Place(results[i])); + callback(new Ox.MapPlace(parseGeodata(results[i]))); return false; } }); } else { - callback(Place(results[0])); + callback(new Ox.MapPlace(parseGeodata(results[0]))); } } else { callback(null); @@ -9591,7 +9612,7 @@ requires if (status == google.maps.GeocoderStatus.OK) { if (status != google.maps.GeocoderStatus.ZERO_RESULTS) { Ox.print('GEOCODER RESULT', results[0]) - callback(Place(results[0])); + callback(new Ox.MapPlace(parseGeodata(results[0]))); } else { callback(null); } @@ -9625,40 +9646,36 @@ requires } function initMap() { + var mapBounds; self.geocoder = new google.maps.Geocoder(); self.places = []; self.options.places.forEach(function(place, i) { + var placeBounds = new google.maps.LatLngBounds( + new google.maps.LatLng(place.south, place.west), + new google.maps.LatLng(place.north, place.east) + ); if (Ox.isUndefined(place.id)) { place.id = Ox.uid(); } - self.places[i] = Place(Ox.clone(place)); - if (i == 0) { - Ox.print('0000', self.places[i].bounds, self.places[i].bounds.union) - } else { - Ox.print('$$$$', self.bounds) - } - self.bounds = i == 0 ? - new google.maps.LatLngBounds( - new google.maps.LatLng(self.places[i].south, self.places[i].west), - new google.maps.LatLng(self.places[i].north, self.places[i].east) - ) : - self.bounds.union(self.places[i].bounds); + mapBounds = i == 0 ? placeBounds : mapBounds.union(placeBounds); }); - self.center = self.bounds ? self.bounds.getCenter() : new google.maps.LatLng(0, 0); + self.center = mapBounds ? mapBounds.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], { + that.map = self.map = new google.maps.Map(self.$map.$element[0], { center: self.center, disableDefaultUI: true, disableDoubleClickZoom: true, mapTypeId: google.maps.MapTypeId[getMapType()], zoom: self.zoom }); - if (self.bounds) { - self.map.fitBounds(self.bounds); + if (mapBounds) { + self.map.fitBounds(mapBounds); self.zoom = self.map.getZoom(); } - self.places.forEach(function(place) { - place.add(self.map); + self.options.places.forEach(function(place, i) { + self.places[i] = new Ox.MapPlace(Ox.extend({ + map: that + }, place)).add(); }); google.maps.event.addListener(self.map, 'click', clickMap); google.maps.event.addListener(self.map, 'zoom_changed', zoomChanged); @@ -9671,12 +9688,21 @@ requires self.map.panBy(x * self.options.width / 2, y * getMapHeight() / 2); }; - function panToPlace() { - Ox.print('panToPlace:', self.options.selected) - if (self.options.selected !== null) { - self.map.panTo(getPlaceById(self.options.selected).center); - } - } + function parseGeodata(data) { + var bounds = data.geometry.bounds || data.geometry.viewport, + place = { + // countryCode: Ox.getCountryCode(data.formatted_address), + east: bounds.getNorthEast().lng(), + geoname: data.formatted_address, + id: '_' + Ox.uid(), + map: that, + name: data.formatted_address.split(', ')[0], + north: bounds.getNorthEast().lat(), + south: bounds.getSouthWest().lat(), + west: bounds.getSouthWest().lng() + }; + return place; + } function removePlace(id) { @@ -9713,7 +9739,7 @@ requires self.options.selected = id; self.selected = id; setStatus(); - //that.triggerEvent('select', place); + that.triggerEvent('select', place); /* that.triggerEvent('select', { id: self.options.selected @@ -9755,6 +9781,21 @@ requires }); } + function resizeMap() { + Ox.print('w', self.options.width, 'h', self.options.height); + var center = self.map.getCenter(); + that.css({ + height: self.options.height + 'px', + width: self.options.width + 'px' + }); + self.$map.css({ + height: getMapHeight() + 'px', + width: self.options.width + 'px' + }); + google.maps.event.trigger(self.map, 'resize'); + self.map.setCenter(center); + } + function zoom(z) { self.map.setZoom(self.map.getZoom() + z); } @@ -9775,7 +9816,8 @@ requires } function Marker(place) { - var marker = new google.maps.Marker({ + var editing = false, + marker = new google.maps.Marker({ position: place.center, title: place.name }), @@ -9784,17 +9826,20 @@ requires setOptions(); Ox.print('MARKER', marker) function click() { - var metaKey = self.metaKey; + var metaKey = self.metaKey, + shiftKey = self.shiftKey; timeout = setTimeout(function() { Ox.print('$$$$ CLICK', metaKey, selected) if (!selected) { selected = true; selectPlace(place.id); - } else if (!metaKey) { - panToPlace(place); - } else { + } else if (shiftKey) { + zoomToPlace(place) + } else if (metaKey) { selected = false; selectPlace(null); + } else { + panToPlace(place); } }, 250); Ox.print('$$$$ TIMEOUT') @@ -9813,7 +9858,7 @@ requires marker.setOptions({ icon: oxui.path + 'png/ox.ui/marker' + (place.id[0] == '_' ? 'Result' : '') + - (selected ? 'Selected' : '') + '.png' + (selected ? 'Selected' : (editing ? 'Editing' : '')) + '.png' }); } return { @@ -9821,12 +9866,16 @@ requires Ox.print('Marker.add()') marker.setMap(self.map); google.maps.event.addListener(marker, 'click', click); - google.maps.event.addListener(marker, 'dblclick', dblclick); + //google.maps.event.addListener(marker, 'dblclick', dblclick); }, deselect: function() { selected = false; setOptions(); }, + edit: function() { + editing = true; + setOptions(); + }, remove: function() { marker.setMap(null); google.maps.event.clearListeners(marker); @@ -9834,6 +9883,10 @@ requires select: function() { selected = true; setOptions(); + }, + submit: function() { + editing = false; + setOptions(); } }; }; @@ -9876,6 +9929,16 @@ requires {lat: place.north, lng: place.east} ) }); + place.points = { + sw: new google.maps.LatLng(place.south, place.west), + s: new google.maps.LatLng(place.south, place.lng), + se: new google.maps.LatLng(place.south, place.east), + w: new google.maps.LatLng(place.lat, place.west), + e: new google.maps.LatLng(place.lat, place.east), + nw: new google.maps.LatLng(place.north, place.west), + n: new google.maps.LatLng(place.north, place.lng), + ne: new google.maps.LatLng(place.north, place.east), + }; Ox.print('PLACE', place) marker = Marker(place); polygon = Polygon(place); @@ -9890,6 +9953,9 @@ requires marker.deselect(); polygon.remove(); }, + edit: function() { + polygon.select(); + }, remove: function() { Ox.print('REMOVE!!!', selected) if (place.id[0] == '_') { @@ -9903,12 +9969,17 @@ requires selected = true; marker.select(); polygon.add(); + }, + submit: function() { + polygon.deselect(); } }); }; function Polygon(place) { - var listeners = {}, + var markers = Ox.map(place.points, function(v, k) { + return PolygonMarker(place, k); + }), polygon = new google.maps.Polygon({ paths: [ new google.maps.LatLng(place.south, place.west), @@ -9919,10 +9990,15 @@ requires ] }), selected = false; + Ox.print('markers', markers) setOptions(); function click() { selected = !selected; - setOptions(); + if (selected) { + place.edit(); + } else { + place.submit(); + } } function setOptions() { var color = selected ? '#8080FF' : '#FFFFFF'; @@ -9939,23 +10015,87 @@ requires add: function() { Ox.print('Polygon.add()') polygon.setMap(self.map); - listeners.click = google.maps.event.addListener(polygon, 'click', click); + google.maps.event.addListener(polygon, 'click', click); }, deselect: function() { selected = false; setOptions(); + Ox.forEach(markers, function(marker) { + marker.remove(); + }); }, remove: function() { polygon.setMap(null); - google.maps.event.removeListener(listeners.click); + google.maps.event.clearListeners(polygon); }, select: function() { + Ox.print('Polygon.select()') selected = true; setOptions(); + Ox.forEach(markers, function(marker) { + marker.add(); + }); } }; } + function PolygonMarker(place, position) { + var markerImage = new google.maps.MarkerImage( + oxui.path + 'png/ox.ui/polygonResize.png', + new google.maps.Size(16, 16), + new google.maps.Point(0, 0), + new google.maps.Point(8, 8) + ), + marker = new google.maps.Marker({ + cursor: position + '-resize', + draggable: true, + icon: markerImage, + position: place.points[position], + raiseOnDrag: false + }); + function dragstart() { + + } + function drag(e) { + var lat = e.latLng.lat(), + lng = e.latLng.lng(); + if (position.indexOf('s') > -1) { + place.south = lat; + } + if (position.indexOf('w') > -1) { + place.west = lng; + } + if (position.indexOf('n') > -1) { + place.north = lat; + } + if (position.indexOf('e') > -1) { + place.east = lng; + } + /* + place.bounds = new google.maps.LatLngBounds({ + new google.maps.LatLng(place.south, place.west), + new google.maps.LatLng(place.north, place.east) + }); + place.center = place.bounds.getCenter(); + */ + } + function dragend() { + + } + return { + add: function() { + marker.setMap(self.map); + google.maps.event.addListener(marker, 'dragstart', dragstart); + google.maps.event.addListener(marker, 'drag', drag); + google.maps.event.addListener(marker, 'dragend', dragend); + }, + remove: function() { + marker.setMap(null); + google.maps.event.clearListeners(marker); + } + } + } + function Rectangle(area) { // fixme: not used var latlng = { sw: new google.maps.LatLng(area[0][0], area[0][1]), @@ -9996,7 +10136,9 @@ requires } self.onChange = function(key, value) { - if (key == 'places') { + if (key == 'height' || key == 'width') { + resizeMap(); + } else if (key == 'places') { loadPlaces(); } else if (key == 'selected') { selectPlace(value); @@ -10005,9 +10147,19 @@ requires } }; - that.removePlace = function(id) { - - }; + that.getKey = function() { + var key = null; + if (self.shiftKey) { + key = 'shift' + } else if (self.metaKey) { + key = 'meta' + } + return key; + } + + that.editPlace = function() { + getPlaceById(self.options.selected).edit(); + } that.findPlace = function(name, callback) { getPlaceByName(name, function(place) { @@ -10026,6 +10178,17 @@ requires } callback(place); }); + }; + + that.panToPlace = function() { + Ox.print('panToPlace:', self.options.selected) + if (self.options.selected !== null) { + self.map.panTo(getPlaceById(self.options.selected).center); + } + }; + + that.removePlace = function(id) { + }; that.resizeMap = function() { @@ -10045,11 +10208,11 @@ requires }); } - that.zoomToPlace = function(id) { - Ox.print('zoomToPlace', id) - var place = getPlaceById(id); - self.bounds = place.bounds; - self.map.fitBounds(self.bounds); + that.zoomToPlace = function() { + Ox.print('zoomToPlace') + if (self.options.selected !== null) { + self.map.fitBounds(getPlaceById(self.options.selected).bounds); + } }; that.zoom = function(value) { @@ -10060,6 +10223,306 @@ requires }; + Ox.MapPlace = function(options) { + + var options = Ox.extend({ + east: 0, + editing: false, + geoname: '', + map: null, + name: '', + north: 0, + selected: false, + south: 0, + type: [], + west: 0 + }, options), + that = this; + + Ox.forEach(options, function(val, key) { + that[key] = val; + }); + that.points = { + ne: new google.maps.LatLng(that.north, that.east), + sw: new google.maps.LatLng(that.south, that.west) + }; + that.bounds = new google.maps.LatLngBounds(that.points.sw, that.points.ne); + that.center = that.bounds.getCenter(); + that.lat = that.center.lat(); + that.lng = that.center.lng(); + Ox.extend(that.points, { + center: that.center, + e: new google.maps.LatLng(that.lat, that.east), + s: new google.maps.LatLng(that.south, that.lng), + se: new google.maps.LatLng(that.south, that.east), + n: new google.maps.LatLng(that.north, that.lng), + nw: new google.maps.LatLng(that.north, that.west), + w: new google.maps.LatLng(that.lat, that.west), + }); + that.marker = new Ox.MapMarker({ + map: that.map, + place: that + }); + that.polygon = new Ox.MapPolygon({ + map: that.map, + place: that + }); + + that.add = function() { + Ox.print('MapPlace add', that) + that.marker.add(); + return that; + }; + + that.deselect = function() { + that.selected = false; + that.marker.update(); + that.polygon.remove(); + return that; + }; + + that.edit = function() { + that.editing = true; + that.marker.update(); + that.polygon.select(); + return that; + } + + that.remove = function() { + Ox.print('MapPlace remove', that) + that.editing && that.submit(); + that.selected && that.deselect(); + that.marker.remove(); + return that; + }; + + that.select = function() { + that.selected = true; + that.marker.update(); + that.polygon.add(); + return that; + }; + + that.submit = function() { + Ox.print('submit') + that.editing = false; + that.marker.update(); + that.polygon.deselect(); + return that; + } + + return that; + + }; + + Ox.MapMarker = function(options) { + + var options = Ox.extend({ + map: null, + place: null + }, options), + that = this; + + Ox.forEach(options, function(val, key) { + that[key] = val; + }); + that.marker = new google.maps.Marker({ + position: that.place.center, + title: that.place.name + }); + + setOptions(); + + function click() { + var selected = null; + if (!that.place.selected) { + that.map.options({selected: that.place.id}); + } else if (that.map.getKey() == 'meta') { + that.map.options({selected: null}); + } else if (that.map.getKey() == 'shift') { + that.map.zoomToPlace(); + } else { + that.map.panToPlace(); + } + } + + function setOptions() { + that.marker.setOptions({ + icon: new google.maps.MarkerImage( + oxui.path + 'png/ox.ui/mapMarker' + + (that.place.id[0] == '_' ? 'Result' : '') + + (that.place.editing ? 'Editing' : ( + that.place.selected ? 'Selected' : '' + )) + '.png', + new google.maps.Size(16, 16), + new google.maps.Point(0, 0), + new google.maps.Point(8, 8) + ) + }); + } + + that.add = function() { + Ox.print('MapMarker add', that) + that.marker.setMap(that.map.map); + google.maps.event.addListener(that.marker, 'click', click); + return that; + }; + + that.remove = function() { + that.marker.setMap(null); + google.maps.event.clearListeners(that.marker); + return that; + }; + + that.update = function() { + setOptions(); + } + + return that; + + }; + + Ox.MapPolygon = function(options, self) { + + var options = Ox.extend({ + map: null, + place: null + }, options), + that = this; + + Ox.forEach(options, function(val, key) { + that[key] = val; + }); + + that.polygon = new google.maps.Polygon({ + clickable: true, + paths: [ + that.place.points.sw, + that.place.points.nw, + that.place.points.ne, + that.place.points.se, + that.place.points.sw + ], + }); + that.markers = Ox.map(that.place.points, function(point, position) { + return new Ox.MapPolygonMarker({ + map: that.map, + place: that.place, + position: position + }); + }); + + setOptions(); + + function click() { + if (!that.place.editing) { + that.place.edit(); + } else if (that.map.getKey() == 'meta') { + that.place.submit(); + } else if (that.map.getKey() == 'shift') { + that.map.zoomToPlace(); + } else { + that.map.panToPlace(); + } + + } + + function setOptions() { + var color = that.place.editing ? '#8080FF' : '#FFFFFF'; + that.polygon.setOptions({ + fillColor: color, + fillOpacity: that.place.editing ? 0.1 : 0, + strokeColor: color, + strokeOpacity: 1, + strokeWeight: 2 + }) + } + + that.add = function() { + that.polygon.setMap(that.map.map); + google.maps.event.addListener(that.polygon, 'click', click); + return that; + }; + + that.deselect = function() { + setOptions(); + Ox.forEach(that.markers, function(marker) { + marker.remove(); + }); + }; + + that.remove = function() { + that.polygon.setMap(null); + google.maps.event.clearListeners(that.polygon); + return that + } + + that.select = function() { + setOptions(); + Ox.forEach(that.markers, function(marker) { + marker.add(); + }); + }; + + return that; + + }; + + Ox.MapPolygonMarker = function(options, self) { + + var options = Ox.extend({ + map: null, + place: null, + position: '' + }, options), + that = this; + + Ox.forEach(options, function(val, key) { + that[key] = val; + }); + + that.markerImage = new google.maps.MarkerImage + that.marker = new google.maps.Marker({ + cursor: that.position + '-resize', + draggable: true, + icon: new google.maps.MarkerImage( + oxui.path + 'png/ox.ui/mapMarkerResize.png', + new google.maps.Size(16, 16), + new google.maps.Point(0, 0), + new google.maps.Point(8, 8) + ), + position: that.place.points[that.position], + raiseOnDrag: false + }); + + function dragstart(e) { + + } + + function drag(e) { + + } + + function dragend(e) { + + } + + that.add = function() { + that.marker.setMap(that.map.map); + google.maps.event.addListener(that.marker, 'dragstart', dragstart); + google.maps.event.addListener(that.marker, 'drag', drag); + google.maps.event.addListener(that.marker, 'dragend', dragend); + }; + + that.remove = function() { + that.marker.setMap(null); + google.maps.event.clearListeners(that.marker); + }; + + return that; + + }; + /** options height image height (px)