Fenêtres et menus
Saisie, confirmation et choix dans MrPoulpi UI : fenêtres bloquantes, OpenUI, menus en sections, actions client et actions serveur sécurisées.
Trois types de fenêtre : saisie (input), confirmation (confirm) et choix (choice). Une seule fenêtre est ouverte à la fois ; en ouvrir une autre remplace la première.
Pendant qu’une fenêtre est ouverte, le joueur a le curseur et ne contrôle plus son personnage. Échap ferme la fenêtre, Entrée valide la saisie, Tab passe d’un bouton à l’autre.
Fenêtres bloquantes
La façon la plus simple : la fonction attend la réponse du joueur et la renvoie. Appelez-la dans un thread.
CreateThread(function()
local plate = exports.mrpoulpi_ui:Input({ title = 'Plaque', placeholder = '12ABC345', maxLength = 8 })
if not plate then return end
if not exports.mrpoulpi_ui:Confirm(('Enregistrer la plaque %s ?'):format(plate)) then return end
local method = exports.mrpoulpi_ui:Choice({
title = 'Paiement',
options = {
{ id = 'bank', label = 'Banque', variant = 'success' },
{ id = 'cash', label = 'Liquide', variant = 'info' }
}
})
if method then
TriggerServerEvent('garage:buyPlate', plate, method)
end
end)
| Export | Renvoie | Si le joueur annule |
|---|---|---|
Input(data) |
le texte saisi, ou un nombre avec inputType = 'number' |
nil |
Confirm(data) |
true s’il confirme, false s’il refuse |
false |
Choice(data) |
l’id de l’option, puis l’option complète |
nil |
Si la fenêtre est fermée par un autre script ou remplacée par une autre, la fonction renvoie la valeur d’annulation.
Champs d’une fenêtre
Ces champs servent aussi bien aux fonctions bloquantes qu’à OpenUI.
Communs
| Champ | Défaut | Description |
|---|---|---|
type |
'choice' |
input, confirm ou choice. Inutile avec Input, Confirm et Choice. |
title |
— | Titre de la fenêtre. |
cursor |
true |
false donne le focus sans afficher le curseur. |
action |
— | Action appelée à la validation (saisie et confirmation). Voir Actions. |
server |
false |
Avec action, envoie l’action au serveur. |
Tous les textes acceptent une clé de shared/locales.lua à la place du texte.
Saisie (input)
| Champ | Défaut | Description |
|---|---|---|
placeholder |
« Saisissez une valeur » | Texte grisé dans le champ vide. |
value |
vide | Valeur déjà remplie. |
maxLength |
Config.Input.maxLength |
Nombre de caractères, jamais plus que Config.Input.maxLength. |
inputType |
'text' |
'number' n’accepte que des nombres et renvoie un nombre. |
required |
true |
false accepte une saisie vide. |
Confirmation (confirm)
| Champ | Défaut | Description |
|---|---|---|
question |
— | Question affichée. |
confirmLabel |
« Confirmer » | Bouton de validation. |
cancelLabel |
« Annuler » | Bouton de refus. |
Choix (choice)
| Champ | Défaut | Description |
|---|---|---|
options |
— | Liste des boutons (ci-dessous). |
cancel |
true |
Ajoute un bouton pour fermer. |
cancelLabel |
« Annuler » ou « Fermer » | Texte de ce bouton. |
columns |
3 |
Nombre de colonnes (1 à 4) d’un menu en sections. |
Chaque option :
| Champ | Description |
|---|---|
id |
Identifiant renvoyé. Par défaut, la position dans la liste. |
label |
Texte du bouton. |
variant |
Couleur : success, info, warning, danger ou neutral (défaut). |
group |
Titre de section. Voir Menus en sections. |
disabled |
true affiche le bouton grisé, impossible à cliquer. |
keepOpen |
true laisse la fenêtre ouverte après le clic. |
action, server |
Action déclenchée par ce bouton. |
onSelect |
Fonction appelée au clic : onSelect(payload, context). Client uniquement. |
ace |
Menu du serveur uniquement : l’option n’est montrée qu’aux joueurs qui ont cette ACE. |
Menus en sections
Dès qu’une option a un group, la fenêtre devient un menu : les options sont rangées sous un titre par groupe, dans l’ordre où les groupes apparaissent, et le bouton de fermeture passe en bas.
exports.mrpoulpi_ui:OpenUI({
type = 'choice',
title = 'Garage',
columns = 2,
options = {
{ id = 'out', group = 'Véhicules', label = 'Sortir', variant = 'success', action = 'garage:out' },
{ id = 'store', group = 'Véhicules', label = 'Ranger', action = 'garage:store' },
{ id = 'repair', group = 'Services', label = 'Réparer', variant = 'warning', action = 'garage:repair' },
{ id = 'wash', group = 'Services', label = 'Laver', disabled = true }
}
})
Avec keepOpen = true, le joueur peut cliquer plusieurs boutons à la suite. Choice ne rend la main qu’au clic sur une option sans keepOpen, ou à la fermeture.
Actions
Plutôt que d’attendre la réponse, vous pouvez associer une action à un bouton. C’est utile pour un menu ouvert depuis le serveur, ou réutilisé à plusieurs endroits.
Au clic, dans cet ordre :
onSelectde l’option, s’il existe ;- le hook client
Hooks.OnAction(name, payload, context); - l’action client enregistrée sous ce nom, si elle existe ;
- sinon, si l’option a
server = true, l’action est envoyée au serveur.
Le payload vaut { id = '…' } pour un choix et { value = … } pour une saisie ou une confirmation. context est la fenêtre entière.
Action client
exports.mrpoulpi_ui:RegisterUIAction('garage:out', function(payload, context)
print('Option choisie :', payload.id)
end)
L’action est supprimée automatiquement quand la ressource qui l’a enregistrée s’arrête.
Action serveur
exports.mrpoulpi_ui:RegisterServerAction('shop:payBank', function(source, payload)
-- payload.id ou payload.value, déjà vérifiés
end)
RegisterNetEvent('shop:open', function()
exports.mrpoulpi_ui:OpenUI(source, {
type = 'choice',
title = 'Paiement',
options = {
{ id = 'bank', label = 'Banque', variant = 'success', action = 'shop:payBank', server = true },
{ id = 'cash', label = 'Liquide', variant = 'info', action = 'shop:payCash', server = true }
}
})
end)
Le serveur accepte une action seulement dans deux cas :
| Cas | Condition |
|---|---|
Action enregistrée avec RegisterServerAction |
Toujours acceptée. Avec { requirePermission = true } en 3ᵉ argument, réservée aux joueurs qui ont la permission du menu. |
Option server = true de la dernière fenêtre ouverte par le serveur pour ce joueur, sans RegisterServerAction |
Réservée aux joueurs qui ont la permission du menu, puis traitée par Hooks.OnServerAction. Valable une fois, sauf option keepOpen. |
Pour une fenêtre destinée à tous les joueurs, utilisez donc RegisterServerAction.
Avant d’arriver dans votre callback, chaque action est aussi :
- limitée à une toutes les
Config.Security.actionCooldownmillisecondes par joueur ; - refusée si son nom dépasse 64 caractères ;
- nettoyée : seuls
id(64 caractères au plus) etvalue(texte deConfig.Input.maxLengthcaractères au plus, nombre ou booléen) sont transmis ; - soumise à
Hooks.CanUseAction(source, name, payload).
Les refus sont passés à Hooks.Log (unknown_action, action_denied, invalid_payload).
Modifier une fenêtre ouverte
exports.mrpoulpi_ui:SetUIData({ title = 'Garage (3 véhicules)' })
Les champs donnés remplacent les anciens ; les autres sont gardés. Pour suivre l’ouverture et la fermeture depuis un autre script, écoutez les events locaux mrpoulpi_ui:opened et mrpoulpi_ui:closed.
Bloquer l’ouverture
Dans client/hooks.lua, Hooks.CanOpen peut refuser une fenêtre selon l’état du joueur :
function Hooks.CanOpen(data)
if IsEntityDead(PlayerPedId()) then
return false
end
return true
end
Les fonctions bloquantes renvoient alors directement la valeur d’annulation.