Newer Older
178 lines | 6.373kb
Bogdan Timofte authored 2 weeks ago
1
//
2
//  ControlView.swift
3
//  USB Meter
4
//
5
//  Created by Bogdan Timofte on 09/03/2020.
6
//  Copyright © 2020 Bogdan Timofte. All rights reserved.
7
//
8

            
9
import SwiftUI
10

            
11
struct ControlView: View {
12

            
13
    @EnvironmentObject private var meter: Meter
Bogdan Timofte authored 2 weeks ago
14
    var compactLayout: Bool = false
15
    var availableSize: CGSize? = nil
Bogdan Timofte authored 2 weeks ago
16
    var showsHeader: Bool = true
Bogdan Timofte authored 2 weeks ago
17

            
18
    var body: some View {
Bogdan Timofte authored 2 weeks ago
19
        VStack(alignment: .leading, spacing: 14) {
Bogdan Timofte authored 2 weeks ago
20
            if showsHeader {
21
                HStack {
22
                    Text("Controls")
23
                        .font(.headline)
24
                    Spacer()
25
                    Text(meter.reportsCurrentScreenIndex ? "Device Screen" : "Page Controls")
26
                        .font(.caption.weight(.semibold))
27
                        .foregroundColor(.secondary)
28
                }
Bogdan Timofte authored 2 weeks ago
29
            }
30

            
Bogdan Timofte authored 2 weeks ago
31
            if compactLayout {
32
                if usesExpandedCompactLayout {
33
                    Spacer(minLength: 0)
34

            
35
                    VStack(spacing: 12) {
36
                        HStack(spacing: 12) {
37
                            controlButton(
38
                                title: "Prev",
39
                                symbol: "chevron.left",
40
                                tint: .indigo,
41
                                action: { meter.previousScreen() }
42
                            )
43

            
44
                            currentScreenCard
45
                                .frame(maxWidth: .infinity, minHeight: 112)
46
                                .padding(.horizontal, 14)
47
                                .meterCard(tint: meter.color, fillOpacity: 0.06, strokeOpacity: 0.10)
48
                        }
49

            
50
                        HStack(spacing: 12) {
51
                            controlButton(
52
                                title: "Rotate",
53
                                symbol: "rotate.right.fill",
54
                                tint: .orange,
55
                                action: { meter.rotateScreen() }
56
                            )
57

            
58
                            controlButton(
59
                                title: "Next",
60
                                symbol: "chevron.right",
61
                                tint: .indigo,
62
                                action: { meter.nextScreen() }
63
                            )
64
                        }
65
                    }
66

            
67
                    Spacer(minLength: 0)
68
                } else {
69
                    HStack(spacing: 10) {
70
                        controlButton(
71
                            title: "Prev",
72
                            symbol: "chevron.left",
73
                            tint: .indigo,
74
                            action: { meter.previousScreen() }
75
                        )
Bogdan Timofte authored 2 weeks ago
76

            
Bogdan Timofte authored 2 weeks ago
77
                        currentScreenCard
78
                            .frame(maxWidth: .infinity, minHeight: 82)
79
                            .padding(.horizontal, 10)
80
                            .meterCard(tint: meter.color, fillOpacity: 0.06, strokeOpacity: 0.10)
81

            
82
                        controlButton(
83
                            title: "Rotate",
84
                            symbol: "rotate.right.fill",
85
                            tint: .orange,
86
                            action: { meter.rotateScreen() }
87
                        )
88

            
89
                        controlButton(
90
                            title: "Next",
91
                            symbol: "chevron.right",
92
                            tint: .indigo,
93
                            action: { meter.nextScreen() }
94
                        )
95
                    }
96
                }
97
            } else {
98
                HStack(spacing: 12) {
99
                    controlButton(
100
                        title: "Prev",
101
                        symbol: "chevron.left",
102
                        tint: .indigo,
103
                        action: { meter.previousScreen() }
104
                    )
105

            
106
                    currentScreenCard
107
                    .frame(maxWidth: .infinity, minHeight: 92)
108
                    .padding(.horizontal, 12)
109
                    .meterCard(tint: meter.color, fillOpacity: 0.06, strokeOpacity: 0.10)
110

            
111
                    controlButton(
112
                        title: "Next",
113
                        symbol: "chevron.right",
114
                        tint: .indigo,
115
                        action: { meter.nextScreen() }
116
                    )
117
                }
Bogdan Timofte authored 2 weeks ago
118

            
119
                controlButton(
Bogdan Timofte authored 2 weeks ago
120
                    title: "Rotate Screen",
121
                    symbol: "rotate.right.fill",
122
                    tint: .orange,
123
                    compact: false,
124
                    action: { meter.rotateScreen() }
Bogdan Timofte authored 2 weeks ago
125
                )
126
            }
127
        }
Bogdan Timofte authored 2 weeks ago
128
        .frame(maxWidth: .infinity, maxHeight: compactLayout ? .infinity : nil, alignment: .topLeading)
Bogdan Timofte authored 2 weeks ago
129
    }
130

            
Bogdan Timofte authored 2 weeks ago
131
    @ViewBuilder
132
    private var currentScreenCard: some View {
133
        if meter.reportsCurrentScreenIndex {
134
            Text(meter.currentScreenDescription)
Bogdan Timofte authored 2 weeks ago
135
                .font((usesExpandedCompactLayout ? Font.title3 : .subheadline).weight(.semibold))
Bogdan Timofte authored 2 weeks ago
136
                .multilineTextAlignment(.center)
137
        } else {
138
            VStack {
139
                Image(systemName: "questionmark.square.dashed")
Bogdan Timofte authored 2 weeks ago
140
                    .font(.system(size: usesExpandedCompactLayout ? 30 : 24, weight: .semibold))
Bogdan Timofte authored 2 weeks ago
141
                    .foregroundColor(.secondary)
142
            }
143
        }
144
    }
145

            
Bogdan Timofte authored 2 weeks ago
146
    private var usesExpandedCompactLayout: Bool {
147
        compactLayout && (availableSize?.height ?? 0) >= 520
148
    }
149

            
Bogdan Timofte authored 2 weeks ago
150
    private func controlButton(
151
        title: String,
152
        symbol: String,
153
        tint: Color,
154
        compact: Bool = true,
155
        action: @escaping () -> Void
156
    ) -> some View {
157
        Button(action: action) {
158
            VStack(spacing: 10) {
159
                Image(systemName: symbol)
160
                    .font(.system(size: compact ? 18 : 20, weight: .semibold))
161
                Text(title)
162
                    .font(.footnote.weight(.semibold))
163
                    .multilineTextAlignment(.center)
Bogdan Timofte authored 2 weeks ago
164
            }
Bogdan Timofte authored 2 weeks ago
165
            .foregroundColor(tint)
Bogdan Timofte authored 2 weeks ago
166
            .frame(maxWidth: .infinity, minHeight: compact ? (usesExpandedCompactLayout ? 112 : 92) : 68)
Bogdan Timofte authored 2 weeks ago
167
            .padding(.horizontal, 8)
168
            .meterCard(tint: tint, fillOpacity: 0.10, strokeOpacity: 0.14)
Bogdan Timofte authored 2 weeks ago
169
        }
Bogdan Timofte authored 2 weeks ago
170
        .buttonStyle(.plain)
Bogdan Timofte authored 2 weeks ago
171
    }
172
}
173

            
174
struct ControlView_Previews: PreviewProvider {
175
    static var previews: some View {
176
        ControlView()
177
    }
178
}