; VarForm.ahk — Mini-formulaire des variables manuelles d'un prompt (architecture §10.4). ; Construit dynamiquement un contrôle par variable selon son type. Échap = annulation complète. class VarForm { GuiObj := "" Controls := Map() ; nom -> Map(ctrl, def) Callback := "" ; Func(values Map) ou Func("") si annulé PromptRef := "" ; defaults : Map nom -> valeur proposée (défaut déclaré, surchargé par les derniers choix) Show(prompt, varDefs, defaults, callback) { this.PromptRef := prompt this.Callback := callback this.Controls := Map() if (this.GuiObj != "") this.GuiObj.Destroy() g := Gui("+AlwaysOnTop -MaximizeBox", prompt.Title " — paramètres") g.SetFont("s10", "Segoe UI") this.GuiObj := g for def in varDefs { name := def["name"] label := def["label"] type := def["type"] defaultVal := defaults.Has(name) ? String(defaults[name]) : def["default"] g.Add("Text", "xm w340", label (def["required"] ? " *" : "")) ctrl := "" switch type { case "enum": choices := def["choices"].Length > 0 ? def["choices"] : [defaultVal] ctrl := g.Add("ComboBox", "xm w340", choices) idx := 0 for i, c in choices { if (String(c) = defaultVal) { idx := i break } } ctrl.Value := idx > 0 ? idx : 1 case "bool": ctrl := g.Add("CheckBox", "xm w340", label) ctrl.Value := (defaultVal = "true" || defaultVal = "1") ? 1 : 0 ; Le libellé au-dessus fait doublon pour une case : on masque le texte de la case. ctrl.Text := "Oui" case "multiline": ctrl := g.Add("Edit", "xm w340 r4", defaultVal) case "password": ctrl := g.Add("Edit", "xm w340 Password", "") case "date": ctrl := g.Add("Edit", "xm w340", defaultVal != "" ? defaultVal : FormatTime(, "yyyy-MM-dd")) default: ; text, number ctrl := g.Add("Edit", "xm w340", defaultVal) } this.Controls[name] := Map("ctrl", ctrl, "def", def) } btnOk := g.Add("Button", "xm w160 Default", "Insérer le prompt") btnOk.OnEvent("Click", (*) => this.Submit()) btnCancel := g.Add("Button", "x+20 w160", "Annuler (Échap)") btnCancel.OnEvent("Click", (*) => this.Cancel()) g.OnEvent("Escape", (*) => this.Cancel()) g.OnEvent("Close", (*) => this.Cancel()) g.Show() ; Focus sur le premier contrôle. for name, entry in this.Controls { entry["ctrl"].Focus() break } } Submit() { values := Map() for name, entry in this.Controls { ctrl := entry["ctrl"] def := entry["def"] type := def["type"] val := "" if (type = "bool") { if (def["choices"].Length >= 2) val := ctrl.Value ? String(def["choices"][1]) : String(def["choices"][2]) else val := ctrl.Value ? (def["default"] != "" ? def["default"] : "oui") : "" } else if (type = "enum") { val := ctrl.Text } else { val := ctrl.Value } if (def["required"] && Trim(val) = "") { ctrl.Focus() TrayTip("La variable « " def["label"] " » est requise.", "PromptKey") return } if (type = "number" && val != "" && !IsNumber(val)) { ctrl.Focus() TrayTip("La variable « " def["label"] " » doit être un nombre.", "PromptKey") return } values[name] := val } cb := this.Callback this.GuiObj.Destroy() this.GuiObj := "" cb(values) } Cancel() { cb := this.Callback if (this.GuiObj != "") { this.GuiObj.Destroy() this.GuiObj := "" } if (cb != "") cb("") } }