- Picker : recherche instantanée, aperçu, navigation clavier complète, raccourcis actifs seulement dans sa fenêtre (HotIfWinActive) - Gestionnaire : arbre des catégories, favoris/récents/erreurs, aperçu, création depuis le presse-papiers, suppression par la corbeille - Éditeur : métadonnées, insertion/déclaration de variables synchronisées, validation en direct, Tester (prévisualisation résolue, sans injection) - VarForm : un contrôle par type de variable, requis validés, Échap annule toute l'injection et rend le focus
116 lines
4.3 KiB
AutoHotkey
116 lines
4.3 KiB
AutoHotkey
; 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("")
|
|
}
|
|
}
|