NUI functions - UI scaling

I made a crude example of the NUI functions, based loosely on the Beamdog demo script.

It doesn’t seem to work correctly if the UI scale is changed - anyone know how to fix that?

If you’re active on Discord, you may want to reach out to tinygiant. He may be able to help with some basics; he’s been working up a whole library/system built on NUI to do all kinds of fun things.

His work is on github, afaik, and he’s in a polish and refactor stage atm, last I hear.


In bh_do_slideshow.nss change line 86/87 do

  float fScale = GetPlayerDeviceProperty(oPC, PLAYER_DEVICE_PROPERTY_GUI_SCALE) / 100.0;
  float fFullWidth  = GetPlayerDeviceProperty(oPC, PLAYER_DEVICE_PROPERTY_GUI_WIDTH) / fScale;
  float fFullHeight = GetPlayerDeviceProperty(oPC, PLAYER_DEVICE_PROPERTY_GUI_HEIGHT) / fScale;

Apparently NWN does not adjust the window sizes depending on the user’s scale factor. This can be a problem if the user changes the scale factor while there’s a window open. But perhaps it’s possible to catch that and adjust the open/created windows accordingly.


Thanks for that.

Since one or two people have expressed interest, I’ve updated the demo to support UI scaling and other suggested improvements.


did anyone managed to create a button with both image and text? I cannot figure this out…

Something like this:

json jButtonImage = NuiButtonImage(...);

json jDrawList = JsonArray();
     jDrawList = JsonArrayInsert(jDrawList, NuiDrawListText(JsonBool(...), NuiColor(...), NuiRect(...), JsonString("Your Text"));

jButtonImage = NuiDrawList(jButtonImage, JsonBool(...), jDrawList);

thanks, this did not provide what I wanted, but got me into right direction

EDIT: hmm it seems this causes bug, or I am doing something wrong. When I use this, any additional buttons will not render border nor text.

Here is a code of a simple table I am trying to do, it renders only first button, despite the second button is right under it and can be clicked into.

void NuiTest()
json col;
json row;

col = JsonArray();
row = JsonArray();
json jButtonImage;
json jDrawList;

jButtonImage = NuiId(NuiButtonSelect(JsonString("Button 1 Text"),NuiBind("btn1selected")),"btn1");
jDrawList = JsonArray();
jDrawList = JsonArrayInsert(jDrawList, NuiDrawListImage(JsonBool(TRUE), JsonString("ir_use"), NuiRect(5.0,20.0,0.0,0.0), JsonInt(NUI_ASPECT_EXACT), JsonInt(NUI_HALIGN_LEFT), JsonInt(NUI_VALIGN_MIDDLE)));
jButtonImage = NuiDrawList(jButtonImage, JsonBool(TRUE), jDrawList);
jButtonImage = NuiWidth(jButtonImage, 400.0);
jButtonImage = NuiHeight(jButtonImage, 40.0);
row = JsonArray();
row = JsonArrayInsert(row, jButtonImage);
col = JsonArrayInsert(col, NuiRow(row));
row = JsonArray();

json btn2 = NuiId(NuiButtonSelect(JsonString("Button 2 Text"),NuiBind("btn2selected")),"btn2");
row = JsonArrayInsert(row, btn2);
col = JsonArrayInsert(col, NuiRow(row));

row = JsonArray();
    row = JsonArrayInsert(row, NuiSpacer());
    row = JsonArrayInsert(row, NuiSpacer());
 //   row = JsonArrayInsert(row, NuiSpacer());

col = JsonArrayInsert(col, NuiRow(row));

json root = NuiCol(col);
json nui = NuiWindow(root,JsonString("Test NUI"),NuiRect(420.0, 50.0, 420.0, 600.0),JsonBool(FALSE),JsonBool(FALSE),JsonBool(TRUE),JsonBool(FALSE),JsonBool(TRUE));

int token = NuiCreate(GetFirstPC(), nui, "testnui");

NuiSetBind(GetFirstPC(), token, "btn1selected", JsonBool(0));
NuiSetBind(GetFirstPC(), token, "btn2selected", JsonBool(0));


If i delete the drawlist code, both buttons show up properly, but without the image I wanted in first place…

And what about an option to make a multilanguaged text? Ie. button or just element with a TLK reference that will show the text from client’s TLK instead?

Sorry about the low bar I’m about to introduce but how exactly do I get your demo to work?

So far I have put all the files from the download in my override, started a new module, typed DebugMode 1( success) then tilde again and pasted in the ##dm_runscript bh_slides and got function not found…

If you are using Tilde, then do not type the hash characters, which are only used in the chat window.

1 Like


You stumbled upon a bug I found some time ago and haven’t reliably found a way around yet. Whenver a control has a drawing (drawlist) attached to it, subsequent controls will not render. I’m still working on identifying exactly how to contain that. I’ve had some luck by containing the drawlist control within a controlgroup or within it’s own column/row, but that’s not really an ideal solution.

You should be able to do this by setting a bind for the value your looking for. In this case, you can bind the button’s label and then set that bind to whatever value you want when you open the form.

Thought so… I also tried to workaround and avoid this, but no luck yet.

That is not the same though. I already tried to put the integer value into various tags like strref, StrRef etc. but it didn’t work.

The problem here is that I can not check every possible language and return that language string. I mean, it actually is possible to do that way I guess, but highly impractical… Imagine making a custom GUI that allows to select any feat as a reward for a quest or something. I would have to manually translate every existing feat into 7 languages if I wanted to replicate the StrRef functionality. (Not that this would be possible to do via conversation dynamically either…)

Sorry, I misunderstood your request. I’ll let you know if I can nail down a solution for isolating the rendering issue for drawlists.

I’ve had some luck containing the drawlist rendering issue. If you want a widget to have a drawlist element, try containing that widget within its own controlgroup. You can set the border to invisible and scrollbars to none to prevent the control group itself from being visible. Do not put any other widgets in this control group. See if that helps prevent the rendering issue.

It took some time to adjust it as NuiGroup seems to wrap the element with a 2px border from the “inside” and setting it to invisible wasn’t enough as the border still cut the original button border. But I managed to make it work. Thanks, this workaround does the trick, nice find.

I haven’t tried this yet, but you can try setting the padding of the control group to 0.0 to see if it’ll let the controls get a little closer to the edge of the group.

Found another work around with the help of another programmer:

If you set jScissor in NuiDrawList to FALSE, the rendering issue appears to go away and you don’t need to use control groups to contain the drawlist issue.

Warning: I have not yet determined what other issue turning scissoring off might cause … so use at your own risk.