diff --git a/src/SUMMARY.md b/src/SUMMARY.md index 214492024..60a866259 100644 --- a/src/SUMMARY.md +++ b/src/SUMMARY.md @@ -51,7 +51,9 @@ SS14 By Example - [Porting Appearance Visualizers](en/ss14-by-example/making-a-sprite-dynamic/porting-appearance-visualizers.md) - [Basic Networking and You](en/ss14-by-example/basic-networking-and-you.md) - [Fluent and Localization](en/ss14-by-example/fluent-and-localization.md) -- [UI Survival Guide](en/ss14-by-example/ui-survival-guide.md) +- [UI and You](en/ss14-by-example/ui-and-you.md) + - [UI Cookbook](en/ss14-by-example/ui-and-you/ui-cookbook.md) +- [UI Survival Guide](en/ss14-by-example/ui-survival-guide.md) Robust Toolbox diff --git a/src/en/ss14-by-example/ui-and-you.md b/src/en/ss14-by-example/ui-and-you.md new file mode 100644 index 000000000..748612baa --- /dev/null +++ b/src/en/ss14-by-example/ui-and-you.md @@ -0,0 +1,474 @@ +# UI and You + +Or how I learned to stop worrying and love Sheetlets. + +```admonish note +The UI system in SS14 has been through several iterations, and much of the +current UI code is very much antiquated. When creating UI, it is generally very +helpful to reference other code, however when referencing code when making +your UI, please keep the age of the code in mind. + +If you find some code that is not up to the current conventions, refactors are +always appreciated! +``` + +Before learning how it should be done in SS14, it's important to understand how +the engine handles UI. Please reference the [user interface documentation](../robust-toolbox/user-interface.md) +first. + +## Okay, but how do I make it fancy? + +### `FancyWindow` + +`DefaultWindow` is depreciated. Unless you're making your own custom window, +`FancyWindow` should be used in all circumstances. It has additional properties +that integrate with SS14 better than `DefaultWindow`. + +The `Stylesheet` property allows you to give a window to take styles from a +certain stylesheet. The default stylesheet is `Nanotransen`, but in certain +circumstances you may want to use others. Currently there are the following +stylesheets: + +- `Nanotransen` - The default stylesheet. Used for any standard player-facing Uis +- `System` - Primarily used for admin and sandbox UIs +- `Syndicate` (COMING SOON™) - Used for any UIs affiliated with the syndicate + +### `StyleClass` + +Any styles classes that can be reused must be defined in `Content.Client/Stylesheets/StyleClass.cs`. +This is to centralize the location of all available style classes, for ease of +access and prevention of duplicate style classes. + +Any style classes that are generic / can be used for more than one element are +defined at the top. For example, the style class `positive` affects `Button`, +`Panel`, and `Label`. + +The rest of the style classes are defined for a specific generic UI element. +Some common style classes are as follows: + +- `OpenLeft`: Makes the button flat on its left side +- `OpenRight`: Makes the button flat on its right side +- `OpenBoth`: Makes the button flat on both sides; square +- `LabelSubtext`: Makes the label smaller and a more muted color +- `LabelKeyText`: Makes the label bold and a highlight color +- `LabelWeak`: Weak is the opposite of strong; makes the label a more muted color + +There are many more than this, but if you want to know exactly what a given label +does, its as simple as looking at the field's usages, and reading the style rule definition. +This is where it may be helpful to use the Rider IDE, as it has a fantastic implementation of this feature, +but its probably possible in other IDEs as well. + +```admonish tip +In general, if you are doing UI dev, I would recommend using the Rider IDE. It +eats up quite a bit of RAM, but it provides autocomplete in XAML files, a lot +of really nice auto-refactoring and searching features, and very decent git +integration. Give it a shot! +``` + +## Writing Styles + +This section concerns style rules. For most UIs, editing these will be unnecessary, +however you should ALWAYS prefer to use style classes instead of hardcoding colors +or resources that could be commonly used. + +### All hail the mighty `Sheetlet` + +It's important to understand that basically, a stylesheet is a massive list of +every single style rule. Instead of manually +making a giant list of style rules (because that would be ridiculous... haha... ha....), +the responsibility of chipping into this list is distributed between many Sheetlets. +Each Sheetlet returns a small chunk of style rules, which is agglomerated into the +final list at the end. + +```admonish note +Previously every single style rule was in one giant list: `StyleNano.cs`, a 1600 +line pit of despair where dreams went to die. +``` + +There are, primarily, two types of Sheetlets: + +- **Generic Sheetlets**: These go in `Content.Client/Stylesheets/Sheetlets`. + These stylesheets concern generic UI elements used in many different UIs, and + should be written generically to work with any stylesheet. +- **Specific Sheetlets**: These go along with the `*.xaml` files they are associated + with. These stylesheets concern UI elements that are specific to a single UI, + and should be written to work with the specific stylesheet they are associated + with. + +We will go into more detail about the specific conventions to follow for both of +these later. + +All sheetlets should have the `[CommonSheetlet]` attribute. This is used so +stylesheets can find all the sheetlets that have this attribute and add their +styles to their list. + +```admonish tip +Do not forget the `[CommonSheetlet]` attribute. +``` + +### Style Rules + +Each style rule +has a few different components to it (This will look familiar to anyone who knows CSS): + +**The selector**: This limits the elements that a style rule can affect. This is +made up of a few different parts: + +- `Type`: The type of element this rule affects. Anything inheriting from this + type will be affected by this rule. This is similar to the element selector + in css. +- `StyleClasses`: The classes that the element must have to be affected by this + rule. The element must have all of these classes to be affected by this rule. +- `StyleIdentifier`: The identifier of the element. This is a unique identifier + that can be used to target a specific element. This should be used sparingly, + when there is only one instance of the element that needs to be styled in a + highly specific manner. There may only be one of these specified. +- `PseudoClasses`: These are special classes that can be used to target elements + in a specific state. For example, this is used to style buttons differently + when hovered or pressed or whatever. + +Selectors that specify more of these parts are more "specific", and will take +priority over less specific elements. + +**The properties**: Any elements matching the selector will then have their properties +modified by the style rule. These are the same properties you would define in +the XAML. + +To assist with constructing these style rules, there are helper methods defined in +`Content.Client/Stylesheets/StylesheetHelpers`. + +I think it's best to show an examples of style rules instead of describing all +their intricacies since the code is pretty self-explanatory. + +```cs +// you need this using statement to use the helper methods +using static Content.Client.Stylesheets.Redux.StylesheetHelpers; + +var rules = +[ + // select any element... + E() + // ...with the class "negative" + .Class(StyleClass.Negative) + // ...and set its font color to the text color from the negative palette + .FontColor(sheet.NegativePalette.Text), + + // select any `Label`... + E