diff options
Diffstat (limited to 'Xamarin.Forms.Maps.Tizen/MapRenderer.cs')
-rwxr-xr-x | Xamarin.Forms.Maps.Tizen/MapRenderer.cs | 287 |
1 files changed, 245 insertions, 42 deletions
diff --git a/Xamarin.Forms.Maps.Tizen/MapRenderer.cs b/Xamarin.Forms.Maps.Tizen/MapRenderer.cs index b7278dcc..d61f6a27 100755 --- a/Xamarin.Forms.Maps.Tizen/MapRenderer.cs +++ b/Xamarin.Forms.Maps.Tizen/MapRenderer.cs @@ -1,47 +1,250 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Collections.Specialized; +using System.ComponentModel; +using ElmSharp; +using Tizen.Location; +using Tizen.Maps; using Xamarin.Forms.Platform.Tizen; -using TForms = Xamarin.Forms.Platform.Tizen.Forms; namespace Xamarin.Forms.Maps.Tizen { - public class MapRenderer : ViewRenderer<Map, MapControl> - { - public MapRenderer() - { - RegisterPropertyHandler(Map.MapTypeProperty, UpdateMapType); - RegisterPropertyHandler(Map.IsShowingUserProperty, UpdateIsShowingUser); - RegisterPropertyHandler(Map.HasScrollEnabledProperty, UpdateHasScrollEnabled); - RegisterPropertyHandler(Map.HasZoomEnabledProperty, UpdateHasZoomEnabled); - } - - protected override void OnElementChanged(ElementChangedEventArgs<Map> e) - { - base.OnElementChanged(e); - - if (Control == null) - { - var mapControl = new MapControl(TForms.Context.MainWindow); - SetNativeControl(mapControl); - } - } - - void UpdateMapType() - { - // TODO - } - - void UpdateIsShowingUser() - { - // TODO - } - - void UpdateHasScrollEnabled() - { - // TODO - } - - void UpdateHasZoomEnabled() - { - // TODO - } - } + public class MapRenderer : ViewRenderer<Map, MapView> + { + const string MoveMessageName = "MapMoveToRegion"; + + bool _disposed; + Overlay _marker; + bool _isLocatorStarted = false; + Lazy<Locator> _locator = new Lazy<Locator>(InitializeLocator); + Dictionary<Pin, MapObject> _pins = new Dictionary<Pin, MapObject>(); + + static Locator InitializeLocator() + { + var locator = new Locator(LocationType.Hybrid) + { + // Set the default interval to 15s same as UWP + Interval = 15 + }; + return locator; + } + + public MapRenderer() + { + } + + protected override void OnElementChanged(ElementChangedEventArgs<Map> e) + { + if (Control == null) + { + var mapControl = new MapView(Platform.Tizen.Forms.Context.MainWindow, FormsMaps.MapService); + SetNativeControl(mapControl); + } + + if (e.OldElement != null) + { + ((ObservableCollection<Pin>)e.OldElement.Pins).CollectionChanged -= OnCollectionChanged; + + MessagingCenter.Unsubscribe<Map, MapSpan>(this, MoveMessageName); + } + if (e.NewElement != null) + { + ((ObservableCollection<Pin>)e.NewElement.Pins).CollectionChanged += OnCollectionChanged; + if (e.NewElement.Pins.Count > 0) + { + AddPins(e.NewElement.Pins); + } + + MessagingCenter.Subscribe<Map, MapSpan>(this, MoveMessageName, OnMoveToRegion, e.NewElement); + + UpdateMapType(); + UpdateHasScrollEnabled(); + UpdateHasZoomEnabled(); + UpdateIsShowingUser(); + } + base.OnElementChanged(e); + } + + protected override void Dispose(bool disposing) + { + if (_disposed) + { + return; + } + + _disposed = true; + + if (disposing) + { + MessagingCenter.Unsubscribe<Map, MapSpan>(this, "MapMoveToRegion"); + if (Element != null) + { + ((ObservableCollection<Pin>)Element.Pins).CollectionChanged -= OnCollectionChanged; + } + Control.Unrealize(); + } + base.Dispose(disposing); + } + + protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e) + { + base.OnElementPropertyChanged(sender, e); + + if (e.PropertyName == Map.MapTypeProperty.PropertyName) + UpdateMapType(); + else if (e.PropertyName == Map.IsShowingUserProperty.PropertyName) + UpdateIsShowingUser(); + else if (e.PropertyName == Map.HasScrollEnabledProperty.PropertyName) + UpdateHasScrollEnabled(); + else if (e.PropertyName == Map.HasZoomEnabledProperty.PropertyName) + UpdateHasZoomEnabled(); + } + + void OnMoveToRegion(Map map, MapSpan span) + { + var newCenter = new Geocoordinates(span.Center.Latitude, span.Center.Longitude); + Control.Center = newCenter; + } + + + void OnCollectionChanged(object sender, NotifyCollectionChangedEventArgs e) + { + if (e.NewItems != null) + { + AddPins(e.NewItems); + } + if (e.OldItems != null) + { + RemovePins(e.OldItems); + } + if (e.Action == NotifyCollectionChangedAction.Reset) + { + ClearPins(); + } + } + + void AddPins(IEnumerable pins) + { + foreach (Pin pin in pins) + { + var coordinates = new Geocoordinates(pin.Position.Latitude, pin.Position.Longitude); + var rectangle = new Background(Platform.Tizen.Forms.Context.MainWindow); + // TODO: Need to change BubbleOverlay to default Marker + // TODO: Need to handle Pin.Clicked event + var nativePin = new BubbleOverlay(coordinates, rectangle); + Control.Add(nativePin); + _pins.Add(pin, nativePin); + } + } + + void RemovePins(IEnumerable pins) + { + foreach (Pin pin in pins) + { + if (_pins.ContainsKey(pin)) + { + Control.Remove(_pins[pin]); + _pins.Remove(pin); + } + } + } + + void ClearPins() + { + foreach (var pin in _pins) + { + Control.Remove(pin.Value); + } + _pins.Clear(); + } + + void UpdateHasZoomEnabled() + { + if (Element.HasZoomEnabled == true) + Control.ZoomChanged += Dummy; + else + Control.ZoomChanged -= Dummy; + } + + void UpdateHasScrollEnabled() + { + if (Element.HasScrollEnabled == true) + Control.Scrolled += Dummy; + else + Control.Scrolled -= Dummy; + } + + void Dummy(object sender, MapGestureEventArgs e) + { + //TODO: The implementation of Tizen.Maps needs to be changed to remove this method + } + + void ApplyIsShowingUser(Geocoordinates coordinates) + { + if (_marker == null) + { + var rectangle = new Background(Platform.Tizen.Forms.Context.MainWindow); + // TODO: Need to change BubbleOverlay to Default Overlay + _marker = new BubbleOverlay(coordinates, rectangle); + _marker.IsVisible = false; + Control.Add(_marker); + } + _marker.Coordinates = coordinates; + + if (!_marker.IsVisible) + { + _marker.IsVisible = true; + Control.Center = coordinates; + Control.ZoomLevel = 13; + } + } + void UpdateIsShowingUser() + { + if (Element.IsShowingUser) + { + _locator.Value.LocationChanged += OnLocationChanged; + if (!_isLocatorStarted) + { + _locator.Value.Start(); + _isLocatorStarted = true; + } + } + else + { + if (_locator.IsValueCreated) + { + _locator.Value.LocationChanged -= OnLocationChanged; + _locator.Value.Stop(); + _isLocatorStarted = false; + } + if (_marker != null) + _marker.IsVisible = false; + } + } + + void OnLocationChanged(object sender, LocationChangedEventArgs e) + { + ApplyIsShowingUser(new Geocoordinates(e.Location.Latitude, e.Location.Longitude)); + } + + void UpdateMapType() + { + switch (Element.MapType) + { + case MapType.Street: + Control.MapType = MapTypes.Normal; + break; + case MapType.Satellite: + Control.MapType = MapTypes.Satellite; + break; + case MapType.Hybrid: + Control.MapType = MapTypes.Hybrid; + break; + default: + throw new ArgumentOutOfRangeException(); + } + } + } } |