Confirmedusers
13,514
edits
Mirotworez (talk | contribs) mNo edit summary |
Mirotworez (talk | contribs) (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> |