-
Notifications
You must be signed in to change notification settings - Fork 113
widget_sample
title: GUI Widget Sample description: Standalone NeL GUI showcase sample (nl_sample_gui) using the legacy w_ interface skin published: true editor: markdown
nl_sample_gui (nel/samples/gui/) is a standalone showcase of the NLGUI widget library. It boots the widget manager, view renderer and interface parser outside the Ryzom client, parses a self-contained interface definition, and renders it with the legacy w_ interface skin — the original beveled reference style whose window frames (w_header_*, w_l0_*, w_l1_*, w_modal_*, w_scroll_l0_*) were later replaced name-for-name by the shipped skin_* set. The sample keeps this otherwise-unused skin exercised and doubles as a minimal reference for embedding NLGUI in any NeL application.
-
main.cpp— bootstrap:UDriver+ text context,CViewRenderer::setDriver/setTextContext+init, atlasloadTextures,parseInterface,updateAllLocalisedElements,activateMasterGroup("ui:sample"), then the pump/draw loop (EventServer.pump→sendClockTickEvent→checkCoords→drawViews). ANLGUI::CEventListenerroutes driver mouse events into the widget manager. -
data/config_sample.xml— master<root id="sample">, database defaults, and thew_skinoptionsblocks (layer0,skin_modal,container_move_opt,container_insertion_opt,context_menu_back, …). -
data/widgets_sample.xml— shared widget styles (text_button_16,button_ok,tab_button) on thew_text_button_*/w_tab_*textures. -
data/main_sample.xml— the showcase windows, thegeneric_pointerview, and the<tree>nodes that register windows.
No interface texture data lives in the code repository. At build time, CMake runs the build_interface tool over interfaces/v3/ of a ryzomcore_graphics checkout (NL_GRAPHICS_DIR, default sibling of the source tree) and packs gui_sample_atlas.png/.txt into the build directory — the same pattern the WebGL water sample uses for its assets. build_interface gained a -k/--keep-going flag for this: input files that cannot be loaded as bitmaps (e.g. unmaterialized git-lfs pointer files) are skipped with a warning instead of aborting the pack. The font comes from fonts/basic.ttf in the same checkout.
The Emscripten build preloads the generated atlas, the XML and the font into the .data bundle; when cross-compiling, point NL_BUILD_INTERFACE_TOOL at a host-built build_interface.
Native (needs WITH_GUI=ON, which needs Lua and ryzom/luabind; build both into a local prefix and pass LUA_*/LUABIND_* cache variables if the distribution does not package them):
cmake -DWITH_GUI=ON -DWITH_NEL_SAMPLES=ON ...
ninja nl_sample_gui
bin/nl_sample_gui # interactive, ESC quits
bin/nl_sample_gui --screenshot out.png --frames 10 # headless witness (works under xvfb-run)
NLGUI ships the widget-level handlers (set, tab_select, ic_* container buttons, combo box, select number, …) but some conventional handlers live in the Ryzom client. The sample registers its own equivalents: proc (run an interface procedure), enter_modal / leave_modal (CWidgetManager::enableModalWindow), and sample_quit.
A launcher window toggles one showcase window per family; the four container layer skins (layer0…layer3, pure w_l0_*…w_l3_* options blocks) are spread across them. Covered and interaction-verified under Xvfb with xdotool: text views (sizes, colors, case modes, multi-line), bitmaps (scaled/tiled), text_number/digit/text_quantity, bar/bar3 gauges, push/toggle/radio buttons, text buttons, sliders on both axes bound to UI:TEMP:* database entries, edit boxes (typed input works), scroll_text (which contains the runtime-filled group_list), group_tree with arbo_* fold arrows, menus (checkable, grayed, separator, nested submenu — a submenu is a nested <action> inside an <action>, not a <menu> element), the combo box with its dropdown, select_number, the color picker (palette + a makeRGB(...) link recoloring a swatch), tab groups, stacked modals (push_modal/pop_modal), a <link> showing a warning icon above a threshold, and the contacts-style popin rollout with the original anatomy: window contents live in the header groups, the section below is the open rollout where child containers dock via nested <tree> nodes, and a contact entry is a closed container — just its title bar with icons in header_closed. With the child list open, the engine draws the top block, the m_open left rail, and the floating el/em/er_open ending strip; the right edge of the rollout section is genuinely open (the shipped skin_ layers instead patch a single repeated right-edge texture over it, e.g. skin_l1_r for tx_tr/tx_r/tx_br). The sample keeps the docked entries on the standard beveled layer skins. (An aside for future work: layer0_content/layer1_content are near-frameless options blocks — every frame slot mapped to the w_l1_spe_blank filler with a w_l1_r_spe right cap — that survive unreferenced in the shipped client config, still pointing at the w_ textures; a faithful reconstruction of the original rollout composition likely involves them plus the era's translucent window alpha, but the attempt in the sample was reverted as it did not read right. When the popin list overflows the parent's height cap, the list scrollbar sits in the left m_open rail — the draw code labels that rail "ScrollBar Placement".) Not exercised: group_html/group_table (need the web stack wired), Lua-scripted UI (handler registered, no demo), edit_box_decor, group_frame/header.
Note on container layers: standalone windows can force a deeper skin with options="layer1..3", but the engine normally derives the layer from popin nesting depth.
NLGUI expects several things from the embedding application that the Ryzom client normally supplies:
-
CInterfaceLink::CInterfaceLinkUpdater— instantiate one after creating the widget manager; without it,<link>elements never evaluate (database observer flushes are what pump triggered links). CallCInterfaceLink::updateAllLinks()once after parsing for the initial evaluation. -
CDBGroupComboBox::selectMenu/selectMenuOut/measureMenu— static ids the combo dropdown machinery resolves; point them at your master group's menus. -
Action handlers with client-side conventions:
proc,enter_modal/leave_modal,push_modal/pop_modal,active_menu,lua.
-
Container windows need the global options blocks.
CGroupContainer::setupdereferencescontainer_move_optunchecked — without that options block the firstupdateAllLocalisedElementscrashes. -
Fresh database leaves default to 0.
UI:SAVE:CONTENT_ALPHA,UI:SAVE:CONTAINER_ALPHAand friends must be declared (255) in the XML or every window renders fully transparent. LikewiseUI:SAVE:*_ROLLOVER_FACTORare inverted factors: 255 = no fade-out when the mouse is not over the window, 0 = fade to invisible. -
Root-level plain
<group>s are parsed but never drawn — only windows registered on the master group (containers via<tree>, modals viaenableModalWindow) render. Put HUD-style elements inside a registered window. -
%case_upperetc. are interface defines, not built-ins — declarecase_normal…case_first_word_letter_up(0…5). - The texture lookup normalizes
.png→.tgaon both the atlas-load and lookup sides, so interface XML keeps the canonical.tganames while the atlas is packed from.pngsources. The color picker is the exception: it reads its palette as a loose file (it needs pixel access), so the palette png is staged next to the atlas andCPath::remapExtension("png", "tga", true)is set before the search paths are indexed. - Container windows compute their height from the content group unless
resizer="true"; a fixed-size window withresizer="false"and an empty-sized content collapses to its title bar. -
dbview_quantity's registered class name istext_quantity(notquantity). - Two NLGUI bugs fixed while building this:
CEventListenernever subscribed keyboard events (edit boxes were deaf outside the client), andCGroupTree::SNode::parsecrashed on a<node>withopened=but noshow=(wrong pointer guarded).
The GUI stack builds for the web sample target. Recipe (dev-box; prefix paths are examples):
-
Cross-build the static deps with the emsdk into a local prefix:
- Lua 5.1.5:
make generic CC="emcc -O2" AR="emar rcu" RANLIB=emranlib,make install INSTALL_TOP=<prefix>. - libxml2 (2.12.x):
emcmake cmakewith-DBUILD_SHARED_LIBS=OFF -DLIBXML2_WITH_{PYTHON,ICONV,LZMA,ZLIB,TESTS,PROGRAMS}=OFF. -
ryzom/luabind:
emcmake cmakeagainst the wasm Lua. Boost is headers-only here, but do not pass/usr/includeas the Boost include dir — host headers poison the emscripten sysroot; symlinkboost/into a clean directory instead.
- Lua 5.1.5:
-
curl/openssl are not built —
nel/samples/gui/emscripten/nel_wasm_stubs.c(compiled with emcc, archived aslibcurl.a/libssl.a/libcrypto.ain the prefix, with real curl headers copied alongside) provides symbol-level stubs whose entry points fail the way the real libraries would. NeL's error paths handle that; a JS missing-function import would abort at the first call instead (CCurlHttpClient::connectdereferencescurl_version_info()unconditionally, so that one returns a static struct). SysV IPC stubs cover nelmisc shared memory. -
Configure the emscripten tree with
WITH_GUI=ON WITH_WEB=ON WITH_LUA51=ONplusLUA_*,LUABIND_*,Boost_INCLUDE_DIR,LibXml2_DIR=<prefix>/lib/cmake/libxml2-<ver>,CURL_INCLUDE_DIR/CURL_LIBRARY,OPENSSL_*pointing at the prefix, andNL_BUILD_INTERFACE_TOOL=<host build>/bin/build_interfacefor the atlas pack. The root CMake emscripten branch probes these instead of compiling XML support out (nelmiscgains realCIXmlon wasm this way). - The sample selects
UDriver::OpenGlEs3under emscripten and defaults to the 1600x1200 showcase layout; the html page CSS-scales the canvas. Deploys next to the other WebGL samples (nl_sample_gui.html/.js/.wasm/.data).
Verified in headless chromium over SwiftShader WebGL: rendering matches the native build, including evaluated <link>s and the color picker palette.
- M1 (landed): skeleton —
w_layer0 container window with header/title/buttons,w_modalmodal viaenter_modal, mouse pointer, frame-capped loop, headless screenshot mode, xdotool-verified event chain under Xvfb. - M2 (landed): comprehensive widget coverage as described above, every interaction verified headless.
- M3 (landed): Emscripten/WebGL build deployed with the other NeL web samples.