@@ -18,10 +18,10 @@ struct MeterView: View {
|
||
| 18 | 18 |
@State var recordingViewVisibility: Bool = false |
| 19 | 19 |
@State var measurementsViewVisibility: Bool = false |
| 20 | 20 |
private var myBounds: CGRect { UIScreen.main.bounds }
|
| 21 |
- |
|
| 22 |
- private let actionColumns = [ |
|
| 23 |
- GridItem(.adaptive(minimum: 112, maximum: 180), spacing: 12) |
|
| 24 |
- ] |
|
| 21 |
+ private let actionButtonSpacing: CGFloat = 12 |
|
| 22 |
+ private let actionButtonMaxWidth: CGFloat = 156 |
|
| 23 |
+ private let actionButtonMinWidth: CGFloat = 88 |
|
| 24 |
+ private let actionButtonHeight: CGFloat = 108 |
|
| 25 | 25 |
|
| 26 | 26 |
var body: some View {
|
| 27 | 27 |
ScrollView {
|
@@ -112,33 +112,42 @@ struct MeterView: View {
|
||
| 112 | 112 |
} |
| 113 | 113 |
|
| 114 | 114 |
private var actionGrid: some View {
|
| 115 |
- LazyVGrid(columns: actionColumns, spacing: 12) {
|
|
| 116 |
- meterSheetButton(icon: "square.grid.2x2.fill", title: meter.dataGroupsTitle, tint: .teal) {
|
|
| 117 |
- dataGroupsViewVisibility.toggle() |
|
| 118 |
- } |
|
| 119 |
- .sheet(isPresented: $dataGroupsViewVisibility) {
|
|
| 120 |
- DataGroupsView(visibility: $dataGroupsViewVisibility) |
|
| 121 |
- .environmentObject(meter) |
|
| 122 |
- } |
|
| 115 |
+ GeometryReader { proxy in
|
|
| 116 |
+ let buttonWidth = actionButtonWidth(for: proxy.size.width) |
|
| 123 | 117 |
|
| 124 |
- if meter.supportsRecordingView {
|
|
| 125 |
- meterSheetButton(icon: "gauge.with.dots.needle.50percent", title: "Charge Record", tint: .pink) {
|
|
| 126 |
- recordingViewVisibility.toggle() |
|
| 127 |
- } |
|
| 128 |
- .sheet(isPresented: $recordingViewVisibility) {
|
|
| 129 |
- RecordingView(visibility: $recordingViewVisibility) |
|
| 130 |
- .environmentObject(meter) |
|
| 131 |
- } |
|
| 132 |
- } |
|
| 118 |
+ HStack {
|
|
| 119 |
+ Spacer(minLength: 0) |
|
| 120 |
+ HStack(spacing: actionButtonSpacing) {
|
|
| 121 |
+ meterSheetButton(icon: "square.grid.2x2.fill", title: meter.dataGroupsTitle, tint: .teal, width: buttonWidth) {
|
|
| 122 |
+ dataGroupsViewVisibility.toggle() |
|
| 123 |
+ } |
|
| 124 |
+ .sheet(isPresented: $dataGroupsViewVisibility) {
|
|
| 125 |
+ DataGroupsView(visibility: $dataGroupsViewVisibility) |
|
| 126 |
+ .environmentObject(meter) |
|
| 127 |
+ } |
|
| 133 | 128 |
|
| 134 |
- meterSheetButton(icon: "clock.arrow.circlepath", title: "App History", tint: .blue) {
|
|
| 135 |
- measurementsViewVisibility.toggle() |
|
| 136 |
- } |
|
| 137 |
- .sheet(isPresented: $measurementsViewVisibility) {
|
|
| 138 |
- MeasurementsView(visibility: $measurementsViewVisibility) |
|
| 139 |
- .environmentObject(meter.measurements) |
|
| 129 |
+ if meter.supportsRecordingView {
|
|
| 130 |
+ meterSheetButton(icon: "gauge.with.dots.needle.50percent", title: "Charge Record", tint: .pink, width: buttonWidth) {
|
|
| 131 |
+ recordingViewVisibility.toggle() |
|
| 132 |
+ } |
|
| 133 |
+ .sheet(isPresented: $recordingViewVisibility) {
|
|
| 134 |
+ RecordingView(visibility: $recordingViewVisibility) |
|
| 135 |
+ .environmentObject(meter) |
|
| 136 |
+ } |
|
| 137 |
+ } |
|
| 138 |
+ |
|
| 139 |
+ meterSheetButton(icon: "clock.arrow.circlepath", title: "App History", tint: .blue, width: buttonWidth) {
|
|
| 140 |
+ measurementsViewVisibility.toggle() |
|
| 141 |
+ } |
|
| 142 |
+ .sheet(isPresented: $measurementsViewVisibility) {
|
|
| 143 |
+ MeasurementsView(visibility: $measurementsViewVisibility) |
|
| 144 |
+ .environmentObject(meter.measurements) |
|
| 145 |
+ } |
|
| 146 |
+ } |
|
| 147 |
+ Spacer(minLength: 0) |
|
| 140 | 148 |
} |
| 141 | 149 |
} |
| 150 |
+ .frame(height: actionButtonHeight) |
|
| 142 | 151 |
} |
| 143 | 152 |
|
| 144 | 153 |
fileprivate func connectionControlButton() -> some View {
|
@@ -184,7 +193,7 @@ struct MeterView: View {
|
||
| 184 | 193 |
} |
| 185 | 194 |
} |
| 186 | 195 |
|
| 187 |
- fileprivate func meterSheetButton(icon: String, title: String, tint: Color, action: @escaping () -> Void) -> some View {
|
|
| 196 |
+ fileprivate func meterSheetButton(icon: String, title: String, tint: Color, width: CGFloat, action: @escaping () -> Void) -> some View {
|
|
| 188 | 197 |
Button(action: action) {
|
| 189 | 198 |
VStack(spacing: 10) {
|
| 190 | 199 |
Image(systemName: icon) |
@@ -198,13 +207,22 @@ struct MeterView: View {
|
||
| 198 | 207 |
.minimumScaleFactor(0.9) |
| 199 | 208 |
} |
| 200 | 209 |
.foregroundColor(tint) |
| 201 |
- .frame(maxWidth: .infinity, minHeight: 106) |
|
| 202 |
- .padding(.horizontal, 8) |
|
| 210 |
+ .frame(width: width, height: actionButtonHeight) |
|
| 203 | 211 |
.meterCard(tint: tint, fillOpacity: 0.18, strokeOpacity: 0.22) |
| 204 | 212 |
} |
| 205 | 213 |
.buttonStyle(.plain) |
| 206 | 214 |
} |
| 207 | 215 |
|
| 216 |
+ private var visibleActionButtonCount: CGFloat {
|
|
| 217 |
+ meter.supportsRecordingView ? 3 : 2 |
|
| 218 |
+ } |
|
| 219 |
+ |
|
| 220 |
+ private func actionButtonWidth(for availableWidth: CGFloat) -> CGFloat {
|
|
| 221 |
+ let spacingWidth = actionButtonSpacing * max(visibleActionButtonCount - 1, 0) |
|
| 222 |
+ let fittedWidth = floor((availableWidth - spacingWidth) / visibleActionButtonCount) |
|
| 223 |
+ return min(actionButtonMaxWidth, max(actionButtonMinWidth, fittedWidth)) |
|
| 224 |
+ } |
|
| 225 |
+ |
|
| 208 | 226 |
private var statusText: String {
|
| 209 | 227 |
switch meter.operationalState {
|
| 210 | 228 |
case .notPresent: |