Init
This commit is contained in:
100
content/ui-systems/_index.en.md
Normal file
100
content/ui-systems/_index.en.md
Normal file
@@ -0,0 +1,100 @@
|
||||
---
|
||||
title: UI Systems
|
||||
type: docs
|
||||
weight: 5
|
||||
---
|
||||
|
||||
The UI Systems section covers user interface, permissions, and custom pages.
|
||||
|
||||
## Overview
|
||||
|
||||
{{< cards cols="2" >}}
|
||||
{{< card link="hud-manager" title="HUD Manager" subtitle="Control visibility of HUD components" icon="eye" >}}
|
||||
{{< card link="custom-pages" title="Custom Pages" subtitle="Create custom UI overlays" icon="document-text" >}}
|
||||
{{< card link="windows" title="Windows" subtitle="Inventory and crafting windows" icon="collection" >}}
|
||||
{{< card link="ui-files" title="UI Files" subtitle="The .ui markup language" icon="code" >}}
|
||||
{{< card link="ui-syntax" title="UI Syntax" subtitle="Variables, imports, templates" icon="document" >}}
|
||||
{{< card link="ui-widgets" title="UI Widgets" subtitle="Available widget types" icon="cube" >}}
|
||||
{{< card link="ui-properties" title="UI Properties" subtitle="Anchor, layout, padding" icon="adjustments" >}}
|
||||
{{< card link="ui-styles" title="UI Styles" subtitle="Styling system" icon="color-swatch" >}}
|
||||
{{< card link="permissions" title="Permissions" subtitle="Player permissions and access control" icon="shield-check" >}}
|
||||
{{< /cards >}}
|
||||
|
||||
## Key Concepts
|
||||
|
||||
### HUD Components
|
||||
|
||||
The HUD consists of built-in components that can be shown or hidden:
|
||||
|
||||
- **Hotbar** - Item slots at the bottom of the screen
|
||||
- **Health/Mana/Stamina** - Vital stat bars
|
||||
- **Chat** - Text communication
|
||||
- **Compass** - Direction indicator
|
||||
- **Notifications** - Alert messages
|
||||
- And many more...
|
||||
|
||||
### Custom Pages
|
||||
|
||||
Custom pages allow you to create overlay UIs using the `UICommandBuilder`:
|
||||
|
||||
```java
|
||||
public class MyPage extends CustomUIPage {
|
||||
|
||||
public MyPage(PlayerRef ref) {
|
||||
super(ref, CustomPageLifetime.CanDismiss);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void build(Ref<EntityStore> ref, UICommandBuilder builder,
|
||||
UIEventBuilder events, Store<EntityStore> store) {
|
||||
// Build UI using builder.set(), builder.append(), etc.
|
||||
builder.append("Pages/MyTemplate.ui");
|
||||
builder.set("#title", "Welcome!");
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Page Manager
|
||||
|
||||
Each player has a `PageManager` that handles custom pages:
|
||||
|
||||
```java
|
||||
Player player = ...;
|
||||
PageManager pageManager = player.getPageManager();
|
||||
|
||||
// Open a custom page
|
||||
pageManager.openCustomPage(ref, store, new MyPage(player.getPlayerRef()));
|
||||
|
||||
// Close to normal view
|
||||
pageManager.setPage(ref, store, Page.None);
|
||||
```
|
||||
|
||||
## Accessing the HUD Manager
|
||||
|
||||
```java
|
||||
Player player = ...;
|
||||
HudManager hudManager = player.getHudManager();
|
||||
|
||||
// Hide all HUD components
|
||||
hudManager.setVisibleHudComponents(player.getPlayerRef());
|
||||
|
||||
// Show specific components
|
||||
hudManager.showHudComponents(player.getPlayerRef(),
|
||||
HudComponent.Hotbar,
|
||||
HudComponent.Health
|
||||
);
|
||||
```
|
||||
|
||||
## Architecture
|
||||
|
||||
```
|
||||
Player
|
||||
├── HudManager → Controls HUD visibility
|
||||
├── PageManager → Manages custom pages
|
||||
│ └── CustomUIPage → Your custom UI
|
||||
└── WindowManager → Manages windows (inventory, crafting)
|
||||
```
|
||||
|
||||
{{< callout type="info" >}}
|
||||
UI operations are typically performed through the `PlayerRef` or `Player` component. Access these through events or the command context.
|
||||
{{< /callout >}}
|
||||
97
content/ui-systems/_index.fr.md
Normal file
97
content/ui-systems/_index.fr.md
Normal file
@@ -0,0 +1,97 @@
|
||||
---
|
||||
title: Systèmes UI
|
||||
type: docs
|
||||
weight: 5
|
||||
---
|
||||
|
||||
La section Systèmes UI couvre l'interface utilisateur, les permissions et les pages personnalisées.
|
||||
|
||||
## Vue d'Ensemble
|
||||
|
||||
{{< cards cols="2" >}}
|
||||
{{< card link="hud-manager" title="Gestionnaire HUD" subtitle="Contrôler la visibilité des éléments HUD" icon="eye" >}}
|
||||
{{< card link="custom-pages" title="Pages Personnalisées" subtitle="Créer des interfaces interactives" icon="document" >}}
|
||||
{{< card link="windows" title="Fenêtres" subtitle="Conteneurs d'inventaire et crafting" icon="collection" >}}
|
||||
{{< card link="ui-files" title="Fichiers UI" subtitle="Le langage de balisage .ui" icon="code" >}}
|
||||
{{< card link="ui-syntax" title="Syntaxe UI" subtitle="Variables, imports, templates" icon="document" >}}
|
||||
{{< card link="ui-widgets" title="Widgets UI" subtitle="Types de widgets disponibles" icon="cube" >}}
|
||||
{{< card link="ui-properties" title="Propriétés UI" subtitle="Anchor, layout, padding" icon="adjustments" >}}
|
||||
{{< card link="ui-styles" title="Styles UI" subtitle="Système de styles" icon="color-swatch" >}}
|
||||
{{< card link="permissions" title="Permissions" subtitle="Permissions joueur et contrôle d'accès" icon="shield-check" >}}
|
||||
{{< /cards >}}
|
||||
|
||||
### Architecture UI
|
||||
|
||||
Le système UI se compose de trois couches principales :
|
||||
|
||||
1. **HUD** - Éléments persistants à l'écran (barre de vie, hotbar, etc.)
|
||||
2. **Pages** - Overlays plein écran (menus, interfaces personnalisées)
|
||||
3. **Fenêtres** - Interfaces de conteneur (coffres, crafting)
|
||||
|
||||
### Accéder au Système UI
|
||||
|
||||
```java
|
||||
Player player = ...;
|
||||
|
||||
// Gestionnaire HUD - contrôle la visibilité des composants HUD
|
||||
HudManager hudManager = player.getHudManager();
|
||||
|
||||
// Gestionnaire de Pages - gère les overlays et pages personnalisées
|
||||
PageManager pageManager = player.getPageManager();
|
||||
|
||||
// Gestionnaire de Fenêtres - gère les interfaces de conteneur
|
||||
WindowManager windowManager = player.getWindowManager();
|
||||
```
|
||||
|
||||
## Utilisation Rapide
|
||||
|
||||
### Afficher/Masquer les Éléments HUD
|
||||
|
||||
```java
|
||||
// Masquer le compas et le speedomètre
|
||||
hudManager.hideHudComponents(player.getPlayerRef(),
|
||||
HudComponent.Compass,
|
||||
HudComponent.Speedometer
|
||||
);
|
||||
|
||||
// N'afficher que les éléments essentiels
|
||||
hudManager.setVisibleHudComponents(player.getPlayerRef(),
|
||||
HudComponent.Hotbar,
|
||||
HudComponent.Health,
|
||||
HudComponent.Reticle
|
||||
);
|
||||
```
|
||||
|
||||
### Ouvrir une Page Personnalisée
|
||||
|
||||
```java
|
||||
// Créer et ouvrir une page personnalisée
|
||||
MyCustomPage page = new MyCustomPage(player.getPlayerRef());
|
||||
pageManager.openCustomPage(
|
||||
player.getReference(),
|
||||
player.getReference().getStore(),
|
||||
page
|
||||
);
|
||||
```
|
||||
|
||||
### Ouvrir une Fenêtre de Conteneur
|
||||
|
||||
```java
|
||||
// Ouvrir un conteneur de coffre
|
||||
ContainerWindow window = new ContainerWindow(
|
||||
1, // ID de fenêtre
|
||||
WindowType.Container,
|
||||
chestContainer
|
||||
);
|
||||
pageManager.setPageWithWindows(ref, store, Page.None, true, window);
|
||||
```
|
||||
|
||||
## Bonnes Pratiques
|
||||
|
||||
{{< callout type="info" >}}
|
||||
**Directives UI :**
|
||||
- Utilisez toujours `PlayerRef` lors de l'appel des méthodes HUD
|
||||
- Nettoyez les pages et fenêtres lors de la déconnexion du joueur
|
||||
- Utilisez `sendUpdate()` pour les petits changements, `rebuild()` pour les changements majeurs
|
||||
- Testez les interactions UI dans différents modes de jeu
|
||||
{{< /callout >}}
|
||||
341
content/ui-systems/custom-pages.en.md
Normal file
341
content/ui-systems/custom-pages.en.md
Normal file
@@ -0,0 +1,341 @@
|
||||
---
|
||||
title: Custom Pages
|
||||
type: docs
|
||||
weight: 2
|
||||
---
|
||||
|
||||
Custom pages allow plugins to create interactive UI overlays that can receive user input and display dynamic content.
|
||||
|
||||
**Package:** `com.hypixel.hytale.server.core.entity.entities.player.pages`
|
||||
|
||||
## Page Lifetimes
|
||||
|
||||
Control how pages can be closed:
|
||||
|
||||
| Lifetime | Description |
|
||||
|----------|-------------|
|
||||
| `CustomPageLifetime.CantClose` | Page cannot be dismissed by the player |
|
||||
| `CustomPageLifetime.CanDismiss` | Player can close with Escape key |
|
||||
| `CustomPageLifetime.CanDismissOrCloseThroughInteraction` | Can close via Escape or interaction |
|
||||
|
||||
## Creating a Custom Page
|
||||
|
||||
Extend `CustomUIPage`:
|
||||
|
||||
```java
|
||||
public class WelcomePage extends CustomUIPage {
|
||||
|
||||
public WelcomePage(PlayerRef playerRef) {
|
||||
super(playerRef, CustomPageLifetime.CanDismiss);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void build(Ref<EntityStore> ref, UICommandBuilder builder,
|
||||
UIEventBuilder events, Store<EntityStore> store) {
|
||||
// Load a UI template from assets (extension .ui is REQUIRED)
|
||||
builder.append("Pages/WelcomeScreen.ui");
|
||||
|
||||
// Set dynamic values
|
||||
builder.set("#player_name", playerRef.getUsername());
|
||||
builder.set("#server_name", "My Server");
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## UICommandBuilder
|
||||
|
||||
Build UI content dynamically:
|
||||
|
||||
### Append Content
|
||||
|
||||
```java
|
||||
// Append a UI template (extension .ui is REQUIRED)
|
||||
builder.append("Pages/TemplatePath.ui");
|
||||
|
||||
// Append to a specific selector
|
||||
builder.append("#container", "Pages/ChildTemplate.ui");
|
||||
|
||||
// Append inline YAML/JSON
|
||||
builder.appendInline("#list", "{ type: text, content: 'Hello' }");
|
||||
```
|
||||
|
||||
### Set Values
|
||||
|
||||
```java
|
||||
// Set text
|
||||
builder.set("#title", "Welcome!");
|
||||
builder.set("#description", Message.translation("my.key"));
|
||||
|
||||
// Set numbers
|
||||
builder.set("#score", 1500);
|
||||
builder.set("#progress", 0.75f);
|
||||
|
||||
// Set boolean
|
||||
builder.set("#visible", true);
|
||||
|
||||
// Set to null
|
||||
builder.setNull("#optional_field");
|
||||
```
|
||||
|
||||
### Set Objects
|
||||
|
||||
```java
|
||||
// Set ItemStack
|
||||
ItemStack item = ...;
|
||||
builder.setObject("#item_display", item);
|
||||
|
||||
// Set UI Area
|
||||
Area area = new Area(0, 0, 100, 50);
|
||||
builder.setObject("#bounds", area);
|
||||
|
||||
// Set arrays/lists
|
||||
builder.set("#items", itemStackArray);
|
||||
builder.set("#options", stringList);
|
||||
```
|
||||
|
||||
### Remove Content
|
||||
|
||||
```java
|
||||
// Clear children of an element
|
||||
builder.clear("#container");
|
||||
|
||||
// Remove an element entirely
|
||||
builder.remove("#element_id");
|
||||
|
||||
// Insert before an element
|
||||
builder.insertBefore("#existing", "Pages/NewElement.ui");
|
||||
```
|
||||
|
||||
## UIEventBuilder
|
||||
|
||||
Bind events to UI elements using `addEventBinding`:
|
||||
|
||||
```java
|
||||
import com.hypixel.hytale.protocol.packets.interface_.CustomUIEventBindingType;
|
||||
import com.hypixel.hytale.server.core.ui.builder.EventData;
|
||||
|
||||
@Override
|
||||
public void build(Ref<EntityStore> ref, UICommandBuilder builder,
|
||||
UIEventBuilder events, Store<EntityStore> store) {
|
||||
builder.append("Pages/Menu.ui");
|
||||
|
||||
// Bind click events using addEventBinding
|
||||
events.addEventBinding(CustomUIEventBindingType.Activating, "#button_start",
|
||||
EventData.of("Action", "start_game"));
|
||||
events.addEventBinding(CustomUIEventBindingType.Activating, "#button_settings",
|
||||
EventData.of("Action", "open_settings"));
|
||||
}
|
||||
```
|
||||
|
||||
### Event Binding Types
|
||||
|
||||
| Type | Description |
|
||||
|------|-------------|
|
||||
| `Activating` | Button click/activation |
|
||||
| `RightClicking` | Right-click action |
|
||||
| `DoubleClicking` | Double-click action |
|
||||
| `MouseEntered` | Mouse hover enter |
|
||||
| `MouseExited` | Mouse hover exit |
|
||||
| `ValueChanged` | Input value changed |
|
||||
| `FocusGained` | Element focused |
|
||||
| `FocusLost` | Element lost focus |
|
||||
|
||||
## Handling Events
|
||||
|
||||
Override `handleDataEvent` to process user interactions. The `rawData` parameter contains JSON with the event data:
|
||||
|
||||
```java
|
||||
public class MenuPage extends CustomUIPage {
|
||||
|
||||
public MenuPage(PlayerRef ref) {
|
||||
super(ref, CustomPageLifetime.CanDismiss);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void build(Ref<EntityStore> ref, UICommandBuilder builder,
|
||||
UIEventBuilder events, Store<EntityStore> store) {
|
||||
builder.append("Pages/MainMenu.ui");
|
||||
|
||||
events.addEventBinding(CustomUIEventBindingType.Activating, "#play_button",
|
||||
EventData.of("Action", "play"));
|
||||
events.addEventBinding(CustomUIEventBindingType.Activating, "#quit_button",
|
||||
EventData.of("Action", "quit"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleDataEvent(Ref<EntityStore> ref, Store<EntityStore> store, String rawData) {
|
||||
// rawData contains JSON like: {"Action":"play"}
|
||||
if (rawData.contains("\"Action\":\"play\"")) {
|
||||
startGame();
|
||||
} else if (rawData.contains("\"Action\":\"quit\"")) {
|
||||
close();
|
||||
}
|
||||
}
|
||||
|
||||
private void startGame() {
|
||||
// Game logic...
|
||||
close(); // Close the page
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
{{< callout type="info" >}}
|
||||
**Tip:** For more complex event handling, consider using a JSON parser library or extending `InteractiveCustomUIPage<T>` with a typed data class.
|
||||
{{< /callout >}}
|
||||
|
||||
## Opening Pages
|
||||
|
||||
Use `PageManager` to open pages:
|
||||
|
||||
```java
|
||||
Player player = ...;
|
||||
PageManager pageManager = player.getPageManager();
|
||||
|
||||
// Open custom page
|
||||
pageManager.openCustomPage(
|
||||
player.getReference(),
|
||||
player.getReference().getStore(),
|
||||
new MenuPage(player.getPlayerRef())
|
||||
);
|
||||
```
|
||||
|
||||
## Closing Pages
|
||||
|
||||
```java
|
||||
// From within the page
|
||||
protected void close() {
|
||||
// Inherited method - closes this page
|
||||
}
|
||||
|
||||
// From outside
|
||||
pageManager.setPage(ref, store, Page.None);
|
||||
```
|
||||
|
||||
## Updating Pages
|
||||
|
||||
Update content without rebuilding:
|
||||
|
||||
```java
|
||||
// Send update with new commands
|
||||
UICommandBuilder update = new UICommandBuilder();
|
||||
update.set("#score", newScore);
|
||||
sendUpdate(update);
|
||||
|
||||
// Full rebuild
|
||||
rebuild();
|
||||
|
||||
// Clear and update
|
||||
sendUpdate(update, true); // clear=true
|
||||
```
|
||||
|
||||
## Page with Windows
|
||||
|
||||
Open pages alongside inventory windows:
|
||||
|
||||
```java
|
||||
// Open page with windows
|
||||
pageManager.openCustomPageWithWindows(
|
||||
ref, store,
|
||||
new CraftingPage(playerRef),
|
||||
craftingWindow,
|
||||
playerInventoryWindow
|
||||
);
|
||||
```
|
||||
|
||||
## Interactive Page Example
|
||||
|
||||
```java
|
||||
public class ShopPage extends CustomUIPage {
|
||||
|
||||
private int selectedItem = -1;
|
||||
private final List<ShopItem> items;
|
||||
|
||||
public ShopPage(PlayerRef ref, List<ShopItem> items) {
|
||||
super(ref, CustomPageLifetime.CanDismiss);
|
||||
this.items = items;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void build(Ref<EntityStore> ref, UICommandBuilder builder,
|
||||
UIEventBuilder events, Store<EntityStore> store) {
|
||||
builder.append("Pages/Shop.ui");
|
||||
|
||||
// Populate items
|
||||
for (int i = 0; i < items.size(); i++) {
|
||||
ShopItem item = items.get(i);
|
||||
builder.set("#item_" + i + "_name", item.getName());
|
||||
builder.set("#item_" + i + "_price", item.getPrice());
|
||||
events.addEventBinding(CustomUIEventBindingType.Activating, "#item_" + i,
|
||||
EventData.of("Action", "select").append("Index", String.valueOf(i)));
|
||||
}
|
||||
|
||||
events.addEventBinding(CustomUIEventBindingType.Activating, "#buy_button",
|
||||
EventData.of("Action", "buy"));
|
||||
events.addEventBinding(CustomUIEventBindingType.Activating, "#close_button",
|
||||
EventData.of("Action", "close"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleDataEvent(Ref<EntityStore> ref, Store<EntityStore> store, String rawData) {
|
||||
// Parse JSON event data
|
||||
if (rawData.contains("\"Action\":\"select\"")) {
|
||||
// Extract index from JSON
|
||||
int indexStart = rawData.indexOf("\"Index\":\"") + 9;
|
||||
int indexEnd = rawData.indexOf("\"", indexStart);
|
||||
selectedItem = Integer.parseInt(rawData.substring(indexStart, indexEnd));
|
||||
updateSelection();
|
||||
} else if (rawData.contains("\"Action\":\"buy\"") && selectedItem >= 0) {
|
||||
purchaseItem(selectedItem);
|
||||
} else if (rawData.contains("\"Action\":\"close\"")) {
|
||||
close();
|
||||
}
|
||||
}
|
||||
|
||||
private void updateSelection() {
|
||||
UICommandBuilder update = new UICommandBuilder();
|
||||
update.set("#selected_index", selectedItem);
|
||||
update.set("#selected_name", items.get(selectedItem).getName());
|
||||
sendUpdate(update);
|
||||
}
|
||||
|
||||
private void purchaseItem(int index) {
|
||||
// Purchase logic...
|
||||
rebuild(); // Refresh UI
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Built-in Pages
|
||||
|
||||
Available page types:
|
||||
|
||||
| Page | Description |
|
||||
|------|-------------|
|
||||
| `Page.None` | No page open (close current page) |
|
||||
| `Page.Bench` | Crafting/workbench interface |
|
||||
| `Page.Inventory` | Player inventory |
|
||||
| `Page.ToolsSettings` | Tools settings |
|
||||
| `Page.Map` | World map |
|
||||
| `Page.MachinimaEditor` | Machinima editor |
|
||||
| `Page.ContentCreation` | Content creation tools |
|
||||
| `Page.Custom` | Custom UI page |
|
||||
|
||||
```java
|
||||
// Open built-in page
|
||||
pageManager.setPage(ref, store, Page.Inventory);
|
||||
```
|
||||
|
||||
## Best Practices
|
||||
|
||||
{{< callout type="info" >}}
|
||||
**Custom Page Guidelines:**
|
||||
- Use `CanDismiss` unless the page must be modal
|
||||
- Handle the `onDismiss` callback for cleanup
|
||||
- Use `sendUpdate()` for small changes, `rebuild()` for major changes
|
||||
- Store page state in instance fields
|
||||
- Close pages properly using `close()` or `setPage(Page.None)`
|
||||
{{< /callout >}}
|
||||
|
||||
{{< callout type="warning" >}}
|
||||
**Important:** Always check if `playerRef.getReference()` is null before accessing the store, as the player may have disconnected.
|
||||
{{< /callout >}}
|
||||
341
content/ui-systems/custom-pages.fr.md
Normal file
341
content/ui-systems/custom-pages.fr.md
Normal file
@@ -0,0 +1,341 @@
|
||||
---
|
||||
title: Pages Personnalisées
|
||||
type: docs
|
||||
weight: 2
|
||||
---
|
||||
|
||||
Les pages personnalisées permettent aux plugins de créer des overlays UI interactifs qui peuvent recevoir des entrées utilisateur et afficher du contenu dynamique.
|
||||
|
||||
**Package:** `com.hypixel.hytale.server.core.entity.entities.player.pages`
|
||||
|
||||
## Durées de Vie des Pages
|
||||
|
||||
Contrôle comment les pages peuvent être fermées :
|
||||
|
||||
| Durée de Vie | Description |
|
||||
|--------------|-------------|
|
||||
| `CustomPageLifetime.CantClose` | La page ne peut pas être fermée par le joueur |
|
||||
| `CustomPageLifetime.CanDismiss` | Le joueur peut fermer avec Échap |
|
||||
| `CustomPageLifetime.CanDismissOrCloseThroughInteraction` | Peut fermer via Échap ou interaction |
|
||||
|
||||
## Créer une Page Personnalisée
|
||||
|
||||
Étendez `CustomUIPage` :
|
||||
|
||||
```java
|
||||
public class WelcomePage extends CustomUIPage {
|
||||
|
||||
public WelcomePage(PlayerRef playerRef) {
|
||||
super(playerRef, CustomPageLifetime.CanDismiss);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void build(Ref<EntityStore> ref, UICommandBuilder builder,
|
||||
UIEventBuilder events, Store<EntityStore> store) {
|
||||
// Charger un template UI depuis les assets (extension .ui OBLIGATOIRE)
|
||||
builder.append("Pages/WelcomeScreen.ui");
|
||||
|
||||
// Définir des valeurs dynamiques
|
||||
builder.set("#player_name", playerRef.getUsername());
|
||||
builder.set("#server_name", "Mon Serveur");
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## UICommandBuilder
|
||||
|
||||
Construire du contenu UI dynamiquement :
|
||||
|
||||
### Ajouter du Contenu
|
||||
|
||||
```java
|
||||
// Ajouter un template UI (extension .ui OBLIGATOIRE)
|
||||
builder.append("Pages/TemplatePath.ui");
|
||||
|
||||
// Ajouter à un sélecteur spécifique
|
||||
builder.append("#container", "Pages/ChildTemplate.ui");
|
||||
|
||||
// Ajouter du YAML/JSON inline
|
||||
builder.appendInline("#list", "{ type: text, content: 'Bonjour' }");
|
||||
```
|
||||
|
||||
### Définir des Valeurs
|
||||
|
||||
```java
|
||||
// Définir du texte
|
||||
builder.set("#title", "Bienvenue !");
|
||||
builder.set("#description", Message.translation("my.key"));
|
||||
|
||||
// Définir des nombres
|
||||
builder.set("#score", 1500);
|
||||
builder.set("#progress", 0.75f);
|
||||
|
||||
// Définir un booléen
|
||||
builder.set("#visible", true);
|
||||
|
||||
// Mettre à null
|
||||
builder.setNull("#optional_field");
|
||||
```
|
||||
|
||||
### Définir des Objets
|
||||
|
||||
```java
|
||||
// Définir un ItemStack
|
||||
ItemStack item = ...;
|
||||
builder.setObject("#item_display", item);
|
||||
|
||||
// Définir une Zone UI
|
||||
Area area = new Area(0, 0, 100, 50);
|
||||
builder.setObject("#bounds", area);
|
||||
|
||||
// Définir des tableaux/listes
|
||||
builder.set("#items", itemStackArray);
|
||||
builder.set("#options", stringList);
|
||||
```
|
||||
|
||||
### Supprimer du Contenu
|
||||
|
||||
```java
|
||||
// Vider les enfants d'un élément
|
||||
builder.clear("#container");
|
||||
|
||||
// Supprimer un élément entièrement
|
||||
builder.remove("#element_id");
|
||||
|
||||
// Insérer avant un élément
|
||||
builder.insertBefore("#existing", "Pages/NewElement.ui");
|
||||
```
|
||||
|
||||
## UIEventBuilder
|
||||
|
||||
Lier des événements aux éléments UI avec `addEventBinding` :
|
||||
|
||||
```java
|
||||
import com.hypixel.hytale.protocol.packets.interface_.CustomUIEventBindingType;
|
||||
import com.hypixel.hytale.server.core.ui.builder.EventData;
|
||||
|
||||
@Override
|
||||
public void build(Ref<EntityStore> ref, UICommandBuilder builder,
|
||||
UIEventBuilder events, Store<EntityStore> store) {
|
||||
builder.append("Pages/Menu.ui");
|
||||
|
||||
// Lier des événements de clic avec addEventBinding
|
||||
events.addEventBinding(CustomUIEventBindingType.Activating, "#button_start",
|
||||
EventData.of("Action", "start_game"));
|
||||
events.addEventBinding(CustomUIEventBindingType.Activating, "#button_settings",
|
||||
EventData.of("Action", "open_settings"));
|
||||
}
|
||||
```
|
||||
|
||||
### Types de Liaison d'Événements
|
||||
|
||||
| Type | Description |
|
||||
|------|-------------|
|
||||
| `Activating` | Clic/activation de bouton |
|
||||
| `RightClicking` | Action clic droit |
|
||||
| `DoubleClicking` | Action double-clic |
|
||||
| `MouseEntered` | Entrée du survol souris |
|
||||
| `MouseExited` | Sortie du survol souris |
|
||||
| `ValueChanged` | Valeur d'entrée changée |
|
||||
| `FocusGained` | Élément focus |
|
||||
| `FocusLost` | Élément perd le focus |
|
||||
|
||||
## Gérer les Événements
|
||||
|
||||
Surchargez `handleDataEvent` pour traiter les interactions utilisateur. Le paramètre `rawData` contient du JSON avec les données de l'événement :
|
||||
|
||||
```java
|
||||
public class MenuPage extends CustomUIPage {
|
||||
|
||||
public MenuPage(PlayerRef ref) {
|
||||
super(ref, CustomPageLifetime.CanDismiss);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void build(Ref<EntityStore> ref, UICommandBuilder builder,
|
||||
UIEventBuilder events, Store<EntityStore> store) {
|
||||
builder.append("Pages/MainMenu.ui");
|
||||
|
||||
events.addEventBinding(CustomUIEventBindingType.Activating, "#play_button",
|
||||
EventData.of("Action", "play"));
|
||||
events.addEventBinding(CustomUIEventBindingType.Activating, "#quit_button",
|
||||
EventData.of("Action", "quit"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleDataEvent(Ref<EntityStore> ref, Store<EntityStore> store, String rawData) {
|
||||
// rawData contient du JSON comme : {"Action":"play"}
|
||||
if (rawData.contains("\"Action\":\"play\"")) {
|
||||
startGame();
|
||||
} else if (rawData.contains("\"Action\":\"quit\"")) {
|
||||
close();
|
||||
}
|
||||
}
|
||||
|
||||
private void startGame() {
|
||||
// Logique de jeu...
|
||||
close(); // Fermer la page
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
{{< callout type="info" >}}
|
||||
**Conseil :** Pour une gestion d'événements plus complexe, envisagez d'utiliser une bibliothèque de parsing JSON ou d'étendre `InteractiveCustomUIPage<T>` avec une classe de données typée.
|
||||
{{< /callout >}}
|
||||
|
||||
## Ouvrir des Pages
|
||||
|
||||
Utilisez `PageManager` pour ouvrir des pages :
|
||||
|
||||
```java
|
||||
Player player = ...;
|
||||
PageManager pageManager = player.getPageManager();
|
||||
|
||||
// Ouvrir une page personnalisée
|
||||
pageManager.openCustomPage(
|
||||
player.getReference(),
|
||||
player.getReference().getStore(),
|
||||
new MenuPage(player.getPlayerRef())
|
||||
);
|
||||
```
|
||||
|
||||
## Fermer des Pages
|
||||
|
||||
```java
|
||||
// Depuis l'intérieur de la page
|
||||
protected void close() {
|
||||
// Méthode héritée - ferme cette page
|
||||
}
|
||||
|
||||
// Depuis l'extérieur
|
||||
pageManager.setPage(ref, store, Page.None);
|
||||
```
|
||||
|
||||
## Mettre à Jour des Pages
|
||||
|
||||
Mettre à jour le contenu sans reconstruire :
|
||||
|
||||
```java
|
||||
// Envoyer une mise à jour avec de nouvelles commandes
|
||||
UICommandBuilder update = new UICommandBuilder();
|
||||
update.set("#score", newScore);
|
||||
sendUpdate(update);
|
||||
|
||||
// Reconstruction complète
|
||||
rebuild();
|
||||
|
||||
// Vider et mettre à jour
|
||||
sendUpdate(update, true); // clear=true
|
||||
```
|
||||
|
||||
## Page avec Fenêtres
|
||||
|
||||
Ouvrir des pages avec des fenêtres d'inventaire :
|
||||
|
||||
```java
|
||||
// Ouvrir une page avec des fenêtres
|
||||
pageManager.openCustomPageWithWindows(
|
||||
ref, store,
|
||||
new CraftingPage(playerRef),
|
||||
craftingWindow,
|
||||
playerInventoryWindow
|
||||
);
|
||||
```
|
||||
|
||||
## Exemple de Page Interactive
|
||||
|
||||
```java
|
||||
public class ShopPage extends CustomUIPage {
|
||||
|
||||
private int selectedItem = -1;
|
||||
private final List<ShopItem> items;
|
||||
|
||||
public ShopPage(PlayerRef ref, List<ShopItem> items) {
|
||||
super(ref, CustomPageLifetime.CanDismiss);
|
||||
this.items = items;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void build(Ref<EntityStore> ref, UICommandBuilder builder,
|
||||
UIEventBuilder events, Store<EntityStore> store) {
|
||||
builder.append("Pages/Shop.ui");
|
||||
|
||||
// Peupler les items
|
||||
for (int i = 0; i < items.size(); i++) {
|
||||
ShopItem item = items.get(i);
|
||||
builder.set("#item_" + i + "_name", item.getName());
|
||||
builder.set("#item_" + i + "_price", item.getPrice());
|
||||
events.addEventBinding(CustomUIEventBindingType.Activating, "#item_" + i,
|
||||
EventData.of("Action", "select").append("Index", String.valueOf(i)));
|
||||
}
|
||||
|
||||
events.addEventBinding(CustomUIEventBindingType.Activating, "#buy_button",
|
||||
EventData.of("Action", "buy"));
|
||||
events.addEventBinding(CustomUIEventBindingType.Activating, "#close_button",
|
||||
EventData.of("Action", "close"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleDataEvent(Ref<EntityStore> ref, Store<EntityStore> store, String rawData) {
|
||||
// Parser les données JSON de l'événement
|
||||
if (rawData.contains("\"Action\":\"select\"")) {
|
||||
// Extraire l'index du JSON
|
||||
int indexStart = rawData.indexOf("\"Index\":\"") + 9;
|
||||
int indexEnd = rawData.indexOf("\"", indexStart);
|
||||
selectedItem = Integer.parseInt(rawData.substring(indexStart, indexEnd));
|
||||
updateSelection();
|
||||
} else if (rawData.contains("\"Action\":\"buy\"") && selectedItem >= 0) {
|
||||
purchaseItem(selectedItem);
|
||||
} else if (rawData.contains("\"Action\":\"close\"")) {
|
||||
close();
|
||||
}
|
||||
}
|
||||
|
||||
private void updateSelection() {
|
||||
UICommandBuilder update = new UICommandBuilder();
|
||||
update.set("#selected_index", selectedItem);
|
||||
update.set("#selected_name", items.get(selectedItem).getName());
|
||||
sendUpdate(update);
|
||||
}
|
||||
|
||||
private void purchaseItem(int index) {
|
||||
// Logique d'achat...
|
||||
rebuild(); // Rafraîchir l'UI
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Pages Intégrées
|
||||
|
||||
Types de pages disponibles :
|
||||
|
||||
| Page | Description |
|
||||
|------|-------------|
|
||||
| `Page.None` | Pas de page ouverte (fermer la page courante) |
|
||||
| `Page.Bench` | Interface d'établi/crafting |
|
||||
| `Page.Inventory` | Inventaire du joueur |
|
||||
| `Page.ToolsSettings` | Paramètres des outils |
|
||||
| `Page.Map` | Carte du monde |
|
||||
| `Page.MachinimaEditor` | Éditeur de machinima |
|
||||
| `Page.ContentCreation` | Outils de création de contenu |
|
||||
| `Page.Custom` | Page UI personnalisée |
|
||||
|
||||
```java
|
||||
// Ouvrir une page intégrée
|
||||
pageManager.setPage(ref, store, Page.Inventory);
|
||||
```
|
||||
|
||||
## Bonnes Pratiques
|
||||
|
||||
{{< callout type="info" >}}
|
||||
**Directives des Pages Personnalisées :**
|
||||
- Utilisez `CanDismiss` sauf si la page doit être modale
|
||||
- Gérez le callback `onDismiss` pour le nettoyage
|
||||
- Utilisez `sendUpdate()` pour les petits changements, `rebuild()` pour les changements majeurs
|
||||
- Stockez l'état de la page dans des champs d'instance
|
||||
- Fermez correctement les pages en utilisant `close()` ou `setPage(Page.None)`
|
||||
{{< /callout >}}
|
||||
|
||||
{{< callout type="warning" >}}
|
||||
**Important :** Vérifiez toujours si `playerRef.getReference()` est null avant d'accéder au store, car le joueur peut s'être déconnecté.
|
||||
{{< /callout >}}
|
||||
232
content/ui-systems/hud-manager.en.md
Normal file
232
content/ui-systems/hud-manager.en.md
Normal file
@@ -0,0 +1,232 @@
|
||||
---
|
||||
title: HUD Manager
|
||||
type: docs
|
||||
weight: 1
|
||||
---
|
||||
|
||||
The `HudManager` controls which HUD components are visible to the player.
|
||||
|
||||
**Package:** `com.hypixel.hytale.server.core.entity.entities.player.hud`
|
||||
|
||||
## HUD Components
|
||||
|
||||
All available HUD components:
|
||||
|
||||
| Component | Description |
|
||||
|-----------|-------------|
|
||||
| `HudComponent.Hotbar` | Player's item hotbar |
|
||||
| `HudComponent.StatusIcons` | Status effect icons |
|
||||
| `HudComponent.Reticle` | Crosshair/targeting reticle |
|
||||
| `HudComponent.Chat` | Chat window |
|
||||
| `HudComponent.Requests` | Pending requests UI |
|
||||
| `HudComponent.Notifications` | Alert notifications |
|
||||
| `HudComponent.KillFeed` | Kill/death messages |
|
||||
| `HudComponent.InputBindings` | Control hints |
|
||||
| `HudComponent.PlayerList` | Tab player list |
|
||||
| `HudComponent.EventTitle` | Large event titles |
|
||||
| `HudComponent.Compass` | Direction compass |
|
||||
| `HudComponent.ObjectivePanel` | Quest/objective tracker |
|
||||
| `HudComponent.PortalPanel` | Portal interface |
|
||||
| `HudComponent.BuilderToolsLegend` | Builder tool hints |
|
||||
| `HudComponent.Speedometer` | Speed indicator |
|
||||
| `HudComponent.UtilitySlotSelector` | Utility slot UI |
|
||||
| `HudComponent.BlockVariantSelector` | Block variant picker |
|
||||
| `HudComponent.BuilderToolsMaterialSlotSelector` | Builder material slots |
|
||||
| `HudComponent.Stamina` | Stamina bar |
|
||||
| `HudComponent.AmmoIndicator` | Ammunition counter |
|
||||
| `HudComponent.Health` | Health bar |
|
||||
| `HudComponent.Mana` | Mana bar |
|
||||
| `HudComponent.Oxygen` | Oxygen/breath bar |
|
||||
| `HudComponent.Sleep` | Sleep indicator |
|
||||
|
||||
## Default Components
|
||||
|
||||
These components are visible by default:
|
||||
|
||||
```java
|
||||
Set<HudComponent> DEFAULT = Set.of(
|
||||
HudComponent.UtilitySlotSelector,
|
||||
HudComponent.BlockVariantSelector,
|
||||
HudComponent.StatusIcons,
|
||||
HudComponent.Hotbar,
|
||||
HudComponent.Chat,
|
||||
HudComponent.Notifications,
|
||||
HudComponent.KillFeed,
|
||||
HudComponent.InputBindings,
|
||||
HudComponent.Reticle,
|
||||
HudComponent.Compass,
|
||||
HudComponent.Speedometer,
|
||||
HudComponent.ObjectivePanel,
|
||||
HudComponent.PortalPanel,
|
||||
HudComponent.EventTitle,
|
||||
HudComponent.Stamina,
|
||||
HudComponent.AmmoIndicator,
|
||||
HudComponent.Health,
|
||||
HudComponent.Mana,
|
||||
HudComponent.Oxygen,
|
||||
HudComponent.BuilderToolsLegend,
|
||||
HudComponent.Sleep
|
||||
);
|
||||
```
|
||||
|
||||
## Accessing the HUD Manager
|
||||
|
||||
```java
|
||||
Player player = ...;
|
||||
HudManager hudManager = player.getHudManager();
|
||||
```
|
||||
|
||||
## Showing Components
|
||||
|
||||
```java
|
||||
// Show specific components (additive)
|
||||
hudManager.showHudComponents(player.getPlayerRef(),
|
||||
HudComponent.Health,
|
||||
HudComponent.Stamina,
|
||||
HudComponent.Hotbar
|
||||
);
|
||||
|
||||
// Show from a Set
|
||||
Set<HudComponent> components = Set.of(
|
||||
HudComponent.Chat,
|
||||
HudComponent.Notifications
|
||||
);
|
||||
hudManager.showHudComponents(player.getPlayerRef(), components);
|
||||
```
|
||||
|
||||
## Hiding Components
|
||||
|
||||
```java
|
||||
// Hide specific components
|
||||
hudManager.hideHudComponents(player.getPlayerRef(),
|
||||
HudComponent.Compass,
|
||||
HudComponent.Speedometer
|
||||
);
|
||||
```
|
||||
|
||||
## Setting Components
|
||||
|
||||
Replace all visible components:
|
||||
|
||||
```java
|
||||
// Set exact visible components (replaces all)
|
||||
hudManager.setVisibleHudComponents(player.getPlayerRef(),
|
||||
HudComponent.Hotbar,
|
||||
HudComponent.Health
|
||||
);
|
||||
|
||||
// Clear all HUD components (empty)
|
||||
hudManager.setVisibleHudComponents(player.getPlayerRef());
|
||||
```
|
||||
|
||||
## Querying Visible Components
|
||||
|
||||
```java
|
||||
Set<HudComponent> visible = hudManager.getVisibleHudComponents();
|
||||
|
||||
if (visible.contains(HudComponent.Health)) {
|
||||
// Health bar is visible
|
||||
}
|
||||
```
|
||||
|
||||
## Resetting the HUD
|
||||
|
||||
```java
|
||||
// Reset to default components and clear custom HUD
|
||||
hudManager.resetHud(player.getPlayerRef());
|
||||
|
||||
// Reset entire UI state
|
||||
hudManager.resetUserInterface(player.getPlayerRef());
|
||||
```
|
||||
|
||||
## Custom HUD Overlay
|
||||
|
||||
For persistent overlays:
|
||||
|
||||
```java
|
||||
public class ScoreboardHud extends CustomUIHud {
|
||||
|
||||
public ScoreboardHud(PlayerRef ref) {
|
||||
super(ref);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void build(UICommandBuilder builder) {
|
||||
// Extension .ui is REQUIRED
|
||||
builder.append("Hud/Scoreboard.ui");
|
||||
builder.set("#score", 1500);
|
||||
builder.set("#rank", "Gold");
|
||||
}
|
||||
}
|
||||
|
||||
// Set custom HUD
|
||||
hudManager.setCustomHud(player.getPlayerRef(), new ScoreboardHud(player.getPlayerRef()));
|
||||
|
||||
// Remove custom HUD
|
||||
hudManager.setCustomHud(player.getPlayerRef(), null);
|
||||
```
|
||||
|
||||
## Practical Examples
|
||||
|
||||
### Cinematic Mode
|
||||
|
||||
Hide all UI for cutscenes:
|
||||
|
||||
```java
|
||||
public void enterCinematicMode(Player player) {
|
||||
HudManager hud = player.getHudManager();
|
||||
|
||||
// Store current state if needed for restoration
|
||||
Set<HudComponent> previous = new HashSet<>(hud.getVisibleHudComponents());
|
||||
|
||||
// Clear all HUD
|
||||
hud.setVisibleHudComponents(player.getPlayerRef());
|
||||
}
|
||||
|
||||
public void exitCinematicMode(Player player, Set<HudComponent> restore) {
|
||||
player.getHudManager().setVisibleHudComponents(player.getPlayerRef(), restore);
|
||||
}
|
||||
```
|
||||
|
||||
### Minimal HUD Mode
|
||||
|
||||
Show only essential components:
|
||||
|
||||
```java
|
||||
public void setMinimalHud(Player player) {
|
||||
player.getHudManager().setVisibleHudComponents(player.getPlayerRef(),
|
||||
HudComponent.Hotbar,
|
||||
HudComponent.Health,
|
||||
HudComponent.Reticle
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
### Builder Mode HUD
|
||||
|
||||
Show builder-specific components:
|
||||
|
||||
```java
|
||||
public void enableBuilderHud(Player player) {
|
||||
HudManager hud = player.getHudManager();
|
||||
hud.showHudComponents(player.getPlayerRef(),
|
||||
HudComponent.BuilderToolsLegend,
|
||||
HudComponent.BuilderToolsMaterialSlotSelector,
|
||||
HudComponent.BlockVariantSelector
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
## Best Practices
|
||||
|
||||
{{< callout type="info" >}}
|
||||
**HUD Guidelines:**
|
||||
- Always use `PlayerRef` when calling HUD methods
|
||||
- Store previous state before clearing if you need to restore later
|
||||
- Consider game mode when deciding which components to show
|
||||
- Use `resetHud()` to return to default state
|
||||
{{< /callout >}}
|
||||
|
||||
{{< callout type="warning" >}}
|
||||
**Performance Note:** Avoid rapid toggling of HUD components as each change sends packets to the client.
|
||||
{{< /callout >}}
|
||||
232
content/ui-systems/hud-manager.fr.md
Normal file
232
content/ui-systems/hud-manager.fr.md
Normal file
@@ -0,0 +1,232 @@
|
||||
---
|
||||
title: Gestionnaire HUD
|
||||
type: docs
|
||||
weight: 1
|
||||
---
|
||||
|
||||
Le `HudManager` contrôle quels composants HUD sont visibles pour le joueur.
|
||||
|
||||
**Package:** `com.hypixel.hytale.server.core.entity.entities.player.hud`
|
||||
|
||||
## Composants HUD
|
||||
|
||||
Tous les composants HUD disponibles :
|
||||
|
||||
| Composant | Description |
|
||||
|-----------|-------------|
|
||||
| `HudComponent.Hotbar` | Barre d'objets du joueur |
|
||||
| `HudComponent.StatusIcons` | Icônes d'effets de statut |
|
||||
| `HudComponent.Reticle` | Réticule/viseur |
|
||||
| `HudComponent.Chat` | Fenêtre de chat |
|
||||
| `HudComponent.Requests` | UI des demandes en attente |
|
||||
| `HudComponent.Notifications` | Notifications d'alerte |
|
||||
| `HudComponent.KillFeed` | Messages de kill/mort |
|
||||
| `HudComponent.InputBindings` | Indications de contrôle |
|
||||
| `HudComponent.PlayerList` | Liste des joueurs (Tab) |
|
||||
| `HudComponent.EventTitle` | Grands titres d'événements |
|
||||
| `HudComponent.Compass` | Boussole de direction |
|
||||
| `HudComponent.ObjectivePanel` | Suivi de quêtes/objectifs |
|
||||
| `HudComponent.PortalPanel` | Interface de portail |
|
||||
| `HudComponent.BuilderToolsLegend` | Indications d'outils de construction |
|
||||
| `HudComponent.Speedometer` | Indicateur de vitesse |
|
||||
| `HudComponent.UtilitySlotSelector` | UI des slots d'utilitaires |
|
||||
| `HudComponent.BlockVariantSelector` | Sélecteur de variantes de blocs |
|
||||
| `HudComponent.BuilderToolsMaterialSlotSelector` | Slots de matériaux du builder |
|
||||
| `HudComponent.Stamina` | Barre d'endurance |
|
||||
| `HudComponent.AmmoIndicator` | Compteur de munitions |
|
||||
| `HudComponent.Health` | Barre de vie |
|
||||
| `HudComponent.Mana` | Barre de mana |
|
||||
| `HudComponent.Oxygen` | Barre d'oxygène/respiration |
|
||||
| `HudComponent.Sleep` | Indicateur de sommeil |
|
||||
|
||||
## Composants par Défaut
|
||||
|
||||
Ces composants sont visibles par défaut :
|
||||
|
||||
```java
|
||||
Set<HudComponent> DEFAULT = Set.of(
|
||||
HudComponent.UtilitySlotSelector,
|
||||
HudComponent.BlockVariantSelector,
|
||||
HudComponent.StatusIcons,
|
||||
HudComponent.Hotbar,
|
||||
HudComponent.Chat,
|
||||
HudComponent.Notifications,
|
||||
HudComponent.KillFeed,
|
||||
HudComponent.InputBindings,
|
||||
HudComponent.Reticle,
|
||||
HudComponent.Compass,
|
||||
HudComponent.Speedometer,
|
||||
HudComponent.ObjectivePanel,
|
||||
HudComponent.PortalPanel,
|
||||
HudComponent.EventTitle,
|
||||
HudComponent.Stamina,
|
||||
HudComponent.AmmoIndicator,
|
||||
HudComponent.Health,
|
||||
HudComponent.Mana,
|
||||
HudComponent.Oxygen,
|
||||
HudComponent.BuilderToolsLegend,
|
||||
HudComponent.Sleep
|
||||
);
|
||||
```
|
||||
|
||||
## Accéder au Gestionnaire HUD
|
||||
|
||||
```java
|
||||
Player player = ...;
|
||||
HudManager hudManager = player.getHudManager();
|
||||
```
|
||||
|
||||
## Afficher des Composants
|
||||
|
||||
```java
|
||||
// Afficher des composants spécifiques (additif)
|
||||
hudManager.showHudComponents(player.getPlayerRef(),
|
||||
HudComponent.Health,
|
||||
HudComponent.Stamina,
|
||||
HudComponent.Hotbar
|
||||
);
|
||||
|
||||
// Afficher depuis un Set
|
||||
Set<HudComponent> components = Set.of(
|
||||
HudComponent.Chat,
|
||||
HudComponent.Notifications
|
||||
);
|
||||
hudManager.showHudComponents(player.getPlayerRef(), components);
|
||||
```
|
||||
|
||||
## Masquer des Composants
|
||||
|
||||
```java
|
||||
// Masquer des composants spécifiques
|
||||
hudManager.hideHudComponents(player.getPlayerRef(),
|
||||
HudComponent.Compass,
|
||||
HudComponent.Speedometer
|
||||
);
|
||||
```
|
||||
|
||||
## Définir les Composants
|
||||
|
||||
Remplacer tous les composants visibles :
|
||||
|
||||
```java
|
||||
// Définir exactement les composants visibles (remplace tout)
|
||||
hudManager.setVisibleHudComponents(player.getPlayerRef(),
|
||||
HudComponent.Hotbar,
|
||||
HudComponent.Health
|
||||
);
|
||||
|
||||
// Vider tous les composants HUD
|
||||
hudManager.setVisibleHudComponents(player.getPlayerRef());
|
||||
```
|
||||
|
||||
## Requêter les Composants Visibles
|
||||
|
||||
```java
|
||||
Set<HudComponent> visible = hudManager.getVisibleHudComponents();
|
||||
|
||||
if (visible.contains(HudComponent.Health)) {
|
||||
// La barre de vie est visible
|
||||
}
|
||||
```
|
||||
|
||||
## Réinitialiser le HUD
|
||||
|
||||
```java
|
||||
// Réinitialiser aux composants par défaut et vider le HUD personnalisé
|
||||
hudManager.resetHud(player.getPlayerRef());
|
||||
|
||||
// Réinitialiser l'état UI complet
|
||||
hudManager.resetUserInterface(player.getPlayerRef());
|
||||
```
|
||||
|
||||
## HUD Personnalisé
|
||||
|
||||
Pour les overlays persistants :
|
||||
|
||||
```java
|
||||
public class ScoreboardHud extends CustomUIHud {
|
||||
|
||||
public ScoreboardHud(PlayerRef ref) {
|
||||
super(ref);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void build(UICommandBuilder builder) {
|
||||
// L'extension .ui est OBLIGATOIRE
|
||||
builder.append("Hud/Scoreboard.ui");
|
||||
builder.set("#score", 1500);
|
||||
builder.set("#rank", "Or");
|
||||
}
|
||||
}
|
||||
|
||||
// Définir le HUD personnalisé
|
||||
hudManager.setCustomHud(player.getPlayerRef(), new ScoreboardHud(player.getPlayerRef()));
|
||||
|
||||
// Supprimer le HUD personnalisé
|
||||
hudManager.setCustomHud(player.getPlayerRef(), null);
|
||||
```
|
||||
|
||||
## Exemples Pratiques
|
||||
|
||||
### Mode Cinématique
|
||||
|
||||
Masquer toute l'UI pour les cinématiques :
|
||||
|
||||
```java
|
||||
public void enterCinematicMode(Player player) {
|
||||
HudManager hud = player.getHudManager();
|
||||
|
||||
// Stocker l'état actuel si nécessaire pour restauration
|
||||
Set<HudComponent> previous = new HashSet<>(hud.getVisibleHudComponents());
|
||||
|
||||
// Vider tout le HUD
|
||||
hud.setVisibleHudComponents(player.getPlayerRef());
|
||||
}
|
||||
|
||||
public void exitCinematicMode(Player player, Set<HudComponent> restore) {
|
||||
player.getHudManager().setVisibleHudComponents(player.getPlayerRef(), restore);
|
||||
}
|
||||
```
|
||||
|
||||
### Mode HUD Minimal
|
||||
|
||||
N'afficher que les composants essentiels :
|
||||
|
||||
```java
|
||||
public void setMinimalHud(Player player) {
|
||||
player.getHudManager().setVisibleHudComponents(player.getPlayerRef(),
|
||||
HudComponent.Hotbar,
|
||||
HudComponent.Health,
|
||||
HudComponent.Reticle
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
### HUD Mode Construction
|
||||
|
||||
Afficher les composants spécifiques au builder :
|
||||
|
||||
```java
|
||||
public void enableBuilderHud(Player player) {
|
||||
HudManager hud = player.getHudManager();
|
||||
hud.showHudComponents(player.getPlayerRef(),
|
||||
HudComponent.BuilderToolsLegend,
|
||||
HudComponent.BuilderToolsMaterialSlotSelector,
|
||||
HudComponent.BlockVariantSelector
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
## Bonnes Pratiques
|
||||
|
||||
{{< callout type="info" >}}
|
||||
**Directives HUD :**
|
||||
- Utilisez toujours `PlayerRef` lors de l'appel des méthodes HUD
|
||||
- Stockez l'état précédent avant de vider si vous devez restaurer plus tard
|
||||
- Considérez le mode de jeu lors du choix des composants à afficher
|
||||
- Utilisez `resetHud()` pour revenir à l'état par défaut
|
||||
{{< /callout >}}
|
||||
|
||||
{{< callout type="warning" >}}
|
||||
**Note de Performance :** Évitez le basculement rapide des composants HUD car chaque changement envoie des paquets au client.
|
||||
{{< /callout >}}
|
||||
349
content/ui-systems/permissions/_index.en.md
Normal file
349
content/ui-systems/permissions/_index.en.md
Normal file
@@ -0,0 +1,349 @@
|
||||
---
|
||||
title: Permissions System
|
||||
type: docs
|
||||
weight: 12
|
||||
---
|
||||
|
||||
The Permissions system provides fine-grained access control for commands, editor features, and custom plugin functionality.
|
||||
|
||||
**Package:** `com.hypixel.hytale.server.core.permissions`
|
||||
|
||||
## Overview
|
||||
|
||||
Hytale uses a permission system with:
|
||||
- **User permissions** - Directly assigned to individual players
|
||||
- **Group permissions** - Inherited by all members of a group
|
||||
- **Permission providers** - Custom logic for dynamic permissions
|
||||
|
||||
## Accessing the Permissions Module
|
||||
|
||||
```java
|
||||
import com.hypixel.hytale.server.core.permissions.PermissionsModule;
|
||||
|
||||
// Use static get() method - NOT HytaleServer.get().getPermissionsModule()
|
||||
PermissionsModule permissions = PermissionsModule.get();
|
||||
```
|
||||
|
||||
## Checking Permissions
|
||||
|
||||
```java
|
||||
UUID playerUuid = player.getPlayerRef().getUuid();
|
||||
|
||||
// Check if player has permission
|
||||
boolean canEdit = permissions.hasPermission(playerUuid, "hytale.editor.asset");
|
||||
|
||||
// Check in command context
|
||||
if (permissions.hasPermission(ctx.sender().getUuid(), "myplugin.admin")) {
|
||||
// Admin-only logic
|
||||
}
|
||||
```
|
||||
|
||||
## User Permissions
|
||||
|
||||
Manage permissions for individual players:
|
||||
|
||||
```java
|
||||
UUID playerUuid = player.getPlayerRef().getUuid();
|
||||
|
||||
// Add permissions
|
||||
permissions.addUserPermission(playerUuid, Set.of(
|
||||
"myplugin.feature.create",
|
||||
"myplugin.feature.delete"
|
||||
));
|
||||
|
||||
// Remove permissions
|
||||
permissions.removeUserPermission(playerUuid, Set.of(
|
||||
"myplugin.feature.delete"
|
||||
));
|
||||
```
|
||||
|
||||
## Group Permissions
|
||||
|
||||
Groups allow shared permissions across multiple players:
|
||||
|
||||
### Managing Groups
|
||||
|
||||
```java
|
||||
// Add player to a group
|
||||
permissions.addUserToGroup(playerUuid, "moderators");
|
||||
|
||||
// Remove player from a group
|
||||
permissions.removeUserFromGroup(playerUuid, "moderators");
|
||||
|
||||
// Get all groups for a player
|
||||
Set<String> groups = permissions.getGroupsForUser(playerUuid);
|
||||
```
|
||||
|
||||
### Group Permission Events
|
||||
|
||||
Listen for group changes using specific event subclasses:
|
||||
|
||||
```java
|
||||
import com.hypixel.hytale.server.core.event.events.permissions.*;
|
||||
|
||||
// Player ADDED to group
|
||||
getEventRegistry().register(PlayerGroupEvent.Added.class, event -> {
|
||||
UUID playerUuid = event.getPlayerUuid();
|
||||
String group = event.getGroupName(); // Note: getGroupName(), NOT getGroup()
|
||||
log("Player joined group: " + group);
|
||||
});
|
||||
|
||||
// Player REMOVED from group
|
||||
getEventRegistry().register(PlayerGroupEvent.Removed.class, event -> {
|
||||
UUID playerUuid = event.getPlayerUuid();
|
||||
String group = event.getGroupName();
|
||||
log("Player left group: " + group);
|
||||
});
|
||||
|
||||
// Group permissions ADDED
|
||||
getEventRegistry().register(GroupPermissionChangeEvent.Added.class, event -> {
|
||||
String group = event.getGroupName();
|
||||
Set<String> added = event.getAddedPermissions();
|
||||
log("Group " + group + " got permissions: " + added);
|
||||
});
|
||||
|
||||
// Group permissions REMOVED
|
||||
getEventRegistry().register(GroupPermissionChangeEvent.Removed.class, event -> {
|
||||
String group = event.getGroupName();
|
||||
Set<String> removed = event.getRemovedPermissions();
|
||||
log("Group " + group + " lost permissions: " + removed);
|
||||
});
|
||||
|
||||
// Player permissions ADDED
|
||||
getEventRegistry().register(PlayerPermissionChangeEvent.PermissionsAdded.class, event -> {
|
||||
UUID playerUuid = event.getPlayerUuid();
|
||||
Set<String> added = event.getAddedPermissions();
|
||||
});
|
||||
|
||||
// Player permissions REMOVED
|
||||
getEventRegistry().register(PlayerPermissionChangeEvent.PermissionsRemoved.class, event -> {
|
||||
UUID playerUuid = event.getPlayerUuid();
|
||||
Set<String> removed = event.getRemovedPermissions();
|
||||
});
|
||||
```
|
||||
|
||||
## Built-in Permissions
|
||||
|
||||
Hytale includes many built-in permissions:
|
||||
|
||||
### Command Permissions
|
||||
|
||||
| Permission | Description |
|
||||
|------------|-------------|
|
||||
| `hytale.command.*` | All command access |
|
||||
| `hytale.command.gamemode` | Change game mode |
|
||||
| `hytale.command.tp` | Teleportation |
|
||||
| `hytale.command.give` | Give items |
|
||||
| `hytale.command.time` | Time control |
|
||||
|
||||
### Editor Permissions
|
||||
|
||||
| Permission | Description |
|
||||
|------------|-------------|
|
||||
| `hytale.editor.asset` | Asset editing |
|
||||
| `hytale.editor.packs.*` | Pack management |
|
||||
| `hytale.editor.builderTools` | Builder tools access |
|
||||
| `hytale.editor.brush.*` | Brush tools |
|
||||
| `hytale.editor.prefab.*` | Prefab editing |
|
||||
| `hytale.editor.selection.*` | Selection tools |
|
||||
| `hytale.editor.history` | Undo/redo history |
|
||||
|
||||
### Camera Permissions
|
||||
|
||||
| Permission | Description |
|
||||
|------------|-------------|
|
||||
| `hytale.camera.flycam` | Free camera mode |
|
||||
|
||||
## Custom Permission Provider
|
||||
|
||||
Implement `PermissionProvider` for dynamic permission logic:
|
||||
|
||||
{{< callout type="info" >}}
|
||||
**Note:** `PermissionProvider` is an interface that provides sets of permissions, not a simple hasPermission check. The `PermissionsModule` checks these sets.
|
||||
{{< /callout >}}
|
||||
|
||||
```java
|
||||
import com.hypixel.hytale.server.core.permissions.provider.PermissionProvider;
|
||||
|
||||
public class VIPPermissionProvider implements PermissionProvider {
|
||||
private final Map<UUID, Set<String>> vipPermissions = new ConcurrentHashMap<>();
|
||||
private final Map<UUID, Set<String>> vipGroups = new ConcurrentHashMap<>();
|
||||
|
||||
@Override
|
||||
@Nonnull
|
||||
public String getName() {
|
||||
return "VIPPermissionProvider";
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<String> getUserPermissions(@Nonnull UUID uuid) {
|
||||
// Return the permissions for this user
|
||||
// VIP users get extra permissions automatically
|
||||
if (isVIP(uuid)) {
|
||||
Set<String> perms = new HashSet<>(vipPermissions.getOrDefault(uuid, Collections.emptySet()));
|
||||
perms.add("vip.lounge");
|
||||
perms.add("vip.cosmetics");
|
||||
return perms;
|
||||
}
|
||||
return vipPermissions.getOrDefault(uuid, Collections.emptySet());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addUserPermissions(@Nonnull UUID uuid, @Nonnull Set<String> permissions) {
|
||||
vipPermissions.computeIfAbsent(uuid, k -> new HashSet<>()).addAll(permissions);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeUserPermissions(@Nonnull UUID uuid, @Nonnull Set<String> permissions) {
|
||||
Set<String> userPerms = vipPermissions.get(uuid);
|
||||
if (userPerms != null) {
|
||||
userPerms.removeAll(permissions);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<String> getGroupPermissions(@Nonnull String group) {
|
||||
return Collections.emptySet();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addGroupPermissions(@Nonnull String group, @Nonnull Set<String> permissions) {}
|
||||
|
||||
@Override
|
||||
public void removeGroupPermissions(@Nonnull String group, @Nonnull Set<String> permissions) {}
|
||||
|
||||
@Override
|
||||
public Set<String> getGroupsForUser(@Nonnull UUID uuid) {
|
||||
return vipGroups.getOrDefault(uuid, Collections.emptySet());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addUserToGroup(@Nonnull UUID uuid, @Nonnull String group) {
|
||||
vipGroups.computeIfAbsent(uuid, k -> new HashSet<>()).add(group);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeUserFromGroup(@Nonnull UUID uuid, @Nonnull String group) {
|
||||
Set<String> groups = vipGroups.get(uuid);
|
||||
if (groups != null) {
|
||||
groups.remove(group);
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isVIP(UUID uuid) {
|
||||
// Your VIP checking logic
|
||||
return vipDatabase.contains(uuid);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Registering Custom Providers
|
||||
|
||||
```java
|
||||
@Override
|
||||
public void start() {
|
||||
PermissionsModule permissions = PermissionsModule.get();
|
||||
permissions.addProvider(new VIPPermissionProvider());
|
||||
}
|
||||
```
|
||||
|
||||
## Permission Wildcards
|
||||
|
||||
Permissions support wildcard matching:
|
||||
|
||||
```java
|
||||
// Grant all permissions under a namespace
|
||||
permissions.addUserPermission(playerUuid, Set.of("myplugin.*"));
|
||||
|
||||
// This now passes:
|
||||
permissions.hasPermission(playerUuid, "myplugin.anything");
|
||||
permissions.hasPermission(playerUuid, "myplugin.feature.nested");
|
||||
```
|
||||
|
||||
## Command Permission Integration
|
||||
|
||||
Commands automatically check permissions based on their ID:
|
||||
|
||||
```java
|
||||
public class AdminCommand extends AbstractCommand {
|
||||
|
||||
public AdminCommand() {
|
||||
super("admin", "myplugin.commands.admin.description");
|
||||
// Permission check is automatic based on command registration
|
||||
}
|
||||
|
||||
@Override
|
||||
protected CompletableFuture<Void> execute(CommandContext ctx) {
|
||||
// Only players with appropriate permission reach here
|
||||
return null;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Practical Examples
|
||||
|
||||
### Role-Based Access
|
||||
|
||||
```java
|
||||
public class RoleManager {
|
||||
private final PermissionsModule permissions;
|
||||
|
||||
public RoleManager() {
|
||||
this.permissions = PermissionsModule.get();
|
||||
}
|
||||
|
||||
public void promoteToModerator(UUID playerUuid) {
|
||||
permissions.addUserToGroup(playerUuid, "moderators");
|
||||
permissions.addUserPermission(playerUuid, Set.of(
|
||||
"server.kick",
|
||||
"server.mute",
|
||||
"server.warn"
|
||||
));
|
||||
}
|
||||
|
||||
public void demoteFromModerator(UUID playerUuid) {
|
||||
permissions.removeUserFromGroup(playerUuid, "moderators");
|
||||
permissions.removeUserPermission(playerUuid, Set.of(
|
||||
"server.kick",
|
||||
"server.mute",
|
||||
"server.warn"
|
||||
));
|
||||
}
|
||||
|
||||
public boolean canModerate(UUID playerUuid) {
|
||||
return permissions.getGroupsForUser(playerUuid).contains("moderators");
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Feature Gating
|
||||
|
||||
```java
|
||||
public void useFeature(Player player, String featureName) {
|
||||
UUID uuid = player.getPlayerRef().getUuid();
|
||||
PermissionsModule perms = PermissionsModule.get();
|
||||
|
||||
String permission = "myplugin.feature." + featureName;
|
||||
if (!perms.hasPermission(uuid, permission)) {
|
||||
player.sendMessage(Message.translation("error.no_permission"));
|
||||
return;
|
||||
}
|
||||
|
||||
// Execute feature
|
||||
executeFeature(player, featureName);
|
||||
}
|
||||
```
|
||||
|
||||
## Best Practices
|
||||
|
||||
{{< callout type="info" >}}
|
||||
**Permission Guidelines:**
|
||||
- Use namespaced permissions (e.g., `myplugin.feature.name`)
|
||||
- Prefer groups for role-based access over individual permissions
|
||||
- Check permissions at entry points, not deep in logic
|
||||
- Use wildcards sparingly and intentionally
|
||||
{{< /callout >}}
|
||||
|
||||
{{< callout type="warning" >}}
|
||||
**Security Note:** Always validate permissions server-side. Never trust client-reported permission states.
|
||||
{{< /callout >}}
|
||||
349
content/ui-systems/permissions/_index.fr.md
Normal file
349
content/ui-systems/permissions/_index.fr.md
Normal file
@@ -0,0 +1,349 @@
|
||||
---
|
||||
title: Système de Permissions
|
||||
type: docs
|
||||
weight: 12
|
||||
---
|
||||
|
||||
Le système de Permissions fournit un contrôle d'accès granulaire pour les commandes, les fonctionnalités de l'éditeur et les fonctionnalités personnalisées des plugins.
|
||||
|
||||
**Package:** `com.hypixel.hytale.server.core.permissions`
|
||||
|
||||
## Vue d'Ensemble
|
||||
|
||||
Hytale utilise un système de permissions avec :
|
||||
- **Permissions utilisateur** - Directement assignées aux joueurs individuels
|
||||
- **Permissions de groupe** - Héritées par tous les membres d'un groupe
|
||||
- **Fournisseurs de permissions** - Logique personnalisée pour les permissions dynamiques
|
||||
|
||||
## Accéder au Module de Permissions
|
||||
|
||||
```java
|
||||
import com.hypixel.hytale.server.core.permissions.PermissionsModule;
|
||||
|
||||
// Utiliser la méthode statique get() - PAS HytaleServer.get().getPermissionsModule()
|
||||
PermissionsModule permissions = PermissionsModule.get();
|
||||
```
|
||||
|
||||
## Vérifier les Permissions
|
||||
|
||||
```java
|
||||
UUID playerUuid = player.getPlayerRef().getUuid();
|
||||
|
||||
// Vérifier si le joueur a la permission
|
||||
boolean canEdit = permissions.hasPermission(playerUuid, "hytale.editor.asset");
|
||||
|
||||
// Vérifier dans le contexte de commande
|
||||
if (permissions.hasPermission(ctx.sender().getUuid(), "myplugin.admin")) {
|
||||
// Logique réservée aux admins
|
||||
}
|
||||
```
|
||||
|
||||
## Permissions Utilisateur
|
||||
|
||||
Gérer les permissions pour les joueurs individuels :
|
||||
|
||||
```java
|
||||
UUID playerUuid = player.getPlayerRef().getUuid();
|
||||
|
||||
// Ajouter des permissions
|
||||
permissions.addUserPermission(playerUuid, Set.of(
|
||||
"myplugin.feature.create",
|
||||
"myplugin.feature.delete"
|
||||
));
|
||||
|
||||
// Supprimer des permissions
|
||||
permissions.removeUserPermission(playerUuid, Set.of(
|
||||
"myplugin.feature.delete"
|
||||
));
|
||||
```
|
||||
|
||||
## Permissions de Groupe
|
||||
|
||||
Les groupes permettent de partager des permissions entre plusieurs joueurs :
|
||||
|
||||
### Gérer les Groupes
|
||||
|
||||
```java
|
||||
// Ajouter un joueur à un groupe
|
||||
permissions.addUserToGroup(playerUuid, "moderators");
|
||||
|
||||
// Retirer un joueur d'un groupe
|
||||
permissions.removeUserFromGroup(playerUuid, "moderators");
|
||||
|
||||
// Obtenir tous les groupes d'un joueur
|
||||
Set<String> groups = permissions.getGroupsForUser(playerUuid);
|
||||
```
|
||||
|
||||
### Événements de Permissions de Groupe
|
||||
|
||||
Écouter les changements de groupes en utilisant des sous-classes spécifiques :
|
||||
|
||||
```java
|
||||
import com.hypixel.hytale.server.core.event.events.permissions.*;
|
||||
|
||||
// Joueur AJOUTÉ à un groupe
|
||||
getEventRegistry().register(PlayerGroupEvent.Added.class, event -> {
|
||||
UUID playerUuid = event.getPlayerUuid();
|
||||
String group = event.getGroupName(); // Note: getGroupName(), PAS getGroup()
|
||||
log("Joueur a rejoint le groupe : " + group);
|
||||
});
|
||||
|
||||
// Joueur RETIRÉ d'un groupe
|
||||
getEventRegistry().register(PlayerGroupEvent.Removed.class, event -> {
|
||||
UUID playerUuid = event.getPlayerUuid();
|
||||
String group = event.getGroupName();
|
||||
log("Joueur a quitté le groupe : " + group);
|
||||
});
|
||||
|
||||
// Permissions du groupe AJOUTÉES
|
||||
getEventRegistry().register(GroupPermissionChangeEvent.Added.class, event -> {
|
||||
String group = event.getGroupName();
|
||||
Set<String> added = event.getAddedPermissions();
|
||||
log("Groupe " + group + " a reçu les permissions : " + added);
|
||||
});
|
||||
|
||||
// Permissions du groupe RETIRÉES
|
||||
getEventRegistry().register(GroupPermissionChangeEvent.Removed.class, event -> {
|
||||
String group = event.getGroupName();
|
||||
Set<String> removed = event.getRemovedPermissions();
|
||||
log("Groupe " + group + " a perdu les permissions : " + removed);
|
||||
});
|
||||
|
||||
// Permissions du joueur AJOUTÉES
|
||||
getEventRegistry().register(PlayerPermissionChangeEvent.PermissionsAdded.class, event -> {
|
||||
UUID playerUuid = event.getPlayerUuid();
|
||||
Set<String> added = event.getAddedPermissions();
|
||||
});
|
||||
|
||||
// Permissions du joueur RETIRÉES
|
||||
getEventRegistry().register(PlayerPermissionChangeEvent.PermissionsRemoved.class, event -> {
|
||||
UUID playerUuid = event.getPlayerUuid();
|
||||
Set<String> removed = event.getRemovedPermissions();
|
||||
});
|
||||
```
|
||||
|
||||
## Permissions Intégrées
|
||||
|
||||
Hytale inclut de nombreuses permissions intégrées :
|
||||
|
||||
### Permissions de Commandes
|
||||
|
||||
| Permission | Description |
|
||||
|------------|-------------|
|
||||
| `hytale.command.*` | Accès à toutes les commandes |
|
||||
| `hytale.command.gamemode` | Changer de mode de jeu |
|
||||
| `hytale.command.tp` | Téléportation |
|
||||
| `hytale.command.give` | Donner des objets |
|
||||
| `hytale.command.time` | Contrôle du temps |
|
||||
|
||||
### Permissions de l'Éditeur
|
||||
|
||||
| Permission | Description |
|
||||
|------------|-------------|
|
||||
| `hytale.editor.asset` | Édition des assets |
|
||||
| `hytale.editor.packs.*` | Gestion des packs |
|
||||
| `hytale.editor.builderTools` | Accès aux outils de construction |
|
||||
| `hytale.editor.brush.*` | Outils de pinceau |
|
||||
| `hytale.editor.prefab.*` | Édition des prefabs |
|
||||
| `hytale.editor.selection.*` | Outils de sélection |
|
||||
| `hytale.editor.history` | Historique annuler/rétablir |
|
||||
|
||||
### Permissions de Caméra
|
||||
|
||||
| Permission | Description |
|
||||
|------------|-------------|
|
||||
| `hytale.camera.flycam` | Mode caméra libre |
|
||||
|
||||
## Fournisseur de Permission Personnalisé
|
||||
|
||||
Implémentez `PermissionProvider` pour une logique de permission dynamique :
|
||||
|
||||
{{< callout type="info" >}}
|
||||
**Note :** `PermissionProvider` est une interface qui fournit des ensembles de permissions, pas une simple vérification hasPermission. Le `PermissionsModule` vérifie ces ensembles.
|
||||
{{< /callout >}}
|
||||
|
||||
```java
|
||||
import com.hypixel.hytale.server.core.permissions.provider.PermissionProvider;
|
||||
|
||||
public class VIPPermissionProvider implements PermissionProvider {
|
||||
private final Map<UUID, Set<String>> vipPermissions = new ConcurrentHashMap<>();
|
||||
private final Map<UUID, Set<String>> vipGroups = new ConcurrentHashMap<>();
|
||||
|
||||
@Override
|
||||
@Nonnull
|
||||
public String getName() {
|
||||
return "VIPPermissionProvider";
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<String> getUserPermissions(@Nonnull UUID uuid) {
|
||||
// Retourner les permissions pour cet utilisateur
|
||||
// Les utilisateurs VIP reçoivent des permissions supplémentaires automatiquement
|
||||
if (isVIP(uuid)) {
|
||||
Set<String> perms = new HashSet<>(vipPermissions.getOrDefault(uuid, Collections.emptySet()));
|
||||
perms.add("vip.lounge");
|
||||
perms.add("vip.cosmetics");
|
||||
return perms;
|
||||
}
|
||||
return vipPermissions.getOrDefault(uuid, Collections.emptySet());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addUserPermissions(@Nonnull UUID uuid, @Nonnull Set<String> permissions) {
|
||||
vipPermissions.computeIfAbsent(uuid, k -> new HashSet<>()).addAll(permissions);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeUserPermissions(@Nonnull UUID uuid, @Nonnull Set<String> permissions) {
|
||||
Set<String> userPerms = vipPermissions.get(uuid);
|
||||
if (userPerms != null) {
|
||||
userPerms.removeAll(permissions);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<String> getGroupPermissions(@Nonnull String group) {
|
||||
return Collections.emptySet();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addGroupPermissions(@Nonnull String group, @Nonnull Set<String> permissions) {}
|
||||
|
||||
@Override
|
||||
public void removeGroupPermissions(@Nonnull String group, @Nonnull Set<String> permissions) {}
|
||||
|
||||
@Override
|
||||
public Set<String> getGroupsForUser(@Nonnull UUID uuid) {
|
||||
return vipGroups.getOrDefault(uuid, Collections.emptySet());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addUserToGroup(@Nonnull UUID uuid, @Nonnull String group) {
|
||||
vipGroups.computeIfAbsent(uuid, k -> new HashSet<>()).add(group);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeUserFromGroup(@Nonnull UUID uuid, @Nonnull String group) {
|
||||
Set<String> groups = vipGroups.get(uuid);
|
||||
if (groups != null) {
|
||||
groups.remove(group);
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isVIP(UUID uuid) {
|
||||
// Votre logique de vérification VIP
|
||||
return vipDatabase.contains(uuid);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Enregistrer des Fournisseurs Personnalisés
|
||||
|
||||
```java
|
||||
@Override
|
||||
public void start() {
|
||||
PermissionsModule permissions = PermissionsModule.get();
|
||||
permissions.addProvider(new VIPPermissionProvider());
|
||||
}
|
||||
```
|
||||
|
||||
## Wildcards de Permission
|
||||
|
||||
Les permissions supportent les correspondances avec wildcard :
|
||||
|
||||
```java
|
||||
// Accorder toutes les permissions sous un namespace
|
||||
permissions.addUserPermission(playerUuid, Set.of("myplugin.*"));
|
||||
|
||||
// Ceci passe maintenant :
|
||||
permissions.hasPermission(playerUuid, "myplugin.anything");
|
||||
permissions.hasPermission(playerUuid, "myplugin.feature.nested");
|
||||
```
|
||||
|
||||
## Intégration des Permissions de Commandes
|
||||
|
||||
Les commandes vérifient automatiquement les permissions basées sur leur ID :
|
||||
|
||||
```java
|
||||
public class AdminCommand extends AbstractCommand {
|
||||
|
||||
public AdminCommand() {
|
||||
super("admin", "myplugin.commands.admin.description");
|
||||
// La vérification de permission est automatique basée sur l'enregistrement de la commande
|
||||
}
|
||||
|
||||
@Override
|
||||
protected CompletableFuture<Void> execute(CommandContext ctx) {
|
||||
// Seuls les joueurs avec la permission appropriée arrivent ici
|
||||
return null;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Exemples Pratiques
|
||||
|
||||
### Accès Basé sur les Rôles
|
||||
|
||||
```java
|
||||
public class RoleManager {
|
||||
private final PermissionsModule permissions;
|
||||
|
||||
public RoleManager() {
|
||||
this.permissions = PermissionsModule.get();
|
||||
}
|
||||
|
||||
public void promoteToModerator(UUID playerUuid) {
|
||||
permissions.addUserToGroup(playerUuid, "moderators");
|
||||
permissions.addUserPermission(playerUuid, Set.of(
|
||||
"server.kick",
|
||||
"server.mute",
|
||||
"server.warn"
|
||||
));
|
||||
}
|
||||
|
||||
public void demoteFromModerator(UUID playerUuid) {
|
||||
permissions.removeUserFromGroup(playerUuid, "moderators");
|
||||
permissions.removeUserPermission(playerUuid, Set.of(
|
||||
"server.kick",
|
||||
"server.mute",
|
||||
"server.warn"
|
||||
));
|
||||
}
|
||||
|
||||
public boolean canModerate(UUID playerUuid) {
|
||||
return permissions.getGroupsForUser(playerUuid).contains("moderators");
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Verrouillage de Fonctionnalités
|
||||
|
||||
```java
|
||||
public void useFeature(Player player, String featureName) {
|
||||
UUID uuid = player.getPlayerRef().getUuid();
|
||||
PermissionsModule perms = PermissionsModule.get();
|
||||
|
||||
String permission = "myplugin.feature." + featureName;
|
||||
if (!perms.hasPermission(uuid, permission)) {
|
||||
player.sendMessage(Message.translation("error.no_permission"));
|
||||
return;
|
||||
}
|
||||
|
||||
// Exécuter la fonctionnalité
|
||||
executeFeature(player, featureName);
|
||||
}
|
||||
```
|
||||
|
||||
## Bonnes Pratiques
|
||||
|
||||
{{< callout type="info" >}}
|
||||
**Directives des Permissions :**
|
||||
- Utilisez des permissions avec namespace (ex: `myplugin.feature.name`)
|
||||
- Préférez les groupes pour l'accès basé sur les rôles plutôt que les permissions individuelles
|
||||
- Vérifiez les permissions aux points d'entrée, pas profondément dans la logique
|
||||
- Utilisez les wildcards avec parcimonie et intentionnellement
|
||||
{{< /callout >}}
|
||||
|
||||
{{< callout type="warning" >}}
|
||||
**Note de Sécurité :** Validez toujours les permissions côté serveur. Ne faites jamais confiance aux états de permission rapportés par le client.
|
||||
{{< /callout >}}
|
||||
161
content/ui-systems/ui-files.en.md
Normal file
161
content/ui-systems/ui-files.en.md
Normal file
@@ -0,0 +1,161 @@
|
||||
---
|
||||
title: UI Files
|
||||
type: docs
|
||||
weight: 10
|
||||
---
|
||||
|
||||
UI files (`.ui`) are Hytale's declarative markup language for defining user interfaces. They describe the structure, layout, and styling of UI elements that can be loaded by plugins via `UICommandBuilder.append()`.
|
||||
|
||||
## File Location
|
||||
|
||||
UI files are typically stored in the Assets directory:
|
||||
|
||||
```
|
||||
Assets/
|
||||
Common/UI/Custom/ # Server-side custom UI
|
||||
Pages/ # Custom page templates
|
||||
Hud/ # Custom HUD elements
|
||||
Common.ui # Shared definitions
|
||||
Sounds.ui # Sound definitions
|
||||
Client/Interface/ # Client-side UI
|
||||
InGame/Hud/ # HUD components
|
||||
Common/ # Common components
|
||||
Common.ui # Client shared definitions
|
||||
```
|
||||
|
||||
## Basic Structure
|
||||
|
||||
A `.ui` file consists of variable definitions and widget declarations:
|
||||
|
||||
```
|
||||
// Import external definitions
|
||||
$Common = "../Common.ui";
|
||||
|
||||
// Define local variables
|
||||
@ButtonHeight = 44;
|
||||
@TextColor = #96a9be;
|
||||
|
||||
// Define a widget tree
|
||||
Group #Container {
|
||||
Anchor: (Width: 400, Height: 300);
|
||||
Background: (Color: #000000(0.8));
|
||||
|
||||
Label #Title {
|
||||
Text: "Hello World";
|
||||
Style: (FontSize: 24, TextColor: @TextColor);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Loading UI Files from Plugins
|
||||
|
||||
Use `UICommandBuilder.append()` to load a UI file:
|
||||
|
||||
```java
|
||||
@Override
|
||||
public void build(Ref<EntityStore> ref, UICommandBuilder builder,
|
||||
UIEventBuilder events, Store<EntityStore> store) {
|
||||
// Load the UI template (extension .ui is REQUIRED)
|
||||
builder.append("Pages/MyPage.ui");
|
||||
|
||||
// Append to a specific element
|
||||
builder.append("#ContentList", "Pages/ListItem.ui");
|
||||
|
||||
// Set dynamic values using selectors
|
||||
builder.set("#Title", "Welcome, " + playerRef.getUsername());
|
||||
}
|
||||
```
|
||||
|
||||
### Path Resolution
|
||||
|
||||
The path is relative to `Common/UI/Custom/`. The `.ui` extension is **required**.
|
||||
|
||||
| Path in `append()` | Resolved Location |
|
||||
|-------------------|-------------------|
|
||||
| `Pages/MyPage.ui` | `Common/UI/Custom/Pages/MyPage.ui` |
|
||||
| `Common.ui` | `Common/UI/Custom/Common.ui` |
|
||||
|
||||
### For Java Plugins (Mods)
|
||||
|
||||
When creating a Java plugin with custom UI, place your `.ui` files in the resources folder:
|
||||
|
||||
```
|
||||
your-plugin/
|
||||
src/main/
|
||||
java/ # Java source code
|
||||
resources/
|
||||
Common/UI/Custom/ # UI files go here
|
||||
Pages/
|
||||
MyPage.ui
|
||||
MyButton.ui
|
||||
Common.ui # Your shared definitions
|
||||
plugin.json # Plugin manifest
|
||||
```
|
||||
|
||||
Set `"IncludesAssetPack": true` in your `plugin.json` to enable asset loading:
|
||||
|
||||
```json
|
||||
{
|
||||
"Group": "MyGroup",
|
||||
"Name": "MyPlugin",
|
||||
"Version": "1.0.0",
|
||||
"Main": "com.example.MyPlugin",
|
||||
"IncludesAssetPack": true
|
||||
}
|
||||
```
|
||||
|
||||
{{< callout type="info" >}}
|
||||
The server automatically looks for UI files in `Common/UI/Custom/` within your plugin's asset pack. This is why paths like `Pages/MyPage.ui` work without specifying the full path.
|
||||
{{< /callout >}}
|
||||
|
||||
## Key Concepts
|
||||
|
||||
### Variables
|
||||
|
||||
Variables store reusable values:
|
||||
|
||||
```
|
||||
@Height = 50; // Number
|
||||
@Color = #ff5500; // Color
|
||||
@Style = (FontSize: 16, RenderBold: true); // Object
|
||||
```
|
||||
|
||||
### Imports
|
||||
|
||||
Import definitions from other files:
|
||||
|
||||
```
|
||||
$Common = "Common.ui"; // Import file
|
||||
$Common.@DefaultButtonStyle // Reference imported variable
|
||||
```
|
||||
|
||||
### Widget IDs
|
||||
|
||||
Use `#` to assign IDs that can be targeted from Java:
|
||||
|
||||
```
|
||||
Label #PlayerName {
|
||||
Text: "Unknown";
|
||||
}
|
||||
```
|
||||
|
||||
```java
|
||||
builder.set("#PlayerName", player.getUsername());
|
||||
```
|
||||
|
||||
### Localization
|
||||
|
||||
Use `%` prefix for translation keys:
|
||||
|
||||
```
|
||||
Label {
|
||||
Text: %server.ui.welcome.title;
|
||||
}
|
||||
```
|
||||
|
||||
## Next Steps
|
||||
|
||||
- [UI Syntax](ui-syntax) - Detailed syntax reference
|
||||
- [UI Widgets](ui-widgets) - Available widget types
|
||||
- [UI Properties](ui-properties) - Common properties
|
||||
- [UI Styles](ui-styles) - Styling system
|
||||
161
content/ui-systems/ui-files.fr.md
Normal file
161
content/ui-systems/ui-files.fr.md
Normal file
@@ -0,0 +1,161 @@
|
||||
---
|
||||
title: Fichiers UI
|
||||
type: docs
|
||||
weight: 10
|
||||
---
|
||||
|
||||
Les fichiers UI (`.ui`) sont le langage de balisage déclaratif de Hytale pour définir les interfaces utilisateur. Ils décrivent la structure, la disposition et le style des éléments UI qui peuvent être chargés par les plugins via `UICommandBuilder.append()`.
|
||||
|
||||
## Emplacement des Fichiers
|
||||
|
||||
Les fichiers UI sont généralement stockés dans le répertoire Assets :
|
||||
|
||||
```
|
||||
Assets/
|
||||
Common/UI/Custom/ # UI personnalisée côté serveur
|
||||
Pages/ # Templates de pages personnalisées
|
||||
Hud/ # Éléments HUD personnalisés
|
||||
Common.ui # Définitions partagées
|
||||
Sounds.ui # Définitions de sons
|
||||
Client/Interface/ # UI côté client
|
||||
InGame/Hud/ # Composants HUD
|
||||
Common/ # Composants communs
|
||||
Common.ui # Définitions partagées client
|
||||
```
|
||||
|
||||
## Structure de Base
|
||||
|
||||
Un fichier `.ui` se compose de définitions de variables et de déclarations de widgets :
|
||||
|
||||
```
|
||||
// Importer des définitions externes
|
||||
$Common = "../Common.ui";
|
||||
|
||||
// Définir des variables locales
|
||||
@ButtonHeight = 44;
|
||||
@TextColor = #96a9be;
|
||||
|
||||
// Définir un arbre de widgets
|
||||
Group #Container {
|
||||
Anchor: (Width: 400, Height: 300);
|
||||
Background: (Color: #000000(0.8));
|
||||
|
||||
Label #Title {
|
||||
Text: "Bonjour le monde";
|
||||
Style: (FontSize: 24, TextColor: @TextColor);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Charger des Fichiers UI depuis les Plugins
|
||||
|
||||
Utilisez `UICommandBuilder.append()` pour charger un fichier UI :
|
||||
|
||||
```java
|
||||
@Override
|
||||
public void build(Ref<EntityStore> ref, UICommandBuilder builder,
|
||||
UIEventBuilder events, Store<EntityStore> store) {
|
||||
// Charger le template UI (extension .ui OBLIGATOIRE)
|
||||
builder.append("Pages/MyPage.ui");
|
||||
|
||||
// Ajouter à un élément spécifique
|
||||
builder.append("#ContentList", "Pages/ListItem.ui");
|
||||
|
||||
// Définir des valeurs dynamiques avec des sélecteurs
|
||||
builder.set("#Title", "Bienvenue, " + playerRef.getUsername());
|
||||
}
|
||||
```
|
||||
|
||||
### Résolution des Chemins
|
||||
|
||||
Le chemin est relatif à `Common/UI/Custom/`. L'extension `.ui` est **obligatoire**.
|
||||
|
||||
| Chemin dans `append()` | Emplacement Résolu |
|
||||
|------------------------|-------------------|
|
||||
| `Pages/MyPage.ui` | `Common/UI/Custom/Pages/MyPage.ui` |
|
||||
| `Common.ui` | `Common/UI/Custom/Common.ui` |
|
||||
|
||||
### Pour les Plugins Java (Mods)
|
||||
|
||||
Lors de la création d'un plugin Java avec une UI personnalisée, placez vos fichiers `.ui` dans le dossier resources :
|
||||
|
||||
```
|
||||
your-plugin/
|
||||
src/main/
|
||||
java/ # Code source Java
|
||||
resources/
|
||||
Common/UI/Custom/ # Les fichiers UI vont ici
|
||||
Pages/
|
||||
MyPage.ui
|
||||
MyButton.ui
|
||||
Common.ui # Vos définitions partagées
|
||||
plugin.json # Manifeste du plugin
|
||||
```
|
||||
|
||||
Définissez `"IncludesAssetPack": true` dans votre `plugin.json` pour activer le chargement des assets :
|
||||
|
||||
```json
|
||||
{
|
||||
"Group": "MyGroup",
|
||||
"Name": "MyPlugin",
|
||||
"Version": "1.0.0",
|
||||
"Main": "com.example.MyPlugin",
|
||||
"IncludesAssetPack": true
|
||||
}
|
||||
```
|
||||
|
||||
{{< callout type="info" >}}
|
||||
Le serveur cherche automatiquement les fichiers UI dans `Common/UI/Custom/` au sein de l'asset pack de votre plugin. C'est pourquoi des chemins comme `Pages/MyPage.ui` fonctionnent sans spécifier le chemin complet.
|
||||
{{< /callout >}}
|
||||
|
||||
## Concepts Clés
|
||||
|
||||
### Variables
|
||||
|
||||
Les variables stockent des valeurs réutilisables :
|
||||
|
||||
```
|
||||
@Height = 50; // Nombre
|
||||
@Color = #ff5500; // Couleur
|
||||
@Style = (FontSize: 16, RenderBold: true); // Objet
|
||||
```
|
||||
|
||||
### Imports
|
||||
|
||||
Importer des définitions depuis d'autres fichiers :
|
||||
|
||||
```
|
||||
$Common = "Common.ui"; // Importer un fichier
|
||||
$Common.@DefaultButtonStyle // Référencer une variable importée
|
||||
```
|
||||
|
||||
### IDs de Widget
|
||||
|
||||
Utilisez `#` pour assigner des IDs ciblables depuis Java :
|
||||
|
||||
```
|
||||
Label #PlayerName {
|
||||
Text: "Inconnu";
|
||||
}
|
||||
```
|
||||
|
||||
```java
|
||||
builder.set("#PlayerName", player.getUsername());
|
||||
```
|
||||
|
||||
### Localisation
|
||||
|
||||
Utilisez le préfixe `%` pour les clés de traduction :
|
||||
|
||||
```
|
||||
Label {
|
||||
Text: %server.ui.welcome.title;
|
||||
}
|
||||
```
|
||||
|
||||
## Étapes Suivantes
|
||||
|
||||
- [Syntaxe UI](ui-syntax) - Référence de syntaxe détaillée
|
||||
- [Widgets UI](ui-widgets) - Types de widgets disponibles
|
||||
- [Propriétés UI](ui-properties) - Propriétés communes
|
||||
- [Styles UI](ui-styles) - Système de styles
|
||||
384
content/ui-systems/ui-properties.en.md
Normal file
384
content/ui-systems/ui-properties.en.md
Normal file
@@ -0,0 +1,384 @@
|
||||
---
|
||||
title: UI Properties
|
||||
type: docs
|
||||
weight: 13
|
||||
---
|
||||
|
||||
This page documents common properties available on UI widgets.
|
||||
|
||||
## Anchor (Positioning)
|
||||
|
||||
The `Anchor` property controls widget position and size.
|
||||
|
||||
### Position Properties
|
||||
|
||||
```
|
||||
Anchor: (
|
||||
Left: 10, // Distance from left edge
|
||||
Right: 10, // Distance from right edge
|
||||
Top: 10, // Distance from top edge
|
||||
Bottom: 10 // Distance from bottom edge
|
||||
);
|
||||
```
|
||||
|
||||
### Size Properties
|
||||
|
||||
```
|
||||
Anchor: (
|
||||
Width: 200, // Fixed width
|
||||
Height: 100 // Fixed height
|
||||
);
|
||||
```
|
||||
|
||||
### Shorthand Properties
|
||||
|
||||
```
|
||||
Anchor: (Full: 10); // All sides = 10
|
||||
Anchor: (Horizontal: 20); // Left and Right = 20
|
||||
Anchor: (Vertical: 15); // Top and Bottom = 15
|
||||
```
|
||||
|
||||
### Combined Example
|
||||
|
||||
```
|
||||
// Fixed size, positioned from top-left
|
||||
Anchor: (Left: 50, Top: 100, Width: 300, Height: 200);
|
||||
|
||||
// Fill parent with margins
|
||||
Anchor: (Full: 16);
|
||||
|
||||
// Anchored to bottom-right corner
|
||||
Anchor: (Right: 20, Bottom: 20, Width: 100, Height: 40);
|
||||
|
||||
// Full width, fixed height at bottom
|
||||
Anchor: (Horizontal: 0, Bottom: 0, Height: 50);
|
||||
```
|
||||
|
||||
## Background
|
||||
|
||||
The `Background` property sets widget background appearance.
|
||||
|
||||
### Solid Color
|
||||
|
||||
```
|
||||
Background: (Color: #ff5500);
|
||||
Background: (Color: #000000(0.5)); // With opacity
|
||||
```
|
||||
|
||||
### Simple Texture
|
||||
|
||||
```
|
||||
Background: "MyTexture.png";
|
||||
Background: (TexturePath: "MyTexture.png");
|
||||
```
|
||||
|
||||
### 9-Patch (Stretchable) Texture
|
||||
|
||||
```
|
||||
// Uniform border
|
||||
Background: (TexturePath: "Panel.png", Border: 20);
|
||||
|
||||
// Separate horizontal/vertical borders
|
||||
Background: (
|
||||
TexturePath: "Button.png",
|
||||
HorizontalBorder: 80,
|
||||
VerticalBorder: 12
|
||||
);
|
||||
```
|
||||
|
||||
### Using PatchStyle
|
||||
|
||||
```
|
||||
@MyBackground = PatchStyle(
|
||||
TexturePath: "Panel.png",
|
||||
Border: 16
|
||||
);
|
||||
|
||||
Group {
|
||||
Background: @MyBackground;
|
||||
}
|
||||
```
|
||||
|
||||
## Padding
|
||||
|
||||
The `Padding` property sets inner spacing.
|
||||
|
||||
```
|
||||
Padding: (Full: 16); // All sides
|
||||
Padding: (Horizontal: 20); // Left and Right
|
||||
Padding: (Vertical: 10); // Top and Bottom
|
||||
Padding: (Left: 10, Right: 20); // Individual sides
|
||||
Padding: (Top: 5, Bottom: 15, Horizontal: 10);
|
||||
```
|
||||
|
||||
### Using Padding Constructor
|
||||
|
||||
```
|
||||
@ContentPadding = Padding(Full: 16, Top: 8);
|
||||
|
||||
Group {
|
||||
Padding: @ContentPadding;
|
||||
}
|
||||
```
|
||||
|
||||
## LayoutMode
|
||||
|
||||
The `LayoutMode` property controls how children are arranged.
|
||||
|
||||
### Stacking Modes
|
||||
|
||||
| Mode | Description |
|
||||
|------|-------------|
|
||||
| `Top` | Stack children from top to bottom |
|
||||
| `Bottom` | Stack children from bottom to top |
|
||||
| `Left` | Stack children from left to right |
|
||||
| `Right` | Stack children from right to left |
|
||||
|
||||
```
|
||||
Group {
|
||||
LayoutMode: Top; // Vertical list, top-aligned
|
||||
|
||||
Label { Text: "First"; Anchor: (Height: 30); }
|
||||
Label { Text: "Second"; Anchor: (Height: 30); }
|
||||
Label { Text: "Third"; Anchor: (Height: 30); }
|
||||
}
|
||||
```
|
||||
|
||||
### Centering Modes
|
||||
|
||||
| Mode | Description |
|
||||
|------|-------------|
|
||||
| `Middle` | Center children vertically |
|
||||
| `CenterMiddle` | Center children both horizontally and vertically |
|
||||
|
||||
```
|
||||
Group {
|
||||
LayoutMode: CenterMiddle;
|
||||
|
||||
Label { Text: "Centered!"; }
|
||||
}
|
||||
```
|
||||
|
||||
### Scrolling Modes
|
||||
|
||||
| Mode | Description |
|
||||
|------|-------------|
|
||||
| `TopScrolling` | Vertical scroll, content from top |
|
||||
| `BottomScrolling` | Vertical scroll, content from bottom (chat-style) |
|
||||
|
||||
```
|
||||
Group #ChatLog {
|
||||
LayoutMode: BottomScrolling;
|
||||
ScrollbarStyle: @DefaultScrollbarStyle;
|
||||
AutoScrollDown: true;
|
||||
}
|
||||
```
|
||||
|
||||
### Wrapping Mode
|
||||
|
||||
| Mode | Description |
|
||||
|------|-------------|
|
||||
| `LeftCenterWrap` | Flow left-to-right, wrap to next row |
|
||||
|
||||
```
|
||||
Group #ItemGrid {
|
||||
LayoutMode: LeftCenterWrap;
|
||||
|
||||
// Items will wrap to new rows
|
||||
}
|
||||
```
|
||||
|
||||
## FlexWeight
|
||||
|
||||
The `FlexWeight` property controls flexible sizing in layout.
|
||||
|
||||
```
|
||||
Group {
|
||||
LayoutMode: Left;
|
||||
|
||||
Group {
|
||||
Anchor: (Width: 100); // Fixed width
|
||||
}
|
||||
|
||||
Group {
|
||||
FlexWeight: 1; // Takes remaining space
|
||||
}
|
||||
|
||||
Group {
|
||||
FlexWeight: 2; // Takes 2x the space of FlexWeight: 1
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Visible
|
||||
|
||||
Controls widget visibility.
|
||||
|
||||
```
|
||||
Group #Panel {
|
||||
Visible: true; // or false, or @Variable
|
||||
}
|
||||
|
||||
Button #CloseButton {
|
||||
Visible: @CloseButton; // Controlled by template parameter
|
||||
}
|
||||
```
|
||||
|
||||
## Text
|
||||
|
||||
Sets text content for Label and TextButton widgets.
|
||||
|
||||
```
|
||||
Label {
|
||||
Text: "Static text";
|
||||
}
|
||||
|
||||
Label {
|
||||
Text: %server.ui.title; // Translation key
|
||||
}
|
||||
|
||||
Label #DynamicText {
|
||||
Text: ""; // Set from Java
|
||||
}
|
||||
```
|
||||
|
||||
## ScrollbarStyle
|
||||
|
||||
Configures scrollbar appearance for scrolling containers.
|
||||
|
||||
```
|
||||
Group {
|
||||
LayoutMode: TopScrolling;
|
||||
ScrollbarStyle: (
|
||||
Spacing: 6,
|
||||
Size: 6,
|
||||
Background: (TexturePath: "Scrollbar.png", Border: 3),
|
||||
Handle: (TexturePath: "ScrollbarHandle.png", Border: 3),
|
||||
HoveredHandle: (TexturePath: "ScrollbarHandleHovered.png", Border: 3),
|
||||
DraggedHandle: (TexturePath: "ScrollbarHandleDragged.png", Border: 3)
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
### ScrollbarStyle Options
|
||||
|
||||
| Property | Description |
|
||||
|----------|-------------|
|
||||
| `Spacing` | Gap between scrollbar and content |
|
||||
| `Size` | Scrollbar width/height |
|
||||
| `Background` | Track background |
|
||||
| `Handle` | Normal handle appearance |
|
||||
| `HoveredHandle` | Handle when hovered |
|
||||
| `DraggedHandle` | Handle when dragging |
|
||||
| `OnlyVisibleWhenHovered` | Hide when not interacting |
|
||||
|
||||
## AutoScrollDown
|
||||
|
||||
For BottomScrolling containers, automatically scroll to new content.
|
||||
|
||||
```
|
||||
Group #ChatLog {
|
||||
LayoutMode: BottomScrolling;
|
||||
AutoScrollDown: true;
|
||||
}
|
||||
```
|
||||
|
||||
## Disabled
|
||||
|
||||
Disables interaction with a widget.
|
||||
|
||||
```
|
||||
Button #SubmitButton {
|
||||
Disabled: false;
|
||||
}
|
||||
|
||||
ActionButton #Binding {
|
||||
Disabled: true;
|
||||
}
|
||||
```
|
||||
|
||||
## TooltipText
|
||||
|
||||
Displays tooltip on hover.
|
||||
|
||||
```
|
||||
Button #InfoButton {
|
||||
TooltipText: %ui.tooltip.help;
|
||||
}
|
||||
```
|
||||
|
||||
## TextTooltipStyle
|
||||
|
||||
Configures tooltip appearance.
|
||||
|
||||
```
|
||||
Button {
|
||||
TooltipText: "Help text";
|
||||
TextTooltipStyle: (
|
||||
Background: (TexturePath: "TooltipBg.png", Border: 24),
|
||||
MaxWidth: 400,
|
||||
LabelStyle: (Wrap: true, FontSize: 16),
|
||||
Padding: 24
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
## Common Property Combinations
|
||||
|
||||
### Panel with Title and Content
|
||||
|
||||
```
|
||||
Group #Panel {
|
||||
Anchor: (Width: 400, Height: 300);
|
||||
Background: (TexturePath: "Panel.png", Border: 20);
|
||||
LayoutMode: Top;
|
||||
Padding: (Full: 16);
|
||||
|
||||
Label #Title {
|
||||
Anchor: (Height: 40);
|
||||
// ...
|
||||
}
|
||||
|
||||
Group #Content {
|
||||
FlexWeight: 1;
|
||||
LayoutMode: TopScrolling;
|
||||
ScrollbarStyle: @DefaultScrollbarStyle;
|
||||
Padding: (Top: 8);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Horizontal Button Row
|
||||
|
||||
```
|
||||
Group #ButtonRow {
|
||||
Anchor: (Height: 50);
|
||||
LayoutMode: Right;
|
||||
Padding: (Horizontal: 10);
|
||||
|
||||
TextButton #Cancel {
|
||||
Anchor: (Width: 100);
|
||||
}
|
||||
|
||||
Group { Anchor: (Width: 10); } // Spacer
|
||||
|
||||
TextButton #Confirm {
|
||||
Anchor: (Width: 100);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Full-Screen Overlay
|
||||
|
||||
```
|
||||
Group #Overlay {
|
||||
Anchor: (Full: 0);
|
||||
Background: (Color: #000000(0.7));
|
||||
LayoutMode: CenterMiddle;
|
||||
|
||||
Group #Dialog {
|
||||
Anchor: (Width: 500, Height: 300);
|
||||
Background: (TexturePath: "Dialog.png", Border: 20);
|
||||
}
|
||||
}
|
||||
```
|
||||
384
content/ui-systems/ui-properties.fr.md
Normal file
384
content/ui-systems/ui-properties.fr.md
Normal file
@@ -0,0 +1,384 @@
|
||||
---
|
||||
title: Propriétés UI
|
||||
type: docs
|
||||
weight: 13
|
||||
---
|
||||
|
||||
Cette page documente les propriétés communes disponibles sur les widgets UI.
|
||||
|
||||
## Anchor (Positionnement)
|
||||
|
||||
La propriété `Anchor` contrôle la position et la taille du widget.
|
||||
|
||||
### Propriétés de Position
|
||||
|
||||
```
|
||||
Anchor: (
|
||||
Left: 10, // Distance depuis le bord gauche
|
||||
Right: 10, // Distance depuis le bord droit
|
||||
Top: 10, // Distance depuis le bord supérieur
|
||||
Bottom: 10 // Distance depuis le bord inférieur
|
||||
);
|
||||
```
|
||||
|
||||
### Propriétés de Taille
|
||||
|
||||
```
|
||||
Anchor: (
|
||||
Width: 200, // Largeur fixe
|
||||
Height: 100 // Hauteur fixe
|
||||
);
|
||||
```
|
||||
|
||||
### Propriétés Raccourcies
|
||||
|
||||
```
|
||||
Anchor: (Full: 10); // Tous les côtés = 10
|
||||
Anchor: (Horizontal: 20); // Gauche et Droite = 20
|
||||
Anchor: (Vertical: 15); // Haut et Bas = 15
|
||||
```
|
||||
|
||||
### Exemple Combiné
|
||||
|
||||
```
|
||||
// Taille fixe, positionné depuis le coin supérieur gauche
|
||||
Anchor: (Left: 50, Top: 100, Width: 300, Height: 200);
|
||||
|
||||
// Remplit le parent avec des marges
|
||||
Anchor: (Full: 16);
|
||||
|
||||
// Ancré au coin inférieur droit
|
||||
Anchor: (Right: 20, Bottom: 20, Width: 100, Height: 40);
|
||||
|
||||
// Pleine largeur, hauteur fixe en bas
|
||||
Anchor: (Horizontal: 0, Bottom: 0, Height: 50);
|
||||
```
|
||||
|
||||
## Background
|
||||
|
||||
La propriété `Background` définit l'apparence du fond du widget.
|
||||
|
||||
### Couleur Unie
|
||||
|
||||
```
|
||||
Background: (Color: #ff5500);
|
||||
Background: (Color: #000000(0.5)); // Avec opacité
|
||||
```
|
||||
|
||||
### Texture Simple
|
||||
|
||||
```
|
||||
Background: "MyTexture.png";
|
||||
Background: (TexturePath: "MyTexture.png");
|
||||
```
|
||||
|
||||
### Texture 9-Patch (Étirable)
|
||||
|
||||
```
|
||||
// Bordure uniforme
|
||||
Background: (TexturePath: "Panel.png", Border: 20);
|
||||
|
||||
// Bordures horizontales/verticales séparées
|
||||
Background: (
|
||||
TexturePath: "Button.png",
|
||||
HorizontalBorder: 80,
|
||||
VerticalBorder: 12
|
||||
);
|
||||
```
|
||||
|
||||
### Utiliser PatchStyle
|
||||
|
||||
```
|
||||
@MyBackground = PatchStyle(
|
||||
TexturePath: "Panel.png",
|
||||
Border: 16
|
||||
);
|
||||
|
||||
Group {
|
||||
Background: @MyBackground;
|
||||
}
|
||||
```
|
||||
|
||||
## Padding
|
||||
|
||||
La propriété `Padding` définit l'espacement intérieur.
|
||||
|
||||
```
|
||||
Padding: (Full: 16); // Tous les côtés
|
||||
Padding: (Horizontal: 20); // Gauche et Droite
|
||||
Padding: (Vertical: 10); // Haut et Bas
|
||||
Padding: (Left: 10, Right: 20); // Côtés individuels
|
||||
Padding: (Top: 5, Bottom: 15, Horizontal: 10);
|
||||
```
|
||||
|
||||
### Utiliser le Constructeur Padding
|
||||
|
||||
```
|
||||
@ContentPadding = Padding(Full: 16, Top: 8);
|
||||
|
||||
Group {
|
||||
Padding: @ContentPadding;
|
||||
}
|
||||
```
|
||||
|
||||
## LayoutMode
|
||||
|
||||
La propriété `LayoutMode` contrôle l'arrangement des enfants.
|
||||
|
||||
### Modes d'Empilement
|
||||
|
||||
| Mode | Description |
|
||||
|------|-------------|
|
||||
| `Top` | Empile les enfants de haut en bas |
|
||||
| `Bottom` | Empile les enfants de bas en haut |
|
||||
| `Left` | Empile les enfants de gauche à droite |
|
||||
| `Right` | Empile les enfants de droite à gauche |
|
||||
|
||||
```
|
||||
Group {
|
||||
LayoutMode: Top; // Liste verticale, alignée en haut
|
||||
|
||||
Label { Text: "Premier"; Anchor: (Height: 30); }
|
||||
Label { Text: "Deuxième"; Anchor: (Height: 30); }
|
||||
Label { Text: "Troisième"; Anchor: (Height: 30); }
|
||||
}
|
||||
```
|
||||
|
||||
### Modes de Centrage
|
||||
|
||||
| Mode | Description |
|
||||
|------|-------------|
|
||||
| `Middle` | Centre les enfants verticalement |
|
||||
| `CenterMiddle` | Centre les enfants horizontalement et verticalement |
|
||||
|
||||
```
|
||||
Group {
|
||||
LayoutMode: CenterMiddle;
|
||||
|
||||
Label { Text: "Centré !"; }
|
||||
}
|
||||
```
|
||||
|
||||
### Modes avec Défilement
|
||||
|
||||
| Mode | Description |
|
||||
|------|-------------|
|
||||
| `TopScrolling` | Défilement vertical, contenu depuis le haut |
|
||||
| `BottomScrolling` | Défilement vertical, contenu depuis le bas (style chat) |
|
||||
|
||||
```
|
||||
Group #ChatLog {
|
||||
LayoutMode: BottomScrolling;
|
||||
ScrollbarStyle: @DefaultScrollbarStyle;
|
||||
AutoScrollDown: true;
|
||||
}
|
||||
```
|
||||
|
||||
### Mode Retour à la Ligne
|
||||
|
||||
| Mode | Description |
|
||||
|------|-------------|
|
||||
| `LeftCenterWrap` | Flux gauche-droite, retour à la ligne suivante |
|
||||
|
||||
```
|
||||
Group #ItemGrid {
|
||||
LayoutMode: LeftCenterWrap;
|
||||
|
||||
// Les items passeront à la ligne suivante
|
||||
}
|
||||
```
|
||||
|
||||
## FlexWeight
|
||||
|
||||
La propriété `FlexWeight` contrôle le dimensionnement flexible dans la mise en page.
|
||||
|
||||
```
|
||||
Group {
|
||||
LayoutMode: Left;
|
||||
|
||||
Group {
|
||||
Anchor: (Width: 100); // Largeur fixe
|
||||
}
|
||||
|
||||
Group {
|
||||
FlexWeight: 1; // Prend l'espace restant
|
||||
}
|
||||
|
||||
Group {
|
||||
FlexWeight: 2; // Prend 2x l'espace de FlexWeight: 1
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Visible
|
||||
|
||||
Contrôle la visibilité du widget.
|
||||
|
||||
```
|
||||
Group #Panel {
|
||||
Visible: true; // ou false, ou @Variable
|
||||
}
|
||||
|
||||
Button #CloseButton {
|
||||
Visible: @CloseButton; // Contrôlé par paramètre de template
|
||||
}
|
||||
```
|
||||
|
||||
## Text
|
||||
|
||||
Définit le contenu texte pour les widgets Label et TextButton.
|
||||
|
||||
```
|
||||
Label {
|
||||
Text: "Texte statique";
|
||||
}
|
||||
|
||||
Label {
|
||||
Text: %server.ui.title; // Clé de traduction
|
||||
}
|
||||
|
||||
Label #DynamicText {
|
||||
Text: ""; // Défini depuis Java
|
||||
}
|
||||
```
|
||||
|
||||
## ScrollbarStyle
|
||||
|
||||
Configure l'apparence de la scrollbar pour les conteneurs défilants.
|
||||
|
||||
```
|
||||
Group {
|
||||
LayoutMode: TopScrolling;
|
||||
ScrollbarStyle: (
|
||||
Spacing: 6,
|
||||
Size: 6,
|
||||
Background: (TexturePath: "Scrollbar.png", Border: 3),
|
||||
Handle: (TexturePath: "ScrollbarHandle.png", Border: 3),
|
||||
HoveredHandle: (TexturePath: "ScrollbarHandleHovered.png", Border: 3),
|
||||
DraggedHandle: (TexturePath: "ScrollbarHandleDragged.png", Border: 3)
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
### Options ScrollbarStyle
|
||||
|
||||
| Propriété | Description |
|
||||
|-----------|-------------|
|
||||
| `Spacing` | Écart entre la scrollbar et le contenu |
|
||||
| `Size` | Largeur/hauteur de la scrollbar |
|
||||
| `Background` | Fond de la piste |
|
||||
| `Handle` | Apparence normale de la poignée |
|
||||
| `HoveredHandle` | Poignée au survol |
|
||||
| `DraggedHandle` | Poignée pendant le glissement |
|
||||
| `OnlyVisibleWhenHovered` | Masquer quand pas d'interaction |
|
||||
|
||||
## AutoScrollDown
|
||||
|
||||
Pour les conteneurs BottomScrolling, défile automatiquement vers le nouveau contenu.
|
||||
|
||||
```
|
||||
Group #ChatLog {
|
||||
LayoutMode: BottomScrolling;
|
||||
AutoScrollDown: true;
|
||||
}
|
||||
```
|
||||
|
||||
## Disabled
|
||||
|
||||
Désactive l'interaction avec un widget.
|
||||
|
||||
```
|
||||
Button #SubmitButton {
|
||||
Disabled: false;
|
||||
}
|
||||
|
||||
ActionButton #Binding {
|
||||
Disabled: true;
|
||||
}
|
||||
```
|
||||
|
||||
## TooltipText
|
||||
|
||||
Affiche une infobulle au survol.
|
||||
|
||||
```
|
||||
Button #InfoButton {
|
||||
TooltipText: %ui.tooltip.help;
|
||||
}
|
||||
```
|
||||
|
||||
## TextTooltipStyle
|
||||
|
||||
Configure l'apparence de l'infobulle.
|
||||
|
||||
```
|
||||
Button {
|
||||
TooltipText: "Texte d'aide";
|
||||
TextTooltipStyle: (
|
||||
Background: (TexturePath: "TooltipBg.png", Border: 24),
|
||||
MaxWidth: 400,
|
||||
LabelStyle: (Wrap: true, FontSize: 16),
|
||||
Padding: 24
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
## Combinaisons de Propriétés Courantes
|
||||
|
||||
### Panneau avec Titre et Contenu
|
||||
|
||||
```
|
||||
Group #Panel {
|
||||
Anchor: (Width: 400, Height: 300);
|
||||
Background: (TexturePath: "Panel.png", Border: 20);
|
||||
LayoutMode: Top;
|
||||
Padding: (Full: 16);
|
||||
|
||||
Label #Title {
|
||||
Anchor: (Height: 40);
|
||||
// ...
|
||||
}
|
||||
|
||||
Group #Content {
|
||||
FlexWeight: 1;
|
||||
LayoutMode: TopScrolling;
|
||||
ScrollbarStyle: @DefaultScrollbarStyle;
|
||||
Padding: (Top: 8);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Rangée de Boutons Horizontale
|
||||
|
||||
```
|
||||
Group #ButtonRow {
|
||||
Anchor: (Height: 50);
|
||||
LayoutMode: Right;
|
||||
Padding: (Horizontal: 10);
|
||||
|
||||
TextButton #Cancel {
|
||||
Anchor: (Width: 100);
|
||||
}
|
||||
|
||||
Group { Anchor: (Width: 10); } // Espaceur
|
||||
|
||||
TextButton #Confirm {
|
||||
Anchor: (Width: 100);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Overlay Plein Écran
|
||||
|
||||
```
|
||||
Group #Overlay {
|
||||
Anchor: (Full: 0);
|
||||
Background: (Color: #000000(0.7));
|
||||
LayoutMode: CenterMiddle;
|
||||
|
||||
Group #Dialog {
|
||||
Anchor: (Width: 500, Height: 300);
|
||||
Background: (TexturePath: "Dialog.png", Border: 20);
|
||||
}
|
||||
}
|
||||
```
|
||||
367
content/ui-systems/ui-styles.en.md
Normal file
367
content/ui-systems/ui-styles.en.md
Normal file
@@ -0,0 +1,367 @@
|
||||
---
|
||||
title: UI Styles
|
||||
type: docs
|
||||
weight: 14
|
||||
---
|
||||
|
||||
This page documents the styling system for Hytale UI widgets.
|
||||
|
||||
## Style States
|
||||
|
||||
Interactive widgets support multiple states:
|
||||
|
||||
| State | When Applied |
|
||||
|-------|--------------|
|
||||
| `Default` | Normal state |
|
||||
| `Hovered` | Mouse over widget |
|
||||
| `Pressed` | Mouse button held |
|
||||
| `Disabled` | Widget is disabled |
|
||||
|
||||
```
|
||||
Style: (
|
||||
Default: (Background: "Button.png"),
|
||||
Hovered: (Background: "ButtonHovered.png"),
|
||||
Pressed: (Background: "ButtonPressed.png"),
|
||||
Disabled: (Background: "ButtonDisabled.png")
|
||||
);
|
||||
```
|
||||
|
||||
## LabelStyle
|
||||
|
||||
Text styling for Label widgets.
|
||||
|
||||
```
|
||||
@MyLabelStyle = LabelStyle(
|
||||
FontSize: 16,
|
||||
FontName: "Default", // or "Secondary"
|
||||
TextColor: #ffffff,
|
||||
RenderBold: true,
|
||||
RenderUppercase: false,
|
||||
LetterSpacing: 0,
|
||||
Wrap: false,
|
||||
HorizontalAlignment: Center, // Start, Center, End
|
||||
VerticalAlignment: Center, // Top, Center, Bottom
|
||||
OutlineColor: #000000(0.5)
|
||||
);
|
||||
|
||||
Label {
|
||||
Style: @MyLabelStyle;
|
||||
}
|
||||
```
|
||||
|
||||
### LabelStyle Properties
|
||||
|
||||
| Property | Type | Description |
|
||||
|----------|------|-------------|
|
||||
| `FontSize` | number | Text size |
|
||||
| `FontName` | string | Font family ("Default", "Secondary") |
|
||||
| `TextColor` | color | Text color |
|
||||
| `RenderBold` | bool | Bold text |
|
||||
| `RenderUppercase` | bool | Force uppercase |
|
||||
| `LetterSpacing` | number | Space between characters |
|
||||
| `Wrap` | bool | Enable text wrapping |
|
||||
| `HorizontalAlignment` | enum | Start, Center, End |
|
||||
| `VerticalAlignment` | enum | Top, Center, Bottom |
|
||||
| `OutlineColor` | color | Text outline color |
|
||||
| `Alignment` | enum | Shorthand for both alignments (Center) |
|
||||
|
||||
## ButtonStyle
|
||||
|
||||
Styling for Button widgets (without text).
|
||||
|
||||
```
|
||||
@MyButtonStyle = ButtonStyle(
|
||||
Default: (Background: (TexturePath: "Button.png", Border: 12)),
|
||||
Hovered: (Background: (TexturePath: "ButtonHovered.png", Border: 12)),
|
||||
Pressed: (Background: (TexturePath: "ButtonPressed.png", Border: 12)),
|
||||
Disabled: (Background: (TexturePath: "ButtonDisabled.png", Border: 12)),
|
||||
Sounds: @ButtonSounds
|
||||
);
|
||||
|
||||
Button {
|
||||
Style: @MyButtonStyle;
|
||||
}
|
||||
```
|
||||
|
||||
### Button State Properties
|
||||
|
||||
| Property | Type | Description |
|
||||
|----------|------|-------------|
|
||||
| `Background` | PatchStyle | Background appearance |
|
||||
|
||||
## TextButtonStyle
|
||||
|
||||
Styling for TextButton widgets.
|
||||
|
||||
```
|
||||
@MyTextButtonStyle = TextButtonStyle(
|
||||
Default: (
|
||||
Background: (TexturePath: "Button.png", Border: 12),
|
||||
LabelStyle: (FontSize: 17, TextColor: #bfcdd5, RenderBold: true)
|
||||
),
|
||||
Hovered: (
|
||||
Background: (TexturePath: "ButtonHovered.png", Border: 12),
|
||||
LabelStyle: (FontSize: 17, TextColor: #ffffff, RenderBold: true)
|
||||
),
|
||||
Pressed: (
|
||||
Background: (TexturePath: "ButtonPressed.png", Border: 12),
|
||||
LabelStyle: (FontSize: 17, TextColor: #aaaaaa, RenderBold: true)
|
||||
),
|
||||
Disabled: (
|
||||
Background: (TexturePath: "ButtonDisabled.png", Border: 12),
|
||||
LabelStyle: (FontSize: 17, TextColor: #797b7c, RenderBold: true)
|
||||
),
|
||||
Sounds: @ButtonSounds
|
||||
);
|
||||
```
|
||||
|
||||
### TextButton State Properties
|
||||
|
||||
| Property | Type | Description |
|
||||
|----------|------|-------------|
|
||||
| `Background` | PatchStyle | Background appearance |
|
||||
| `LabelStyle` | LabelStyle | Text styling |
|
||||
|
||||
## PatchStyle
|
||||
|
||||
9-patch texture configuration for stretchable backgrounds.
|
||||
|
||||
```
|
||||
@MyPatchStyle = PatchStyle(
|
||||
TexturePath: "Panel.png",
|
||||
Border: 16 // Uniform border
|
||||
);
|
||||
|
||||
@MyPatchStyle2 = PatchStyle(
|
||||
TexturePath: "Button.png",
|
||||
HorizontalBorder: 80, // Left/right border
|
||||
VerticalBorder: 12 // Top/bottom border
|
||||
);
|
||||
|
||||
// With color tint
|
||||
@ColoredPatch = PatchStyle(
|
||||
Color: #ff0000(0.5) // Semi-transparent red
|
||||
);
|
||||
```
|
||||
|
||||
### PatchStyle Properties
|
||||
|
||||
| Property | Type | Description |
|
||||
|----------|------|-------------|
|
||||
| `TexturePath` | string | Path to texture file |
|
||||
| `Border` | number | Uniform 9-patch border |
|
||||
| `HorizontalBorder` | number | Left/right 9-patch border |
|
||||
| `VerticalBorder` | number | Top/bottom 9-patch border |
|
||||
| `Color` | color | Solid color (instead of texture) |
|
||||
|
||||
## InputFieldStyle
|
||||
|
||||
Styling for text input fields.
|
||||
|
||||
```
|
||||
@MyInputStyle = InputFieldStyle(
|
||||
TextColor: #ffffff,
|
||||
FontSize: 16
|
||||
);
|
||||
|
||||
@MyPlaceholderStyle = InputFieldStyle(
|
||||
TextColor: #6e7da1
|
||||
);
|
||||
|
||||
TextField {
|
||||
Style: @MyInputStyle;
|
||||
PlaceholderStyle: @MyPlaceholderStyle;
|
||||
}
|
||||
```
|
||||
|
||||
## SliderStyle
|
||||
|
||||
Styling for slider controls.
|
||||
|
||||
```
|
||||
@MySliderStyle = SliderStyle(
|
||||
Background: (TexturePath: "SliderBackground.png", Border: 2),
|
||||
Handle: "SliderHandle.png",
|
||||
HandleWidth: 16,
|
||||
HandleHeight: 16,
|
||||
Sounds: (
|
||||
Activate: (SoundPath: "SliderTick.ogg", Volume: 10),
|
||||
MouseHover: (SoundPath: "Hover.ogg", Volume: 6)
|
||||
)
|
||||
);
|
||||
```
|
||||
|
||||
### SliderStyle Properties
|
||||
|
||||
| Property | Type | Description |
|
||||
|----------|------|-------------|
|
||||
| `Background` | PatchStyle | Track background |
|
||||
| `Handle` | string | Handle texture path |
|
||||
| `HandleWidth` | number | Handle width |
|
||||
| `HandleHeight` | number | Handle height |
|
||||
| `Sounds` | object | Sound effects |
|
||||
|
||||
## CheckBoxStyle
|
||||
|
||||
Styling for checkbox controls.
|
||||
|
||||
```
|
||||
@MyCheckBoxStyle = CheckBoxStyle(
|
||||
Unchecked: (
|
||||
DefaultBackground: (Color: #00000000),
|
||||
HoveredBackground: (Color: #ffffff20),
|
||||
PressedBackground: (Color: #ffffff10),
|
||||
DisabledBackground: (Color: #424242),
|
||||
ChangedSound: (SoundPath: "Untick.ogg", Volume: 6)
|
||||
),
|
||||
Checked: (
|
||||
DefaultBackground: (TexturePath: "Checkmark.png"),
|
||||
HoveredBackground: (TexturePath: "Checkmark.png"),
|
||||
PressedBackground: (TexturePath: "Checkmark.png"),
|
||||
ChangedSound: (SoundPath: "Tick.ogg", Volume: 6)
|
||||
)
|
||||
);
|
||||
```
|
||||
|
||||
## DropdownBoxStyle
|
||||
|
||||
Styling for dropdown menus.
|
||||
|
||||
```
|
||||
@MyDropdownStyle = DropdownBoxStyle(
|
||||
DefaultBackground: (TexturePath: "Dropdown.png", Border: 16),
|
||||
HoveredBackground: (TexturePath: "DropdownHovered.png", Border: 16),
|
||||
PressedBackground: (TexturePath: "DropdownPressed.png", Border: 16),
|
||||
DefaultArrowTexturePath: "DropdownCaret.png",
|
||||
HoveredArrowTexturePath: "DropdownCaret.png",
|
||||
PressedArrowTexturePath: "DropdownCaretPressed.png",
|
||||
ArrowWidth: 13,
|
||||
ArrowHeight: 18,
|
||||
LabelStyle: (TextColor: #96a9be, FontSize: 13),
|
||||
EntryLabelStyle: (TextColor: #b7cedd),
|
||||
SelectedEntryLabelStyle: (TextColor: #b7cedd, RenderBold: true),
|
||||
HorizontalPadding: 8,
|
||||
PanelBackground: (TexturePath: "DropdownBox.png", Border: 16),
|
||||
PanelPadding: 6,
|
||||
PanelAlign: Right, // or Bottom
|
||||
PanelOffset: 7,
|
||||
EntryHeight: 31,
|
||||
EntriesInViewport: 10,
|
||||
HoveredEntryBackground: (Color: #0a0f17),
|
||||
PressedEntryBackground: (Color: #0f1621),
|
||||
Sounds: @DropdownBoxSounds,
|
||||
EntrySounds: @ButtonSounds
|
||||
);
|
||||
```
|
||||
|
||||
## ScrollbarStyle
|
||||
|
||||
Styling for scrollbars.
|
||||
|
||||
```
|
||||
@MyScrollbarStyle = ScrollbarStyle(
|
||||
Spacing: 6,
|
||||
Size: 6,
|
||||
Background: (TexturePath: "Scrollbar.png", Border: 3),
|
||||
Handle: (TexturePath: "ScrollbarHandle.png", Border: 3),
|
||||
HoveredHandle: (TexturePath: "ScrollbarHandleHovered.png", Border: 3),
|
||||
DraggedHandle: (TexturePath: "ScrollbarHandleDragged.png", Border: 3),
|
||||
OnlyVisibleWhenHovered: false
|
||||
);
|
||||
```
|
||||
|
||||
## TabNavigationStyle
|
||||
|
||||
Styling for tab navigation.
|
||||
|
||||
```
|
||||
@TabStyle = TabStyleState(
|
||||
Background: "Tab.png",
|
||||
Overlay: "TabOverlay.png",
|
||||
IconAnchor: (Width: 44, Height: 44),
|
||||
Anchor: (Width: 82, Height: 62)
|
||||
);
|
||||
|
||||
@MyTabsStyle = TabNavigationStyle(
|
||||
TabStyle: (
|
||||
Default: @TabStyle,
|
||||
Hovered: (...@TabStyle, Background: "TabHovered.png"),
|
||||
Pressed: (...@TabStyle, Background: "TabPressed.png")
|
||||
),
|
||||
SelectedTabStyle: (
|
||||
Default: (
|
||||
...@TabStyle,
|
||||
Overlay: "TabSelectedOverlay.png"
|
||||
)
|
||||
),
|
||||
TabSounds: @TabSounds,
|
||||
SeparatorAnchor: (Width: 5, Height: 34),
|
||||
SeparatorBackground: "TabSeparator.png"
|
||||
);
|
||||
```
|
||||
|
||||
## TextTooltipStyle
|
||||
|
||||
Styling for text tooltips.
|
||||
|
||||
```
|
||||
@MyTooltipStyle = TextTooltipStyle(
|
||||
Background: (TexturePath: "TooltipBackground.png", Border: 24),
|
||||
MaxWidth: 400,
|
||||
LabelStyle: (Wrap: true, FontSize: 16),
|
||||
Padding: 24
|
||||
);
|
||||
```
|
||||
|
||||
## Sound Definitions
|
||||
|
||||
Sounds are defined as objects with audio properties.
|
||||
|
||||
```
|
||||
@ButtonSounds = (
|
||||
Activate: (
|
||||
SoundPath: "Sounds/ButtonActivate.ogg",
|
||||
Volume: 6,
|
||||
MinPitch: -0.2,
|
||||
MaxPitch: 0.2
|
||||
),
|
||||
MouseHover: (
|
||||
SoundPath: "Sounds/ButtonHover.ogg",
|
||||
Volume: 6
|
||||
)
|
||||
);
|
||||
|
||||
@DropdownBoxSounds = DropdownBoxSounds(
|
||||
Activate: (SoundPath: "Tick.ogg", Volume: 6),
|
||||
MouseHover: (SoundPath: "Hover.ogg", Volume: 6),
|
||||
Close: (SoundPath: "Untick.ogg", Volume: 6)
|
||||
);
|
||||
```
|
||||
|
||||
### Sound Properties
|
||||
|
||||
| Property | Type | Description |
|
||||
|----------|------|-------------|
|
||||
| `SoundPath` | string | Path to audio file |
|
||||
| `Volume` | number | Volume level (can be negative) |
|
||||
| `MinPitch` | number | Minimum pitch variation |
|
||||
| `MaxPitch` | number | Maximum pitch variation |
|
||||
|
||||
## Style Inheritance
|
||||
|
||||
Use the spread operator to extend styles:
|
||||
|
||||
```
|
||||
@BaseButtonStyle = TextButtonStyle(
|
||||
Default: (Background: @DefaultBg, LabelStyle: @DefaultLabel),
|
||||
Hovered: (Background: @HoveredBg, LabelStyle: @DefaultLabel),
|
||||
Pressed: (Background: @PressedBg, LabelStyle: @DefaultLabel),
|
||||
Sounds: @ButtonSounds
|
||||
);
|
||||
|
||||
@DestructiveButtonStyle = TextButtonStyle(
|
||||
...@BaseButtonStyle,
|
||||
Default: (...@BaseButtonStyle.Default, Background: @DestructiveBg),
|
||||
Sounds: @DestructiveSounds
|
||||
);
|
||||
```
|
||||
367
content/ui-systems/ui-styles.fr.md
Normal file
367
content/ui-systems/ui-styles.fr.md
Normal file
@@ -0,0 +1,367 @@
|
||||
---
|
||||
title: Styles UI
|
||||
type: docs
|
||||
weight: 14
|
||||
---
|
||||
|
||||
Cette page documente le système de styles pour les widgets UI de Hytale.
|
||||
|
||||
## États de Style
|
||||
|
||||
Les widgets interactifs supportent plusieurs états :
|
||||
|
||||
| État | Quand Appliqué |
|
||||
|------|----------------|
|
||||
| `Default` | État normal |
|
||||
| `Hovered` | Souris sur le widget |
|
||||
| `Pressed` | Bouton de souris maintenu |
|
||||
| `Disabled` | Widget désactivé |
|
||||
|
||||
```
|
||||
Style: (
|
||||
Default: (Background: "Button.png"),
|
||||
Hovered: (Background: "ButtonHovered.png"),
|
||||
Pressed: (Background: "ButtonPressed.png"),
|
||||
Disabled: (Background: "ButtonDisabled.png")
|
||||
);
|
||||
```
|
||||
|
||||
## LabelStyle
|
||||
|
||||
Style de texte pour les widgets Label.
|
||||
|
||||
```
|
||||
@MyLabelStyle = LabelStyle(
|
||||
FontSize: 16,
|
||||
FontName: "Default", // ou "Secondary"
|
||||
TextColor: #ffffff,
|
||||
RenderBold: true,
|
||||
RenderUppercase: false,
|
||||
LetterSpacing: 0,
|
||||
Wrap: false,
|
||||
HorizontalAlignment: Center, // Start, Center, End
|
||||
VerticalAlignment: Center, // Top, Center, Bottom
|
||||
OutlineColor: #000000(0.5)
|
||||
);
|
||||
|
||||
Label {
|
||||
Style: @MyLabelStyle;
|
||||
}
|
||||
```
|
||||
|
||||
### Propriétés LabelStyle
|
||||
|
||||
| Propriété | Type | Description |
|
||||
|-----------|------|-------------|
|
||||
| `FontSize` | nombre | Taille du texte |
|
||||
| `FontName` | chaîne | Famille de police ("Default", "Secondary") |
|
||||
| `TextColor` | couleur | Couleur du texte |
|
||||
| `RenderBold` | bool | Texte en gras |
|
||||
| `RenderUppercase` | bool | Forcer les majuscules |
|
||||
| `LetterSpacing` | nombre | Espace entre les caractères |
|
||||
| `Wrap` | bool | Activer le retour à la ligne |
|
||||
| `HorizontalAlignment` | enum | Start, Center, End |
|
||||
| `VerticalAlignment` | enum | Top, Center, Bottom |
|
||||
| `OutlineColor` | couleur | Couleur du contour du texte |
|
||||
| `Alignment` | enum | Raccourci pour les deux alignements (Center) |
|
||||
|
||||
## ButtonStyle
|
||||
|
||||
Style pour les widgets Button (sans texte).
|
||||
|
||||
```
|
||||
@MyButtonStyle = ButtonStyle(
|
||||
Default: (Background: (TexturePath: "Button.png", Border: 12)),
|
||||
Hovered: (Background: (TexturePath: "ButtonHovered.png", Border: 12)),
|
||||
Pressed: (Background: (TexturePath: "ButtonPressed.png", Border: 12)),
|
||||
Disabled: (Background: (TexturePath: "ButtonDisabled.png", Border: 12)),
|
||||
Sounds: @ButtonSounds
|
||||
);
|
||||
|
||||
Button {
|
||||
Style: @MyButtonStyle;
|
||||
}
|
||||
```
|
||||
|
||||
### Propriétés d'État Button
|
||||
|
||||
| Propriété | Type | Description |
|
||||
|-----------|------|-------------|
|
||||
| `Background` | PatchStyle | Apparence du fond |
|
||||
|
||||
## TextButtonStyle
|
||||
|
||||
Style pour les widgets TextButton.
|
||||
|
||||
```
|
||||
@MyTextButtonStyle = TextButtonStyle(
|
||||
Default: (
|
||||
Background: (TexturePath: "Button.png", Border: 12),
|
||||
LabelStyle: (FontSize: 17, TextColor: #bfcdd5, RenderBold: true)
|
||||
),
|
||||
Hovered: (
|
||||
Background: (TexturePath: "ButtonHovered.png", Border: 12),
|
||||
LabelStyle: (FontSize: 17, TextColor: #ffffff, RenderBold: true)
|
||||
),
|
||||
Pressed: (
|
||||
Background: (TexturePath: "ButtonPressed.png", Border: 12),
|
||||
LabelStyle: (FontSize: 17, TextColor: #aaaaaa, RenderBold: true)
|
||||
),
|
||||
Disabled: (
|
||||
Background: (TexturePath: "ButtonDisabled.png", Border: 12),
|
||||
LabelStyle: (FontSize: 17, TextColor: #797b7c, RenderBold: true)
|
||||
),
|
||||
Sounds: @ButtonSounds
|
||||
);
|
||||
```
|
||||
|
||||
### Propriétés d'État TextButton
|
||||
|
||||
| Propriété | Type | Description |
|
||||
|-----------|------|-------------|
|
||||
| `Background` | PatchStyle | Apparence du fond |
|
||||
| `LabelStyle` | LabelStyle | Style du texte |
|
||||
|
||||
## PatchStyle
|
||||
|
||||
Configuration de texture 9-patch pour les fonds étirables.
|
||||
|
||||
```
|
||||
@MyPatchStyle = PatchStyle(
|
||||
TexturePath: "Panel.png",
|
||||
Border: 16 // Bordure uniforme
|
||||
);
|
||||
|
||||
@MyPatchStyle2 = PatchStyle(
|
||||
TexturePath: "Button.png",
|
||||
HorizontalBorder: 80, // Bordure gauche/droite
|
||||
VerticalBorder: 12 // Bordure haut/bas
|
||||
);
|
||||
|
||||
// Avec teinte de couleur
|
||||
@ColoredPatch = PatchStyle(
|
||||
Color: #ff0000(0.5) // Rouge semi-transparent
|
||||
);
|
||||
```
|
||||
|
||||
### Propriétés PatchStyle
|
||||
|
||||
| Propriété | Type | Description |
|
||||
|-----------|------|-------------|
|
||||
| `TexturePath` | chaîne | Chemin vers le fichier texture |
|
||||
| `Border` | nombre | Bordure 9-patch uniforme |
|
||||
| `HorizontalBorder` | nombre | Bordure 9-patch gauche/droite |
|
||||
| `VerticalBorder` | nombre | Bordure 9-patch haut/bas |
|
||||
| `Color` | couleur | Couleur unie (au lieu de texture) |
|
||||
|
||||
## InputFieldStyle
|
||||
|
||||
Style pour les champs de saisie texte.
|
||||
|
||||
```
|
||||
@MyInputStyle = InputFieldStyle(
|
||||
TextColor: #ffffff,
|
||||
FontSize: 16
|
||||
);
|
||||
|
||||
@MyPlaceholderStyle = InputFieldStyle(
|
||||
TextColor: #6e7da1
|
||||
);
|
||||
|
||||
TextField {
|
||||
Style: @MyInputStyle;
|
||||
PlaceholderStyle: @MyPlaceholderStyle;
|
||||
}
|
||||
```
|
||||
|
||||
## SliderStyle
|
||||
|
||||
Style pour les contrôles curseur.
|
||||
|
||||
```
|
||||
@MySliderStyle = SliderStyle(
|
||||
Background: (TexturePath: "SliderBackground.png", Border: 2),
|
||||
Handle: "SliderHandle.png",
|
||||
HandleWidth: 16,
|
||||
HandleHeight: 16,
|
||||
Sounds: (
|
||||
Activate: (SoundPath: "SliderTick.ogg", Volume: 10),
|
||||
MouseHover: (SoundPath: "Hover.ogg", Volume: 6)
|
||||
)
|
||||
);
|
||||
```
|
||||
|
||||
### Propriétés SliderStyle
|
||||
|
||||
| Propriété | Type | Description |
|
||||
|-----------|------|-------------|
|
||||
| `Background` | PatchStyle | Fond de la piste |
|
||||
| `Handle` | chaîne | Chemin texture de la poignée |
|
||||
| `HandleWidth` | nombre | Largeur de la poignée |
|
||||
| `HandleHeight` | nombre | Hauteur de la poignée |
|
||||
| `Sounds` | objet | Effets sonores |
|
||||
|
||||
## CheckBoxStyle
|
||||
|
||||
Style pour les cases à cocher.
|
||||
|
||||
```
|
||||
@MyCheckBoxStyle = CheckBoxStyle(
|
||||
Unchecked: (
|
||||
DefaultBackground: (Color: #00000000),
|
||||
HoveredBackground: (Color: #ffffff20),
|
||||
PressedBackground: (Color: #ffffff10),
|
||||
DisabledBackground: (Color: #424242),
|
||||
ChangedSound: (SoundPath: "Untick.ogg", Volume: 6)
|
||||
),
|
||||
Checked: (
|
||||
DefaultBackground: (TexturePath: "Checkmark.png"),
|
||||
HoveredBackground: (TexturePath: "Checkmark.png"),
|
||||
PressedBackground: (TexturePath: "Checkmark.png"),
|
||||
ChangedSound: (SoundPath: "Tick.ogg", Volume: 6)
|
||||
)
|
||||
);
|
||||
```
|
||||
|
||||
## DropdownBoxStyle
|
||||
|
||||
Style pour les menus déroulants.
|
||||
|
||||
```
|
||||
@MyDropdownStyle = DropdownBoxStyle(
|
||||
DefaultBackground: (TexturePath: "Dropdown.png", Border: 16),
|
||||
HoveredBackground: (TexturePath: "DropdownHovered.png", Border: 16),
|
||||
PressedBackground: (TexturePath: "DropdownPressed.png", Border: 16),
|
||||
DefaultArrowTexturePath: "DropdownCaret.png",
|
||||
HoveredArrowTexturePath: "DropdownCaret.png",
|
||||
PressedArrowTexturePath: "DropdownCaretPressed.png",
|
||||
ArrowWidth: 13,
|
||||
ArrowHeight: 18,
|
||||
LabelStyle: (TextColor: #96a9be, FontSize: 13),
|
||||
EntryLabelStyle: (TextColor: #b7cedd),
|
||||
SelectedEntryLabelStyle: (TextColor: #b7cedd, RenderBold: true),
|
||||
HorizontalPadding: 8,
|
||||
PanelBackground: (TexturePath: "DropdownBox.png", Border: 16),
|
||||
PanelPadding: 6,
|
||||
PanelAlign: Right, // ou Bottom
|
||||
PanelOffset: 7,
|
||||
EntryHeight: 31,
|
||||
EntriesInViewport: 10,
|
||||
HoveredEntryBackground: (Color: #0a0f17),
|
||||
PressedEntryBackground: (Color: #0f1621),
|
||||
Sounds: @DropdownBoxSounds,
|
||||
EntrySounds: @ButtonSounds
|
||||
);
|
||||
```
|
||||
|
||||
## ScrollbarStyle
|
||||
|
||||
Style pour les barres de défilement.
|
||||
|
||||
```
|
||||
@MyScrollbarStyle = ScrollbarStyle(
|
||||
Spacing: 6,
|
||||
Size: 6,
|
||||
Background: (TexturePath: "Scrollbar.png", Border: 3),
|
||||
Handle: (TexturePath: "ScrollbarHandle.png", Border: 3),
|
||||
HoveredHandle: (TexturePath: "ScrollbarHandleHovered.png", Border: 3),
|
||||
DraggedHandle: (TexturePath: "ScrollbarHandleDragged.png", Border: 3),
|
||||
OnlyVisibleWhenHovered: false
|
||||
);
|
||||
```
|
||||
|
||||
## TabNavigationStyle
|
||||
|
||||
Style pour la navigation par onglets.
|
||||
|
||||
```
|
||||
@TabStyle = TabStyleState(
|
||||
Background: "Tab.png",
|
||||
Overlay: "TabOverlay.png",
|
||||
IconAnchor: (Width: 44, Height: 44),
|
||||
Anchor: (Width: 82, Height: 62)
|
||||
);
|
||||
|
||||
@MyTabsStyle = TabNavigationStyle(
|
||||
TabStyle: (
|
||||
Default: @TabStyle,
|
||||
Hovered: (...@TabStyle, Background: "TabHovered.png"),
|
||||
Pressed: (...@TabStyle, Background: "TabPressed.png")
|
||||
),
|
||||
SelectedTabStyle: (
|
||||
Default: (
|
||||
...@TabStyle,
|
||||
Overlay: "TabSelectedOverlay.png"
|
||||
)
|
||||
),
|
||||
TabSounds: @TabSounds,
|
||||
SeparatorAnchor: (Width: 5, Height: 34),
|
||||
SeparatorBackground: "TabSeparator.png"
|
||||
);
|
||||
```
|
||||
|
||||
## TextTooltipStyle
|
||||
|
||||
Style pour les infobulles texte.
|
||||
|
||||
```
|
||||
@MyTooltipStyle = TextTooltipStyle(
|
||||
Background: (TexturePath: "TooltipBackground.png", Border: 24),
|
||||
MaxWidth: 400,
|
||||
LabelStyle: (Wrap: true, FontSize: 16),
|
||||
Padding: 24
|
||||
);
|
||||
```
|
||||
|
||||
## Définitions de Sons
|
||||
|
||||
Les sons sont définis comme des objets avec des propriétés audio.
|
||||
|
||||
```
|
||||
@ButtonSounds = (
|
||||
Activate: (
|
||||
SoundPath: "Sounds/ButtonActivate.ogg",
|
||||
Volume: 6,
|
||||
MinPitch: -0.2,
|
||||
MaxPitch: 0.2
|
||||
),
|
||||
MouseHover: (
|
||||
SoundPath: "Sounds/ButtonHover.ogg",
|
||||
Volume: 6
|
||||
)
|
||||
);
|
||||
|
||||
@DropdownBoxSounds = DropdownBoxSounds(
|
||||
Activate: (SoundPath: "Tick.ogg", Volume: 6),
|
||||
MouseHover: (SoundPath: "Hover.ogg", Volume: 6),
|
||||
Close: (SoundPath: "Untick.ogg", Volume: 6)
|
||||
);
|
||||
```
|
||||
|
||||
### Propriétés de Son
|
||||
|
||||
| Propriété | Type | Description |
|
||||
|-----------|------|-------------|
|
||||
| `SoundPath` | chaîne | Chemin vers le fichier audio |
|
||||
| `Volume` | nombre | Niveau de volume (peut être négatif) |
|
||||
| `MinPitch` | nombre | Variation de hauteur minimale |
|
||||
| `MaxPitch` | nombre | Variation de hauteur maximale |
|
||||
|
||||
## Héritage de Styles
|
||||
|
||||
Utilisez l'opérateur spread pour étendre les styles :
|
||||
|
||||
```
|
||||
@BaseButtonStyle = TextButtonStyle(
|
||||
Default: (Background: @DefaultBg, LabelStyle: @DefaultLabel),
|
||||
Hovered: (Background: @HoveredBg, LabelStyle: @DefaultLabel),
|
||||
Pressed: (Background: @PressedBg, LabelStyle: @DefaultLabel),
|
||||
Sounds: @ButtonSounds
|
||||
);
|
||||
|
||||
@DestructiveButtonStyle = TextButtonStyle(
|
||||
...@BaseButtonStyle,
|
||||
Default: (...@BaseButtonStyle.Default, Background: @DestructiveBg),
|
||||
Sounds: @DestructiveSounds
|
||||
);
|
||||
```
|
||||
331
content/ui-systems/ui-syntax.en.md
Normal file
331
content/ui-systems/ui-syntax.en.md
Normal file
@@ -0,0 +1,331 @@
|
||||
---
|
||||
title: UI Syntax
|
||||
type: docs
|
||||
weight: 11
|
||||
---
|
||||
|
||||
This page covers the complete syntax of Hytale's UI markup language.
|
||||
|
||||
## Comments
|
||||
|
||||
```
|
||||
// Single line comment
|
||||
|
||||
/* Multi-line
|
||||
comment */
|
||||
```
|
||||
|
||||
## Variables
|
||||
|
||||
### Local Variables
|
||||
|
||||
Define variables with `@` prefix:
|
||||
|
||||
```
|
||||
@MyNumber = 50;
|
||||
@MyString = "Hello";
|
||||
@MyColor = #ff5500;
|
||||
@MyObject = (Key: value, Other: 123);
|
||||
```
|
||||
|
||||
### Variable Types
|
||||
|
||||
| Type | Example |
|
||||
|------|---------|
|
||||
| Number | `@Size = 50;` |
|
||||
| String | `@Text = "Hello";` |
|
||||
| Color | `@Color = #ff5500;` |
|
||||
| Object | `@Obj = (Width: 100, Height: 50);` |
|
||||
| Array | `@List = [item1, item2, item3];` |
|
||||
| Boolean | `@Visible = true;` |
|
||||
|
||||
### Using Variables
|
||||
|
||||
Reference variables with `@`:
|
||||
|
||||
```
|
||||
Group {
|
||||
Anchor: (Height: @MyNumber);
|
||||
Background: (Color: @MyColor);
|
||||
}
|
||||
```
|
||||
|
||||
## Imports
|
||||
|
||||
### Import Files
|
||||
|
||||
Use `$` prefix to import external files:
|
||||
|
||||
```
|
||||
$Common = "Common.ui";
|
||||
$Sounds = "../Sounds.ui";
|
||||
$ClientCommon = "../../Common.ui";
|
||||
```
|
||||
|
||||
### Reference Imported Variables
|
||||
|
||||
Access imported variables with dot notation:
|
||||
|
||||
```
|
||||
$Common.@DefaultButtonStyle
|
||||
$Sounds.@ButtonsLight
|
||||
```
|
||||
|
||||
### Use Imported Templates
|
||||
|
||||
Instantiate templates from imports:
|
||||
|
||||
```
|
||||
$Common.@TextButton {
|
||||
@Text = "Click Me";
|
||||
}
|
||||
```
|
||||
|
||||
## Colors
|
||||
|
||||
### Hexadecimal
|
||||
|
||||
```
|
||||
@Color1 = #ff5500; // RGB
|
||||
@Color2 = #ff5500ff; // RGBA
|
||||
```
|
||||
|
||||
### With Opacity
|
||||
|
||||
```
|
||||
@Color3 = #ff5500(0.5); // 50% opacity
|
||||
@Color4 = #000000(0.8); // 80% opacity
|
||||
```
|
||||
|
||||
## Objects
|
||||
|
||||
### Basic Object
|
||||
|
||||
```
|
||||
@Style = (
|
||||
FontSize: 16,
|
||||
TextColor: #ffffff,
|
||||
RenderBold: true
|
||||
);
|
||||
```
|
||||
|
||||
### Nested Objects
|
||||
|
||||
```
|
||||
@ButtonStyle = (
|
||||
Default: (
|
||||
Background: (TexturePath: "Button.png", Border: 12)
|
||||
),
|
||||
Hovered: (
|
||||
Background: (TexturePath: "ButtonHovered.png", Border: 12)
|
||||
)
|
||||
);
|
||||
```
|
||||
|
||||
## Spread Operator
|
||||
|
||||
Use `...` to extend/merge objects:
|
||||
|
||||
```
|
||||
@BaseStyle = (
|
||||
FontSize: 16,
|
||||
TextColor: #ffffff
|
||||
);
|
||||
|
||||
@ExtendedStyle = (
|
||||
...@BaseStyle, // Inherit all properties from @BaseStyle
|
||||
RenderBold: true // Add/override properties
|
||||
);
|
||||
```
|
||||
|
||||
Spread works in any object context:
|
||||
|
||||
```
|
||||
Style: (
|
||||
...$Common.@DefaultButtonStyle,
|
||||
Sounds: (
|
||||
...$Sounds.@ButtonsLight,
|
||||
Activate: (Volume: 10)
|
||||
)
|
||||
);
|
||||
```
|
||||
|
||||
## Templates (Macros)
|
||||
|
||||
### Define a Template
|
||||
|
||||
Templates are reusable widget definitions with parameters:
|
||||
|
||||
```
|
||||
@MyButton = TextButton {
|
||||
@Text = ""; // Parameter with default
|
||||
@Anchor = Anchor(); // Parameter with default
|
||||
@Sounds = (); // Empty default
|
||||
|
||||
Style: @DefaultTextButtonStyle;
|
||||
Anchor: (...@Anchor, Height: 44);
|
||||
Text: @Text;
|
||||
};
|
||||
```
|
||||
|
||||
### Instantiate a Template
|
||||
|
||||
```
|
||||
// Use with defaults
|
||||
@MyButton {}
|
||||
|
||||
// Override parameters
|
||||
@MyButton {
|
||||
@Text = "Submit";
|
||||
@Anchor = (Width: 200);
|
||||
}
|
||||
|
||||
// From import
|
||||
$Common.@TextButton {
|
||||
@Text = %ui.button.confirm;
|
||||
}
|
||||
```
|
||||
|
||||
## Widget Declarations
|
||||
|
||||
### Basic Widget
|
||||
|
||||
```
|
||||
WidgetType {
|
||||
Property: value;
|
||||
}
|
||||
```
|
||||
|
||||
### Widget with ID
|
||||
|
||||
IDs start with `#` and allow targeting from Java. IDs must be in **UpperCamelCase** format (no hyphens or underscores):
|
||||
|
||||
```
|
||||
Label #PlayerName {
|
||||
Text: "Unknown";
|
||||
}
|
||||
|
||||
// Valid IDs
|
||||
#MainPanel
|
||||
#ConfirmButton
|
||||
#PlayerHealthBar
|
||||
|
||||
// Invalid IDs (will cause errors)
|
||||
#main-panel // No hyphens allowed
|
||||
#confirm_button // No underscores allowed
|
||||
#playerhealthbar // Should be UpperCamelCase
|
||||
```
|
||||
|
||||
### Nested Widgets
|
||||
|
||||
```
|
||||
Group #Container {
|
||||
Label #Title {
|
||||
Text: "Header";
|
||||
}
|
||||
|
||||
Group #Content {
|
||||
Label {
|
||||
Text: "Body text";
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Anonymous Widgets
|
||||
|
||||
Widgets without ID are anonymous:
|
||||
|
||||
```
|
||||
Group {
|
||||
Label { Text: "No ID"; }
|
||||
}
|
||||
```
|
||||
|
||||
## Selectors
|
||||
|
||||
Selectors are strings starting with `#` used to target elements:
|
||||
|
||||
```java
|
||||
// In Java code
|
||||
builder.set("#PlayerName", "Steve");
|
||||
builder.append("#Container", "ui/child_template");
|
||||
builder.clear("#Content");
|
||||
```
|
||||
|
||||
## Translation Keys
|
||||
|
||||
Use `%` prefix for localized strings:
|
||||
|
||||
```
|
||||
Label {
|
||||
Text: %server.ui.shop.title;
|
||||
}
|
||||
|
||||
TextButton {
|
||||
Text: %client.button.confirm;
|
||||
}
|
||||
```
|
||||
|
||||
## Typed Constructors
|
||||
|
||||
Some complex types use function-style constructors:
|
||||
|
||||
```
|
||||
// Style constructors
|
||||
@Style = LabelStyle(FontSize: 16, TextColor: #fff);
|
||||
@BtnStyle = ButtonStyle(Default: (...), Hovered: (...));
|
||||
|
||||
// Layout constructors
|
||||
@Pad = Padding(Full: 10);
|
||||
@Anch = Anchor(Width: 100, Height: 50);
|
||||
|
||||
// Visual constructors
|
||||
@Bg = PatchStyle(TexturePath: "bg.png", Border: 12);
|
||||
@Scroll = ScrollbarStyle(Size: 6, Spacing: 8);
|
||||
```
|
||||
|
||||
## Complete Example
|
||||
|
||||
```
|
||||
$Common = "Common.ui";
|
||||
$Sounds = "Sounds.ui";
|
||||
|
||||
@PanelWidth = 400;
|
||||
@PanelHeight = 300;
|
||||
@TitleColor = #b4c8c9;
|
||||
|
||||
@PanelTitle = Label {
|
||||
@Text = "";
|
||||
|
||||
Style: (
|
||||
FontSize: 20,
|
||||
TextColor: @TitleColor,
|
||||
RenderBold: true,
|
||||
HorizontalAlignment: Center
|
||||
);
|
||||
Text: @Text;
|
||||
};
|
||||
|
||||
Group #MainPanel {
|
||||
Anchor: (Width: @PanelWidth, Height: @PanelHeight);
|
||||
Background: (TexturePath: "Panel.png", Border: 20);
|
||||
LayoutMode: Top;
|
||||
Padding: (Full: 16);
|
||||
|
||||
@PanelTitle {
|
||||
@Text = %ui.panel.title;
|
||||
}
|
||||
|
||||
Group #Content {
|
||||
FlexWeight: 1;
|
||||
LayoutMode: TopScrolling;
|
||||
ScrollbarStyle: $Common.@DefaultScrollbarStyle;
|
||||
}
|
||||
|
||||
$Common.@TextButton #ConfirmButton {
|
||||
@Text = %ui.button.confirm;
|
||||
@Sounds = $Sounds.@ButtonsLight;
|
||||
}
|
||||
}
|
||||
```
|
||||
331
content/ui-systems/ui-syntax.fr.md
Normal file
331
content/ui-systems/ui-syntax.fr.md
Normal file
@@ -0,0 +1,331 @@
|
||||
---
|
||||
title: Syntaxe UI
|
||||
type: docs
|
||||
weight: 11
|
||||
---
|
||||
|
||||
Cette page couvre la syntaxe complète du langage de balisage UI de Hytale.
|
||||
|
||||
## Commentaires
|
||||
|
||||
```
|
||||
// Commentaire sur une ligne
|
||||
|
||||
/* Commentaire
|
||||
multi-lignes */
|
||||
```
|
||||
|
||||
## Variables
|
||||
|
||||
### Variables Locales
|
||||
|
||||
Définissez les variables avec le préfixe `@` :
|
||||
|
||||
```
|
||||
@MyNumber = 50;
|
||||
@MyString = "Bonjour";
|
||||
@MyColor = #ff5500;
|
||||
@MyObject = (Key: value, Other: 123);
|
||||
```
|
||||
|
||||
### Types de Variables
|
||||
|
||||
| Type | Exemple |
|
||||
|------|---------|
|
||||
| Nombre | `@Size = 50;` |
|
||||
| Chaîne | `@Text = "Bonjour";` |
|
||||
| Couleur | `@Color = #ff5500;` |
|
||||
| Objet | `@Obj = (Width: 100, Height: 50);` |
|
||||
| Tableau | `@List = [item1, item2, item3];` |
|
||||
| Booléen | `@Visible = true;` |
|
||||
|
||||
### Utiliser les Variables
|
||||
|
||||
Référencez les variables avec `@` :
|
||||
|
||||
```
|
||||
Group {
|
||||
Anchor: (Height: @MyNumber);
|
||||
Background: (Color: @MyColor);
|
||||
}
|
||||
```
|
||||
|
||||
## Imports
|
||||
|
||||
### Importer des Fichiers
|
||||
|
||||
Utilisez le préfixe `$` pour importer des fichiers externes :
|
||||
|
||||
```
|
||||
$Common = "Common.ui";
|
||||
$Sounds = "../Sounds.ui";
|
||||
$ClientCommon = "../../Common.ui";
|
||||
```
|
||||
|
||||
### Référencer les Variables Importées
|
||||
|
||||
Accédez aux variables importées avec la notation pointée :
|
||||
|
||||
```
|
||||
$Common.@DefaultButtonStyle
|
||||
$Sounds.@ButtonsLight
|
||||
```
|
||||
|
||||
### Utiliser les Templates Importés
|
||||
|
||||
Instanciez les templates depuis les imports :
|
||||
|
||||
```
|
||||
$Common.@TextButton {
|
||||
@Text = "Cliquez-moi";
|
||||
}
|
||||
```
|
||||
|
||||
## Couleurs
|
||||
|
||||
### Hexadécimal
|
||||
|
||||
```
|
||||
@Color1 = #ff5500; // RGB
|
||||
@Color2 = #ff5500ff; // RGBA
|
||||
```
|
||||
|
||||
### Avec Opacité
|
||||
|
||||
```
|
||||
@Color3 = #ff5500(0.5); // 50% d'opacité
|
||||
@Color4 = #000000(0.8); // 80% d'opacité
|
||||
```
|
||||
|
||||
## Objets
|
||||
|
||||
### Objet Simple
|
||||
|
||||
```
|
||||
@Style = (
|
||||
FontSize: 16,
|
||||
TextColor: #ffffff,
|
||||
RenderBold: true
|
||||
);
|
||||
```
|
||||
|
||||
### Objets Imbriqués
|
||||
|
||||
```
|
||||
@ButtonStyle = (
|
||||
Default: (
|
||||
Background: (TexturePath: "Button.png", Border: 12)
|
||||
),
|
||||
Hovered: (
|
||||
Background: (TexturePath: "ButtonHovered.png", Border: 12)
|
||||
)
|
||||
);
|
||||
```
|
||||
|
||||
## Opérateur Spread
|
||||
|
||||
Utilisez `...` pour étendre/fusionner des objets :
|
||||
|
||||
```
|
||||
@BaseStyle = (
|
||||
FontSize: 16,
|
||||
TextColor: #ffffff
|
||||
);
|
||||
|
||||
@ExtendedStyle = (
|
||||
...@BaseStyle, // Hérite de toutes les propriétés de @BaseStyle
|
||||
RenderBold: true // Ajoute/remplace des propriétés
|
||||
);
|
||||
```
|
||||
|
||||
Le spread fonctionne dans tout contexte d'objet :
|
||||
|
||||
```
|
||||
Style: (
|
||||
...$Common.@DefaultButtonStyle,
|
||||
Sounds: (
|
||||
...$Sounds.@ButtonsLight,
|
||||
Activate: (Volume: 10)
|
||||
)
|
||||
);
|
||||
```
|
||||
|
||||
## Templates (Macros)
|
||||
|
||||
### Définir un Template
|
||||
|
||||
Les templates sont des définitions de widgets réutilisables avec paramètres :
|
||||
|
||||
```
|
||||
@MyButton = TextButton {
|
||||
@Text = ""; // Paramètre avec défaut
|
||||
@Anchor = Anchor(); // Paramètre avec défaut
|
||||
@Sounds = (); // Défaut vide
|
||||
|
||||
Style: @DefaultTextButtonStyle;
|
||||
Anchor: (...@Anchor, Height: 44);
|
||||
Text: @Text;
|
||||
};
|
||||
```
|
||||
|
||||
### Instancier un Template
|
||||
|
||||
```
|
||||
// Utiliser avec les défauts
|
||||
@MyButton {}
|
||||
|
||||
// Remplacer les paramètres
|
||||
@MyButton {
|
||||
@Text = "Valider";
|
||||
@Anchor = (Width: 200);
|
||||
}
|
||||
|
||||
// Depuis un import
|
||||
$Common.@TextButton {
|
||||
@Text = %ui.button.confirm;
|
||||
}
|
||||
```
|
||||
|
||||
## Déclarations de Widgets
|
||||
|
||||
### Widget Simple
|
||||
|
||||
```
|
||||
WidgetType {
|
||||
Property: value;
|
||||
}
|
||||
```
|
||||
|
||||
### Widget avec ID
|
||||
|
||||
Les IDs commencent par `#` et permettent le ciblage depuis Java. Les IDs doivent être en format **UpperCamelCase** (pas de tirets ni underscores) :
|
||||
|
||||
```
|
||||
Label #PlayerName {
|
||||
Text: "Inconnu";
|
||||
}
|
||||
|
||||
// IDs valides
|
||||
#MainPanel
|
||||
#ConfirmButton
|
||||
#PlayerHealthBar
|
||||
|
||||
// IDs invalides (causeront des erreurs)
|
||||
#main-panel // Pas de tirets
|
||||
#confirm_button // Pas d'underscores
|
||||
#playerhealthbar // Doit être en UpperCamelCase
|
||||
```
|
||||
|
||||
### Widgets Imbriqués
|
||||
|
||||
```
|
||||
Group #Container {
|
||||
Label #Title {
|
||||
Text: "En-tête";
|
||||
}
|
||||
|
||||
Group #Content {
|
||||
Label {
|
||||
Text: "Corps du texte";
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Widgets Anonymes
|
||||
|
||||
Les widgets sans ID sont anonymes :
|
||||
|
||||
```
|
||||
Group {
|
||||
Label { Text: "Pas d'ID"; }
|
||||
}
|
||||
```
|
||||
|
||||
## Sélecteurs
|
||||
|
||||
Les sélecteurs sont des chaînes commençant par `#` utilisées pour cibler des éléments :
|
||||
|
||||
```java
|
||||
// Dans le code Java
|
||||
builder.set("#PlayerName", "Steve");
|
||||
builder.append("#Container", "ui/child_template");
|
||||
builder.clear("#Content");
|
||||
```
|
||||
|
||||
## Clés de Traduction
|
||||
|
||||
Utilisez le préfixe `%` pour les chaînes localisées :
|
||||
|
||||
```
|
||||
Label {
|
||||
Text: %server.ui.shop.title;
|
||||
}
|
||||
|
||||
TextButton {
|
||||
Text: %client.button.confirm;
|
||||
}
|
||||
```
|
||||
|
||||
## Constructeurs Typés
|
||||
|
||||
Certains types complexes utilisent des constructeurs de style fonction :
|
||||
|
||||
```
|
||||
// Constructeurs de styles
|
||||
@Style = LabelStyle(FontSize: 16, TextColor: #fff);
|
||||
@BtnStyle = ButtonStyle(Default: (...), Hovered: (...));
|
||||
|
||||
// Constructeurs de layout
|
||||
@Pad = Padding(Full: 10);
|
||||
@Anch = Anchor(Width: 100, Height: 50);
|
||||
|
||||
// Constructeurs visuels
|
||||
@Bg = PatchStyle(TexturePath: "bg.png", Border: 12);
|
||||
@Scroll = ScrollbarStyle(Size: 6, Spacing: 8);
|
||||
```
|
||||
|
||||
## Exemple Complet
|
||||
|
||||
```
|
||||
$Common = "Common.ui";
|
||||
$Sounds = "Sounds.ui";
|
||||
|
||||
@PanelWidth = 400;
|
||||
@PanelHeight = 300;
|
||||
@TitleColor = #b4c8c9;
|
||||
|
||||
@PanelTitle = Label {
|
||||
@Text = "";
|
||||
|
||||
Style: (
|
||||
FontSize: 20,
|
||||
TextColor: @TitleColor,
|
||||
RenderBold: true,
|
||||
HorizontalAlignment: Center
|
||||
);
|
||||
Text: @Text;
|
||||
};
|
||||
|
||||
Group #MainPanel {
|
||||
Anchor: (Width: @PanelWidth, Height: @PanelHeight);
|
||||
Background: (TexturePath: "Panel.png", Border: 20);
|
||||
LayoutMode: Top;
|
||||
Padding: (Full: 16);
|
||||
|
||||
@PanelTitle {
|
||||
@Text = %ui.panel.title;
|
||||
}
|
||||
|
||||
Group #Content {
|
||||
FlexWeight: 1;
|
||||
LayoutMode: TopScrolling;
|
||||
ScrollbarStyle: $Common.@DefaultScrollbarStyle;
|
||||
}
|
||||
|
||||
$Common.@TextButton #ConfirmButton {
|
||||
@Text = %ui.button.confirm;
|
||||
@Sounds = $Sounds.@ButtonsLight;
|
||||
}
|
||||
}
|
||||
```
|
||||
393
content/ui-systems/ui-widgets.en.md
Normal file
393
content/ui-systems/ui-widgets.en.md
Normal file
@@ -0,0 +1,393 @@
|
||||
---
|
||||
title: UI Widgets
|
||||
type: docs
|
||||
weight: 12
|
||||
---
|
||||
|
||||
This page documents all available widget types in Hytale's UI system.
|
||||
|
||||
## Container Widgets
|
||||
|
||||
### Group
|
||||
|
||||
Basic container for organizing other widgets.
|
||||
|
||||
```
|
||||
Group #Container {
|
||||
Anchor: (Width: 400, Height: 300);
|
||||
Background: (Color: #000000(0.5));
|
||||
LayoutMode: Top;
|
||||
Padding: (Full: 16);
|
||||
|
||||
// Child widgets...
|
||||
}
|
||||
```
|
||||
|
||||
**Key Properties:**
|
||||
- `Anchor` - Position and size
|
||||
- `Background` - Background color or texture
|
||||
- `LayoutMode` - Child arrangement mode
|
||||
- `Padding` - Inner spacing
|
||||
- `Visible` - Show/hide
|
||||
- `FlexWeight` - Flexible sizing weight
|
||||
|
||||
## Text Widgets
|
||||
|
||||
### Label
|
||||
|
||||
Displays static or dynamic text.
|
||||
|
||||
```
|
||||
Label #Title {
|
||||
Text: "Hello World";
|
||||
Style: (
|
||||
FontSize: 24,
|
||||
TextColor: #ffffff,
|
||||
RenderBold: true,
|
||||
HorizontalAlignment: Center,
|
||||
VerticalAlignment: Center
|
||||
);
|
||||
Anchor: (Height: 40);
|
||||
}
|
||||
```
|
||||
|
||||
**Key Properties:**
|
||||
- `Text` - Text content (string or `%translation.key`)
|
||||
- `Style` - LabelStyle object
|
||||
- `Anchor` - Position and size
|
||||
- `Padding` - Text padding
|
||||
|
||||
## Button Widgets
|
||||
|
||||
### Button
|
||||
|
||||
Clickable button without text label.
|
||||
|
||||
```
|
||||
Button #CloseButton {
|
||||
Anchor: (Width: 32, Height: 32);
|
||||
Style: (
|
||||
Default: (Background: "CloseButton.png"),
|
||||
Hovered: (Background: "CloseButtonHovered.png"),
|
||||
Pressed: (Background: "CloseButtonPressed.png"),
|
||||
Disabled: (Background: "CloseButtonDisabled.png"),
|
||||
Sounds: @ButtonSounds
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
### TextButton
|
||||
|
||||
Button with text label.
|
||||
|
||||
```
|
||||
TextButton #SubmitButton {
|
||||
Text: %ui.button.submit;
|
||||
Style: (
|
||||
Default: (
|
||||
Background: (TexturePath: "Button.png", Border: 12),
|
||||
LabelStyle: (FontSize: 16, TextColor: #ffffff)
|
||||
),
|
||||
Hovered: (
|
||||
Background: (TexturePath: "ButtonHovered.png", Border: 12),
|
||||
LabelStyle: (FontSize: 16, TextColor: #ffffff)
|
||||
),
|
||||
Pressed: (
|
||||
Background: (TexturePath: "ButtonPressed.png", Border: 12),
|
||||
LabelStyle: (FontSize: 16, TextColor: #cccccc)
|
||||
),
|
||||
Sounds: @ButtonSounds
|
||||
);
|
||||
Anchor: (Height: 44);
|
||||
Padding: (Horizontal: 24);
|
||||
}
|
||||
```
|
||||
|
||||
### BackButton
|
||||
|
||||
Pre-styled back/dismiss button.
|
||||
|
||||
```
|
||||
BackButton {}
|
||||
```
|
||||
|
||||
### ActionButton
|
||||
|
||||
Button that displays an action name with input binding.
|
||||
|
||||
```
|
||||
ActionButton #BindingInventory {
|
||||
Disabled: true;
|
||||
LayoutMode: Right;
|
||||
Alignment: Right;
|
||||
ActionName: %client.hud.inputBindings.inventory;
|
||||
Anchor: (Top: 15);
|
||||
}
|
||||
```
|
||||
|
||||
## Input Widgets
|
||||
|
||||
### TextField
|
||||
|
||||
Single-line text input.
|
||||
|
||||
```
|
||||
TextField #NameInput {
|
||||
Anchor: (Height: 38);
|
||||
Style: @DefaultInputFieldStyle;
|
||||
PlaceholderStyle: @DefaultInputFieldPlaceholderStyle;
|
||||
Background: (TexturePath: "InputBox.png", Border: 16);
|
||||
Padding: (Horizontal: 10);
|
||||
PlaceholderText: %ui.placeholder.enterName;
|
||||
}
|
||||
```
|
||||
|
||||
### NumberField
|
||||
|
||||
Numeric input field.
|
||||
|
||||
```
|
||||
NumberField #QuantityInput {
|
||||
Anchor: (Width: 100, Height: 38);
|
||||
Style: @DefaultInputFieldStyle;
|
||||
Background: (TexturePath: "InputBox.png", Border: 16);
|
||||
Padding: (Horizontal: 10);
|
||||
Min: 1;
|
||||
Max: 100;
|
||||
}
|
||||
```
|
||||
|
||||
### CompactTextField
|
||||
|
||||
Expandable search-style text field.
|
||||
|
||||
```
|
||||
CompactTextField #SearchInput {
|
||||
Anchor: (Height: 30);
|
||||
CollapsedWidth: 34;
|
||||
ExpandedWidth: 200;
|
||||
PlaceholderText: %ui.search.placeholder;
|
||||
Style: (FontSize: 16);
|
||||
PlaceholderStyle: (TextColor: #3d5a85, RenderUppercase: true, FontSize: 14);
|
||||
Padding: (Horizontal: 12, Left: 34);
|
||||
Decoration: (
|
||||
Default: (
|
||||
Icon: (Texture: "SearchIcon.png", Width: 16, Height: 16, Offset: 9),
|
||||
ClearButtonStyle: @ClearButtonStyle
|
||||
)
|
||||
);
|
||||
ExpandSound: (SoundPath: "Sounds/Expand.ogg", Volume: 6);
|
||||
CollapseSound: (SoundPath: "Sounds/Collapse.ogg", Volume: 5);
|
||||
}
|
||||
```
|
||||
|
||||
### Slider
|
||||
|
||||
Horizontal slider control.
|
||||
|
||||
```
|
||||
Slider #VolumeSlider {
|
||||
Anchor: (Width: 200, Height: 16);
|
||||
Style: (
|
||||
Background: (TexturePath: "SliderBackground.png", Border: 2),
|
||||
Handle: "SliderHandle.png",
|
||||
HandleWidth: 16,
|
||||
HandleHeight: 16,
|
||||
Sounds: (
|
||||
Activate: (SoundPath: "Tick.ogg", Volume: 10),
|
||||
MouseHover: (SoundPath: "Hover.ogg", Volume: 6)
|
||||
)
|
||||
);
|
||||
Min: 0;
|
||||
Max: 100;
|
||||
Value: 50;
|
||||
}
|
||||
```
|
||||
|
||||
### SliderNumberField
|
||||
|
||||
Combined slider with numeric display.
|
||||
|
||||
```
|
||||
SliderNumberField #BrightnessSlider {
|
||||
Anchor: (Width: 270, Height: 5);
|
||||
SliderStyle: @DefaultSliderStyle;
|
||||
NumberFieldStyle: @DefaultInputFieldStyle;
|
||||
}
|
||||
```
|
||||
|
||||
### CheckBox
|
||||
|
||||
Toggle checkbox.
|
||||
|
||||
```
|
||||
CheckBox #EnableOption {
|
||||
Anchor: (Width: 22, Height: 22);
|
||||
Background: (TexturePath: "CheckBoxFrame.png", Border: 7);
|
||||
Padding: (Full: 4);
|
||||
Style: (
|
||||
Unchecked: (
|
||||
DefaultBackground: (Color: #00000000),
|
||||
HoveredBackground: (Color: #00000000),
|
||||
ChangedSound: (SoundPath: "Untick.ogg", Volume: 6)
|
||||
),
|
||||
Checked: (
|
||||
DefaultBackground: (TexturePath: "Checkmark.png"),
|
||||
HoveredBackground: (TexturePath: "Checkmark.png"),
|
||||
ChangedSound: (SoundPath: "Tick.ogg", Volume: 6)
|
||||
)
|
||||
);
|
||||
Value: false;
|
||||
}
|
||||
```
|
||||
|
||||
### DropdownBox
|
||||
|
||||
Dropdown selection menu.
|
||||
|
||||
```
|
||||
DropdownBox #LanguageSelector {
|
||||
Anchor: (Width: 330, Height: 32);
|
||||
Style: (
|
||||
DefaultBackground: (TexturePath: "Dropdown.png", Border: 16),
|
||||
HoveredBackground: (TexturePath: "DropdownHovered.png", Border: 16),
|
||||
PressedBackground: (TexturePath: "DropdownPressed.png", Border: 16),
|
||||
DefaultArrowTexturePath: "DropdownCaret.png",
|
||||
ArrowWidth: 13,
|
||||
ArrowHeight: 18,
|
||||
LabelStyle: (TextColor: #96a9be, FontSize: 13),
|
||||
PanelBackground: (TexturePath: "DropdownBox.png", Border: 16),
|
||||
EntryHeight: 31,
|
||||
EntriesInViewport: 10,
|
||||
Sounds: @DropdownBoxSounds
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
## Display Widgets
|
||||
|
||||
### Sprite
|
||||
|
||||
Animated or static image.
|
||||
|
||||
```
|
||||
Sprite #LoadingSpinner {
|
||||
Anchor: (Width: 32, Height: 32);
|
||||
TexturePath: "Spinner.png";
|
||||
Frame: (Width: 32, Height: 32, PerRow: 8, Count: 72);
|
||||
FramesPerSecond: 30;
|
||||
}
|
||||
```
|
||||
|
||||
### AssetImage
|
||||
|
||||
Display an asset image (item icon, etc.).
|
||||
|
||||
```
|
||||
AssetImage #ItemIcon {
|
||||
Anchor: (Width: 64, Height: 64);
|
||||
}
|
||||
```
|
||||
|
||||
### ProgressBar
|
||||
|
||||
Progress indicator bar.
|
||||
|
||||
```
|
||||
ProgressBar #HealthBar {
|
||||
Anchor: (Width: 200, Height: 20);
|
||||
BarTexturePath: "HealthBarFill.png";
|
||||
Alignment: Horizontal;
|
||||
Direction: Start;
|
||||
Value: 0.75;
|
||||
}
|
||||
```
|
||||
|
||||
**Properties:**
|
||||
- `Alignment` - `Horizontal` or `Vertical`
|
||||
- `Direction` - `Start` or `End`
|
||||
- `Value` - 0.0 to 1.0
|
||||
|
||||
## Inventory Widgets
|
||||
|
||||
### ItemGrid
|
||||
|
||||
Grid display for inventory items.
|
||||
|
||||
```
|
||||
ItemGrid #HotbarGrid {
|
||||
SlotsPerRow: 9;
|
||||
Style: (
|
||||
SlotBackground: "ItemSlot.png",
|
||||
SlotSize: 64,
|
||||
SlotSpacing: 4,
|
||||
HoveredSlotBackground: "ItemSlotHovered.png",
|
||||
SelectedSlotBackground: "ItemSlotSelected.png"
|
||||
);
|
||||
Background: (TexturePath: "HotbarBackground.png", Border: 10);
|
||||
Padding: 4;
|
||||
RenderItemQualityBackground: true;
|
||||
AreItemsDraggable: true;
|
||||
}
|
||||
```
|
||||
|
||||
## Navigation Widgets
|
||||
|
||||
### TabNavigation
|
||||
|
||||
Tab-based navigation.
|
||||
|
||||
```
|
||||
TabNavigation #CategoryTabs {
|
||||
Style: (
|
||||
TabStyle: (
|
||||
Default: (Background: "Tab.png", IconAnchor: (Width: 44, Height: 44)),
|
||||
Hovered: (Background: "TabHovered.png"),
|
||||
Pressed: (Background: "TabPressed.png")
|
||||
),
|
||||
SelectedTabStyle: (
|
||||
Default: (Background: "TabSelected.png", Overlay: "TabSelectedOverlay.png")
|
||||
),
|
||||
TabSounds: @TabSounds
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
## Tooltip Properties
|
||||
|
||||
Many widgets support tooltips:
|
||||
|
||||
```
|
||||
TextButton #InfoButton {
|
||||
TooltipText: %ui.tooltip.info;
|
||||
TextTooltipStyle: (
|
||||
Background: (TexturePath: "TooltipBackground.png", Border: 24),
|
||||
MaxWidth: 400,
|
||||
LabelStyle: (Wrap: true, FontSize: 16),
|
||||
Padding: 24
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
## Widget Summary Table
|
||||
|
||||
| Widget | Purpose |
|
||||
|--------|---------|
|
||||
| `Group` | Container for layout |
|
||||
| `Label` | Text display |
|
||||
| `Button` | Clickable button |
|
||||
| `TextButton` | Button with text |
|
||||
| `BackButton` | Pre-styled back button |
|
||||
| `ActionButton` | Action with keybind display |
|
||||
| `TextField` | Text input |
|
||||
| `NumberField` | Numeric input |
|
||||
| `CompactTextField` | Expandable search field |
|
||||
| `Slider` | Slider control |
|
||||
| `SliderNumberField` | Slider with number display |
|
||||
| `CheckBox` | Toggle checkbox |
|
||||
| `DropdownBox` | Selection dropdown |
|
||||
| `Sprite` | Image/animation |
|
||||
| `AssetImage` | Asset icon display |
|
||||
| `ProgressBar` | Progress indicator |
|
||||
| `ItemGrid` | Inventory grid |
|
||||
| `TabNavigation` | Tab navigation |
|
||||
393
content/ui-systems/ui-widgets.fr.md
Normal file
393
content/ui-systems/ui-widgets.fr.md
Normal file
@@ -0,0 +1,393 @@
|
||||
---
|
||||
title: Widgets UI
|
||||
type: docs
|
||||
weight: 12
|
||||
---
|
||||
|
||||
Cette page documente tous les types de widgets disponibles dans le système UI de Hytale.
|
||||
|
||||
## Widgets Conteneurs
|
||||
|
||||
### Group
|
||||
|
||||
Conteneur de base pour organiser d'autres widgets.
|
||||
|
||||
```
|
||||
Group #Container {
|
||||
Anchor: (Width: 400, Height: 300);
|
||||
Background: (Color: #000000(0.5));
|
||||
LayoutMode: Top;
|
||||
Padding: (Full: 16);
|
||||
|
||||
// Widgets enfants...
|
||||
}
|
||||
```
|
||||
|
||||
**Propriétés Clés :**
|
||||
- `Anchor` - Position et taille
|
||||
- `Background` - Couleur ou texture de fond
|
||||
- `LayoutMode` - Mode d'arrangement des enfants
|
||||
- `Padding` - Espacement intérieur
|
||||
- `Visible` - Afficher/masquer
|
||||
- `FlexWeight` - Poids de dimensionnement flexible
|
||||
|
||||
## Widgets Texte
|
||||
|
||||
### Label
|
||||
|
||||
Affiche du texte statique ou dynamique.
|
||||
|
||||
```
|
||||
Label #Title {
|
||||
Text: "Bonjour le monde";
|
||||
Style: (
|
||||
FontSize: 24,
|
||||
TextColor: #ffffff,
|
||||
RenderBold: true,
|
||||
HorizontalAlignment: Center,
|
||||
VerticalAlignment: Center
|
||||
);
|
||||
Anchor: (Height: 40);
|
||||
}
|
||||
```
|
||||
|
||||
**Propriétés Clés :**
|
||||
- `Text` - Contenu texte (chaîne ou `%translation.key`)
|
||||
- `Style` - Objet LabelStyle
|
||||
- `Anchor` - Position et taille
|
||||
- `Padding` - Marge du texte
|
||||
|
||||
## Widgets Boutons
|
||||
|
||||
### Button
|
||||
|
||||
Bouton cliquable sans label texte.
|
||||
|
||||
```
|
||||
Button #CloseButton {
|
||||
Anchor: (Width: 32, Height: 32);
|
||||
Style: (
|
||||
Default: (Background: "CloseButton.png"),
|
||||
Hovered: (Background: "CloseButtonHovered.png"),
|
||||
Pressed: (Background: "CloseButtonPressed.png"),
|
||||
Disabled: (Background: "CloseButtonDisabled.png"),
|
||||
Sounds: @ButtonSounds
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
### TextButton
|
||||
|
||||
Bouton avec label texte.
|
||||
|
||||
```
|
||||
TextButton #SubmitButton {
|
||||
Text: %ui.button.submit;
|
||||
Style: (
|
||||
Default: (
|
||||
Background: (TexturePath: "Button.png", Border: 12),
|
||||
LabelStyle: (FontSize: 16, TextColor: #ffffff)
|
||||
),
|
||||
Hovered: (
|
||||
Background: (TexturePath: "ButtonHovered.png", Border: 12),
|
||||
LabelStyle: (FontSize: 16, TextColor: #ffffff)
|
||||
),
|
||||
Pressed: (
|
||||
Background: (TexturePath: "ButtonPressed.png", Border: 12),
|
||||
LabelStyle: (FontSize: 16, TextColor: #cccccc)
|
||||
),
|
||||
Sounds: @ButtonSounds
|
||||
);
|
||||
Anchor: (Height: 44);
|
||||
Padding: (Horizontal: 24);
|
||||
}
|
||||
```
|
||||
|
||||
### BackButton
|
||||
|
||||
Bouton retour/fermer pré-stylisé.
|
||||
|
||||
```
|
||||
BackButton {}
|
||||
```
|
||||
|
||||
### ActionButton
|
||||
|
||||
Bouton qui affiche un nom d'action avec sa touche associée.
|
||||
|
||||
```
|
||||
ActionButton #BindingInventory {
|
||||
Disabled: true;
|
||||
LayoutMode: Right;
|
||||
Alignment: Right;
|
||||
ActionName: %client.hud.inputBindings.inventory;
|
||||
Anchor: (Top: 15);
|
||||
}
|
||||
```
|
||||
|
||||
## Widgets de Saisie
|
||||
|
||||
### TextField
|
||||
|
||||
Champ de saisie texte mono-ligne.
|
||||
|
||||
```
|
||||
TextField #NameInput {
|
||||
Anchor: (Height: 38);
|
||||
Style: @DefaultInputFieldStyle;
|
||||
PlaceholderStyle: @DefaultInputFieldPlaceholderStyle;
|
||||
Background: (TexturePath: "InputBox.png", Border: 16);
|
||||
Padding: (Horizontal: 10);
|
||||
PlaceholderText: %ui.placeholder.enterName;
|
||||
}
|
||||
```
|
||||
|
||||
### NumberField
|
||||
|
||||
Champ de saisie numérique.
|
||||
|
||||
```
|
||||
NumberField #QuantityInput {
|
||||
Anchor: (Width: 100, Height: 38);
|
||||
Style: @DefaultInputFieldStyle;
|
||||
Background: (TexturePath: "InputBox.png", Border: 16);
|
||||
Padding: (Horizontal: 10);
|
||||
Min: 1;
|
||||
Max: 100;
|
||||
}
|
||||
```
|
||||
|
||||
### CompactTextField
|
||||
|
||||
Champ de texte extensible style recherche.
|
||||
|
||||
```
|
||||
CompactTextField #SearchInput {
|
||||
Anchor: (Height: 30);
|
||||
CollapsedWidth: 34;
|
||||
ExpandedWidth: 200;
|
||||
PlaceholderText: %ui.search.placeholder;
|
||||
Style: (FontSize: 16);
|
||||
PlaceholderStyle: (TextColor: #3d5a85, RenderUppercase: true, FontSize: 14);
|
||||
Padding: (Horizontal: 12, Left: 34);
|
||||
Decoration: (
|
||||
Default: (
|
||||
Icon: (Texture: "SearchIcon.png", Width: 16, Height: 16, Offset: 9),
|
||||
ClearButtonStyle: @ClearButtonStyle
|
||||
)
|
||||
);
|
||||
ExpandSound: (SoundPath: "Sounds/Expand.ogg", Volume: 6);
|
||||
CollapseSound: (SoundPath: "Sounds/Collapse.ogg", Volume: 5);
|
||||
}
|
||||
```
|
||||
|
||||
### Slider
|
||||
|
||||
Contrôle curseur horizontal.
|
||||
|
||||
```
|
||||
Slider #VolumeSlider {
|
||||
Anchor: (Width: 200, Height: 16);
|
||||
Style: (
|
||||
Background: (TexturePath: "SliderBackground.png", Border: 2),
|
||||
Handle: "SliderHandle.png",
|
||||
HandleWidth: 16,
|
||||
HandleHeight: 16,
|
||||
Sounds: (
|
||||
Activate: (SoundPath: "Tick.ogg", Volume: 10),
|
||||
MouseHover: (SoundPath: "Hover.ogg", Volume: 6)
|
||||
)
|
||||
);
|
||||
Min: 0;
|
||||
Max: 100;
|
||||
Value: 50;
|
||||
}
|
||||
```
|
||||
|
||||
### SliderNumberField
|
||||
|
||||
Curseur combiné avec affichage numérique.
|
||||
|
||||
```
|
||||
SliderNumberField #BrightnessSlider {
|
||||
Anchor: (Width: 270, Height: 5);
|
||||
SliderStyle: @DefaultSliderStyle;
|
||||
NumberFieldStyle: @DefaultInputFieldStyle;
|
||||
}
|
||||
```
|
||||
|
||||
### CheckBox
|
||||
|
||||
Case à cocher.
|
||||
|
||||
```
|
||||
CheckBox #EnableOption {
|
||||
Anchor: (Width: 22, Height: 22);
|
||||
Background: (TexturePath: "CheckBoxFrame.png", Border: 7);
|
||||
Padding: (Full: 4);
|
||||
Style: (
|
||||
Unchecked: (
|
||||
DefaultBackground: (Color: #00000000),
|
||||
HoveredBackground: (Color: #00000000),
|
||||
ChangedSound: (SoundPath: "Untick.ogg", Volume: 6)
|
||||
),
|
||||
Checked: (
|
||||
DefaultBackground: (TexturePath: "Checkmark.png"),
|
||||
HoveredBackground: (TexturePath: "Checkmark.png"),
|
||||
ChangedSound: (SoundPath: "Tick.ogg", Volume: 6)
|
||||
)
|
||||
);
|
||||
Value: false;
|
||||
}
|
||||
```
|
||||
|
||||
### DropdownBox
|
||||
|
||||
Menu de sélection déroulant.
|
||||
|
||||
```
|
||||
DropdownBox #LanguageSelector {
|
||||
Anchor: (Width: 330, Height: 32);
|
||||
Style: (
|
||||
DefaultBackground: (TexturePath: "Dropdown.png", Border: 16),
|
||||
HoveredBackground: (TexturePath: "DropdownHovered.png", Border: 16),
|
||||
PressedBackground: (TexturePath: "DropdownPressed.png", Border: 16),
|
||||
DefaultArrowTexturePath: "DropdownCaret.png",
|
||||
ArrowWidth: 13,
|
||||
ArrowHeight: 18,
|
||||
LabelStyle: (TextColor: #96a9be, FontSize: 13),
|
||||
PanelBackground: (TexturePath: "DropdownBox.png", Border: 16),
|
||||
EntryHeight: 31,
|
||||
EntriesInViewport: 10,
|
||||
Sounds: @DropdownBoxSounds
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
## Widgets d'Affichage
|
||||
|
||||
### Sprite
|
||||
|
||||
Image animée ou statique.
|
||||
|
||||
```
|
||||
Sprite #LoadingSpinner {
|
||||
Anchor: (Width: 32, Height: 32);
|
||||
TexturePath: "Spinner.png";
|
||||
Frame: (Width: 32, Height: 32, PerRow: 8, Count: 72);
|
||||
FramesPerSecond: 30;
|
||||
}
|
||||
```
|
||||
|
||||
### AssetImage
|
||||
|
||||
Affiche une image d'asset (icône d'item, etc.).
|
||||
|
||||
```
|
||||
AssetImage #ItemIcon {
|
||||
Anchor: (Width: 64, Height: 64);
|
||||
}
|
||||
```
|
||||
|
||||
### ProgressBar
|
||||
|
||||
Barre de progression.
|
||||
|
||||
```
|
||||
ProgressBar #HealthBar {
|
||||
Anchor: (Width: 200, Height: 20);
|
||||
BarTexturePath: "HealthBarFill.png";
|
||||
Alignment: Horizontal;
|
||||
Direction: Start;
|
||||
Value: 0.75;
|
||||
}
|
||||
```
|
||||
|
||||
**Propriétés :**
|
||||
- `Alignment` - `Horizontal` ou `Vertical`
|
||||
- `Direction` - `Start` ou `End`
|
||||
- `Value` - 0.0 à 1.0
|
||||
|
||||
## Widgets d'Inventaire
|
||||
|
||||
### ItemGrid
|
||||
|
||||
Grille d'affichage pour les items d'inventaire.
|
||||
|
||||
```
|
||||
ItemGrid #HotbarGrid {
|
||||
SlotsPerRow: 9;
|
||||
Style: (
|
||||
SlotBackground: "ItemSlot.png",
|
||||
SlotSize: 64,
|
||||
SlotSpacing: 4,
|
||||
HoveredSlotBackground: "ItemSlotHovered.png",
|
||||
SelectedSlotBackground: "ItemSlotSelected.png"
|
||||
);
|
||||
Background: (TexturePath: "HotbarBackground.png", Border: 10);
|
||||
Padding: 4;
|
||||
RenderItemQualityBackground: true;
|
||||
AreItemsDraggable: true;
|
||||
}
|
||||
```
|
||||
|
||||
## Widgets de Navigation
|
||||
|
||||
### TabNavigation
|
||||
|
||||
Navigation par onglets.
|
||||
|
||||
```
|
||||
TabNavigation #CategoryTabs {
|
||||
Style: (
|
||||
TabStyle: (
|
||||
Default: (Background: "Tab.png", IconAnchor: (Width: 44, Height: 44)),
|
||||
Hovered: (Background: "TabHovered.png"),
|
||||
Pressed: (Background: "TabPressed.png")
|
||||
),
|
||||
SelectedTabStyle: (
|
||||
Default: (Background: "TabSelected.png", Overlay: "TabSelectedOverlay.png")
|
||||
),
|
||||
TabSounds: @TabSounds
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
## Propriétés de Tooltip
|
||||
|
||||
De nombreux widgets supportent les tooltips :
|
||||
|
||||
```
|
||||
TextButton #InfoButton {
|
||||
TooltipText: %ui.tooltip.info;
|
||||
TextTooltipStyle: (
|
||||
Background: (TexturePath: "TooltipBackground.png", Border: 24),
|
||||
MaxWidth: 400,
|
||||
LabelStyle: (Wrap: true, FontSize: 16),
|
||||
Padding: 24
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
## Tableau Récapitulatif des Widgets
|
||||
|
||||
| Widget | Usage |
|
||||
|--------|-------|
|
||||
| `Group` | Conteneur pour la mise en page |
|
||||
| `Label` | Affichage de texte |
|
||||
| `Button` | Bouton cliquable |
|
||||
| `TextButton` | Bouton avec texte |
|
||||
| `BackButton` | Bouton retour pré-stylisé |
|
||||
| `ActionButton` | Action avec affichage de touche |
|
||||
| `TextField` | Saisie de texte |
|
||||
| `NumberField` | Saisie numérique |
|
||||
| `CompactTextField` | Champ de recherche extensible |
|
||||
| `Slider` | Contrôle curseur |
|
||||
| `SliderNumberField` | Curseur avec affichage numérique |
|
||||
| `CheckBox` | Case à cocher |
|
||||
| `DropdownBox` | Menu déroulant de sélection |
|
||||
| `Sprite` | Image/animation |
|
||||
| `AssetImage` | Affichage d'icône d'asset |
|
||||
| `ProgressBar` | Indicateur de progression |
|
||||
| `ItemGrid` | Grille d'inventaire |
|
||||
| `TabNavigation` | Navigation par onglets |
|
||||
174
content/ui-systems/windows.en.md
Normal file
174
content/ui-systems/windows.en.md
Normal file
@@ -0,0 +1,174 @@
|
||||
---
|
||||
title: Windows
|
||||
type: docs
|
||||
weight: 3
|
||||
---
|
||||
|
||||
Windows are UI panels for displaying and managing inventory containers, crafting interfaces, and other item-based interactions.
|
||||
|
||||
**Package:** `com.hypixel.hytale.server.core.entity.entities.player.windows`
|
||||
|
||||
## Window Types
|
||||
|
||||
| Type | Description |
|
||||
|------|-------------|
|
||||
| `WindowType.Container` | Standard inventory/container view |
|
||||
| `WindowType.PocketCrafting` | Small crafting grid (2x2) |
|
||||
| `WindowType.BasicCrafting` | Basic crafting table (3x3) |
|
||||
| `WindowType.DiagramCrafting` | Diagram-based crafting |
|
||||
| `WindowType.StructuralCrafting` | Structural/building crafting |
|
||||
| `WindowType.Processing` | Processing/smelting interface |
|
||||
| `WindowType.Memories` | Memories storage interface |
|
||||
|
||||
## Window Manager
|
||||
|
||||
Each player has a `WindowManager` that handles open windows:
|
||||
|
||||
```java
|
||||
Player player = ...;
|
||||
WindowManager windowManager = player.getWindowManager();
|
||||
```
|
||||
|
||||
## Window Classes
|
||||
|
||||
### ContainerWindow
|
||||
|
||||
For standard container interfaces:
|
||||
|
||||
```java
|
||||
import com.hypixel.hytale.server.core.entity.entities.player.windows.ContainerWindow;
|
||||
import com.hypixel.hytale.server.core.inventory.container.ItemContainer;
|
||||
|
||||
// Open a container window - takes just the ItemContainer
|
||||
ContainerWindow window = new ContainerWindow(itemContainer);
|
||||
```
|
||||
|
||||
{{< callout type="info" >}}
|
||||
`ContainerWindow` automatically uses `WindowType.Container`. The window ID is assigned internally.
|
||||
{{< /callout >}}
|
||||
|
||||
### BlockWindow
|
||||
|
||||
`BlockWindow` is an abstract class for block-based containers. It's typically used through built-in interactions rather than instantiated directly.
|
||||
|
||||
```java
|
||||
// BlockWindow is abstract - used internally by block interactions
|
||||
// Constructor: BlockWindow(WindowType, x, y, z, rotationIndex, BlockType)
|
||||
```
|
||||
|
||||
### ItemStackContainerWindow
|
||||
|
||||
For ItemStack-based containers:
|
||||
|
||||
```java
|
||||
import com.hypixel.hytale.server.core.entity.entities.player.windows.ItemStackContainerWindow;
|
||||
import com.hypixel.hytale.server.core.inventory.container.ItemStackItemContainer;
|
||||
|
||||
// Takes an ItemStackItemContainer
|
||||
ItemStackContainerWindow window = new ItemStackContainerWindow(itemStackItemContainer);
|
||||
```
|
||||
|
||||
## Opening Windows
|
||||
|
||||
Use `PageManager.setPageWithWindows()` or `openCustomPageWithWindows()`:
|
||||
|
||||
```java
|
||||
Player player = ...;
|
||||
PageManager pageManager = player.getPageManager();
|
||||
Ref<EntityStore> ref = player.getReference();
|
||||
Store<EntityStore> store = ref.getStore();
|
||||
|
||||
// Open page with inventory windows
|
||||
ContainerWindow chestWindow = new ContainerWindow(chestContainer);
|
||||
|
||||
boolean success = pageManager.setPageWithWindows(
|
||||
ref, store,
|
||||
Page.None, // or Page.Bench, Page.Inventory, etc.
|
||||
true, // canCloseThroughInteraction
|
||||
chestWindow
|
||||
);
|
||||
```
|
||||
|
||||
## With Custom Pages
|
||||
|
||||
Combine windows with custom UI pages:
|
||||
|
||||
```java
|
||||
// Custom crafting UI with windows
|
||||
CraftingPage craftingPage = new CraftingPage(player.getPlayerRef());
|
||||
ContainerWindow inputWindow = new ContainerWindow(1, WindowType.BasicCrafting, inputContainer);
|
||||
ContainerWindow outputWindow = new ContainerWindow(2, WindowType.Container, outputContainer);
|
||||
|
||||
pageManager.openCustomPageWithWindows(
|
||||
ref, store,
|
||||
craftingPage,
|
||||
inputWindow,
|
||||
outputWindow
|
||||
);
|
||||
```
|
||||
|
||||
## Window Events
|
||||
|
||||
Windows interact with the inventory system. Handle inventory changes through the appropriate events and handlers.
|
||||
|
||||
## Practical Example
|
||||
|
||||
### Chest Container UI
|
||||
|
||||
```java
|
||||
public void openChest(Player player, ItemContainer chestContainer) {
|
||||
PageManager pageManager = player.getPageManager();
|
||||
Ref<EntityStore> ref = player.getReference();
|
||||
Store<EntityStore> store = ref.getStore();
|
||||
|
||||
ContainerWindow window = new ContainerWindow(chestContainer);
|
||||
|
||||
pageManager.setPageWithWindows(
|
||||
ref, store,
|
||||
Page.Bench, // Use Bench page for container UI
|
||||
true, // Allow closing via interaction
|
||||
window
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
### Opening Multiple Windows
|
||||
|
||||
```java
|
||||
public void openCraftingUI(Player player, ItemContainer inputContainer,
|
||||
ItemContainer outputContainer) {
|
||||
PageManager pageManager = player.getPageManager();
|
||||
Ref<EntityStore> ref = player.getReference();
|
||||
Store<EntityStore> store = ref.getStore();
|
||||
|
||||
// Create multiple windows
|
||||
ContainerWindow inputWindow = new ContainerWindow(inputContainer);
|
||||
ContainerWindow outputWindow = new ContainerWindow(outputContainer);
|
||||
|
||||
pageManager.setPageWithWindows(
|
||||
ref, store,
|
||||
Page.Bench,
|
||||
true,
|
||||
inputWindow,
|
||||
outputWindow
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
{{< callout type="info" >}}
|
||||
**Note:** `BlockWindow` is abstract and used internally by block interactions. For custom crafting UIs, use `ContainerWindow` with your own containers.
|
||||
{{< /callout >}}
|
||||
|
||||
## Best Practices
|
||||
|
||||
{{< callout type="info" >}}
|
||||
**Window Guidelines:**
|
||||
- Use unique window IDs for each open window
|
||||
- Match `WindowType` to the intended interface
|
||||
- Clean up containers when windows are closed
|
||||
- Use `canCloseThroughInteraction` appropriately
|
||||
{{< /callout >}}
|
||||
|
||||
{{< callout type="warning" >}}
|
||||
**Important:** Windows are tied to container state. Ensure containers persist for the duration the window is open.
|
||||
{{< /callout >}}
|
||||
174
content/ui-systems/windows.fr.md
Normal file
174
content/ui-systems/windows.fr.md
Normal file
@@ -0,0 +1,174 @@
|
||||
---
|
||||
title: Fenêtres
|
||||
type: docs
|
||||
weight: 3
|
||||
---
|
||||
|
||||
Les fenêtres sont des panneaux UI pour afficher et gérer les conteneurs d'inventaire, les interfaces de crafting et autres interactions basées sur les objets.
|
||||
|
||||
**Package:** `com.hypixel.hytale.server.core.entity.entities.player.windows`
|
||||
|
||||
## Types de Fenêtres
|
||||
|
||||
| Type | Description |
|
||||
|------|-------------|
|
||||
| `WindowType.Container` | Vue standard inventaire/conteneur |
|
||||
| `WindowType.PocketCrafting` | Petite grille de crafting (2x2) |
|
||||
| `WindowType.BasicCrafting` | Table de crafting basique (3x3) |
|
||||
| `WindowType.DiagramCrafting` | Crafting basé sur des diagrammes |
|
||||
| `WindowType.StructuralCrafting` | Crafting structurel/construction |
|
||||
| `WindowType.Processing` | Interface de traitement/fonte |
|
||||
| `WindowType.Memories` | Interface de stockage des Mémoires |
|
||||
|
||||
## Gestionnaire de Fenêtres
|
||||
|
||||
Chaque joueur a un `WindowManager` qui gère les fenêtres ouvertes :
|
||||
|
||||
```java
|
||||
Player player = ...;
|
||||
WindowManager windowManager = player.getWindowManager();
|
||||
```
|
||||
|
||||
## Classes de Fenêtres
|
||||
|
||||
### ContainerWindow
|
||||
|
||||
Pour les interfaces de conteneur standard :
|
||||
|
||||
```java
|
||||
import com.hypixel.hytale.server.core.entity.entities.player.windows.ContainerWindow;
|
||||
import com.hypixel.hytale.server.core.inventory.container.ItemContainer;
|
||||
|
||||
// Ouvrir une fenêtre de conteneur - prend juste l'ItemContainer
|
||||
ContainerWindow window = new ContainerWindow(itemContainer);
|
||||
```
|
||||
|
||||
{{< callout type="info" >}}
|
||||
`ContainerWindow` utilise automatiquement `WindowType.Container`. L'ID de fenêtre est assigné en interne.
|
||||
{{< /callout >}}
|
||||
|
||||
### BlockWindow
|
||||
|
||||
`BlockWindow` est une classe abstraite pour les conteneurs liés aux blocs. Elle est typiquement utilisée via les interactions intégrées plutôt qu'instanciée directement.
|
||||
|
||||
```java
|
||||
// BlockWindow est abstraite - utilisée en interne par les interactions de blocs
|
||||
// Constructeur: BlockWindow(WindowType, x, y, z, rotationIndex, BlockType)
|
||||
```
|
||||
|
||||
### ItemStackContainerWindow
|
||||
|
||||
Pour les conteneurs basés sur ItemStack :
|
||||
|
||||
```java
|
||||
import com.hypixel.hytale.server.core.entity.entities.player.windows.ItemStackContainerWindow;
|
||||
import com.hypixel.hytale.server.core.inventory.container.ItemStackItemContainer;
|
||||
|
||||
// Prend un ItemStackItemContainer
|
||||
ItemStackContainerWindow window = new ItemStackContainerWindow(itemStackItemContainer);
|
||||
```
|
||||
|
||||
## Ouvrir des Fenêtres
|
||||
|
||||
Utilisez `PageManager.setPageWithWindows()` ou `openCustomPageWithWindows()` :
|
||||
|
||||
```java
|
||||
Player player = ...;
|
||||
PageManager pageManager = player.getPageManager();
|
||||
Ref<EntityStore> ref = player.getReference();
|
||||
Store<EntityStore> store = ref.getStore();
|
||||
|
||||
// Ouvrir une page avec des fenêtres d'inventaire
|
||||
ContainerWindow chestWindow = new ContainerWindow(chestContainer);
|
||||
|
||||
boolean success = pageManager.setPageWithWindows(
|
||||
ref, store,
|
||||
Page.None, // ou Page.Bench, Page.Inventory, etc.
|
||||
true, // canCloseThroughInteraction
|
||||
chestWindow
|
||||
);
|
||||
```
|
||||
|
||||
## Avec des Pages Personnalisées
|
||||
|
||||
Combiner les fenêtres avec des pages UI personnalisées :
|
||||
|
||||
```java
|
||||
// UI de crafting personnalisée avec fenêtres
|
||||
CraftingPage craftingPage = new CraftingPage(player.getPlayerRef());
|
||||
ContainerWindow inputWindow = new ContainerWindow(inputContainer);
|
||||
ContainerWindow outputWindow = new ContainerWindow(outputContainer);
|
||||
|
||||
pageManager.openCustomPageWithWindows(
|
||||
ref, store,
|
||||
craftingPage,
|
||||
inputWindow,
|
||||
outputWindow
|
||||
);
|
||||
```
|
||||
|
||||
## Événements de Fenêtre
|
||||
|
||||
Les fenêtres interagissent avec le système d'inventaire. Gérez les changements d'inventaire via les événements et handlers appropriés.
|
||||
|
||||
## Exemple Pratique
|
||||
|
||||
### UI de Conteneur Coffre
|
||||
|
||||
```java
|
||||
public void openChest(Player player, ItemContainer chestContainer) {
|
||||
PageManager pageManager = player.getPageManager();
|
||||
Ref<EntityStore> ref = player.getReference();
|
||||
Store<EntityStore> store = ref.getStore();
|
||||
|
||||
ContainerWindow window = new ContainerWindow(chestContainer);
|
||||
|
||||
pageManager.setPageWithWindows(
|
||||
ref, store,
|
||||
Page.Bench, // Utiliser Page.Bench pour l'UI de conteneur
|
||||
true, // Permettre la fermeture via interaction
|
||||
window
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
### Ouvrir Plusieurs Fenêtres
|
||||
|
||||
```java
|
||||
public void openCraftingUI(Player player, ItemContainer inputContainer,
|
||||
ItemContainer outputContainer) {
|
||||
PageManager pageManager = player.getPageManager();
|
||||
Ref<EntityStore> ref = player.getReference();
|
||||
Store<EntityStore> store = ref.getStore();
|
||||
|
||||
// Créer plusieurs fenêtres
|
||||
ContainerWindow inputWindow = new ContainerWindow(inputContainer);
|
||||
ContainerWindow outputWindow = new ContainerWindow(outputContainer);
|
||||
|
||||
pageManager.setPageWithWindows(
|
||||
ref, store,
|
||||
Page.Bench,
|
||||
true,
|
||||
inputWindow,
|
||||
outputWindow
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
{{< callout type="info" >}}
|
||||
**Note :** `BlockWindow` est abstraite et utilisée en interne par les interactions de blocs. Pour des UI de crafting personnalisées, utilisez `ContainerWindow` avec vos propres conteneurs.
|
||||
{{< /callout >}}
|
||||
|
||||
## Bonnes Pratiques
|
||||
|
||||
{{< callout type="info" >}}
|
||||
**Directives des Fenêtres :**
|
||||
- Utilisez des IDs de fenêtre uniques pour chaque fenêtre ouverte
|
||||
- Faites correspondre `WindowType` à l'interface prévue
|
||||
- Nettoyez les conteneurs quand les fenêtres sont fermées
|
||||
- Utilisez `canCloseThroughInteraction` de manière appropriée
|
||||
{{< /callout >}}
|
||||
|
||||
{{< callout type="warning" >}}
|
||||
**Important :** Les fenêtres sont liées à l'état du conteneur. Assurez-vous que les conteneurs persistent pendant toute la durée d'ouverture de la fenêtre.
|
||||
{{< /callout >}}
|
||||
Reference in New Issue
Block a user