From 408a50d75323f17d1136cc56a0d894413d5ca2c1 Mon Sep 17 00:00:00 2001 From: alex-osm Date: Sat, 2 Dec 2023 20:34:01 +0300 Subject: [PATCH] Fix weather center marker position --- .../Map/Layers/OAWeatherRasterLayer.mm | 86 +++++++++++++++++++ .../Map/Widgets/OAMapWidgetRegistry.h | 2 + .../Map/Widgets/OAMapWidgetRegistry.mm | 19 +++- .../Controllers/Map/Widgets/OARulerWidget.mm | 2 +- .../Map/Widgets/Widgets/OAWeatherWidget.mm | 55 ++---------- 5 files changed, 115 insertions(+), 49 deletions(-) diff --git a/Sources/Controllers/Map/Layers/OAWeatherRasterLayer.mm b/Sources/Controllers/Map/Layers/OAWeatherRasterLayer.mm index 01daa382c2..f4daa2f5aa 100644 --- a/Sources/Controllers/Map/Layers/OAWeatherRasterLayer.mm +++ b/Sources/Controllers/Map/Layers/OAWeatherRasterLayer.mm @@ -16,6 +16,7 @@ #import "OAWeatherPlugin.h" #import "OAWeatherToolbar.h" #import "OAMapLayers.h" +#import "OAMapWidgetRegistry.h" #include #include @@ -32,6 +33,11 @@ @implementation OAWeatherRasterLayer OAAutoObserverProxy* _weatherUseOfflineDataChangeObserver; NSMutableArray *_layerChangeObservers; NSMutableArray *_alphaChangeObservers; + + CGSize _cachedViewFrame; + OsmAnd::PointI _cachedCenterPixel; + BOOL _cachedAnyWidgetVisible; + NSTimeInterval _lastUpdateTime; } - (instancetype) initWithMapViewController:(OAMapViewController *)mapViewController layerIndex:(int)layerIndex weatherLayer:(EOAWeatherLayer)weatherLayer date:(NSDate *)date @@ -242,4 +248,84 @@ - (void) updateOpacitySliderVisibility }); } +- (void) onMapFrameRendered +{ + if (CACurrentMediaTime() - _lastUpdateTime < 0.5) + return; + + _lastUpdateTime = CACurrentMediaTime(); + + dispatch_async(dispatch_get_main_queue(), ^{ + + OAMapViewController *mapCtrl = [OARootViewController instance].mapPanel.mapViewController; + + CGSize viewFrame = mapCtrl.view.frame.size; + BOOL frameChanged = !CGSizeEqualToSize(_cachedViewFrame, viewFrame); + OsmAnd::PointI centerPixel = mapCtrl.mapView.getCenterPixel; + BOOL centerPixelChanged = _cachedCenterPixel != centerPixel; + BOOL anyWidgetVisible = OAMapWidgetRegistry.sharedInstance.isAnyWeatherWidgetVisible; + + if (!centerPixelChanged && !frameChanged && _cachedAnyWidgetVisible == anyWidgetVisible) + return; + + if (!anyWidgetVisible) + { + [self setMapCenterMarkerVisibility:NO]; + } + else if (anyWidgetVisible) + { + [self setMapCenterMarkerVisibility:NO]; + [self setMapCenterMarkerVisibility:YES]; + } + + _cachedCenterPixel = centerPixel; + _cachedViewFrame = viewFrame; + _cachedAnyWidgetVisible = anyWidgetVisible; + + }); +} + +- (void) setMapCenterMarkerVisibility:(BOOL)visible +{ + UIView *targetView; + OAMapViewController *mapCtrl = [OARootViewController instance].mapPanel.mapViewController; + UIView *view = mapCtrl.view; + if (view) + { + for (UIView *v in view.subviews) + { + if (v.tag == 2222) + targetView = v; + } + double w = 20; + double h = 20; + if (targetView.tag != 2222 && visible) + { + targetView = [[UIView alloc] initWithFrame:{0, 0, w, h}]; + targetView.backgroundColor = UIColor.clearColor; + targetView.tag = 2222; + + CAShapeLayer *shape = [CAShapeLayer layer]; + [shape setPath:[[UIBezierPath bezierPathWithOvalInRect:CGRectMake(2, 2, w - 4, h - 4)] CGPath]]; + shape.strokeColor = UIColor.redColor.CGColor; + shape.fillColor = UIColor.clearColor.CGColor; + [targetView.layer addSublayer:shape]; + } + if (targetView) + { + if (visible) + { + CGFloat screenScale = mapCtrl.displayDensityFactor; + OsmAnd::PointI centerPixel = mapCtrl.mapView.getCenterPixel; + targetView.frame = {centerPixel.x / screenScale - w / 2.0, centerPixel.y / screenScale - h / 2.0, w, h}; + [view addSubview:targetView]; + } + else + { + [targetView removeFromSuperview]; + } + } + } +} + @end diff --git a/Sources/Controllers/Map/Widgets/OAMapWidgetRegistry.h b/Sources/Controllers/Map/Widgets/OAMapWidgetRegistry.h index 96be3d5cd0..4d456fe274 100644 --- a/Sources/Controllers/Map/Widgets/OAMapWidgetRegistry.h +++ b/Sources/Controllers/Map/Widgets/OAMapWidgetRegistry.h @@ -56,5 +56,7 @@ - (void) clearWidgets; - (void) reorderWidgets; +- (BOOL) isAnyWeatherWidgetVisible; + @end diff --git a/Sources/Controllers/Map/Widgets/OAMapWidgetRegistry.mm b/Sources/Controllers/Map/Widgets/OAMapWidgetRegistry.mm index 8491e9fa94..3b96f01cbf 100644 --- a/Sources/Controllers/Map/Widgets/OAMapWidgetRegistry.mm +++ b/Sources/Controllers/Map/Widgets/OAMapWidgetRegistry.mm @@ -162,11 +162,28 @@ - (void) updateWidgetsInfo:(OAApplicationMode *)appMode return [self getWidgetsForPanel:OAWidgetsPanel.rightPanel]; } +- (BOOL) isAnyWeatherWidgetVisible +{ + OAApplicationMode *mode = [_settings.applicationMode get]; + BOOL weatherToolbarVisible = self.isWeatherToolbarVisible; + for (OAMapWidgetInfo *widgetInfo in OAMapWidgetRegistry.sharedInstance.getAllWidgets) + { + if (widgetInfo.getWidgetType.group == OAWidgetGroup.weather) + { + if (weatherToolbarVisible || [widgetInfo isEnabledForAppMode:mode]) + return YES; + } + } + return NO; +} + - (void) updateInfo:(OAApplicationMode *)mode expanded:(BOOL)expanded { + BOOL weatherToolbarVisible = self.isWeatherToolbarVisible; for (OAMapWidgetInfo *widgetInfo in self.getAllWidgets) { - if ([widgetInfo isEnabledForAppMode:mode] || (self.isWeatherToolbarVisible && widgetInfo.getWidgetType.group == OAWidgetGroup.weather)) + BOOL enabledForAppMode = [widgetInfo isEnabledForAppMode:mode]; + if (enabledForAppMode || (weatherToolbarVisible && widgetInfo.getWidgetType.group == OAWidgetGroup.weather)) [widgetInfo.widget updateInfo]; } } diff --git a/Sources/Controllers/Map/Widgets/OARulerWidget.mm b/Sources/Controllers/Map/Widgets/OARulerWidget.mm index 04a86ff8c0..c77fc5b671 100644 --- a/Sources/Controllers/Map/Widgets/OARulerWidget.mm +++ b/Sources/Controllers/Map/Widgets/OARulerWidget.mm @@ -705,7 +705,7 @@ - (void) drawTriangleArrowByRadius:(double)radius angle:(double)angle center:(CG - (CGPoint) getCenterPoint { - CGFloat screenScale = [UIScreen mainScreen].scale; + CGFloat screenScale = _mapViewController.displayDensityFactor; auto centerPixel = _mapViewController.mapView.getCenterPixel; return CGPointMake(centerPixel.x / screenScale, centerPixel.y / screenScale); } diff --git a/Sources/Controllers/Map/Widgets/Widgets/OAWeatherWidget.mm b/Sources/Controllers/Map/Widgets/Widgets/OAWeatherWidget.mm index 9bf70132d1..2cf8c4b098 100644 --- a/Sources/Controllers/Map/Widgets/Widgets/OAWeatherWidget.mm +++ b/Sources/Controllers/Map/Widgets/Widgets/OAWeatherWidget.mm @@ -31,6 +31,8 @@ @implementation OAWeatherWidget { OsmAnd::PointI _cachedTarget31; OsmAnd::PointI _cachedFixedPixel; + OsmAnd::PointI _cachedCenterPixel; + OsmAnd::PointI _cachedMarkerCenterPixel; OsmAnd::ZoomLevel _cachedZoom; NSDate *_cachedDate; CGSize _cachedViewFrame; @@ -64,31 +66,27 @@ - (BOOL)updateInfo OsmAnd::PointI target31 = mapCtrl.mapView.target31; OsmAnd::PointI fixedPixel = mapCtrl.mapView.fixedPixel; + OsmAnd::PointI centerPixel = mapCtrl.mapView.getCenterPixel; OsmAnd::ZoomLevel zoom = mapCtrl.mapView.zoomLevel; NSDate *date = [OAWeatherHelper roundForecastTimeToHour:mapCtrl.mapLayers.weatherDate]; NSString *bandUnit = [_formatter displayStringFromUnit:[[OAWeatherBand withWeatherBand:_band] getBandUnit]]; BOOL needToUpdate = ![_cachedBandUnit isEqualToString:bandUnit]; CGSize viewFrame = mapCtrl.view.frame.size; BOOL frameChanged = !CGSizeEqualToSize(_cachedViewFrame, viewFrame); + BOOL centerPixelChanged = _cachedCenterPixel != centerPixel; - if (_cachedTarget31 == target31 && _cachedFixedPixel == fixedPixel && _cachedZoom == zoom && !frameChanged && _cachedDate && [_cachedDate isEqualToDate:date] && !needToUpdate) + if (_cachedTarget31 == target31 && _cachedFixedPixel == fixedPixel && !centerPixelChanged && _cachedZoom == zoom && !frameChanged && _cachedDate && [_cachedDate isEqualToDate:date] && !needToUpdate) return false; - if (frameChanged) - { - [self setMapCenterMarkerVisibility:NO]; - [self setMapCenterMarkerVisibility:YES]; - } - _cachedTarget31 = target31; _cachedFixedPixel = fixedPixel; + _cachedCenterPixel = centerPixel; _cachedZoom = zoom; _cachedDate = date; _cachedBandUnit = bandUnit; _cachedViewFrame = viewFrame; - CGFloat scale = mapCtrl.view.contentScaleFactor; - OsmAnd::PointI elevated31 = [OANativeUtilities get31FromElevatedPixel:OsmAnd::PointI(viewFrame.width / 2.0 * scale, viewFrame.height / 2.0 * scale)]; + OsmAnd::PointI elevated31 = [OANativeUtilities get31FromElevatedPixel:centerPixel]; OsmAnd::WeatherTileResourcesManager::ValueRequest _request; _request.clientId = QStringLiteral("OAWeatherWidget"); @@ -128,56 +126,19 @@ - (BOOL)updateInfo { [selfWeak setText:bandValueStr.toNSString() subtext:bandUnit]; } - [selfWeak setMapCenterMarkerVisibility:YES]; } } else if (selfWeak.cachedValue != selfWeak.undefined) { selfWeak.cachedValue = selfWeak.undefined; [selfWeak setText:nil subtext:nil]; - [selfWeak setMapCenterMarkerVisibility:NO]; } }); }; _app.resourcesManager->getWeatherResourcesManager()->obtainValueAsync(_request, _callback); - return true; -} - -- (void) setMapCenterMarkerVisibility:(BOOL)visible -{ - UIView *targetView; - UIView *view = [OARootViewController instance].mapPanel.mapViewController.view; - if (view) - { - for (UIView *v in view.subviews) - { - if (v.tag == 2222) - targetView = v; - } - if (targetView.tag != 2222) - { - double w = 20; - double h = 20; - targetView = [[UIView alloc] initWithFrame:{view.frame.size.width / 2.0 - w / 2.0, view.frame.size.height / 2.0 - h / 2.0, w, h}]; - targetView.backgroundColor = UIColor.clearColor; - targetView.tag = 2222; - - CAShapeLayer *shape = [CAShapeLayer layer]; - [shape setPath:[[UIBezierPath bezierPathWithOvalInRect:CGRectMake(2, 2, w - 4, h - 4)] CGPath]]; - shape.strokeColor = UIColor.redColor.CGColor; - shape.fillColor = UIColor.clearColor.CGColor; - [targetView.layer addSublayer:shape]; - } - if (targetView) - { - if (visible) - [view addSubview:targetView]; - else - [targetView removeFromSuperview]; - } - } + return YES; } @end