Newer Older
175 lines | 6.265kb
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

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

            
Bogdan Timofte authored 2 weeks ago
28
            if compactLayout {
29
                if usesExpandedCompactLayout {
30
                    Spacer(minLength: 0)
31

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

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

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

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

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

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

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

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

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

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

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

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

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

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

            
171
struct ControlView_Previews: PreviewProvider {
172
    static var previews: some View {
173
        ControlView()
174
    }
175
}