diff --git a/.DS_Store b/.DS_Store index cccd18a..8112cff 100644 Binary files a/.DS_Store and b/.DS_Store differ diff --git a/ArkitDoushiQi/ArkitDoushiQi.xcodeproj/project.pbxproj b/ArkitDoushiQi/ArkitDoushiQi.xcodeproj/project.pbxproj index e62728e..e0dd8c0 100644 --- a/ArkitDoushiQi/ArkitDoushiQi.xcodeproj/project.pbxproj +++ b/ArkitDoushiQi/ArkitDoushiQi.xcodeproj/project.pbxproj @@ -30,8 +30,11 @@ C24659E92BF60FAA004E80D5 /* ButtonComponent.swift in Sources */ = {isa = PBXBuildFile; fileRef = C24659E82BF60FAA004E80D5 /* ButtonComponent.swift */; }; C24DAB5C2C061DC700681CD0 /* AI.swift in Sources */ = {isa = PBXBuildFile; fileRef = C24DAB5B2C061DC700681CD0 /* AI.swift */; }; C24DAB5E2C061E3A00681CD0 /* Language.swift in Sources */ = {isa = PBXBuildFile; fileRef = C24DAB5D2C061E3A00681CD0 /* Language.swift */; }; + C24DAB622C062DBC00681CD0 /* ProfileEdit.swift in Sources */ = {isa = PBXBuildFile; fileRef = C24DAB612C062DBC00681CD0 /* ProfileEdit.swift */; }; C25220EE2C00AC7E0026B71F /* GameParametersMenuView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C25220ED2C00AC7E0026B71F /* GameParametersMenuView.swift */; }; - C25220F32C00AF490026B71F /* EditComponent.swift in Sources */ = {isa = PBXBuildFile; fileRef = C25220F22C00AF490026B71F /* EditComponent.swift */; }; + C25220F32C00AF490026B71F /* EditTextComponent.swift in Sources */ = {isa = PBXBuildFile; fileRef = C25220F22C00AF490026B71F /* EditTextComponent.swift */; }; + C2F015042C09BC6B000F7221 /* KeyboardReadable.swift in Sources */ = {isa = PBXBuildFile; fileRef = C2F015032C09BC6B000F7221 /* KeyboardReadable.swift */; }; + C2F015062C09C384000F7221 /* EditImageComponent.swift in Sources */ = {isa = PBXBuildFile; fileRef = C2F015052C09C384000F7221 /* EditImageComponent.swift */; }; C2F394082C0462400070B4F6 /* PhotoButtonComponent.swift in Sources */ = {isa = PBXBuildFile; fileRef = C2F394072C0462400070B4F6 /* PhotoButtonComponent.swift */; }; C2F3940B2C0463940070B4F6 /* ProfileComponent.swift in Sources */ = {isa = PBXBuildFile; fileRef = C2F3940A2C0463940070B4F6 /* ProfileComponent.swift */; }; /* End PBXBuildFile section */ @@ -80,8 +83,11 @@ C24659E82BF60FAA004E80D5 /* ButtonComponent.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ButtonComponent.swift; sourceTree = ""; }; C24DAB5B2C061DC700681CD0 /* AI.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AI.swift; sourceTree = ""; }; C24DAB5D2C061E3A00681CD0 /* Language.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Language.swift; sourceTree = ""; }; + C24DAB612C062DBC00681CD0 /* ProfileEdit.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProfileEdit.swift; sourceTree = ""; }; C25220ED2C00AC7E0026B71F /* GameParametersMenuView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GameParametersMenuView.swift; sourceTree = ""; }; - C25220F22C00AF490026B71F /* EditComponent.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EditComponent.swift; sourceTree = ""; }; + C25220F22C00AF490026B71F /* EditTextComponent.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EditTextComponent.swift; sourceTree = ""; }; + C2F015032C09BC6B000F7221 /* KeyboardReadable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KeyboardReadable.swift; sourceTree = ""; }; + C2F015052C09C384000F7221 /* EditImageComponent.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EditImageComponent.swift; sourceTree = ""; }; C2F394072C0462400070B4F6 /* PhotoButtonComponent.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PhotoButtonComponent.swift; sourceTree = ""; }; C2F3940A2C0463940070B4F6 /* ProfileComponent.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProfileComponent.swift; sourceTree = ""; }; /* End PBXFileReference section */ @@ -192,7 +198,11 @@ C205A2BC2BF373380097BD93 /* Views */ = { isa = PBXGroup; children = ( +<<<<<<< HEAD + C2F015022C09BC56000F7221 /* EventTriggers */, +======= 1607D9C82C09CF4C000AB3F2 /* PartyEnregistery */, +>>>>>>> 40ae735863a246c32eefd036739aa3e93055aaf4 C24DAB5A2C061DAA00681CD0 /* Enum */, C25220F02C00AD7F0026B71F /* Components */, C25220EC2C00AC530026B71F /* GameParametersMenu */, @@ -268,17 +278,27 @@ C20310D52BFCB5FB0031657D /* PickerComponent.swift */, C20310D92BFCC8600031657D /* ToggleComponent.swift */, C24659E82BF60FAA004E80D5 /* ButtonComponent.swift */, - C25220F22C00AF490026B71F /* EditComponent.swift */, + C25220F22C00AF490026B71F /* EditTextComponent.swift */, C2F394072C0462400070B4F6 /* PhotoButtonComponent.swift */, + C2F015052C09C384000F7221 /* EditImageComponent.swift */, ); path = Controls; sourceTree = ""; }; + C2F015022C09BC56000F7221 /* EventTriggers */ = { + isa = PBXGroup; + children = ( + C2F015032C09BC6B000F7221 /* KeyboardReadable.swift */, + ); + path = EventTriggers; + sourceTree = ""; + }; C2F394092C04636C0070B4F6 /* Visuals */ = { isa = PBXGroup; children = ( 1607D9CD2C09CFD3000AB3F2 /* ItemCollectionParty.swift */, C2F3940A2C0463940070B4F6 /* ProfileComponent.swift */, + C24DAB612C062DBC00681CD0 /* ProfileEdit.swift */, ); path = Visuals; sourceTree = ""; @@ -419,6 +439,11 @@ C205A2B92BF373360097BD93 /* ContentView.swift in Sources */, 82CE59EF2C0460E500ADEE24 /* SpriteMoople.swift in Sources */, 82CE59E92C045D1100ADEE24 /* GameScene.swift in Sources */, +<<<<<<< HEAD + C2F015062C09C384000F7221 /* EditImageComponent.swift in Sources */, + 82F9D3312BFE3A9F009EDFAF /* HistoryGameDetail.swift in Sources */, +======= +>>>>>>> 40ae735863a246c32eefd036739aa3e93055aaf4 C24659E92BF60FAA004E80D5 /* ButtonComponent.swift in Sources */, C24DAB5E2C061E3A00681CD0 /* Language.swift in Sources */, C2F394082C0462400070B4F6 /* PhotoButtonComponent.swift in Sources */, @@ -426,16 +451,25 @@ C20310D82BFCC2410031657D /* GeneralParametersMenuView.swift in Sources */, 168CD4FF2C06265B00419510 /* LanguageSettings.swift in Sources */, C2F3940B2C0463940070B4F6 /* ProfileComponent.swift in Sources */, + C2F015042C09BC6B000F7221 /* KeyboardReadable.swift in Sources */, C205A2B72BF373360097BD93 /* ArkitDoushiQiApp.swift in Sources */, 1607D9CE2C09CFD3000AB3F2 /* ItemCollectionParty.swift in Sources */, C24DAB5C2C061DC700681CD0 /* AI.swift in Sources */, +<<<<<<< HEAD + C25220F32C00AF490026B71F /* EditTextComponent.swift in Sources */, +======= C25220F32C00AF490026B71F /* EditComponent.swift in Sources */, 1607D9CB2C09CF4C000AB3F2 /* Stub.swift in Sources */, +>>>>>>> 40ae735863a246c32eefd036739aa3e93055aaf4 C20310D62BFCB5FB0031657D /* PickerComponent.swift in Sources */, 82CE59EB2C045E3800ADEE24 /* GameView.swift in Sources */, C20310DA2BFCC8600031657D /* ToggleComponent.swift in Sources */, C25220EE2C00AC7E0026B71F /* GameParametersMenuView.swift in Sources */, +<<<<<<< HEAD + C24DAB622C062DBC00681CD0 /* ProfileEdit.swift in Sources */, +======= 1607D9CC2C09CF4C000AB3F2 /* PartyEnregistery.swift in Sources */, +>>>>>>> 40ae735863a246c32eefd036739aa3e93055aaf4 ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/ArkitDoushiQi/ArkitDoushiQi/Assets.xcassets/Image.imageset/Contents.json b/ArkitDoushiQi/ArkitDoushiQi/Assets.xcassets/images/profil.imageset/Contents.json similarity index 88% rename from ArkitDoushiQi/ArkitDoushiQi/Assets.xcassets/Image.imageset/Contents.json rename to ArkitDoushiQi/ArkitDoushiQi/Assets.xcassets/images/profil.imageset/Contents.json index a19a549..42378de 100644 --- a/ArkitDoushiQi/ArkitDoushiQi/Assets.xcassets/Image.imageset/Contents.json +++ b/ArkitDoushiQi/ArkitDoushiQi/Assets.xcassets/images/profil.imageset/Contents.json @@ -1,6 +1,7 @@ { "images" : [ { + "filename" : "Unknown.jpeg", "idiom" : "universal", "scale" : "1x" }, diff --git a/ArkitDoushiQi/ArkitDoushiQi/Assets.xcassets/images/profil.imageset/Unknown.jpeg b/ArkitDoushiQi/ArkitDoushiQi/Assets.xcassets/images/profil.imageset/Unknown.jpeg new file mode 100644 index 0000000..9148723 Binary files /dev/null and b/ArkitDoushiQi/ArkitDoushiQi/Assets.xcassets/images/profil.imageset/Unknown.jpeg differ diff --git a/ArkitDoushiQi/ArkitDoushiQi/Views/Components/Controls/EditComponent.swift b/ArkitDoushiQi/ArkitDoushiQi/Views/Components/Controls/EditComponent.swift deleted file mode 100644 index 073ca2b..0000000 --- a/ArkitDoushiQi/ArkitDoushiQi/Views/Components/Controls/EditComponent.swift +++ /dev/null @@ -1,27 +0,0 @@ -// -// EditComponent.swift -// ArkitDoushiQi -// -// Created by Johan LACHENAL on 24/05/2024. -// - -import SwiftUI - -struct EditComponent: View { - let explanation : String - let value : String - @State private var name = "Joueur 1" - var body: some View { - Form { - Section(header : Text(explanation)) { - TextField(value, text : $name) - } - } - } -} - -struct EditComponent_Previews: PreviewProvider { - static var previews: some View { - EditComponent(explanation: "Nom du joueur 1", value : "Joueur 1") - } -} diff --git a/ArkitDoushiQi/ArkitDoushiQi/Views/Components/Controls/EditImageComponent.swift b/ArkitDoushiQi/ArkitDoushiQi/Views/Components/Controls/EditImageComponent.swift new file mode 100644 index 0000000..113e6dd --- /dev/null +++ b/ArkitDoushiQi/ArkitDoushiQi/Views/Components/Controls/EditImageComponent.swift @@ -0,0 +1,74 @@ +// +// EditImageComponent.swift +// ArkitDoushiQi +// +// Created by Johan LACHENAL on 31/05/2024. +// + +import SwiftUI +import PhotosUI + +struct EditImageComponent: View { + @State private var avatarItem: PhotosPickerItem? + @State private var avatarImage: Image? + let color: Color + let profileWidth: CGFloat + let profileHeight: CGFloat + let defaultImage: Image + let imageTextChange: String + var body: some View { + HStack { + + VStack { + HStack { + GeometryReader { geometry in + ZStack { + // Background color + color + + // Profile Image + ProfileComponent(color: color, profileWidth: profileWidth, profileHeight: profileHeight, image: avatarImage ?? defaultImage + ) + } + // Ensure the ZStack takes the size of the GeometryReader + .frame(width: geometry.size.width, height: geometry.size.height) + .clipShape(Circle()) + } + .aspectRatio(1, contentMode: .fit) + .frame(width: profileWidth, height: profileHeight) // Optional fixed size + + PhotosPicker(selection: $avatarItem, matching: .images) { + Text(imageTextChange) + } + .onChange(of: avatarItem) { newValue in + if let newItem = newValue { + Task { + if let data = try? await newItem.loadTransferable(type: Data.self), + let uiImage = UIImage(data: data) { + avatarImage = Image(uiImage: uiImage) + } else { + print("Failed to load image") + } + } + } + } + } + } + } + } +} + +struct EditImageComponent_Previews: PreviewProvider { + static var previews: some View { + EditImageComponent( + color: Color(.red), + profileWidth: 100, + profileHeight: 100, + defaultImage: Image("profil"), + imageTextChange: "Changer d'avatar" + ) + .previewLayout(.sizeThatFits) + .padding() + } +} + diff --git a/ArkitDoushiQi/ArkitDoushiQi/Views/Components/Controls/EditTextComponent.swift b/ArkitDoushiQi/ArkitDoushiQi/Views/Components/Controls/EditTextComponent.swift new file mode 100644 index 0000000..a16a7fb --- /dev/null +++ b/ArkitDoushiQi/ArkitDoushiQi/Views/Components/Controls/EditTextComponent.swift @@ -0,0 +1,30 @@ +// +// EditComponent.swift +// ArkitDoushiQi +// +// Created by Johan LACHENAL on 24/05/2024. +// + +import SwiftUI + +struct EditTextComponent: View { + let explanation : String + @State private var name : String + init(explanation: String, value: String) { + self.explanation = explanation + self.name = value + } + var body: some View { + Form { + Section(header : Text(explanation)) { + TextField(name, text : $name) + } + } + } +} + +struct EditTextComponent_Previews: PreviewProvider { + static var previews: some View { + EditTextComponent(explanation: "Nom du Joueur 1", value: "Joueur 1") + } +} diff --git a/ArkitDoushiQi/ArkitDoushiQi/Views/Components/Visuals/ProfileComponent.swift b/ArkitDoushiQi/ArkitDoushiQi/Views/Components/Visuals/ProfileComponent.swift index 4f12d75..96e5811 100644 --- a/ArkitDoushiQi/ArkitDoushiQi/Views/Components/Visuals/ProfileComponent.swift +++ b/ArkitDoushiQi/ArkitDoushiQi/Views/Components/Visuals/ProfileComponent.swift @@ -8,13 +8,41 @@ import SwiftUI struct ProfileComponent: View { + let color : Color + let profileWidth : CGFloat + let profileHeight : CGFloat + let image : Image var body: some View { - Text(/*@START_MENU_TOKEN@*/"Hello, World!"/*@END_MENU_TOKEN@*/) + GeometryReader { geometry in + ZStack { + // Background color + color + + // Profile Image + image + .resizable() + .scaledToFill() + .clipShape(Circle()) + .frame(width: geometry.size.width * 0.9, height: geometry.size.height * 0.95) // Smaller than the ZStack + } + // Ensure the ZStack takes the size of the GeometryReader + .frame(width: geometry.size.width, height: geometry.size.height) + .clipShape(Circle()) + } + .aspectRatio(1, contentMode: .fit) + .frame(width: profileWidth, height: profileHeight) // Optional fixed size } } struct ProfileComponent_Previews: PreviewProvider { static var previews: some View { - ProfileComponent() + ProfileComponent( + color: Color(.red), + profileWidth: 200, + profileHeight : 200, + image: Image("profil") + ) + .previewLayout(.sizeThatFits) + .padding() } } diff --git a/ArkitDoushiQi/ArkitDoushiQi/Views/Components/Visuals/ProfileEdit.swift b/ArkitDoushiQi/ArkitDoushiQi/Views/Components/Visuals/ProfileEdit.swift new file mode 100644 index 0000000..4da9202 --- /dev/null +++ b/ArkitDoushiQi/ArkitDoushiQi/Views/Components/Visuals/ProfileEdit.swift @@ -0,0 +1,43 @@ +// +// ProfileEdit.swift +// ArkitDoushiQi +// +// Created by Johan LACHENAL on 28/05/2024. +// + +import SwiftUI + +struct ProfileEdit: View { + let color : Color + let profileWidth : CGFloat + let profileHeight : CGFloat + let defaultImage: Image + let imageTextChange : String + var body: some View { + VStack(alignment: .leading) { + EditImageComponent( + color: color, + profileWidth: profileWidth, + profileHeight: profileHeight, + defaultImage: defaultImage, + imageTextChange: imageTextChange + ).padding(EdgeInsets(top: 0, leading: 32, bottom: 0, trailing: 32)) + VStack(alignment: .trailing) { + HStack { + EditTextComponent(explanation: "Nom du Joueur 1", value: "Joueur 1") + } + } + } + } +} + +struct ProfileEdit_Previews: PreviewProvider { + static var previews: some View { + ProfileEdit(color: Color(.red), + profileWidth: 100, + profileHeight: 100, + defaultImage: Image("profil"), + imageTextChange: "Changer d'avatar" + ) + } +} diff --git a/ArkitDoushiQi/ArkitDoushiQi/Views/EventTriggers/KeyboardReadable.swift b/ArkitDoushiQi/ArkitDoushiQi/Views/EventTriggers/KeyboardReadable.swift new file mode 100644 index 0000000..dec17a6 --- /dev/null +++ b/ArkitDoushiQi/ArkitDoushiQi/Views/EventTriggers/KeyboardReadable.swift @@ -0,0 +1,31 @@ +// +// KeyboardReadable.swift +// ArkitDoushiQi +// +// Created by Johan LACHENAL on 31/05/2024. +// + +import Foundation +import Combine +import UIKit + + +// Publisher to read keyboard changes. +protocol KeyboardReadable { + var keyboardPublisher: AnyPublisher { get } +} + +extension KeyboardReadable { + var keyboardPublisher: AnyPublisher { + Publishers.Merge( + NotificationCenter.default + .publisher(for: UIResponder.keyboardWillShowNotification) + .map { _ in true }, + + NotificationCenter.default + .publisher(for: UIResponder.keyboardWillHideNotification) + .map { _ in false } + ) + .eraseToAnyPublisher() + } +} diff --git a/ArkitDoushiQi/ArkitDoushiQi/Views/GameParametersMenu/GameParametersMenuView.swift b/ArkitDoushiQi/ArkitDoushiQi/Views/GameParametersMenu/GameParametersMenuView.swift index 79893b5..13d6346 100644 --- a/ArkitDoushiQi/ArkitDoushiQi/Views/GameParametersMenu/GameParametersMenuView.swift +++ b/ArkitDoushiQi/ArkitDoushiQi/Views/GameParametersMenu/GameParametersMenuView.swift @@ -22,9 +22,10 @@ enum Rules: String, CaseIterable, Identifiable, Hashable { var id: String { self.rawValue } } -struct GameParametersMenuView: View { +struct GameParametersMenuView: View, KeyboardReadable { @State private var selectedAIOption: AIT = .RandomAction @State private var selectedRulesOption: Rules = .Regular + @State private var isKeyboardVisible = false var body: some View { NavigationView { VStack(alignment: .leading) { @@ -37,12 +38,16 @@ struct GameParametersMenuView: View { PickerComponent(title: "Sélectionne une IA :", selectedOption: $selectedAIOption, options: AIT.allCases) - EditComponent(explanation: "Nom du joueur 1", value: "Joueur 1") - EditComponent(explanation: "Nom du joueur 2",value: "Joueur 2") - ButtonComponent(title: "Lancer la partie") { - GameView() - }.padding(EdgeInsets(top: 10, leading: 32, bottom: 10, trailing: 32)) + ProfileEdit(color: Color(.red), profileWidth: 100, profileHeight: 100, defaultImage: Image("profil"), imageTextChange: "changer l'avatar du joueur 1") + ProfileEdit(color: Color(.blue), profileWidth: 100, profileHeight: 100, defaultImage: Image("profil"), imageTextChange: "changer l'avatar du joueur 2") + if !isKeyboardVisible + { + ButtonComponent(title: "Lancer la partie") { + GameView() + }.padding(EdgeInsets(top: 10, leading: 32, bottom: 10, trailing: 32)) + } } + .onReceive(keyboardPublisher) { value in isKeyboardVisible = value } .frame(maxHeight: .infinity, alignment: .top) } }