Skip to content

Commit

Permalink
show anchor
Browse files Browse the repository at this point in the history
  • Loading branch information
bruno-garcia committed Dec 2, 2023
1 parent 5246106 commit 429211c
Show file tree
Hide file tree
Showing 8 changed files with 217 additions and 6 deletions.
7 changes: 5 additions & 2 deletions AnchorAlertApp.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,11 @@
<MauiSplashScreen Include="Resources\Splash\splash.svg" Color="#512BD4" BaseSize="128,128" />

<!-- Images -->
<MauiImage Include="Resources\Images\*" />
<MauiImage Update="Resources\Images\dotnet_bot.png" Resize="True" BaseSize="300,185" />
<!-- Exclude required until this lands: https://github.com/dotnet/maui/pull/18731 -->
<MauiImage Include="Resources\Images\*" Exclude="Resources\Images\.DS_Store" />
<!-- TODO: Do I need to resize this? What will be base size? -->
<MauiImage Update="Resources\Images\anchor_light.png" Resize="True" BaseSize="70,70" />
<MauiImage Update="Resources\Images\anchor_dark.png" Resize="True" BaseSize="70,70" />

<!-- Custom Fonts -->
<MauiFont Include="Resources\Fonts\*" />
Expand Down
190 changes: 190 additions & 0 deletions AnchorPin.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,190 @@
using Microsoft.Maui.Controls.Maps;
using Microsoft.Maui.Maps;
using Microsoft.Maui.Maps.Handlers;
using Microsoft.Maui.Maps.Platform;
using Microsoft.Maui.Platform;
using IMap = Microsoft.Maui.Maps.IMap;
#if IOS || MACCATALYST
using UIKit;
using MapKit;
using CoreLocation;
#endif

namespace AnchorAlertApp;
// https://github.com/VladislavAntonyuk/MauiSamples/tree/main/MauiMaps
public class AnchorPin : Pin
{
public static readonly BindableProperty ImageSourceProperty = BindableProperty.Create(
nameof(ImageSource),
typeof(ImageSource),
typeof(AnchorPin));

public ImageSource? ImageSource
{
get => (ImageSource?)GetValue(ImageSourceProperty);
set => SetValue(ImageSourceProperty, value);
}
}

#if IOS || MACCATALYST
public class CustomAnnotation : MKPointAnnotation
{
public Guid Identifier { get; init; }
public UIImage? Image { get; init; }
public required IMapPin Pin { get; init; }
}
public class AnchorMapHandler : MapHandler
{
private static UIView? lastTouchedView;
public static readonly IPropertyMapper<IMap, IMapHandler> CustomMapper =
new PropertyMapper<IMap, IMapHandler>(Mapper)
{
[nameof(IMap.Pins)] = MapPins,
};

public AnchorMapHandler() : base(CustomMapper, CommandMapper)
{
}

public AnchorMapHandler(IPropertyMapper? mapper = null, CommandMapper? commandMapper = null) : base(
mapper ?? CustomMapper, commandMapper ?? CommandMapper)
{
}

public List<IMKAnnotation> Markers { get; } = new();

protected override void ConnectHandler(MauiMKMapView platformView)
{
base.ConnectHandler(platformView);
platformView.GetViewForAnnotation += GetViewForAnnotations;
}

private static void OnCalloutClicked(IMKAnnotation annotation)
{
var pin = GetPinForAnnotation(annotation);
if (lastTouchedView is MKAnnotationView)
return;
pin?.SendInfoWindowClick();
}

private static MKAnnotationView GetViewForAnnotations(MKMapView mapView, IMKAnnotation annotation)
{
MKAnnotationView annotationView;
if (annotation is CustomAnnotation customAnnotation)
{
annotationView = mapView.DequeueReusableAnnotation(customAnnotation.Identifier.ToString()) ??
new MKAnnotationView(annotation, customAnnotation.Identifier.ToString());
annotationView.Image = customAnnotation.Image;
annotationView.CanShowCallout = true;
}
else if (annotation is MKPointAnnotation)
{
annotationView = mapView.DequeueReusableAnnotation("defaultPin") ??
new MKMarkerAnnotationView(annotation, "defaultPin");
annotationView.CanShowCallout = true;
}
else
{
annotationView = new MKUserLocationView(annotation, null);
}

var result = annotationView ?? new MKAnnotationView(annotation, null);
AttachGestureToPin(result, annotation);
return result;
}

static void AttachGestureToPin(MKAnnotationView mapPin, IMKAnnotation annotation)
{
var recognizers = mapPin.GestureRecognizers;

if (recognizers != null)
{
foreach (var r in recognizers)
{
mapPin.RemoveGestureRecognizer(r);
}
}

var recognizer = new UITapGestureRecognizer(g => OnCalloutClicked(annotation))
{
ShouldReceiveTouch = (gestureRecognizer, touch) =>
{
lastTouchedView = touch.View;
return true;
}
};

mapPin.AddGestureRecognizer(recognizer);
}

static IMapPin? GetPinForAnnotation(IMKAnnotation? annotation)
{
if (annotation is CustomAnnotation customAnnotation)
{
return customAnnotation.Pin;
}

return null;
}

private static new void MapPins(IMapHandler handler, IMap map)
{
if (handler is AnchorMapHandler mapHandler)
{
foreach (var marker in mapHandler.Markers)
{
mapHandler.PlatformView.RemoveAnnotation(marker);
}

mapHandler.Markers.Clear();
mapHandler.AddPins(map.Pins);
}
}

private void AddPins(IEnumerable<IMapPin> mapPins)
{
if (MauiContext is null)
{
return;
}

foreach (var pin in mapPins)
{
var pinHandler = pin.ToHandler(MauiContext);
if (pinHandler is IMapPinHandler mapPinHandler)
{
var markerOption = mapPinHandler.PlatformView;
if (pin is AnchorPin cp)
{
cp.ImageSource.LoadImage(MauiContext, result =>
{
markerOption = new CustomAnnotation()
{
Identifier = cp.Id,
Image = result?.Value,
Title = pin.Label,
Subtitle = pin.Address,
Coordinate = new CLLocationCoordinate2D(pin.Location.Latitude, pin.Location.Longitude),
Pin = cp
};

AddMarker(PlatformView, pin, Markers, markerOption);
});
}
else
{
AddMarker(PlatformView, pin, Markers, markerOption);
}
}
}
}

private static void AddMarker(MauiMKMapView map, IMapPin pin, List<IMKAnnotation> markers, IMKAnnotation annotation)
{
map.AddAnnotation(annotation);
pin.MarkerId = annotation;
markers.Add(annotation);
}
}

