Modding:GUIs: Difference between revisions

From Vintage Story Wiki
Marked this version for translation
mNo edit summary
(Marked this version for translation)
Line 1: Line 1:
{{GameVersion|1.15}}
{{GameVersion|1.15}}
<languages/><translate>
<languages/><translate>
<!--T:1-->
Creating good graphical user interfaces is a challenging task - sometimes even the largest of companies mess it up.
Creating good graphical user interfaces is a challenging task - sometimes even the largest of companies mess it up.


<!--T:2-->
In Vintage Story you currently need to formulate your GUIs in code, which requires acute spacial thinking. Hopefully someday we'll have a point&click GUI designer that takes off a lot of work. Until then, here are some of the essentials.
In Vintage Story you currently need to formulate your GUIs in code, which requires acute spacial thinking. Hopefully someday we'll have a point&click GUI designer that takes off a lot of work. Until then, here are some of the essentials.


<!--T:3-->
'''Protip:'''
'''Protip:'''
  Use the debug keybind to "Cycle Dialog Outline Modes" when building a GUI. It will draw outlines around your GUI element bounds, making it much easier to understand how your code is translated into the visual GUI.
  Use the debug keybind to "Cycle Dialog Outline Modes" when building a GUI. It will draw outlines around your GUI element bounds, making it much easier to understand how your code is translated into the visual GUI.


== Starting out ==
== Starting out == <!--T:4-->
You should encapsulate every GUI Dialog into its own class, albeit a dialog may consist of multiple windows - the vanilla character dialog for example has two - one for the players wearables and one for the player stats. There's a couple of base classes to make your life a bit easier.
You should encapsulate every GUI Dialog into its own class, albeit a dialog may consist of multiple windows - the vanilla character dialog for example has two - one for the players wearables and one for the player stats. There's a couple of base classes to make your life a bit easier.


===Block Entity GUI===
===Block Entity GUI=== <!--T:5-->


<!--T:6-->
To create a GUI that's bound to a block entity, inherit from <code>GuiDialogBlockEntity</code>. In your block entity code you can then create and open that gui e.g. upon player interaction (example: [https://github.com/anegostudios/vssurvivalmod/blob/648193749d2ea5b8c155d27db0c7f6dc1050f9cd/BlockEntity/BEQuern.cs#L602 Quern Block Entity], [https://github.com/anegostudios/vssurvivalmod/blob/master/Gui/GuiDialogBlockEntityQuern.cs Quern Block Dialog])
To create a GUI that's bound to a block entity, inherit from <code>GuiDialogBlockEntity</code>. In your block entity code you can then create and open that gui e.g. upon player interaction (example: [https://github.com/anegostudios/vssurvivalmod/blob/648193749d2ea5b8c155d27db0c7f6dc1050f9cd/BlockEntity/BEQuern.cs#L602 Quern Block Entity], [https://github.com/anegostudios/vssurvivalmod/blob/master/Gui/GuiDialogBlockEntityQuern.cs Quern Block Dialog])


===HUD===
===HUD=== <!--T:7-->


<!--T:8-->
To create a GUI element which is not interactable, inherit from <code>HudElement</code>.
To create a GUI element which is not interactable, inherit from <code>HudElement</code>.


===General Purpose GUI===
===General Purpose GUI=== <!--T:9-->


<!--T:10-->
For any other uses, inerhit from the general purpose class <code>GuiDialog</code>, from which HudElement and GuiDialogBlockEntity also inherit from. You can override <code>ToggleKeyCombinationCode</code> to something like "yourAweseomeHotkeyCode" and use <code>capi.Input.RegisterHotKey</code> + <code>capi.Input.SetHotKeyHandler</code> to have your own keyboard key mapped to opening/closing your GUI (example: [https://github.com/anegostudios/vsessentialsmod/blob/master/Systems/WorldMap/WorldMapManager.cs#L105 World Map])
For any other uses, inerhit from the general purpose class <code>GuiDialog</code>, from which HudElement and GuiDialogBlockEntity also inherit from. You can override <code>ToggleKeyCombinationCode</code> to something like "yourAweseomeHotkeyCode" and use <code>capi.Input.RegisterHotKey</code> + <code>capi.Input.SetHotKeyHandler</code> to have your own keyboard key mapped to opening/closing your GUI (example: [https://github.com/anegostudios/vsessentialsmod/blob/master/Systems/WorldMap/WorldMapManager.cs#L105 World Map])


== GUI Basics ==
== GUI Basics == <!--T:11-->


<!--T:12-->
In general, you can pretty much build your own GUI system if you want to, by just overriding <code>OnRenderGUI</code> and render whatever you like. There's a multitude of overridable methods to handle mouse and keyboard inputs as well, see also the [https://github.com/anegostudios/vsapi/blob/master/Client/UI/Dialog/GuiDialog.cs GuiDialog] class on Github
In general, you can pretty much build your own GUI system if you want to, by just overriding <code>OnRenderGUI</code> and render whatever you like. There's a multitude of overridable methods to handle mouse and keyboard inputs as well, see also the [https://github.com/anegostudios/vsapi/blob/master/Client/UI/Dialog/GuiDialog.cs GuiDialog] class on Github


<!--T:13-->
If you want to use the vanilla GUI system, it's concept is merely a flat or hierarchical list of GUI elements placed at certain positions. The position is determined by an instance of <code>ElementBounds</code>. Let's have a closer look at it's properties:
If you want to use the vanilla GUI system, it's concept is merely a flat or hierarchical list of GUI elements placed at certain positions. The position is determined by an instance of <code>ElementBounds</code>. Let's have a closer look at it's properties:


=== ElementBounds===
=== ElementBounds=== <!--T:14-->


<!--T:15-->
* <code>FixedX</code>/<code>FixedY</code>: The absolute position where the element should be placed
* <code>FixedX</code>/<code>FixedY</code>: The absolute position where the element should be placed
* <code>FixedWidth</code>/<code>FixedHeight</code>: The absolute width and height of the element
* <code>FixedWidth</code>/<code>FixedHeight</code>: The absolute width and height of the element
Line 40: Line 49:
* <code>HorizontalSizing</code>/<code>VerticalSizing</code>: The sizing method to be used, can be either <code>Fixed</code> (default), <code>Percentual</code> or <code>FitToChildren</code>
* <code>HorizontalSizing</code>/<code>VerticalSizing</code>: The sizing method to be used, can be either <code>Fixed</code> (default), <code>Percentual</code> or <code>FitToChildren</code>


===GuiComposer===
===GuiComposer=== <!--T:16-->


<!--T:17-->
This is the component that builds and manages your GUI elements for you. You can create a composer via the client api: <code>capi.Gui.CreateCompo(dialogName, bounds)</code>. 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:
This is the component that builds and manages your GUI elements for you. You can create a composer via the client api: <code>capi.Gui.CreateCompo(dialogName, bounds)</code>. 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:
</translate>
</translate>
Confirmedusers
13,514

edits