Files
diehammer/Bunch-O--Dice/MainView.swift
T

349 lines
12 KiB
Swift

//
// PortraitView.swift
// Bunch O' Dice
//
// Created by Rory Hinnen on 22/6/18.
//
import SwiftUI
struct MainView: View {
enum MenuView: Int {
case history, add, settings
func icon() -> Image {
switch self {
case .history:
return(Image(systemName: "folder"))
case .settings:
return(Image(systemName: "square.and.pencil"))
case .add:
return(Image(systemName: "folder.badge.plus"))
}
}
}
@ViewBuilder private func myCircle() -> some View {
Circle()
.fill(Color.gray)
.blur(radius: 2.0)
.frame(width: controlSize*2.5, height: controlSize*2.5, alignment: .center)
}
@ViewBuilder private func stateView() -> some View {
switch current.state {
case .wound:
woundCalculator(controlSize: controlSize)
case .armour:
armourCalculator(controlSize: controlSize)
default:
hitCalculator(controlSize: controlSize)
}
}
@ViewBuilder private func sheetContent() -> some View {
switch sheet.state {
case .settings:
SettingsView(isShowing: $sheet.isShowing)
case .history:
HistoryView(isShowing: $sheet.isShowing)
default:
EmptyView()
}
}
@ViewBuilder func buttons(color: CGColor, label: String, value: Int) -> some View {
let frameSize = 120.0
let fontSize = 35.0
let blurSize = 5.0
ZStack {
Circle()
.fill(Color(color))
.frame(width: frameSize, height: frameSize)
.blur(radius: blurSize)
VStack{
Text(String(value))
.fontWeight(.black)
Text(label)
.font(.system(size: 20))
}
}
.foregroundColor(.primary)
.font(.system(size: fontSize))
}
//MARK: State Views
@ViewBuilder func armourCalculator(controlSize: Double) -> some View {
HStack(alignment: .top) {
Spacer()
VStack {
Text("Armour")
Group {
Text("▲")
.gesture(TapGesture() .onEnded {
current.addPenetration()
})
Text(
(current.armourPenetration > 0 ?
"+" : "") +
String(current.armourPenetration))
Text("▼")
.gesture(TapGesture() .onEnded {
current.losePenetration()
})
}
.font(.system(size: controlSize))
Text("Penetration")
}
Spacer()
VStack{
Text("Invulnerable")
Toggle("", isOn: $current.invulnerable).labelsHidden()
.padding()
}
Spacer()
VStack{
Text("Reroll")
Button("🎲", action: {
current.dice.roll(howMany: current.total)
})
.padding()
.font(.system(size: controlSize))
}
Spacer()
}
.padding()
}
@ViewBuilder func woundCalculator(controlSize: Double) -> some View {
HStack(alignment: .top) {
Spacer()
VStack {
Text("Attack")
Group {
Text("▲")
.gesture(TapGesture() .onEnded {
current.addStrength()
})
Text(String(current.strength))
Text("▼")
.gesture(TapGesture() .onEnded {
current.loseStrength()
})
}.font(.system(size: controlSize))
Text("Strength")
}
Spacer()
VStack {
Text("Toughness")
Group {
Text("▲")
.gesture(TapGesture() .onEnded {
current.addToughness()
})
Text(String(current.toughness))
Text("▼")
.gesture(TapGesture() .onEnded {
current.loseToughness()
})
}.font(.system(size: controlSize))
Text(" ")
}
Spacer()
VStack {
Text("Wound")
.multilineTextAlignment(.center)
Group {
Text("▲")
.gesture(TapGesture() .onEnded {
current.woundModifier = current.woundModifier.add()
})
Text(
(current.woundModifier.rawValue > 0 ?
"+" : "") +
String(current.woundModifier.rawValue))
Text("▼")
.gesture(TapGesture() .onEnded {
current.woundModifier = current.woundModifier.remove()
})
}.font(.system(size: controlSize))
Text("Modifier")
}
Spacer()
VStack{
Text("Reroll")
Button("🎲", action: {
current.dice.roll(howMany: current.total)
})
.padding()
.font(.system(size: controlSize))
}
Spacer()
}.padding()
}
@ViewBuilder func hitCalculator(controlSize: Double) -> some View {
HStack(alignment: .top) {
Group {
VStack {
Text("Hit")
.multilineTextAlignment(.center)
Group {
Text("▲")
.gesture(TapGesture() .onEnded {
current.modifier = current.modifier.add()
})
Text( (current.modifier.rawValue > 0 ?
"+" : "") +
String(current.modifier.rawValue))
Text("▼")
.gesture(TapGesture() .onEnded {
current.modifier = current.modifier.remove()
})
}
.font(.system(size: controlSize))
Text("Modifier")
}
VStack {
Text("Blow Up")
VStack {
Button(action: {current.dice.blowup(dice: .six)})
{Image(systemName: "die.face.6")
.foregroundColor(.primary)
}
Button(action: {current.dice.blowup(dice: .five)})
{Image(systemName: "die.face.5")
.foregroundColor(.primary)
}
}
.padding()
.font(.system(size: controlSize))
}
VStack{
Text("Reroll")
Button("🎲", action: {
current.dice.roll(howMany: current.total)
})
.padding()
.font(.system(size: controlSize))
}
}
}.padding()
}
//MARK: die views
@ViewBuilder func die(whichDie: Dice.DiceType) -> some View {
let size = 30.0
let displayColorHit = (whichDie.rawValue >= current.cutoff.rawValue) ? Color.red : Color.primary
let displayColorArmor = (whichDie.rawValue <= current.cutoff.rawValue) ? Color.red : Color.primary
let displayColorArmorText = (whichDie.rawValue < current.cutoff.rawValue) ? Color.red : Color.primary
HStack{
Text(String(current.dice.value(which: whichDie)))
.foregroundColor(current.state == .armour ?
displayColorArmorText : displayColorHit)
Image(systemName: "die.face." + String(whichDie.rawValue) + ".fill")
.foregroundColor(current.state == .armour ?
displayColorArmor : displayColorHit)
}
.font(.system(size: size))
.padding(2)
.gesture(TapGesture().onEnded {
if current.state == .hit {
if whichDie.rawValue != 1 {
current.hitCutoff = whichDie }
} else if current.state == .armour {
current.armourSave = Int(whichDie.rawValue)
}
})
}
@ViewBuilder func diePool() -> some View {
VStack(alignment: .leading) {
ForEach(Dice.DiceType.allCases.reversed(), id: \.rawValue) { i in
die(whichDie: i)
}
}
}
//MARK: Var declarations
@EnvironmentObject var current: Roll
@ObservedObject var sheet = SettingsSheet()
@State var showFillView = false
let padSize = 60.0
let controlSize = 30.0
let red = CGColor(red: 1.0, green: 0.3, blue: 0.3, alpha: 1.0)
let blue = CGColor(red: 0.3, green: 0.3, blue: 1.0, alpha: 1.0)
var body: some View {
VStack{
HStack{
Button(action: {current.state = .hit}) {
ZStack{
if current.state == .hit {myCircle()}
Text(RollState.hit.print())}}
Button(action: {current.state = .wound}) {
ZStack{
if current.state == .wound {myCircle()}
Text(RollState.wound.print())}}
Button(action: {current.state = .armour}) {
ZStack{
if current.state == .armour {myCircle()}
Text(RollState.armour.print())}}
}.font(.system(size: 60))
VStack{
HStack {
VStack {
Button(action: {showFillView.toggle()}) {
buttons(color: blue, label: "Pool", value: current.total)
}
.sheet(isPresented: $showFillView,
onDismiss: {current.dice.roll(howMany: current.total)}) {
VStack {
AddToPool()
Button("Accept", action: {showFillView.toggle()})
.padding(20)
}
}
Spacer()
Button(action: current.incrementState) {
buttons(color: red, label: current.state.text(), value: current.result)
}
}.padding(.leading, padSize)
Spacer()
diePool().padding(.trailing, padSize)
}.frame(maxHeight: 285)
stateView()
}.padding()
}
.toolbar {
ToolbarItemGroup(placement: .bottomBar) {
HStack {
Button(action: {self.sheet.state = .history}) {
MenuView.history.icon()}
Button(action: {current.history.insert(Event(total: current.result, pool: current.dice, state: current.state), at: 0)}) {
MenuView.add.icon()}
Button(action: {self.sheet.state = .settings}) {
MenuView.settings.icon()}
}
.font(.system(size: controlSize))
.foregroundColor(.primary)
}
}
.sheet(isPresented: $sheet.isShowing, content: sheetContent)}
}
struct MainView_Previews: PreviewProvider {
static var previews: some View {
MainView()
.environmentObject(Roll())
}
}