1 contributor
//
// ControlView.swift
// USB Meter
//
// Created by Bogdan Timofte on 09/03/2020.
// Copyright © 2020 Bogdan Timofte. All rights reserved.
//
import SwiftUI
struct ControlView: View {
@EnvironmentObject private var meter: Meter
var compactLayout: Bool = false
var availableSize: CGSize? = nil
var showsHeader: Bool = true
var body: some View {
VStack(alignment: .leading, spacing: 14) {
if showsHeader {
HStack {
Text("Controls")
.font(.headline)
Spacer()
Text(meter.reportsCurrentScreenIndex ? "Device Screen" : "Page Controls")
.font(.caption.weight(.semibold))
.foregroundColor(.secondary)
}
}
if compactLayout {
if usesExpandedCompactLayout {
Spacer(minLength: 0)
VStack(spacing: 12) {
HStack(spacing: 12) {
controlButton(
title: "Prev",
symbol: "chevron.left",
tint: .indigo,
action: { meter.previousScreen() }
)
currentScreenCard
.frame(maxWidth: .infinity, minHeight: 112)
.padding(.horizontal, 14)
.meterCard(tint: meter.color, fillOpacity: 0.06, strokeOpacity: 0.10)
}
HStack(spacing: 12) {
controlButton(
title: "Rotate",
symbol: "rotate.right.fill",
tint: .orange,
action: { meter.rotateScreen() }
)
controlButton(
title: "Next",
symbol: "chevron.right",
tint: .indigo,
action: { meter.nextScreen() }
)
}
}
Spacer(minLength: 0)
} else {
HStack(spacing: 10) {
controlButton(
title: "Prev",
symbol: "chevron.left",
tint: .indigo,
action: { meter.previousScreen() }
)
currentScreenCard
.frame(maxWidth: .infinity, minHeight: 82)
.padding(.horizontal, 10)
.meterCard(tint: meter.color, fillOpacity: 0.06, strokeOpacity: 0.10)
controlButton(
title: "Rotate",
symbol: "rotate.right.fill",
tint: .orange,
action: { meter.rotateScreen() }
)
controlButton(
title: "Next",
symbol: "chevron.right",
tint: .indigo,
action: { meter.nextScreen() }
)
}
}
} else {
HStack(spacing: 12) {
controlButton(
title: "Prev",
symbol: "chevron.left",
tint: .indigo,
action: { meter.previousScreen() }
)
currentScreenCard
.frame(maxWidth: .infinity, minHeight: 92)
.padding(.horizontal, 12)
.meterCard(tint: meter.color, fillOpacity: 0.06, strokeOpacity: 0.10)
controlButton(
title: "Next",
symbol: "chevron.right",
tint: .indigo,
action: { meter.nextScreen() }
)
}
controlButton(
title: "Rotate Screen",
symbol: "rotate.right.fill",
tint: .orange,
compact: false,
action: { meter.rotateScreen() }
)
}
}
.frame(maxWidth: .infinity, maxHeight: compactLayout ? .infinity : nil, alignment: .topLeading)
}
@ViewBuilder
private var currentScreenCard: some View {
if meter.reportsCurrentScreenIndex {
Text(meter.currentScreenDescription)
.font((usesExpandedCompactLayout ? Font.title3 : .subheadline).weight(.semibold))
.multilineTextAlignment(.center)
} else {
VStack {
Image(systemName: "questionmark.square.dashed")
.font(.system(size: usesExpandedCompactLayout ? 30 : 24, weight: .semibold))
.foregroundColor(.secondary)
}
}
}
private var usesExpandedCompactLayout: Bool {
compactLayout && (availableSize?.height ?? 0) >= 520
}
private func controlButton(
title: String,
symbol: String,
tint: Color,
compact: Bool = true,
action: @escaping () -> Void
) -> some View {
Button(action: action) {
VStack(spacing: 10) {
Image(systemName: symbol)
.font(.system(size: compact ? 18 : 20, weight: .semibold))
Text(title)
.font(.footnote.weight(.semibold))
.multilineTextAlignment(.center)
}
.foregroundColor(tint)
.frame(maxWidth: .infinity, minHeight: compact ? (usesExpandedCompactLayout ? 112 : 92) : 68)
.padding(.horizontal, 8)
.meterCard(tint: tint, fillOpacity: 0.10, strokeOpacity: 0.14)
}
.buttonStyle(.plain)
}
}
struct ControlView_Previews: PreviewProvider {
static var previews: some View {
ControlView()
}
}