Add description field

This commit is contained in:
2023-07-13 13:02:39 +02:00
parent 60874d4eb0
commit 0ff3803059
4 changed files with 68 additions and 31 deletions

View File

@ -8,6 +8,7 @@
/* Begin PBXBuildFile section */ /* Begin PBXBuildFile section */
680A62122A5F475D004C21A4 /* ViewExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 680A62112A5F475D004C21A4 /* ViewExtensions.swift */; }; 680A62122A5F475D004C21A4 /* ViewExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 680A62112A5F475D004C21A4 /* ViewExtensions.swift */; };
680A62182A600F81004C21A4 /* Task.swift in Sources */ = {isa = PBXBuildFile; fileRef = 680A62172A600F81004C21A4 /* Task.swift */; };
682D06A62A5487D200EA4745 /* LutoApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = 682D06A52A5487D200EA4745 /* LutoApp.swift */; }; 682D06A62A5487D200EA4745 /* LutoApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = 682D06A52A5487D200EA4745 /* LutoApp.swift */; };
682D06A82A5487D200EA4745 /* MainView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 682D06A72A5487D200EA4745 /* MainView.swift */; }; 682D06A82A5487D200EA4745 /* MainView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 682D06A72A5487D200EA4745 /* MainView.swift */; };
682D06AA2A5487D500EA4745 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 682D06A92A5487D500EA4745 /* Assets.xcassets */; }; 682D06AA2A5487D500EA4745 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 682D06A92A5487D500EA4745 /* Assets.xcassets */; };
@ -37,6 +38,7 @@
/* Begin PBXFileReference section */ /* Begin PBXFileReference section */
680A62112A5F475D004C21A4 /* ViewExtensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewExtensions.swift; sourceTree = "<group>"; }; 680A62112A5F475D004C21A4 /* ViewExtensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewExtensions.swift; sourceTree = "<group>"; };
680A62172A600F81004C21A4 /* Task.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Task.swift; sourceTree = "<group>"; };
682D06A22A5487D200EA4745 /* Luto.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Luto.app; sourceTree = BUILT_PRODUCTS_DIR; }; 682D06A22A5487D200EA4745 /* Luto.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Luto.app; sourceTree = BUILT_PRODUCTS_DIR; };
682D06A52A5487D200EA4745 /* LutoApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LutoApp.swift; sourceTree = "<group>"; }; 682D06A52A5487D200EA4745 /* LutoApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LutoApp.swift; sourceTree = "<group>"; };
682D06A72A5487D200EA4745 /* MainView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MainView.swift; sourceTree = "<group>"; }; 682D06A72A5487D200EA4745 /* MainView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MainView.swift; sourceTree = "<group>"; };
@ -85,6 +87,14 @@
path = Utils; path = Utils;
sourceTree = "<group>"; sourceTree = "<group>";
}; };
680A62162A600F75004C21A4 /* Models */ = {
isa = PBXGroup;
children = (
680A62172A600F81004C21A4 /* Task.swift */,
);
path = Models;
sourceTree = "<group>";
};
682D06992A5487D200EA4745 = { 682D06992A5487D200EA4745 = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
@ -108,6 +118,7 @@
682D06A42A5487D200EA4745 /* Luto */ = { 682D06A42A5487D200EA4745 /* Luto */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
680A62162A600F75004C21A4 /* Models */,
683805182A57354900CEF29C /* UI */, 683805182A57354900CEF29C /* UI */,
682D06A52A5487D200EA4745 /* LutoApp.swift */, 682D06A52A5487D200EA4745 /* LutoApp.swift */,
682D06A92A5487D500EA4745 /* Assets.xcassets */, 682D06A92A5487D500EA4745 /* Assets.xcassets */,
@ -283,6 +294,7 @@
files = ( files = (
682D06A82A5487D200EA4745 /* MainView.swift in Sources */, 682D06A82A5487D200EA4745 /* MainView.swift in Sources */,
6838051A2A57356700CEF29C /* TextFieldExtensions.swift in Sources */, 6838051A2A57356700CEF29C /* TextFieldExtensions.swift in Sources */,
680A62182A600F81004C21A4 /* Task.swift in Sources */,
680A62122A5F475D004C21A4 /* ViewExtensions.swift in Sources */, 680A62122A5F475D004C21A4 /* ViewExtensions.swift in Sources */,
682D06A62A5487D200EA4745 /* LutoApp.swift in Sources */, 682D06A62A5487D200EA4745 /* LutoApp.swift in Sources */,
); );

View File

@ -14,7 +14,7 @@ struct LutoApp: App {
var body: some Scene { var body: some Scene {
WindowGroup(id: "MainWindow") { WindowGroup(id: "MainWindow") {
MainView(taskTitle: "", taskDescription: "", listTask: []) MainView()
} }
} }
} }
@ -33,14 +33,14 @@ class AppDelegate: NSObject, NSApplicationDelegate, ObservableObject {
statusItem = NSStatusBar.system.statusItem(withLength: NSStatusItem.variableLength) statusItem = NSStatusBar.system.statusItem(withLength: NSStatusItem.variableLength)
if let statusButton = statusItem.button { if let statusButton = statusItem.button {
statusButton.image = NSImage(systemSymbolName: "brain", accessibilityDescription: "Chart Line") statusButton.image = NSImage(systemSymbolName: "brain", accessibilityDescription: "A brain")
statusButton.action = #selector(togglePopover) statusButton.action = #selector(togglePopover)
} }
self.popover = NSPopover() self.popover = NSPopover()
self.popover.contentSize = NSSize(width: 500, height: 500) self.popover.contentSize = NSSize(width: 500, height: 500)
self.popover.behavior = .transient self.popover.behavior = .transient
self.popover.contentViewController = NSHostingController(rootView: MainView(taskTitle: "", taskDescription: "", listTask: []) self.popover.contentViewController = NSHostingController(rootView: MainView()
) )
} }

