Modding:Interfaces de Usuario (GUI)
This page was last verified for Vintage Story version 1.15.
Crear buenas interfaces gráficas de usuario es una tarea desafiante - a veces, incluso las empresas más grandes se equivocan.
En Vintage Story actualmente se necesitas formular tus GUI en código, lo que requiere un pensamiento espacial agudo. Con suerte, algún día tendremos un diseñador de Interfaz de Usuarios de apuntar y hacer clic que elimine mucho trabajo. Hasta entonces, estos son algunos de los elementos esenciales.
Protip:
Utilice la combinación de teclas de depuración para "Ciclar modos de esquema de diálogo" al crear una GUI. Dibujará contornos alrededor de los límites de los elementos de la GUI, lo que hará que sea mucho más fácil comprender cómo se traduce su código a la GUI visual.
Empezando
Debe encapsular cada cuadro de diálogo GUI en su propia clase, aunque un cuadro de diálogo puede constar de varias ventanas (el cuadro de diálogo de carácter básico, por ejemplo, tiene dos), uno para los dispositivos portátiles de los jugadores y otro para las estadísticas del jugador. Hay un par de clases básicas para hacerte la vida un poco más fácil.
GUI de Entidad de Bloque
TPara crear una GUI vinculada a una entidad de bloque, herede de GuiDialogBlockEntity
. En el código de su entidad de bloque, puede crear y abrir esa interfaz gráfica de usuario, por ejemplo tras la interacción del jugador (ejemplo: Entidad de bloque de Molino, Bloque de dialogo de Molino)
HUD
Para crear un elemento GUI que no sea interactuable, herede de HudElement
.
GUI de Proposito General
Para cualquier otro uso, herede de la clase de propósito general GuiDialog
, del cual también heredan HudElement y GuiDialogBlockEntity. Puedes anular ToggleKeyCombinationCode
a algo como "tuAsombrosoKeyCode" y use capi.Input.RegisterHotKey
+ capi.Input.SetHotKeyHandler
para tener su propia tecla del teclado asignada para abrir/cerrar su GUI (ejemplo: Mapa del Mundo)
Conceptos básicos de la GUI
En general, puedes construir tu propio sistema GUI si lo deseas, simplemente anulando OnRenderGUI
y renderiza lo que quieras. También hay una multitud de métodos reemplazables para manejar las entradas del mouse y del teclado; consulte también la DialogosGui clase en Github
Si desea utilizar el sistema GUI básico, su concepto es simplemente una lista plana o jerárquica de elementos GUI colocados en ciertas posiciones. La posición está determinada por una instancia de ElementBounds
. Echemos un vistazo más de cerca a sus propiedades:
Limites de Elementos
FixedX
/FixedY
: La posición absoluta donde se debe colocar el elemento.FixedWidth
/FixedHeight
: El ancho y alto absolutos del elemento.FixedPaddingX
/FixedPaddingY
: El padding interior absoluto del elemento.FixedMarginX
/FixedMarginY
: El padding exterior absoluto del elemento.ParentBounds
: Los límites principales, en los que reside este elementoChildBounds
: Los límites secundarios que contiene este elementoAlignment
: La alineación del elemento. Si se establece enNone
se utiliza la posición fija X/Y. Para cualquier otro valor, se ignoran los valores fijos X/Y. Por ejemplo cuando usasteRightTop
el elemento siempre estará en la esquina superior derecha de sus límites principales. Si se utilizaRightFixed
el elemento estará alineado a la derecha, pero su posición Y está determinada porFixedY
HorizontalSizing
/VerticalSizing
: El método de dimensionamiento a utilizar puede serFixed
(por defecto),Percentual
oFitToChildren
GuiComposer
This is the component that builds and manages your GUI elements for you. You can create a composer via the client api: capi.Gui.CreateCompo(dialogName, bounds)
. You have to supply it with a unique identifier and the overall dialog bounds. Once you have a GUIComposer instance you can chain-add elements. Here's a small example:
private void SetupDialog()
{
// Auto-sized dialog at the center of the screen
ElementBounds dialogBounds = ElementStdBounds.AutosizedMainDialog.WithAlignment(EnumDialogArea.CenterMiddle);
// Just a simple 300x300 pixel box
ElementBounds textBounds = ElementBounds.Fixed(0, 0, 300, 300);
SingleComposer = capi.Gui.CreateCompo("myAwesomeDialog", dialogBounds)
.AddStaticText("This is a piece of text at the center of your screen - Enjoy!", CairoFont.WhiteDetailText(), textBounds)
.Compose()
;
}
Some explanations:
ElementStdBounds
: Contains a bunch of often used element bounds configurations. See also ElementStdBounds on Github.ElementBounds.Fixed(0, 0, 300, 300)
: Create a new bounds instance with fixedX/Y at 0/0 and a fixed widt/height of 300/300 pixels.CairoFont.WhiteDetailText()
: Create a new font configuration based on a often used size and color, in this case white with font size 14SingleComposer
: This property is defined in theGuiDialog
class. Its a getter/setter to theComposers
dictionary. It contains all the "windows" of this dialog which are then rendered / handled by this GuiDialog instance
Fancying it up
This is of course the absolute minimum example that will only show some text. Let's add a title bar and a dialog background:
private void SetupDialog()
{
// Auto-sized dialog at the center of the screen
ElementBounds dialogBounds = ElementStdBounds.AutosizedMainDialog.WithAlignment(EnumDialogArea.CenterMiddle);
// Just a simple 300x100 pixel box with 40 pixels top spacing for the title bar
ElementBounds textBounds = ElementBounds.Fixed(0, 40, 300, 100);
// Background boundaries. Again, just make it fit it's child elements, then add the text as a child element
ElementBounds bgBounds = ElementBounds.Fill.WithFixedPadding(GuiStyle.ElementToDialogPadding);
bgBounds.BothSizing = ElementSizing.FitToChildren;
bgBounds.WithChildren(textBounds);
SingleComposer = capi.Gui.CreateCompo("myAwesomeDialog", dialogBounds)
.AddShadedDialogBG(bgBounds)
.AddDialogTitleBar("Heck yeah!", OnTitleBarCloseClicked)
.AddStaticText("This is a piece of text at the center of your screen - Enjoy!", CairoFont.WhiteDetailText(), textBounds)
.Compose()
;
}
private void OnTitleBarCloseClicked()
{
TryClose();
}
This covers some of the most basic parts. There is a grand amount of various pre-built UI elements that each come with their own argument list that are in dire need of Documentation. Here's an overview of some of the more commonly used ones
Dialog / Graphics
.AddShadedDialogBG
: Draws a pretty background and dialog border.AddDialogTitleBar
: Draws a title bar with a close button and a button to move around the dialog.AddInset
: Adds a darkened section with a inset border around it
Text
.AddStaticText
: Add a static snippet of text.AddDynamicText
: Add a snippet of text that can be set to other texts without the need to redraw the whole dialog.AddRichtext
: Same as.AddDynamicText
but allows use of VTML - a minimalist version of HTML code.AddHoverText
: When the mouse cursor moves over the element boundaries, will show supplied text as a tooltip
UI Control/Input
.AddButton
: Adds a clickable button.AddDropDown
: Adds a drop down element.AddHorizontalTabs
: Adds horizontally aligned tabs, like the ingame chat window has.AddVerticalScrollbar
: Adds a vertical scrollbar.AddTextInput
: Adds an single line editable text field.AddNumberInput
: Adds an editable text field built for entering numbers.AddTextArea
: Adds multiple line editable text field
Tables/Grids/Inventory
.AddItemSlotGrid
: Create a grid displaying the contents of supplied inventory (example: GuiDialogCarcassContents).AddSkillItemGrid
: Create a grid of custom elements (example: GuiDialogBlockEntityRecipeSelector)
Other
.AddIf
/.EndIf
: Can be used to conditionally add certain elements (but you can also just split up your creation code for more fine grained control).BeginClip
/.EndClip
: Used in combination with a scrollbar to cut away oversized content, such as in the creative inventory.AddStaticCustomDraw
: Lets you define your own drawing code to be added to the GUI
Examples
A simple standard dialog, triggered by the keyboard key 'U'
public class GuiDialogAnnoyingText : GuiDialog
{
public override string ToggleKeyCombinationCode => "annoyingtextgui";
public GuiDialogAnnoyingText(ICoreClientAPI capi) : base(capi)
{
SetupDialog();
}
private void SetupDialog()
{
// Auto-sized dialog at the center of the screen
ElementBounds dialogBounds = ElementStdBounds.AutosizedMainDialog.WithAlignment(EnumDialogArea.CenterMiddle);
// Just a simple 300x300 pixel box
ElementBounds textBounds = ElementBounds.Fixed(0, 40, 300, 100);
// Background boundaries. Again, just make it fit it's child elements, then add the text as a child element
ElementBounds bgBounds = ElementBounds.Fill.WithFixedPadding(GuiStyle.ElementToDialogPadding);
bgBounds.BothSizing = ElementSizing.FitToChildren;
bgBounds.WithChildren(textBounds);
// Lastly, create the dialog
SingleComposer = capi.Gui.CreateCompo("myAwesomeDialog", dialogBounds)
.AddShadedDialogBG(bgBounds)
.AddDialogTitleBar("Heck yeah!", OnTitleBarCloseClicked)
.AddStaticText("This is a piece of text at the center of your screen - Enjoy!", CairoFont.WhiteDetailText(), textBounds)
.Compose()
;
}
private void OnTitleBarCloseClicked()
{
TryClose();
}
}
public class AnnoyingTextSystem : ModSystem
{
ICoreClientAPI capi;
GuiDialog dialog;
public override bool ShouldLoad(EnumAppSide forSide)
{
return forSide == EnumAppSide.Client;
}
public override void StartClientSide(ICoreClientAPI api)
{
base.StartClientSide(api);
dialog = new GuiDialogAnnoyingText(api);
capi = api;
capi.Input.RegisterHotKey("annoyingtextgui", "Annoys you with annoyingly centered text", GlKeys.U, HotkeyType.GUIOrOtherControls);
capi.Input.SetHotKeyHandler("annoyingtextgui", ToggleGui);
}
private bool ToggleGui(KeyCombination comb)
{
if (dialog.IsOpened()) dialog.TryClose();
else dialog.TryOpen();
return true;
}
}
TBD
More to come here in the future.
Wondering where some links have gone?
The modding navbox is going through some changes! Check out Navigation Box Updates for more info and help finding specific pages.
Modding | |
---|---|
Modding Introduction | Getting Started • Pack Temático |
Content Modding | Content Mods • Developing a Content Mod • Basic Tutorials • Intermediate Tutorials • Advanced Tutorials • Content Mod Concepts |
Code Modding | Code Mods • Setting up your Development Environment |
Property Overview | Item • Entity • Entity Behaviors • Block • Block Behaviors • Block Classes • Block Entities • Block Entity Behaviors • Collectible Behaviors • World properties |
Workflows & Infrastructure | Modding Efficiency Tips • Mod-engine compatibility • Mod Extensibility • VS Engine |
Additional Resources | Community Resources • Modding API Updates • Programming Languages • List of server commands • List of client commands • Client startup parameters • Server startup parameters Example Mods • API Docs • GitHub Repository |