Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit 57208d6
Showing
12 changed files
with
355 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
|
||
@implementation MKMapItem : CPObject | ||
{ | ||
} | ||
|
||
- (String)typeName | ||
{ | ||
return [self className].substring(2); | ||
} | ||
@end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,118 @@ | ||
@import <Foundation/Foundation.j> | ||
@import "MKMapView.j" | ||
|
||
@implementation MKMapScene : CPObject | ||
{ | ||
MKMapView _mapView @accessors(property=mapView); | ||
CPMutableArray _mapItems; | ||
CPURLConnection _readConnection; | ||
} | ||
|
||
- (id)initWithMapView:(MKMapView)mapView | ||
{ | ||
|
||
if (self = [super init]) { | ||
_mapView = mapView; | ||
_mapItems = [[CPArray alloc] init]; | ||
} | ||
return self; | ||
} | ||
|
||
- (String)json | ||
{ | ||
return CPJSObjectCreateJSON({ | ||
mapItems: [self mapItemsAsJSObject] | ||
}); | ||
} | ||
|
||
- (BOOL)saveToURL:(CPURL)anURL | ||
{ | ||
var request = [CPURLRequest requestWithURL:anURL]; | ||
|
||
[request setHTTPMethod:@"POST"]; | ||
[request setHTTPBody:"data=" + [self json]]; | ||
|
||
[request setValue:@"close" forHTTPHeaderField:@"Connection"]; | ||
|
||
//[request setValue:@"true" forHTTPHeaderField:@"x-cappuccino-overwrite"]; | ||
|
||
var connection = [CPURLConnection connectionWithRequest:request delegate:self]; | ||
} | ||
|
||
- (BOOL)readFromURL:(CPURL)anURL | ||
{ | ||
|
||
[_readConnection cancel]; | ||
_readConnection = [CPURLConnection connectionWithRequest:[CPURLRequest requestWithURL:anURL] delegate:self]; | ||
} | ||
|
||
- (void)connection:(CPURLConnection)aConnection didFailWithError:(CPError)anError | ||
{ | ||
if (aConnection == _readConnection) { | ||
alert('Load failed! ' + anError); | ||
_readConnection = nil; | ||
} else { | ||
alert('Save failed! ' + anError); | ||
} | ||
} | ||
- (void)connection:(CPURLConnection)aConnection didReceiveData:(CPString)aData | ||
{ | ||
if (aConnection == _readConnection) { | ||
var aData = aData.replace('while(1);', ''); | ||
var mapItems = CPJSObjectCreateWithJSON(aData); | ||
for (var i in mapItems) { | ||
var mapItem = mapItems[i]; | ||
[self addMapItem:[[MKMarker alloc] initAtLocation:new GLatLng(mapItem.anchor.y, mapItem.anchor.x)]]; | ||
} | ||
} | ||
} | ||
- (void)connectionDidFinishLoading:(CPURLConnection)aConnection | ||
{ | ||
if (aConnection == _readConnection) { | ||
alert('Loaded successfully!'); | ||
_readConnection = nil; | ||
} else { | ||
alert('Saved successfully!'); | ||
} | ||
} | ||
|
||
|
||
|
||
|
||
- (Object)mapItemsAsJSObject | ||
{ | ||
var items = []; | ||
|
||
var enumerator = [_mapItems objectEnumerator], | ||
item; | ||
|
||
while (item = [enumerator nextObject]) | ||
{ | ||
items.push({ | ||
'class': [item typeName], | ||
'anchor': [[item location].lng(), [item location].lat()] | ||
}); | ||
} | ||
return items; | ||
} | ||
|
||
- (id)initWithCoder:(CPCoder)coder | ||
{ | ||
if (self = [super init]) { | ||
_mapItems = [coder decodeObjectForKey:@"mapItems"]; | ||
} | ||
return self; | ||
} | ||
|
||
- (void)encodeWithCoder:(CPCoder)coder | ||
{ | ||
[coder encodeObject:_mapItems forKey:@"mapItems"]; | ||
} | ||
|
||
- (void)addMapItem:(MKMapItem)mapItem | ||
{ | ||
[_mapItems addObject:mapItem]; | ||
[_mapView addMapItem:mapItem]; | ||
} | ||
|
||
@end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,164 @@ | ||
@import <AppKit/CPView.j> | ||
@import "MKMapScene.j" | ||
@import "MKMarker.j" | ||
|
||
@implementation MKMapView : CPView | ||
{ | ||
CPString _apiKey; | ||
DOMElement _DOMMapElement; | ||
JSObject _gMap @accessors(property=gMap); | ||
MKMapScene _scene @accessors(property=scene); | ||
BOOL _mapReady; | ||
BOOL _googleAjaxLoaded; | ||
} | ||
|
||
- (id)initWithFrame:(CGRect)aFrame apiKey:(CPString)apiKey | ||
{ | ||
_apiKey = apiKey; | ||
if (self = [super initWithFrame:aFrame]) { | ||
_scene = [[MKMapScene alloc] initWithMapView:self]; | ||
|
||
var bounds = [self bounds]; | ||
_DOMMapElement = document.createElement('div'); | ||
with (_DOMMapElement.style) { | ||
position = "absolute"; | ||
left = "0px"; | ||
top = "0px"; | ||
width = "100%"; | ||
height = "100%"; | ||
} | ||
_DOMElement.appendChild(_DOMMapElement); | ||
|
||
// Piggy back on the CPJSONPConnection stuff to load in the Google AJAX loader. | ||
var url = 'http://www.google.com/jsapi?key=' + _apiKey; | ||
var request = [CPURLRequest requestWithURL:url]; | ||
var conn = [CPJSONPConnection sendRequest:request callback:"callback" delegate:self]; | ||
} | ||
|
||
return self; | ||
} | ||
|
||
- (void)connection:(CPJSONPConnection)aConnection didReceiveData:(Object)data | ||
{ | ||
_googleAjaxLoaded = YES; | ||
//console.log("Google AJAX API has loaded"); | ||
// Google API has loaded, now load Google Maps API. The main reason for | ||
// using this is to avoid polluting the global namespace with G* objects | ||
function callback() { | ||
if (_superview) { | ||
[self createMap]; | ||
} | ||
}; | ||
// Load Google Maps API v2.160 | ||
google.load('maps', '2.160', {callback: callback}); | ||
} | ||
|
||
- (void)createMap | ||
{ | ||
var GEvent = google.maps.Event, | ||
GMap2 = google.maps.Map2, | ||
GLatLng = google.maps.LatLng, | ||
GPoint = google.maps.Point; | ||
|
||
//console.log("Creating map"); | ||
_gMap = new GMap2(_DOMMapElement); | ||
//_gMap.addMapType(G_SATELLITE_3D_MAP); | ||
_gMap.setMapType(G_PHYSICAL_MAP); | ||
_gMap.setUIToDefault(); | ||
_gMap.setCenter(new GLatLng(52, -1), 8); | ||
_gMap.enableContinuousZoom(); | ||
|
||
|
||
// Horrible hack to fix dragging of th emap | ||
function startDrag(ev) | ||
{ | ||
if (_gMap._dragging) { | ||
return; | ||
} | ||
_gMap._dragging = true; | ||
_gMap._draggingHandlers = [ | ||
GEvent.addDomListener(document.body, 'mousemove', doDrag), | ||
GEvent.addDomListener(document.body, 'mouseup', endDrag) | ||
]; | ||
_gMap._dragStartLocation = new GPoint(ev.clientX, ev.clientY); | ||
_gMap._dragStartCenter = _gMap.fromLatLngToDivPixel(_gMap.getCenter()); | ||
} | ||
function doDrag(ev) | ||
{ | ||
if (!_gMap._dragging) { | ||
endDrag(ev); | ||
return; | ||
} | ||
|
||
var currentLocation = new GPoint(ev.clientX, ev.clientY); | ||
var x_diff = currentLocation.x - _gMap._dragStartLocation.x; | ||
var y_diff = currentLocation.y - _gMap._dragStartLocation.y; | ||
var x = _gMap._dragStartCenter.x - x_diff; | ||
var y = _gMap._dragStartCenter.y - y_diff; | ||
|
||
var newCenter = new GPoint(x, y); | ||
var destination = _gMap.fromDivPixelToLatLng(newCenter); | ||
|
||
_gMap.setCenter(destination); | ||
_gMap._dragStartLocation = currentLocation; | ||
_gMap._dragStartCenter = _gMap.fromLatLngToDivPixel(_gMap.getCenter()); | ||
} | ||
function endDrag(ev) | ||
{ | ||
if (_gMap._draggingHandlers) { | ||
for (var i=0; i<_gMap._draggingHandlers.length; i++) { | ||
GEvent.removeListener(_gMap._draggingHandlers[i]); | ||
} | ||
delete _gMap._draggingHandlers; | ||
} | ||
if (_gMap._dragging) { | ||
delete _gMap._dragging; | ||
} | ||
} | ||
|
||
|
||
var dragNode = _DOMMapElement.firstChild.firstChild; | ||
GEvent.addDomListener(dragNode, 'mousedown', startDrag); | ||
|
||
// Hack to get mouse up event to work | ||
GEvent.addDomListener(document.body, 'mouseup', function() { GEvent.trigger(window, 'mouseup'); }); | ||
|
||
_mapReady = YES; | ||
} | ||
- (void)setFrameSize:(CGSize)aSize | ||
{ | ||
[super setFrameSize:aSize]; | ||
var bounds = [self bounds]; | ||
if (_gMap) { | ||
_gMap.checkResize(); | ||
} | ||
} | ||
|
||
|
||
- (void)viewDidMoveToSuperview | ||
{ | ||
if (!_mapReady && _googleAjaxLoaded) { | ||
[self createMap]; | ||
} | ||
[super viewDidMoveToSuperview]; | ||
} | ||
|
||
- (MKMarker)addMarker:(MKMarker)marker atLocation:(GLatLng)location | ||
{ | ||
if (_mapReady) { | ||
var gMarker = [marker gMarker]; | ||
gMarker.setLatLng(location); | ||
_gMap.addOverlay(gMarker); | ||
} else { | ||
// TODO some sort of queue? | ||
} | ||
return marker; | ||
} | ||
|
||
- (void)addMapItem:(MKMapItem)mapItem | ||
{ | ||
[mapItem addToMapView:self]; | ||
} | ||
|
||
@end | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
@import <AppKit/CPView.j> | ||
@import "MKMapItem.j" | ||
|
||
@implementation MKMarker : MKMapItem | ||
{ | ||
GMarker _gMarker @accessors(property=gMarker); | ||
GLatLng _location @accessors(property=location); | ||
} | ||
|
||
+ (MKMarker)marker | ||
{ | ||
return [[MKMarker alloc] init]; | ||
} | ||
|
||
- (id)initAtLocation:(GLatLng)aLocation | ||
{ | ||
if (self = [super init]) { | ||
_location = aLocation; | ||
|
||
var flags = ['red', 'blue', 'green', 'black', 'yellow']; | ||
// Pick a random flag | ||
var colour = flags[Math.floor(Math.random()*5)]; | ||
|
||
var flagIcon = new GIcon(); | ||
flagIcon.image = "MapKit/Resources/flag-" + colour + ".png"; | ||
flagIcon.shadow = "MapKit/Resources/flag-shadow.png"; | ||
flagIcon.iconSize = new GSize(32, 32); | ||
flagIcon.shadowSize = new GSize(43, 32); | ||
flagIcon.iconAnchor = new GPoint(4, 30); | ||
flagIcon.infoWindowAnchor = new GPoint(4, 1); | ||
|
||
var markerOptions = { icon: flagIcon, draggable:true }; | ||
_gMarker = new GMarker(aLocation, markerOptions); | ||
|
||
GEvent.addListener(_gMarker, 'dragend', function() { [self updateLocation]; }); | ||
} | ||
return self; | ||
} | ||
|
||
- (void)updateLocation | ||
{ | ||
_location = _gMarker.getLatLng(); | ||
} | ||
|
||
- (void)addToMapView:(MKMapView)mapView | ||
{ | ||
var googleMap = [mapView gMap]; | ||
googleMap.addOverlay(_gMarker); | ||
} | ||
|
||
- (void)encodeWithCoder:(CPCoder)coder | ||
{ | ||
[coder encodeObject:[_location.lat(), _location.lng()] forKey:@"location"]; | ||
} | ||
|
||
@end | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
MapKit for Cappuccino | ||
--------------------- | ||
|
||
A very early version of a Google Maps API abstraction layer written for Cappuccino. | ||
|
||
Don't expect much of anything to work yet. |
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.