diff --git a/Meshtastic.xcodeproj/project.pbxproj b/Meshtastic.xcodeproj/project.pbxproj index f8bf2053..4963df39 100644 --- a/Meshtastic.xcodeproj/project.pbxproj +++ b/Meshtastic.xcodeproj/project.pbxproj @@ -87,6 +87,7 @@ DD8ED9C8289CE4B900B3B0AB /* RoutingError.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD8ED9C7289CE4B900B3B0AB /* RoutingError.swift */; }; DD90860E26F69BAE00DC5189 /* NodeMap.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD90860D26F69BAE00DC5189 /* NodeMap.swift */; }; DD913639270DFF4C00D7ACF3 /* LocalNotificationManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD913638270DFF4C00D7ACF3 /* LocalNotificationManager.swift */; }; + DD94B7402ACCE3BE00DCD1D1 /* MapSettingsForm.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD94B73F2ACCE3BE00DCD1D1 /* MapSettingsForm.swift */; }; DD964FBD296E6B01007C176F /* EmojiOnlyTextField.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD964FBC296E6B01007C176F /* EmojiOnlyTextField.swift */; }; DD964FBF296E76EF007C176F /* WaypointFormView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD964FBE296E76EF007C176F /* WaypointFormView.swift */; }; DD964FC2297272AE007C176F /* WaypointEntityExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD964FC1297272AE007C176F /* WaypointEntityExtension.swift */; }; @@ -298,6 +299,7 @@ DD90860A26F645B700DC5189 /* Meshtastic.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = Meshtastic.entitlements; sourceTree = ""; }; DD90860D26F69BAE00DC5189 /* NodeMap.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NodeMap.swift; sourceTree = ""; }; DD913638270DFF4C00D7ACF3 /* LocalNotificationManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LocalNotificationManager.swift; sourceTree = ""; }; + DD94B73F2ACCE3BE00DCD1D1 /* MapSettingsForm.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MapSettingsForm.swift; sourceTree = ""; }; DD964FBC296E6B01007C176F /* EmojiOnlyTextField.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EmojiOnlyTextField.swift; sourceTree = ""; }; DD964FBE296E76EF007C176F /* WaypointFormView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WaypointFormView.swift; sourceTree = ""; }; DD964FC029724F6D007C176F /* MeshtasticDataModelV6.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = MeshtasticDataModelV6.xcdatamodel; sourceTree = ""; }; @@ -819,6 +821,7 @@ DDDB26402AABEF7B003AFCB7 /* Helpers */ = { isa = PBXGroup; children = ( + DD94B73F2ACCE3BE00DCD1D1 /* MapSettingsForm.swift */, DDDB26432AAC0206003AFCB7 /* NodeDetail.swift */, DDDB26452AACC0B7003AFCB7 /* NodeInfoItem.swift */, DDDB26412AABF655003AFCB7 /* NodeListItem.swift */, @@ -1140,6 +1143,7 @@ DD23A50F26FD1B4400D9B90C /* PeripheralModel.swift in Sources */, DDB6ABDB28B0AC6000384BA1 /* DistanceText.swift in Sources */, DD5E520D298EE33B00D21B61 /* storeforward.pb.swift in Sources */, + DD94B7402ACCE3BE00DCD1D1 /* MapSettingsForm.swift in Sources */, DD964FC2297272AE007C176F /* WaypointEntityExtension.swift in Sources */, 6DA39D8E2A92DC52007E311C /* MeshtasticAppDelegate.swift in Sources */, DD5E520A298EE33B00D21B61 /* channel.pb.swift in Sources */, diff --git a/Meshtastic/Views/Nodes/Helpers/MapSettingsForm.swift b/Meshtastic/Views/Nodes/Helpers/MapSettingsForm.swift new file mode 100644 index 00000000..3093388b --- /dev/null +++ b/Meshtastic/Views/Nodes/Helpers/MapSettingsForm.swift @@ -0,0 +1,96 @@ +// +// MapSettingsForm.swift +// Meshtastic +// +// Created by Garth Vander Houwen on 10/3/23. +// + +import SwiftUI +#if canImport(MapKit) +import MapKit +#endif + +@available(iOS 17.0, macOS 14.0, *) +struct MapSettingsForm: View { + @Environment(\.dismiss) private var dismiss + @State var nodeHistory = false + @State var routeLines = false + @State var convexHull = false + @State var traffic: Bool = false + @State var pointsOfInterest: Bool = false + @State var mapLayer: MapLayer = .standard + + var body: some View { + + VStack { + Form { + Section(header: Text("Map Options")) { + Picker(selection: $mapLayer, label: Text("")) { + ForEach(MapLayer.allCases, id: \.self) { layer in + if layer != MapLayer.offline { + Text(layer.localized) + } + } + } + .pickerStyle(SegmentedPickerStyle()) + .padding(.top, 5) + .padding(.bottom, 5) + Toggle(isOn: $nodeHistory) { + Label("Node History", systemImage: "building.columns.fill") + } + .toggleStyle(SwitchToggleStyle(tint: .accentColor)) + .onTapGesture { + self.nodeHistory.toggle() + UserDefaults.enableMapNodeHistoryPins = self.nodeHistory + } + Toggle(isOn: $routeLines) { + Label("Route Lines", systemImage: "road.lanes") + } + .toggleStyle(SwitchToggleStyle(tint: .accentColor)) + .onTapGesture { + self.routeLines.toggle() + UserDefaults.enableMapRouteLines = self.routeLines + } + Toggle(isOn: $convexHull) { + Label("Convex Hull", systemImage: "button.angledbottom.horizontal.right") + } + .toggleStyle(SwitchToggleStyle(tint: .accentColor)) + .onTapGesture { + self.convexHull.toggle() + UserDefaults.enableMapConvexHull = self.convexHull + } + Toggle(isOn: $traffic) { + Label("Traffic", systemImage: "car") + } + .toggleStyle(SwitchToggleStyle(tint: .accentColor)) + .onTapGesture { + self.traffic.toggle() + UserDefaults.enableMapTraffic = self.traffic + } + Toggle(isOn: $pointsOfInterest) { + Label("Points of Interest", systemImage: "mappin.and.ellipse") + } + .toggleStyle(SwitchToggleStyle(tint: .accentColor)) + .onTapGesture { + self.pointsOfInterest.toggle() + UserDefaults.enableMapPointsOfInterest = self.pointsOfInterest + } + } + } +#if targetEnvironment(macCatalyst) + Button { + dismiss() + } label: { + Label("close", systemImage: "xmark") + } + .buttonStyle(.bordered) + .buttonBorderShape(.capsule) + .controlSize(.large) + .padding() +#endif + } + .presentationDetents([.fraction(0.60)]) + //.presentationDetents([.medium, .large]) + .presentationDragIndicator(.automatic) + } +} diff --git a/Meshtastic/Views/Nodes/Helpers/NodeMapSwiftUI.swift b/Meshtastic/Views/Nodes/Helpers/NodeMapSwiftUI.swift index 1eccc3c6..05e266d7 100644 --- a/Meshtastic/Views/Nodes/Helpers/NodeMapSwiftUI.swift +++ b/Meshtastic/Views/Nodes/Helpers/NodeMapSwiftUI.swift @@ -24,7 +24,7 @@ struct NodeMapSwiftUI: View { /// Map State User Defaults @AppStorage("meshMapShowNodeHistory") private var showNodeHistory = false @AppStorage("meshMapShowRouteLines") private var showRouteLines = false - @AppStorage("meshMapShowConvexHull") private var showConvexHull = true + @AppStorage("enableMapConvexHull") private var showConvexHull = true @AppStorage("enableMapTraffic") private var showTraffic: Bool = true @AppStorage("enableMapPointsOfInterest") private var showPointsOfInterest: Bool = true @AppStorage("mapLayer") private var selectedMapLayer: MapLayer = .hybrid @@ -113,8 +113,9 @@ struct NodeMapSwiftUI: View { ZStack { if position.latest { Circle() - .foregroundStyle(Color(nodeColor.lighter()).opacity(0.4)) - .frame(width: 60, height: 60) + .fill(Color(nodeColor.lighter()).opacity(0.4).shadow(.drop(color: Color(nodeColor).isLight() ? .black : .white, radius: 5))) + .foregroundStyle(Color(nodeColor.lighter()).opacity(0.3)) + .frame(width: 50, height: 50) if pf.contains(.Heading) { Image(systemName: pf.contains(.Speed) && position.speed > 1 ? "location.north" : "octagon") .symbolEffect(.pulse.byLayer)