From 3b057bea71e51a21f4998757af59f59aa55700c0 Mon Sep 17 00:00:00 2001 From: Johannes Date: Mon, 16 Jun 2025 20:47:13 +0200 Subject: [PATCH] Add position mode toggle for CarPlay --- .../Maps/Classes/CarPlay/CarPlayService.swift | 16 +++++++-- .../MapTemplateBuilder.swift | 35 +++++++++++++++++-- 2 files changed, 46 insertions(+), 5 deletions(-) diff --git a/iphone/Maps/Classes/CarPlay/CarPlayService.swift b/iphone/Maps/Classes/CarPlay/CarPlayService.swift index c39ee3957..2cee94ac4 100644 --- a/iphone/Maps/Classes/CarPlay/CarPlayService.swift +++ b/iphone/Maps/Classes/CarPlay/CarPlayService.swift @@ -623,22 +623,32 @@ extension CarPlayService: CarPlayRouterListener { extension CarPlayService: LocationModeListener { func processMyPositionStateModeEvent(_ mode: MWMMyPositionMode) { currentPositionMode = mode - guard let rootMapTemplate = rootMapTemplate, - let info = rootMapTemplate.userInfo as? MapInfo, - info.type == CPConstants.TemplateType.main else { + + // make sure we have a rootMapTemplate + guard let rootMapTemplate = rootMapTemplate else { + return + } + + // exit if we're navigating + guard let info = rootMapTemplate.userInfo as? MapInfo, + info.type == CPConstants.TemplateType.main else { + MapTemplateBuilder.updatePositionModeButton(mapTemplate: rootMapTemplate, newMode: mode) return } switch mode { case .follow, .followAndRotate: if !rootMapTemplate.isPanningInterfaceVisible { MapTemplateBuilder.setupDestinationButton(mapTemplate: rootMapTemplate) + MapTemplateBuilder.updatePositionModeButton(mapTemplate: rootMapTemplate, newMode: mode) } case .notFollow: if !rootMapTemplate.isPanningInterfaceVisible { MapTemplateBuilder.setupRecenterButton(mapTemplate: rootMapTemplate) + MapTemplateBuilder.updatePositionModeButton(mapTemplate: rootMapTemplate, newMode: mode) } case .pendingPosition, .notFollowNoPosition: rootMapTemplate.leadingNavigationBarButtons = [] + MapTemplateBuilder.updatePositionModeButton(mapTemplate: rootMapTemplate, newMode: mode) } } } diff --git a/iphone/Maps/Classes/CarPlay/Template Builders/MapTemplateBuilder.swift b/iphone/Maps/Classes/CarPlay/Template Builders/MapTemplateBuilder.swift index f9cf3694f..fcbaba4bd 100644 --- a/iphone/Maps/Classes/CarPlay/Template Builders/MapTemplateBuilder.swift +++ b/iphone/Maps/Classes/CarPlay/Template Builders/MapTemplateBuilder.swift @@ -5,6 +5,7 @@ final class MapTemplateBuilder { case startPanning case zoomIn case zoomOut + case positionMode } enum BarButtonType { case dismissPaning @@ -69,7 +70,10 @@ final class MapTemplateBuilder { let zoomOutButton = buildMapButton(type: .zoomOut) { _ in FrameworkHelper.zoomMap(.out) } - mapTemplate.mapButtons = [panningButton, zoomInButton, zoomOutButton] + let positionModeButton = buildMapButton(type: .positionMode) { _ in + FrameworkHelper.switchMyPositionMode() + } + mapTemplate.mapButtons = [positionModeButton, panningButton, zoomInButton, zoomOutButton] let settingsButton = buildBarButton(type: .settings) { _ in let gridTemplate = SettingsTemplateBuilder.buildGridTemplate() @@ -99,7 +103,10 @@ final class MapTemplateBuilder { let panningButton = buildMapButton(type: .startPanning) { _ in mapTemplate.showPanningInterface(animated: true) } - mapTemplate.mapButtons = [panningButton] + let positionModeButton = buildMapButton(type: .positionMode) { _ in + FrameworkHelper.switchMyPositionMode() + } + mapTemplate.mapButtons = [positionModeButton, panningButton] setupMuteAndRedirectButtons(template: mapTemplate) let endButton = buildBarButton(type: .endRoute) { _ in CarPlayService.shared.cancelCurrentTrip() @@ -117,6 +124,28 @@ final class MapTemplateBuilder { mapTemplate.leadingNavigationBarButtons = [destinationButton] } + class func updatePositionModeButton(mapTemplate: CPMapTemplate, newMode: MWMMyPositionMode) { + let button = CPMapButton(handler: { _ in + FrameworkHelper.switchMyPositionMode() + }) + + switch newMode { + case .pendingPosition: + button.image = UIImage(named: "btn_pending_light") + case .notFollowNoPosition: + button.image = UIImage(named: "btn_get_position_light") + case .notFollow: + button.image = UIImage(named: "btn_get_position_light") + case .follow: + button.image = UIImage(named: "btn_follow_light") + case .followAndRotate: + button.image = UIImage(named: "btn_follow_and_rotate_light") + } + if mapTemplate.mapButtons.count > 0 { + mapTemplate.mapButtons[0] = button + } + } + class func setupRecenterButton(mapTemplate: CPMapTemplate) { let recenterButton = buildBarButton(type: .recenter) { _ in FrameworkHelper.switchMyPositionMode() @@ -166,6 +195,8 @@ final class MapTemplateBuilder { button.image = UIImage(systemName: "plus") case .zoomOut: button.image = UIImage(systemName: "minus") + case .positionMode: + button.image = UIImage(named: "btn_pending_light") } // Remove code below once Apple has fixed its issue with the button background if #unavailable(iOS 26) {