NLGUI (nel/src/gui, headers nel/include/nel/gui, namespace NLGUI) is NeL's data-driven widget library: the XML-described, database-reactive, Lua-scriptable interface system originally built for the Ryzom client and extracted into the engine so any NeL application can use it. The client keeps its game-specific widgets and handlers on top; the library alone is a complete windowing toolkit.
Documentation for authoring interfaces (XML, layout, widgets, database, scripting) lives under Interface. This section covers the library itself.
nl_sample_gui, the standalone showcase (native + WebGL)The library is a set of cooperating singletons around one element tree:
CWidgetManager owns the master groups (window roots), window ordering and activation, input dispatch, capture and keyboard focus, the mouse pointer, tooltips, modals, procedures, and the frame pump (checkCoords, drawViews, clock-tick events). Holds the parser instance.CInterfaceParser (IParser) parses the merged XML document into elements (pipeline details); extensible with IParserModules for application-specific elements; owns templates, defines, styles, procedures, options blocks and the Lua bootstrap (initLUA).CViewRenderer batches every visible view into per-layer quad streams over the texture atlas; owns screen metrics and the "figur" digit textures. Interfaces render as very few draw calls.CDBManager: the interface database tree; leaf/branch observers feed CInterfaceLink triggers, flushed once per frame.CAHManager: the action handler registry and dispatcher.CLuaManager + CLuaIHM: the shared Lua state and the reflection bridge that exposes widgets as Lua objects.CInterfaceElement id, active, position/size machinery, reflection root
└ CViewBase drawable leaf (views)
└ CCtrlBase + input handling, tooltips (controls)
└ CInterfaceGroup + children (groups, windows)
Groups are controls are views: one factory serves all three XML tags, and each tag merely enforces a dynamic cast. Elements register with NLMISC_REGISTER_OBJECT(CViewBase, Class, std::string, "typename"); the parser instantiates by type= attribute. A <group> with an unknown type degrades to a plain interface_group; unknown views/ctrls fail.
Reflection: classes export properties through REFLECT_* macro tables; the same property set serves Lua field access, <link target=...> writes, getprop(...) reads and the set handler. One registry, four consumers.
Input: driver events → CEventListener (adapter subscribing mouse/keyboard on the event server) → CWidgetManager::handle* → hit-testing through window order → captured/focused element → widget handleEvent → action handlers. Nothing in the library moves pointer button state into the pointer view; the embedder mirrors it (see embedding).
Update/draw per frame: sendClockTickEvent (drives repeat buttons, animations, onclock_tick) → checkCoords/updateCoords (invalidated subtrees re-measure; db-view widgets poll their leaves here) → observer flush (triggered CInterfaceLinks evaluate) → drawViews (renderer batches by window then render layer, applies global color and per-window alphas, draws the pointer last).
The XML type names the library registers, by family. Attributes for each are documented in the linked authoring pages.
| family | types | docs |
|---|---|---|
| plain groups | interface_group, group_wheel |
windows |
| windowing | container, modal, frame, header, header_entry |
windows |
| composition | list, scroll_text, tab, tree, menu, table |
windows |
| text views | text, text_formated, text_id, text_id_formated |
views |
| bitmap views | bitmap, bitmap_combo, generic_pointer |
views |
| database views | text_number, digit, text_quantity, bar, bar3 |
views |
| buttons | button, text_button, tab_button, button_link, tooltip |
controls |
| input | edit_box, edit_box_decor, scroll, colpick, combo_box, select_number |
controls |
| html | html, html_input_offset |
html |
The Ryzom client registers more (sheet, in-scene interfaces, …) into the same factory; those are client code, not library.
Options-block classes (<options type=...>): layer, container_move_opt, container_insertion_opt, list; see skinning.
This library is the Ryzom client's interface code, lifted out of the client tree (where it lived under interface_v3) and librarified into NeL after a decade of production use. The extraction kept the data formats intact: Ryzom's interface XML parses unmodified. A community CEGUI integration is also available as a separate NeL plugin.