API reference

DOM, styles and queries

The document API follows the web's, in C#. If you know document.querySelector and classList, you know most of this page.

Document and elements

using DevCore.UiEngine.Dom;
using DevCore.UiEngine.Dom.Events;

var doc = view.View.Document;
var hp = doc.GetElementById("hp");

hp.TextContent = "100";
hp.ClassList.Toggle("low", health < 20);
hp.SetAttribute("data-team", "red");

doc.QuerySelectorAll(".enemy").ForEach(e => e.Remove());
hp.AddEventListener(EventType.Click, e => Debug.Log("clicked"));

bool match = hp.Matches(".bar.low");
var panel = hp.Closest(".panel");
var fill = hp.QuerySelector(".fill");

Styles

element.Style is the element's inline style. It has two kinds of setters.

MemberMeaning
SetProperty(string name, string value)Any property from CSS text. Parses and allocates: fine for occasional changes
bool Set(CssPropertyId property, float value, CssUnit unit)One length or number, typed: no parsing, no allocation
bool Set(CssPropertyId property, float x, float y, CssUnit unit)A pair: Translate, Scale
bool Set(CssPropertyId property, float number)A plain number: Opacity
bool SetColor(CssPropertyId property, Rgba color)A color
void Remove(CssPropertyId property)Removes the inline value
using DevCore.UiEngine.Css.Properties;   // CssPropertyId
using DevCore.UiEngine.Css.Values;       // CssUnit, Rgba

marker.Style.Set(CssPropertyId.Translate, x, y, CssUnit.Px);
marker.Style.Set(CssPropertyId.Opacity, 0.5f);
bar.Style.Set(CssPropertyId.Width, 40, CssUnit.Percent);
bar.Style.SetColor(CssPropertyId.BackgroundColor, new Rgba(1, 0, 0));
marker.Style.Remove(CssPropertyId.Translate);

translate, rotate, scale and opacity set through the typed setters are written straight to the renderer: no restyle, no layout, no paint. Use them for anything that moves every frame.

Geometry

using DevCore.UiEngine.View;

ClientRect rect = hp.GetBoundingClientRect();    // X, Y, Width, Height, Left, Top, Right, Bottom

Reading geometry brings style and layout up to date first, as in a browser, so a change made just before is included.

ElementFromPoint

using DevCore.UiEngine.View;

Element top = doc.ElementFromPoint(x, y);
var slot = doc.ElementFromPoint(e.ClientX, e.ClientY)?.Closest(".slot");
doc.ElementsFromPoint(x, y, list);               // every element at the point, topmost first

Both behave as in Chrome:

For a per-frame check, DocumentView.HitTest(x, y) is cheaper: it reads the last frame as it is on screen.

Queries by name

Name things in markup with query:api, find them with Q and Query.

var shop = uiView.Q<Shop>("shop");                  // a component: its public [State], props, methods
shop.gold += 100;                                   // batched: the page updates once this frame

var label = uiView.Q("gold-label");                 // an Element
var sword = shop.Q<ItemCard>("item-1");             // inside the shop only
var soldOut = uiView.Query<ItemCard>(className: "sold-out");
var hud = UiSystem.Q<Hud>("hud");                   // over every view

uiView.Query(results, "item");                      // into a list you reuse: no allocation
Rule
TElement or a component type. Component finds any component
WhereOn a UIView, a DocumentView, any node, a component (only its own nodes), or UiSystem (all views)
ComponentsFound by the query:api on their tag, or as the nearest component around an element of that name
NamesMay hold expressions (query:api="item-{item.Id}"). Several things may share a name: Q returns the first in document order
ClassesclassName narrows the search; a component's class is its root element's
HiddenWhat is inside a false {#if}, or destroyed, is not found: Q returns null
CostNames are indexed: a search visits only what has that name and allocates nothing. Still, look things up once and keep them