Je ne sais pas si c'est la solution, mais voici mon code.
Je ne me suis pas attaché à la présentation car je souhaitais juste tester la faisabilité des propos que j'ai tenus hier.
Quelques mots sur ce code.
- A la première utilisation une nouvelle recette est mise en place. Il est donc inutile de cliquer sur le bouton
.
sauvegarde la recette dans la liste des recettes et non pas dans un fichier.
supprime une recette.
- Tu peux mettre autant d'ingrédients que tu souhaites.
- Les recettes sont sauvegarder dans un fichier JSON quand on quitte l'application.
Tu remarquera la simplicité de cette sauvegarde qui se résume à un simple transfert de la liste vers le fichier JSON.
Un autre avantage, est la possibilité de modifier la structure des recettes sans perdre les recettes précédentes.
- A l'ouverture de l'application, l'importation crée une sauvegarde de sécurité. Si tu as fais une bêtise dans les recettes, quitte l'application, supprime le fichier "
".
Code : Tout sélectionner
EnableExplicit
Enumeration Fichier
#JSONFile
EndEnumeration
Enumeration Window
#mf
EndEnumeration
Enumeration Gadgets
#ListRecettes
#Nom
#NbPers
#Preparation
#ListIngredients
#IngredientNouveau
;Mise à jour des recettes
#Nouveau ;Nouvelle recette
#Supprimer ;Supprimer une recette
#Sauvegarder ;Sauvegarder une recette
EndEnumeration
;Nombre de Gadgets Par Ligne d'Ingrédient
#NGPLI = 4
;Recettes
Structure Ingredient ;Ligne d'ingrédient
Quantite.s
Unite.i
Ingredient.s
EndStructure
Structure Recette ;Recette
Nom.s
List Ingredients.Ingredient() ;(0 à N ingrédient)
Preparation.s
Nb_Pers.s
EndStructure
Global NewList Recettes.Recette()
;Gadgets utilisés par chaque ligne d'ingredient
; Une ligne de gadget est composé d'un tableau de x Gadgets
; Dans cette exemple il y a 4 Gadgets (Quantite + Unite + Ingredient + Bouton suppression d'un indgrédient)
Structure LigneIngredient
Array Ingredients.i(#NGPLI-1)
EndStructure
Global NewList ListeIngredients.LigneIngredient()
Global Lig = 10, TokenNouveau.b
;Plan de l'application
Declare Start() ;Affichage de l'application
Declare RecettesListe() ;Liste des recettes
Declare RecetteSelect() ;Sélectionner une recette
Declare RecetteClear() ;Reset d'une recette (Clear de l'ensemble des éléments)
Declare RecetteSupprime() ;Supprimer une recette
Declare RecetteSave() ;Sauvegarde d'une recette
Declare IngredientNouveau() ;Ajouter une nouvelle ligne d'ingrédient
Declare IngredientSupprime() ;Supprimer une ligne d'ingrédient
;Chargement et sauvegarde des données
Declare RecettesCharge()
Declare RecettesSave()
Declare Exit()
Start()
Procedure Start()
OpenWindow(#mf, 0, 0, 800, 600, "Recettes de cuisine", #PB_Window_SystemMenu|#PB_Window_ScreenCentered)
;Liste des recettes
TextGadget(#PB_Any, 10, 10, 200, 22, "Liste des recettes")
ListViewGadget(#ListRecettes, 10, 30, 780, 150)
;Recette
TextGadget(#PB_Any, 10, 200, 100, 22, "Nom")
StringGadget(#Nom, 120, 200, 400, 22, "")
TextGadget(#PB_Any, 10, 230, 100, 22, "Nombre de personne")
StringGadget(#NbPers, 120, 230, 400, 22, "4", #PB_String_Numeric)
TextGadget(#PB_Any, 10, 270, 100, 20, "Préparation")
EditorGadget(#Preparation, 10, 292, 780, 100, #PB_Editor_WordWrap)
ScrollAreaGadget(#ListIngredients, 10, 410, 780, 150, 750, 1000)
CloseGadgetList()
ButtonGadget(#IngredientNouveau, 10, 565, 780, 24, "Ajouter un ingrédient")
ButtonGadget(#Nouveau, 700, 200, 90, 24, "Nouveau")
ButtonGadget(#Supprimer, 700, 230, 90, 24, "Supprimer")
DisableGadget(#Supprimer, #True)
ButtonGadget(#Sauvegarder, 700, 260, 90, 24, "Sauvegarder")
;Declencheur Gadgets
BindGadgetEvent(#ListRecettes, @RecetteSelect())
BindGadgetEvent(#IngredientNouveau, @IngredientNouveau())
BindGadgetEvent(#Nouveau, @RecetteClear())
BindGadgetEvent(#Supprimer, @RecetteSupprime())
BindGadgetEvent(#Sauvegarder, @RecetteSave())
;Déclencheur Window
BindEvent(#PB_Event_CloseWindow, @Exit())
;Affichage des recettes et sélection de la recette 1
If RecettesCharge()
RecettesListe()
SetGadgetState(#ListRecettes, 0)
RecetteSelect()
EndIf
Repeat : WaitWindowEvent() : ForEver
EndProcedure
;-
;- Recettes
Procedure RecettesListe()
ClearGadgetItems(#ListRecettes)
SortStructuredList(Recettes(), #PB_Sort_Ascending , OffsetOf(Recette\Nom), TypeOf(Recette\Nom))
ForEach Recettes()
AddGadgetItem(#ListRecettes, -1, Recettes()\Nom)
Next
If ListSize(Recettes()) = 0
TokenNouveau = #True
IngredientNouveau()
EndIf
EndProcedure
Procedure RecetteSelect()
Protected Index = GetGadgetState(#ListRecettes)
If Index <> -1
RecetteClear() ;Effacer les élements de la recette précédente
SelectElement(Recettes(), Index)
With Recettes()
SetGadgetText(#Nom, \Nom)
SetGadgetText(#NbPers, \Nb_Pers)
SetGadgetText(#Preparation, \Preparation)
ForEach Recettes()\Ingredients()
IngredientNouveau()
SetGadgetText(ListeIngredients()\Ingredients(0), \Ingredients()\Quantite)
SetGadgetState(ListeIngredients()\Ingredients(1), \Ingredients()\Unite)
SetGadgetText(ListeIngredients()\Ingredients(2), \Ingredients()\Ingredient)
Next
EndWith
TokenNouveau = #False
DisableGadget(#Supprimer, #False)
EndIf
EndProcedure
;Mise en place d'une nouvelle recette
Procedure RecetteClear()
Protected n, Gadget
SetGadgetText(#Nom, "")
SetGadgetText(#NbPers, "4")
SetGadgetText(#Preparation, "")
;Supression des lignes d'ingredient de l'ancienne recette si necessaire
ForEach ListeIngredients()
With ListeIngredients()
UnbindGadgetEvent(\Ingredients(3), @IngredientSupprime(), #PB_EventType_LeftClick)
For n = 0 To #NGPLI-1
FreeGadget(\Ingredients(n))
Next
EndWith
Next
ClearList(ListeIngredients())
;Mise en place d'une nouvelle ligne d'ingredient
Lig = 10
If EventGadget() = #Nouveau
IngredientNouveau()
TokenNouveau = #True
DisableGadget(#Supprimer, #True)
EndIf
EndProcedure
;Suppression d'une recette
Procedure RecetteSupprime()
SelectElement(Recettes(),ListIndex(Recettes()))
DeleteElement(Recettes())
RecetteClear()
RecettesListe()
SetGadgetState(#ListRecettes, 0)
RecetteSelect()
EndProcedure
Procedure RecetteSave()
Protected Buffer.s
;Controle de cohérence
; - Nom de la recette obligatoire
If Trim(GetGadgetText(#Nom)) <> ""
If TokenNouveau = #True
AddElement(Recettes())
Else
;C'est une modification : Suppression des anciens ingrédients
ForEach Recettes()\Ingredients()
DeleteElement(Recettes()\Ingredients())
Next
EndIf
;Tronc commun à la création et la modification de recettes
;1er lettre du nom de la recette en majuscule
Buffer = GetGadgetText(#Nom)
Buffer = UCase(LSet(Buffer, 1)) + Mid(Buffer, 2)
SetGadgetText(#Nom, Buffer)
With Recettes()
\Nom = GetGadgetText(#Nom)
\Nb_Pers = GetGadgetText(#NbPers)
\Preparation = GetGadgetText(#Preparation)
ForEach ListeIngredients()
AddElement(Recettes()\Ingredients())
Recettes()\Ingredients()\Quantite = GetGadgetText(ListeIngredients()\Ingredients(0))
Recettes()\Ingredients()\Unite = GetGadgetState(ListeIngredients()\Ingredients(1))
Recettes()\Ingredients()\Ingredient = GetGadgetText(ListeIngredients()\Ingredients(2))
Next
EndWith
TokenNouveau = #False
RecettesListe()
SetGadgetState(#ListRecettes, ListIndex(Recettes()))
RecetteSelect()
Else
MessageRequester("Information", "Avant de sauvegarder, donner un titre à la recette")
EndIf
EndProcedure
;-
;- Ingrédients (Création et suppression)
Procedure IngredientNouveau()
OpenGadgetList(#ListIngredients)
AddElement(ListeIngredients())
With ListeIngredients()
;Quantité
\Ingredients(0) = StringGadget(#PB_Any, 10, Lig, 50, 22, "1", #PB_String_Numeric)
;Unité de mesure
\Ingredients(1) = ComboBoxGadget(#PB_Any, 65, Lig, 70, 22)
AddGadgetItem(\Ingredients(1), -1, "")
AddGadgetItem(\Ingredients(1), -1, "Gramme")
AddGadgetItem(\Ingredients(1), -1, "kg")
AddGadgetItem(\Ingredients(1), -1, "cl")
AddGadgetItem(\Ingredients(1), -1, "Litre")
AddGadgetItem(\Ingredients(1), -1, "Pincée")
AddGadgetItem(\Ingredients(1), -1, "Cuillére")
AddGadgetItem(\Ingredients(1), -1, "Verre")
AddGadgetItem(\Ingredients(1), -1, "Feuille")
AddGadgetItem(\Ingredients(1), -1, "Bouquet")
AddGadgetItem(\Ingredients(1), -1, "Cube")
AddGadgetItem(\Ingredients(1), -1, "Quart")
AddGadgetItem(\Ingredients(1), -1, "Demie")
;Ingrédient
\Ingredients(2) = StringGadget(#PB_Any, 140, Lig, 570, 22, "")
;Bouton suppression
\Ingredients(3) = ButtonGadget(#PB_Any, 725, Lig, 22, 22, "-")
;le bouton suppression mémorise l'index
SetGadgetData(\Ingredients(3), ListIndex(ListeIngredients()))
BindGadgetEvent(\Ingredients(3), @IngredientSupprime(), #PB_EventType_LeftClick)
EndWith
CloseGadgetList()
Lig + 30
EndProcedure
Procedure IngredientSupprime()
Protected Gadget, Index, n
;Quel est le bouton suppression qui a provoquer l'evenement
Gadget = EventGadget()
;Selection de la ligne à supprimer
Index = GetGadgetData(Gadget)
;Suppression de la ligne
If SelectElement(ListeIngredients(), Index)
With ListeIngredients()
UnbindGadgetEvent(\Ingredients(3), @IngredientSupprime(), #PB_EventType_LeftClick)
For n = 0 To #NGPLI-1
FreeGadget(\Ingredients(n))
Next
EndWith
DeleteElement(ListeIngredients())
;Re-Numerotation des lignes
Lig = 10
ForEach ListeIngredients()
With ListeIngredients()
ResizeGadget(\Ingredients(0), 10, Lig, #PB_Ignore, #PB_Ignore)
ResizeGadget(\Ingredients(1), 65, Lig, #PB_Ignore, #PB_Ignore)
ResizeGadget(\Ingredients(2), 120, Lig, #PB_Ignore, #PB_Ignore)
ResizeGadget(\Ingredients(3), 725, Lig, #PB_Ignore, #PB_Ignore)
SetGadgetData(\Ingredients(3), ListIndex(ListeIngredients()))
Lig + 30
EndWith
Next
EndIf
EndProcedure
;-
;- Chargement et sauvegarde des recettes
Procedure RecettesCharge()
;Copie de sécurité
If FileSize("recettes.json") <> -1
CopyFile("recettes.json", "recettes.old.json")
Else
;Récupération du fichier de sécurité si existant
If FileSize("recettes.old.json") <> -1
CopyFile("recettes.old.json", "recettes.json")
EndIf
EndIf
;Chargement des recettes
If LoadJSON(#JSONFile, "recettes.json")
ExtractJSONList(JSONValue(#JSONFile), Recettes())
EndIf
ProcedureReturn #True
EndProcedure
Procedure RecettesSave()
CreateJSON(#JSONFile)
InsertJSONList(JSONValue(#JSONFile), Recettes())
SaveJSON(#JSONFile, "Recettes.json")
ProcedureReturn #True
EndProcedure
;-
;- Sortie avec sauvegarde des recettes
Procedure Exit()
If RecettesSave()
End
EndIf
EndProcedure