Nui basic example
From NWN Lexicon
Jump to navigationJump to searchIntro
Here is a basic example of a small NUI Window.
1. Create a new file called : `nui_example.nss` using contents below.
2. Then Setup OnNuiEvent as such:
#include "nui_example"
void main()
{
object oPlayer = NuiGetEventPlayer();
int nToken = NuiGetEventWindow();
string sEvent = NuiGetEventType();
string sElement = NuiGetEventElement();
int nIndex = NuiGetEventArrayIndex();
string sWindowId = NuiGetWindowId(oPlayer, nToken);
if (sWindowId == NUIEXAMPLE_WINDOW_ID)
{
NUIExample_Events();
return;
}
}
void main()
{
object oPlayer = NuiGetEventPlayer();
int nToken = NuiGetEventWindow();
string sEvent = NuiGetEventType();
string sElement = NuiGetEventElement();
int nIndex = NuiGetEventArrayIndex();
string sWindowId = NuiGetWindowId(oPlayer, nToken);
if (sWindowId == NUIEXAMPLE_WINDOW_ID)
{
NUIExample_Events();
return;
}
}
3. Finally you need to call ```NUIExample_NewWindow(oPlayer);``` from something. This could be an Item's Unique Power, or Placeable a OnUsed Event, etc.
You should hopefully see your new window now:
Code
"nui_example.nss"
#include "nw_inc_nui"
// This is our window id, it's used to differentiate between NUI Windows
const string NUIEXAMPLE_WINDOW_ID = "nui_example";
// This creates our new window. You can call this from anywhere.
// Examples would be: Module (item) OnActivateItem, Placeable OnUsed, Module OnPlayerChat, etc.
void NUIExample_NewWindow(object oPlayer);
// This will refresh data on window.
// This depends on application, but should be called anytime you think the state has changed.
void NUIExample_Update(object oPlayer, int nToken = -1);
// This handles events.
// This should be called from OnNuiEvent
// https://nwnlexicon.com/index.php?title=OnNuiEvent
/* Example:
#include "nui_example"
void main()
{
object oPlayer = NuiGetEventPlayer();
int nToken = NuiGetEventWindow();
string sEvent = NuiGetEventType();
string sElement = NuiGetEventElement();
int nIndex = NuiGetEventArrayIndex();
string sWindowId = NuiGetWindowId(oPlayer, nToken);
if (sWindowId == NUIEXAMPLE_WINDOW_ID)
{
NUIExample_Events();
return;
}
}
*/
void NUIExample_Events();
// Helper function for debugging.
// Log it however you want.
void LogMessage(string sMessage)
{
// WriteTimestampedLogEntry(sMessage);
SendMessageToPC(GetFirstPC(), sMessage);
}
void NUIExample_Events()
{
// Get all our inputs.
object oPlayer = NuiGetEventPlayer();
int nToken = NuiGetEventWindow();
string sEvent = NuiGetEventType();
string sElement = NuiGetEventElement();
int nIndex = NuiGetEventArrayIndex();
string sWindowId = NuiGetWindowId(oPlayer, nToken);
// Not our window!
if (sWindowId != NUIEXAMPLE_WINDOW_ID)
{
LogMessage("NUIExample_Events called for wrong window, expecting: " + NUIEXAMPLE_WINDOW_ID + " but got: " + sWindowId);
return;
}
// If events aren't working, log what is going on.
// If you don't see a bunch of stuff, then likly it's not being called from OnNuiEvent correctly.
// LogMessage("NUIExample: sElement: " + sElement + " sEvent: " + sEvent);
// Here is all our events, we need to sort out what to do, depending on Event and Element.
switch (HashString(sEvent))
{
case ("blur"):
{
}
break;
case ("click"):
{
}
break;
case ("close"):
{
}
break;
case ("focus"):
{
}
break;
case ("mousedown"):
{
}
break;
case ("mousescroll"):
{
}
break;
case ("mouseup"):
{
// Yikes, switch inside a switch.
// But this filters Event mouseup by Element with these Ids (in this case, buttons mostly)
// Ie, when a user is done clicking a button, process what to do for that button type.
switch (HashString(sElement))
{
case ("buttonUpdate"):
{
// They want to call an update.
NUIExample_Update(oPlayer, nToken);
return;
}
break;
case ("buttonCancel"):
{
// They want to close a window.
NuiDestroy(oPlayer, nToken);
return;
}
break;
}
}
break;
case ("open"):
{
}
break;
case ("range"):
{
}
break;
case ("watch"):
{
}
break;
default:
{
LogMessage("NUIExample: Unknown event occured: " + sEvent + " Element: " + sElement);
}
break;
}
}
void NUIExample_Update(object oPlayer, int nToken = -1)
{
// If caller doesn't have our token, be nice and look it up for them.
if (nToken == -1)
{
nToken = NuiFindWindow(oPlayer, NUIEXAMPLE_WINDOW_ID);
}
// Window isn't open, so let's not spend time processing updates.
if (nToken == 0)
{
return;
}
// This is our only update for now.
// For Nui Id "labelMain" it will update it's value with a random number between 1 and 100.
NuiSetBind(oPlayer, nToken, "labelMain", JsonString(IntToString(Random(100) + 1)));
}
void NUIExample_NewWindow(object oPlayer)
{
// This checks if window is already open. If so, we want to close it and create a new one.
// You CAN have multiple windows of same time, but most use cases if you just want one instance?
int nToken = NuiFindWindow(oPlayer, NUIEXAMPLE_WINDOW_ID);
if (nToken != 0)
{
NuiDestroy(oPlayer, nToken);
}
/////////////////////////////////////////
// Build the main root pane here
/////////////////////////////////////////
// This is going to be our entire window that is passed into NuiWindow.
json jRoot = JsonArray();
json jRow;
// Build the first row
{
// Create an array to hold our first row.
jRow = JsonArray();
// Create a label, notice it uses bind "labelMain", instead of static value.
json jLabelMain = NuiLabel(NuiBind("labelMain"), JsonInt(NUI_HALIGN_CENTER), JsonInt(NUI_VALIGN_MIDDLE));
// Add our label to the row
jRow = JsonArrayInsert(jRow, jLabelMain);
// Apply a Layout too it (you can't have widgets hanging about, outside of layout groups)
jRow = NuiRow(jRow);
// Finally we add our finalize row to our main root window.
jRoot = JsonArrayInsert(jRoot, jRow);
}
// Build the second row
{
// Same as before, start with a fresh array to hold our row data.
jRow = JsonArray();
// Make two buttons.
// Notice they have NuiId! If you want to capture events on widgets they MUST have an ID
json jButtonUpdate = NuiId(NuiButton(JsonString("Update")), "buttonUpdate");
json jButtonCancel = NuiId(NuiButton(JsonString("cancel")), "buttonCancel");
// Same as first row, but we goign to add a spacer, then both buttons.
jRow = JsonArrayInsert(jRow, NuiSpacer());
jRow = JsonArrayInsert(jRow, jButtonUpdate);
jRow = JsonArrayInsert(jRow, jButtonCancel);
// again, wrap all the widgets up in a nice group layout.
jRow = NuiRow(jRow);
// then add to main root
jRoot = JsonArrayInsert(jRoot, jRow);
}
///////////////////////////////////////////
// Build final group
///////////////////////////////////////////
// Again, needs a group layout, his is just one big column for window (with 2 rows inside it)
jRoot = NuiCol(jRoot);
/////////////////////////////////////////
// Create new window here
/////////////////////////////////////////
// Creates new window and gets token.
json jNuiWindow = NuiWindow(jRoot, NuiBind("windowtitle"), NuiBind("geometry"), NuiBind("resizable"), NuiBind("collapsed"), NuiBind("closable"), NuiBind("transparent"), NuiBind("border"), JsonBool(TRUE));
nToken = NuiCreate(oPlayer, jNuiWindow, NUIEXAMPLE_WINDOW_ID);
// Good example of how to use bings. "windowtitle" is just a place holder. We want to update it here.
NuiSetBind(oPlayer, nToken, "windowtitle", JsonString("NUI Example"));
// x, y, width, height.
// -1.0f, -1.0f, means to "center" the new NUI Window. Otherwise you can manually place it were you wish.
NuiSetBind(oPlayer, nToken, "geometry", NuiRect(-1.0f, -1.0f, 512.0f, 512.0f));
NuiSetBind(oPlayer, nToken, "collapsed", JsonBool(FALSE));
NuiSetBind(oPlayer, nToken, "resizable", JsonBool(TRUE));
NuiSetBind(oPlayer, nToken, "closable", JsonBool(TRUE));
NuiSetBind(oPlayer, nToken, "transparent", JsonBool(FALSE));
NuiSetBind(oPlayer, nToken, "border", JsonBool(TRUE));
// Refesh the data after window is made.
NUIExample_Update(oPlayer);
}
// This is our window id, it's used to differentiate between NUI Windows
const string NUIEXAMPLE_WINDOW_ID = "nui_example";
// This creates our new window. You can call this from anywhere.
// Examples would be: Module (item) OnActivateItem, Placeable OnUsed, Module OnPlayerChat, etc.
void NUIExample_NewWindow(object oPlayer);
// This will refresh data on window.
// This depends on application, but should be called anytime you think the state has changed.
void NUIExample_Update(object oPlayer, int nToken = -1);
// This handles events.
// This should be called from OnNuiEvent
// https://nwnlexicon.com/index.php?title=OnNuiEvent
/* Example:
#include "nui_example"
void main()
{
object oPlayer = NuiGetEventPlayer();
int nToken = NuiGetEventWindow();
string sEvent = NuiGetEventType();
string sElement = NuiGetEventElement();
int nIndex = NuiGetEventArrayIndex();
string sWindowId = NuiGetWindowId(oPlayer, nToken);
if (sWindowId == NUIEXAMPLE_WINDOW_ID)
{
NUIExample_Events();
return;
}
}
*/
void NUIExample_Events();
// Helper function for debugging.
// Log it however you want.
void LogMessage(string sMessage)
{
// WriteTimestampedLogEntry(sMessage);
SendMessageToPC(GetFirstPC(), sMessage);
}
void NUIExample_Events()
{
// Get all our inputs.
object oPlayer = NuiGetEventPlayer();
int nToken = NuiGetEventWindow();
string sEvent = NuiGetEventType();
string sElement = NuiGetEventElement();
int nIndex = NuiGetEventArrayIndex();
string sWindowId = NuiGetWindowId(oPlayer, nToken);
// Not our window!
if (sWindowId != NUIEXAMPLE_WINDOW_ID)
{
LogMessage("NUIExample_Events called for wrong window, expecting: " + NUIEXAMPLE_WINDOW_ID + " but got: " + sWindowId);
return;
}
// If events aren't working, log what is going on.
// If you don't see a bunch of stuff, then likly it's not being called from OnNuiEvent correctly.
// LogMessage("NUIExample: sElement: " + sElement + " sEvent: " + sEvent);
// Here is all our events, we need to sort out what to do, depending on Event and Element.
switch (HashString(sEvent))
{
case ("blur"):
{
}
break;
case ("click"):
{
}
break;
case ("close"):
{
}
break;
case ("focus"):
{
}
break;
case ("mousedown"):
{
}
break;
case ("mousescroll"):
{
}
break;
case ("mouseup"):
{
// Yikes, switch inside a switch.
// But this filters Event mouseup by Element with these Ids (in this case, buttons mostly)
// Ie, when a user is done clicking a button, process what to do for that button type.
switch (HashString(sElement))
{
case ("buttonUpdate"):
{
// They want to call an update.
NUIExample_Update(oPlayer, nToken);
return;
}
break;
case ("buttonCancel"):
{
// They want to close a window.
NuiDestroy(oPlayer, nToken);
return;
}
break;
}
}
break;
case ("open"):
{
}
break;
case ("range"):
{
}
break;
case ("watch"):
{
}
break;
default:
{
LogMessage("NUIExample: Unknown event occured: " + sEvent + " Element: " + sElement);
}
break;
}
}
void NUIExample_Update(object oPlayer, int nToken = -1)
{
// If caller doesn't have our token, be nice and look it up for them.
if (nToken == -1)
{
nToken = NuiFindWindow(oPlayer, NUIEXAMPLE_WINDOW_ID);
}
// Window isn't open, so let's not spend time processing updates.
if (nToken == 0)
{
return;
}
// This is our only update for now.
// For Nui Id "labelMain" it will update it's value with a random number between 1 and 100.
NuiSetBind(oPlayer, nToken, "labelMain", JsonString(IntToString(Random(100) + 1)));
}
void NUIExample_NewWindow(object oPlayer)
{
// This checks if window is already open. If so, we want to close it and create a new one.
// You CAN have multiple windows of same time, but most use cases if you just want one instance?
int nToken = NuiFindWindow(oPlayer, NUIEXAMPLE_WINDOW_ID);
if (nToken != 0)
{
NuiDestroy(oPlayer, nToken);
}
/////////////////////////////////////////
// Build the main root pane here
/////////////////////////////////////////
// This is going to be our entire window that is passed into NuiWindow.
json jRoot = JsonArray();
json jRow;
// Build the first row
{
// Create an array to hold our first row.
jRow = JsonArray();
// Create a label, notice it uses bind "labelMain", instead of static value.
json jLabelMain = NuiLabel(NuiBind("labelMain"), JsonInt(NUI_HALIGN_CENTER), JsonInt(NUI_VALIGN_MIDDLE));
// Add our label to the row
jRow = JsonArrayInsert(jRow, jLabelMain);
// Apply a Layout too it (you can't have widgets hanging about, outside of layout groups)
jRow = NuiRow(jRow);
// Finally we add our finalize row to our main root window.
jRoot = JsonArrayInsert(jRoot, jRow);
}
// Build the second row
{
// Same as before, start with a fresh array to hold our row data.
jRow = JsonArray();
// Make two buttons.
// Notice they have NuiId! If you want to capture events on widgets they MUST have an ID
json jButtonUpdate = NuiId(NuiButton(JsonString("Update")), "buttonUpdate");
json jButtonCancel = NuiId(NuiButton(JsonString("cancel")), "buttonCancel");
// Same as first row, but we goign to add a spacer, then both buttons.
jRow = JsonArrayInsert(jRow, NuiSpacer());
jRow = JsonArrayInsert(jRow, jButtonUpdate);
jRow = JsonArrayInsert(jRow, jButtonCancel);
// again, wrap all the widgets up in a nice group layout.
jRow = NuiRow(jRow);
// then add to main root
jRoot = JsonArrayInsert(jRoot, jRow);
}
///////////////////////////////////////////
// Build final group
///////////////////////////////////////////
// Again, needs a group layout, his is just one big column for window (with 2 rows inside it)
jRoot = NuiCol(jRoot);
/////////////////////////////////////////
// Create new window here
/////////////////////////////////////////
// Creates new window and gets token.
json jNuiWindow = NuiWindow(jRoot, NuiBind("windowtitle"), NuiBind("geometry"), NuiBind("resizable"), NuiBind("collapsed"), NuiBind("closable"), NuiBind("transparent"), NuiBind("border"), JsonBool(TRUE));
nToken = NuiCreate(oPlayer, jNuiWindow, NUIEXAMPLE_WINDOW_ID);
// Good example of how to use bings. "windowtitle" is just a place holder. We want to update it here.
NuiSetBind(oPlayer, nToken, "windowtitle", JsonString("NUI Example"));
// x, y, width, height.
// -1.0f, -1.0f, means to "center" the new NUI Window. Otherwise you can manually place it were you wish.
NuiSetBind(oPlayer, nToken, "geometry", NuiRect(-1.0f, -1.0f, 512.0f, 512.0f));
NuiSetBind(oPlayer, nToken, "collapsed", JsonBool(FALSE));
NuiSetBind(oPlayer, nToken, "resizable", JsonBool(TRUE));
NuiSetBind(oPlayer, nToken, "closable", JsonBool(TRUE));
NuiSetBind(oPlayer, nToken, "transparent", JsonBool(FALSE));
NuiSetBind(oPlayer, nToken, "border", JsonBool(TRUE));
// Refesh the data after window is made.
NUIExample_Update(oPlayer);
}