13
Luto/Models/Task.swift Normal file
View File

@ -0,0 +1,13 @@
//
// Task.swift
// Luto
//
// Created by Pierre Boulc'h on 13/07/2023.
//
import Foundation
struct Task {
var title: String
var description: String
}

View File

@ -10,39 +10,52 @@ import AppKit
struct MainView: View { struct MainView: View {
private enum FocusStateField: Hashable{
case titleField
case descriptionField
}
@State var taskTitle = "" @State var taskTitle = ""
@State var taskDescription = "" @State var taskDescription = ""
@State var listTask: [String] = [] @State var listTask: [Task] = []
@State var showAdditionnalFields = false @State var showAdditionnalFields = false
@FocusState private var titleFieldInFocus: Bool
@FocusState private var descriptionFieldInFocus: Bool @FocusState private var focusState: FocusStateField?
var body: some View { var body: some View {
VStack { VStack {
Text("Mes tâches") Text("Mes tâches")
LazyVStack(alignment: .leading) { ScrollView {
ForEach(Array(listTask.enumerated()), id: \.offset) { index, task in LazyVStack(alignment: .leading) {
HStack { ForEach(Array(listTask.enumerated()), id: \.offset) { index, task in
Text("\(task)") HStack {
.padding(EdgeInsets(top: 0, leading: 12, bottom: 0, trailing: 8)) VStack(alignment: .leading) {
Spacer() Text("\(task.title)").font(.system(size: 16))
Button(action: { if !task.description.isEmpty {
removeTask(index: index) Text("\(task.description)")
}, label: { }
Image(systemName: "trash") }
}).buttonStyle(PlainButtonStyle()).padding(12) .padding(EdgeInsets(top: 0, leading: 12, bottom: 0, trailing: 8))
.foregroundColor(.accentColor) Spacer()
}.border(width: 5, edges: [.leading], color: .accentColor) Button(action: {
removeTask(index: index)
}, label: {
Image(systemName: "trash")
}).buttonStyle(PlainButtonStyle()).padding(12)
.foregroundColor(.accentColor)
}.border(width: 5, edges: [.leading], color: .accentColor)
}
} }
} }
Spacer() Spacer()
Divider()
HStack { HStack {
TextField("Titre de la tâche ...", text: $taskTitle).focused($titleFieldInFocus).onChange(of: titleFieldInFocus) { isFocused in TextField("Titre de la tâche ...", text: $taskTitle).focused($focusState, equals: .titleField).onChange(of: focusState) { newFocusState in
if !isFocused { if newFocusState != .titleField {
withAnimation { withAnimation {
showAdditionnalFields = true showAdditionnalFields = true
focusState = .descriptionField
} }
} }
}.onSubmit { }.onSubmit {
@ -58,7 +71,9 @@ struct MainView: View {
.cornerRadius(24) .cornerRadius(24)
}.textFieldStyle(OvalTextFieldStyle()) }.textFieldStyle(OvalTextFieldStyle())
if showAdditionnalFields { if showAdditionnalFields {
TextField("Description", text: $taskDescription).focused($descriptionFieldInFocus) TextField("Description ...", text: $taskDescription).focused($focusState, equals: .descriptionField).textFieldStyle(OvalTextFieldStyle()).padding(EdgeInsets(top: 8, leading: 0, bottom: 0, trailing: 0)).onSubmit {
addTask()
}
} }
} }
.padding() .padding()
@ -68,9 +83,12 @@ struct MainView: View {
func addTask() { func addTask() {
if !taskTitle.isEmpty { if !taskTitle.isEmpty {
withAnimation { withAnimation {
listTask.append(taskTitle) listTask.append(Task(title: taskTitle, description: taskDescription))
} }
taskTitle = "" taskTitle = ""
taskDescription = ""
showAdditionnalFields = false
focusState = .titleField
} }
} }
@ -79,16 +97,10 @@ struct MainView: View {
listTask.remove(at: index) listTask.remove(at: index)
} }
} }
init(taskTitle: String = "", taskDescription: String = "", listTask: [String]) {
self.taskTitle = taskTitle
self.taskDescription = taskDescription
self.listTask = listTask
}
} }
struct MainView_Previews: PreviewProvider { struct MainView_Previews: PreviewProvider {
static var previews: some View { static var previews: some View {
MainView(taskTitle: "", taskDescription: "", listTask: []) MainView()
} }
} }