You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
140 lines
4.4 KiB
140 lines
4.4 KiB
//
|
|
// NewGameView.swift
|
|
// App
|
|
//
|
|
// Created by etudiant2 on 21/05/2025.
|
|
//
|
|
|
|
import SwiftUI
|
|
import PhotosUI
|
|
|
|
struct NewGameView: View {
|
|
@StateObject
|
|
private var vm: NewGameVM = NewGameVM()
|
|
@StateObject
|
|
private var p1: PlayerSettingsVM = PlayerSettingsVM(type: .Human)
|
|
@StateObject
|
|
private var p2: PlayerSettingsVM = PlayerSettingsVM(type: .AISimpleNegaMax)
|
|
|
|
var body: some View {
|
|
VStack {
|
|
Form {
|
|
PlayerSectionView("generic.player1.name", color: .piece1, settings: p1)
|
|
PlayerSectionView("generic.player2.name", color: .piece2, settings: p2)
|
|
|
|
HStack {
|
|
Picker("newGame.rules.title", systemImage: "slider.horizontal.3", selection: $vm.rulesType) {
|
|
ForEach(RulesType.allCases) {
|
|
Text($0.baseTranslationKey).tag($0)
|
|
}
|
|
}
|
|
|
|
// TODO: info button
|
|
// Button(action: {
|
|
// // TODO
|
|
// }) {
|
|
// Image(systemName: "questionmark.circle")
|
|
// }
|
|
}
|
|
|
|
Section(header: Label("newGame.dimensions", systemImage: "crop")) {
|
|
Stepper("newGame.dimensions.width \(vm.width)", value: $vm.width)
|
|
Stepper("newGame.dimensions.height \(vm.height)", value: $vm.height)
|
|
Stepper("newGame.dimensions.alignedTokens \(vm.alignedTokens)", value: $vm.alignedTokens)
|
|
}
|
|
|
|
// Section(header: Label("newGame.timeLimit", systemImage: "stopwatch")) {
|
|
//
|
|
// }
|
|
}
|
|
}.toolbar {
|
|
NavigationLink {
|
|
NavigationLazyView(IngameView(settings: vm, player1: p1, player2: p2))
|
|
} label: {
|
|
Label("newGame.play", systemImage: "play")
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// https://stackoverflow.com/questions/57594159/swiftui-navigationlink-loads-destination-view-immediately-without-clicking/61234030#61234030
|
|
struct NavigationLazyView<Content: View>: View {
|
|
let build: () -> Content
|
|
init(_ build: @autoclosure @escaping () -> Content) {
|
|
self.build = build
|
|
}
|
|
var body: Content {
|
|
build()
|
|
}
|
|
}
|
|
|
|
private struct PlayerSectionView: View {
|
|
private let sectionLabel: LocalizedStringKey
|
|
private let pieceColor: Color
|
|
|
|
@ObservedObject
|
|
private var settings: PlayerSettingsVM
|
|
|
|
@State private var photo: PhotosPickerItem? = nil
|
|
|
|
var body: some View {
|
|
Section(header: Label {
|
|
Text(sectionLabel)
|
|
} icon: {
|
|
Circle().fill(self.pieceColor)
|
|
}.fixedSize(horizontal: true, vertical: false)) {
|
|
Picker("newGame.player.type", selection: $settings.type) {
|
|
ForEach(PlayerType.allCases) {
|
|
Text(LocalizedStringKey($0.baseTranslationKey)).tag($0)
|
|
}
|
|
}
|
|
|
|
if (settings.type == .Human) {
|
|
TextField("newGame.player.name", text: $settings.name)
|
|
// TODO: MacOS
|
|
//.textInputSuggestions(isEnabled: true) {
|
|
//
|
|
//}
|
|
}
|
|
|
|
// // TODO: actual photo support
|
|
// Image(systemName: "camera.viewfinder").overlay {
|
|
// PhotosPicker(selection: $photo) {
|
|
// Text("newGame.player.photo.picker")
|
|
// }
|
|
// }
|
|
}
|
|
}
|
|
|
|
init(_ sectionLabel: LocalizedStringKey, color pieceColor: Color, settings: PlayerSettingsVM) {
|
|
self.sectionLabel = sectionLabel
|
|
self.pieceColor = pieceColor
|
|
self.settings = settings
|
|
}
|
|
}
|
|
|
|
extension PlayerType {
|
|
var baseTranslationKey: String {
|
|
return switch (self) {
|
|
case .Human: "generic.player.type.human"
|
|
case .AIRandom: "generic.player.type.aiRandom"
|
|
case .AIFinnishHim: "generic.player.type.aiFinnishHim"
|
|
case .AISimpleNegaMax: "generic.player.type.aiSimpleNegaMax"
|
|
}
|
|
}
|
|
}
|
|
|
|
extension RulesType {
|
|
var baseTranslationKey: LocalizedStringKey {
|
|
return switch (self) {
|
|
case .Classic: "generic.rules.classic.name"
|
|
case .TicTacToe: "generic.rules.tictactoe.name"
|
|
case .PopOut: "generic.rules.popout.name"
|
|
}
|
|
}
|
|
}
|
|
|
|
#Preview {
|
|
NewGameView()
|
|
}
|