Modding:GUIs: Difference between revisions

From Vintage Story Wiki
m
Updated navbox to new code navbox.
(→‎GuiElements: Add GuiElementInset)
m (Updated navbox to new code navbox.)
 
(10 intermediate revisions by 2 users not shown)
Line 1: Line 1:
{{GameVersion|1.19.0}}
{{GameVersion|1.19.3}}


{{#css:
{{#css:
Line 13: Line 13:
<!--T:2-->
<!--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.
__TOC__


== Dialog Outline Modes ==
== Dialog Outline Modes ==
Line 68: Line 70:
[[File:Gui box model.png|box model]]
[[File:Gui box model.png|box model]]


The fields in ElementBounds with the 'abs' prefix should be treated as internal fields. They are written by ElementBounds.CalcWorldBounds. However, these other fields should be set either directly or with helper methods.
The fields in ElementBounds with the 'abs' prefix should be treated as internal fields. They are written by ElementBounds.CalcWorldBounds. However, these other fields may be set either directly or with helper methods.


<!--T:15-->
<!--T:15-->
Line 134: Line 136:


The alignment option can automatically place a child element in any of the 4 corners or 4 edges of the parent. However, the alignment algorithm does nothing to prevent two child elements from overlapping on the same edge/corner. For example, if two text boxes were added to the bottom edge of a dialog, then the two pieces of text would overlap. There are a few options to fix the conflict:
The alignment option can automatically place a child element in any of the 4 corners or 4 edges of the parent. However, the alignment algorithm does nothing to prevent two child elements from overlapping on the same edge/corner. For example, if two text boxes were added to the bottom edge of a dialog, then the two pieces of text would overlap. There are a few options to fix the conflict:
1. Use different edges or corners for the two pieces of text.
# Use different edges or corners for the two pieces of text.
2. Use <code>.WithFixedAlignmentOffset(0, -10)</code> to move one of the children up 10 pixels (relative to the bottom alignment in this example).
# Use <code>.WithFixedAlignmentOffset(0, -10)</code> to move one of the children up 10 pixels (relative to the bottom alignment in this example).
3. Give up on automatic alignment and used fixed alignment instead, where the child coordinates must be calculated exactly relative to the top-left corner of the parent content box.
# Give up on automatic alignment and used fixed alignment instead, where the child coordinates must be calculated exactly relative to the top-left corner of the parent content box.


Typically one uses fixed alignment to layout the dialog. The functions <code>BelowCopy</code> and <code>RightCopy</code> help calculate the bounds next to the previous bounds.
Typically one uses fixed alignment to layout the dialog. The functions <code>BelowCopy</code> and <code>RightCopy</code> help calculate the bounds next to the previous bounds.
Line 142: Line 144:
=== Sizing ===
=== Sizing ===


`ElementSizing.FitToChildren` tells a parent to automatically size itself so that it contains the bottom-right corner of the padding box for all of its children. Note that unlike the HTML flow layout, the VS layout does not prevent the children from overlapping. So the sizing algorithm more or less sizing the parent to fit its largest child.
<code>ElementSizing.FitToChildren</code> tells a parent to automatically size itself so that it contains the bottom-right corner of the padding box for all of its children. Note that unlike the HTML flow layout, the VS layout does not prevent the children from overlapping. So the sizing algorithm is more or less sizing the parent to fit its largest child.


== GUI Basics == <!--T:11-->
== GUI Basics == <!--T:11-->
Line 183: Line 185:
====Tables/Grids/Inventory====
====Tables/Grids/Inventory====


* <code>.AddItemSlotGrid</code>: Create a grid displaying the contents of supplied inventory (example: [https://github.com/anegostudios/vsessentialsmod/blob/master/Gui/GuiDialogCarcassContents.cs GuiDialogCarcassContents])
* <code>.AddItemSlotGrid</code>: Create a grid displaying the contents of supplied inventory (example: [https://github.com/anegostudios/vsessentialsmod/blob/master/Gui/GuiDialogCreatureContents.cs GuiDialogCreatureContents])
* <code>.AddSkillItemGrid</code>: Create a grid of custom elements (example: [https://github.com/anegostudios/vssurvivalmod/blob/master/Gui/GuiDialogBlockEntityRecipeSelector.cs GuiDialogBlockEntityRecipeSelector])
* <code>.AddSkillItemGrid</code>: Create a grid of custom elements (example: [https://github.com/anegostudios/vssurvivalmod/blob/master/Gui/GuiDialogBlockEntityRecipeSelector.cs GuiDialogBlockEntityRecipeSelector])


Line 196: Line 198:


=== GuiElementDialogBackground ===
=== GuiElementDialogBackground ===
Draws a pretty background and dialog border. The background is drawn on both the padding and content boxes. Typically one uses <code>ElementBounds.Fill</code> (with padding optionally set) to set the background for the entire dialog. Although it is technically possible to use smaller bounds. The <code>withTitleBar</code> does not actually draw the title bar, but instead moves the top of the background box down to make room for the title bar.
Draws a pretty background and dialog border. The background is drawn on both the padding and content boxes. Typically one uses <code>ElementBounds.Fill</code> (with padding optionally set) to set the background for the entire dialog. Although it is technically possible to use smaller bounds. The <code>withTitleBar</code> does not actually draw the title bar, but instead moves the top of the background box down <code>GuiStyle.TitleBarHeight</code> units to make room for the title bar.


GuiComposer factory functions:
GuiComposer factory functions:
Line 212: Line 214:


GuiComposer factory functions:
GuiComposer factory functions:
* <code>.AddDialogTitleBar(string text, Action onClose = null, CairoFont font = null, ElementBounds bounds = null)</code>: The default null for the bounds will put the title bar in the correct place.
* <code>.AddDialogTitleBar(string text, Action onClose = null, CairoFont font = null, ElementBounds bounds = null)</code>: The default null for the bounds will put the title bar in the correct place. The default title bar height is <code>GuiStyle.TitleBarHeight</code>.


<gallery>
<gallery>
Line 227: Line 229:
File:AddInset.png|class=pixelated|Inset drawn on top of a background, with 10 units on all sides.
File:AddInset.png|class=pixelated|Inset drawn on top of a background, with 10 units on all sides.
File:AddInset_with_padding.png|class=pixelated|Do not use padding in the inset bounds. Otherwise the rectangle for the darkened section is miscalculated and drawn outside of the embossed border.
File:AddInset_with_padding.png|class=pixelated|Do not use padding in the inset bounds. Otherwise the rectangle for the darkened section is miscalculated and drawn outside of the embossed border.
</gallery>
=== GuiElementStaticText  ===
Add a static snippet of text.
GuiComposer factory functions:
* <code>.AddStaticText(string text, CairoFont font, ElementBounds bounds, string key = null)</code>
* <code>.AddStaticText(string text, CairoFont font, EnumTextOrientation orientation, ElementBounds bounds, string key = null)</code>
* <code>.AddStaticTextAutoBoxSize(string text, CairoFont font, EnumTextOrientation orientation, ElementBounds bounds, string key = null)</code>: adds text and resizes the bounding box such that the text fits on one line. Since the bounds are updated immediately, this may be useful for adding additional components to the right of the text. After calling <code>AddStaticTextAutoBoxSize</code>, one could use <code>newbounds.FixedRightOf(textbounds)</code>,  <code>newbounds.RightOf(textbounds)</code>, or  <code>textbounds.RightCopy()</code>.
* <code>.AddStaticTextAutoFontSize(string text, string text, CairoFont font, ElementBounds bounds, string key = null)</code>: attempts to shrink the font size such that the text fits in one line in <code>bounds</code>.
The standard fonts can be obtained through static factory methods inside of CairoFont. These are commonly used:
* <code>CairoFont.WhiteSmallText()</code>
* <code>CairoFont.WhiteDetailText()</code>
The text orientation would more accurately be called the text justification. It defaults to the font's justification, which is typically left. The options are:
* <code>Left</code>
* <code>Right</code>
* <code>Center</code>
* <code>Justify</code>: does the same thing as Left.
The key option is used to find the static text later with <code>GuiElementStaticText.GetStaticText(SingleComposer, key)</code>.
<gallery>
File:AddStaticText.png|class=pixelated|WhiteSmallText drawn on top of a dialog background, with 10 units of padding.
File:AddStaticTextAutoBoxSize.png|class=pixelated|<code>AddStaticTextAutoBoxSize</code> auto sized the text box such that the single line of text was clipped by the dialog bounds.
File:AddStaticTextAutoFontSize.png|class=pixelated|<code>AddStaticTextAutoFontSize</code> attempted to shrink down the font so that it could fit on a single line.
</gallery>
</gallery>


Line 357: Line 386:
</syntaxhighlight>
</syntaxhighlight>


{{Navbox/modding|Vintage Story}}
{{Navbox/codemodding}}
Confirmedusers
637

edits