#endif
20 changes: 16 additions & 4 deletions MainPage.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -57,9 +57,6 @@ private void UpdateMap(Location location)
Console.WriteLine(map.VisibleRegion.Radius.Meters);
}

// TODO: Show the boat instead
map.IsShowingUser = true;

if (_anchorLocation is null)
{
_isInSafeArea = true;
Expand All @@ -68,6 +65,21 @@ private void UpdateMap(Location location)
_anchorLocation = location;
// _anchorLocation = new Location(42.688329, 17.939085);


// .NET MAUI apps can respond to system theme changes on iOS 13 or greater, Android 10 (API 29) or greater, macOS 10.14 or greater, and Windows 10 or greater.
// TODO: There's a whole theming thing to deal with this: https://learn.microsoft.com/en-us/dotnet/maui/user-interface/system-theme-changes?view=net-maui-8.0
var fileName = Application.Current?.RequestedTheme is AppTheme.Dark ? "anchor_dark.png" : "anchor_light.png";
var anchorPin = new AnchorPin
{
ImageSource = fileName,
Label = "Anchor",
Location = location
};
map.Pins.Add(anchorPin);

// TODO: Show the boat instead
// map.IsShowingUser = true;

var mapSpan = new MapSpan(_anchorLocation, _latLongDegrees, _latLongDegrees);
map.MoveToRegion(mapSpan);

Expand Down Expand Up @@ -114,7 +126,7 @@ private void OnSliderValueChanged(object sender, ValueChangedEventArgs e)
}
}

private async void OnButtonClicked(object sender, EventArgs e)
private void OnButtonClicked(object sender, EventArgs e)
{
var button = sender as Button;
map.MapType = button?.Text switch
Expand Down
6 changes: 6 additions & 0 deletions MauiProgram.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,12 @@ public static MauiApp CreateMauiApp()
builder
.UseMauiApp<App>()
.UseMauiMaps()
.ConfigureMauiHandlers(handlers =>
{
#if IOS || MACCATALYST // ANDROID
handlers.AddHandler<Microsoft.Maui.Controls.Maps.Map, AnchorMapHandler>();
#endif
})
.ConfigureFonts(fonts =>
{
fonts.AddFont("OpenSans-Regular.ttf", "OpenSansRegular");
Expand Down
Empty file removed Resources/Images/anchor.svg
Empty file.
Binary file added Resources/Images/anchor_dark.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added Resources/Images/anchor_light.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file removed Resources/Images/dotnet_bot.png
Binary file not shown.

0 comments on commit 429211c

Please sign in to comment.