I realized "simple" GUI library for GameGuru. Tested on 1.01.0033.
Source code available at :
https://github.com/alex4321/GameGuruUi .
Binary libraries link
v0.1 :
https://www.dropbox.com/s/l1rnienvky18xd2/gameguruui-0.1.zip?dl=0
older:
https://www.dropbox.com/s/sjvw5ra55rberhc/gameguruui.zip?dl=0
For installation you need to unpack all these libraries to GameGuru folder (e.g. C:\Program Files (x86)\Steam\steamapps\common\Game Guru) and require it from global.lua be next code :
UI based on "layers" (can be non-modal - e.g. for HUD, but in this case all input getted by game, not UI) and "modal" - can be used for input (e.g. dialogs).
Each layer contains one or more "blocks", that described by html files.
Next is examples (maybe later I'll create full demo project).
Non-modal layer (to show health)
E.g. , you have next LUA code :
hud = 0
function hud_init(e)
hud = fpscUiCreateLayer("main", {
["health"] = 0,
["healthMax"] = 100
})
fpscUiShowLayer(hud)
HideHuds() -- hide basic hud
end
function hud_main(e)
fpscUiSetVariable(hud, "health", g_PlayerHealth)
end
"Line-by-line" description :
hud = fpscUiCreateLayer("main", {
["health"] = 0,
["healthMax"] = 100
})
- it's load all blocks from "Files/uilayerbank/main/*.html" files, and pass health and healthMax variables.
fpscUiSetVariable(hud, "health", g_PlayerHealth)
informs our layer (and - this blocks) set new value to "health"
Let's see, how we can build block.
E.g. we have next Files/uilayerbank/main/healthbar.html
<!DOCTYPE html>
<html>
<head>
<style type="text/css">
body{ margin: 0px; padding: 0px; background: #000; }
#healthbar { background: #3eff3e; }
</style>
<script src="healthbar.js"></script>
</head>
<body
data-x="0" data-y="0"
data-alignment-x="left" data-alignment-y="top"
data-width="250" data-height="40"
data-cutby="healthbar.png">
<div id="healthbar"> </div>
</body>
</html>
About body attributes:
- data-x, data-y - coords in pixels
- data-x-alignment - can be 'left', 'right', 'center'
- data-y-alignment - can be 'top', 'bottom', 'center'
So it's placed at top left corner.
- data-width, data-height - size in pixels
- data-cutby - path to widget region form mask. Basically, it'll be rectangle, but we can use image with alpha-channel to make non-standart form. In this example image must be in Files/uilayerbank/main/healthbar.png
And, finally - about JS.
You must implement next functions at all blocks:
- function filledBindings();
- function updateBinding(variableName);
You can get variable value by 'variables.get(variableName)', and set by 'variables.set(variableName, value)'
E.g.
healthbar.js
function updateHealth()
{
var health = parseInt(variables.get('health'));
var healthMax = parseInt(variables.get('healthMax'));
var healthPercent = 100 * health / healthMax;
document.getElementById('healthbar').style.width = healthPercent.toString() + '%';
}
function filledBindings()
{
updateHealth();
}
function updateBinding(variableName)
{
if(variableName=='health' || variableName=='healthMax')
{
updateHealth();
}
}
When block initializing - filledBindings function called.
When variabled updated by LUA, or from other block - updateBinding called.
In this example - both functions call updateHealth, that get 2 variable values.
Modal layers
In most - it's seems to non-modal layers. But in this mode you can get input.
E.g. we have next Lua code:
dialogUsed = false
function dialog_main(e)
if dialogUsed==false then
if (GetPlayerDistance(e) < 150) and (g_KeyPressE==1) then
dialogUsed = true
dialogLayer = fpscUiCreateLayer("dialog", {})
fpscUiShowModalLayer(dialogLayer)
local answer = fpscUiGetVariable(dialogLayer, "dialogResult")
Prompt("You typed " .. answer)
fpscUiDestroyLayer(dialogLayer)
end
end
end
Line-by-line :
dialogLayer = fpscUiCreateLayer("dialog", {})
It'll load layer (same as non-modal)
fpscUiShowModalLayer(dialogLayer)
Show layer and wait for exit from it (block mut set modalOpened variable to 0).
local answer = fpscUiGetVariable(dialogLayer, "dialogResult")
Get "dialogResult" variable value, and save it to local answer variable.
And we have next HTML :
<!DOCTYPE html>
<html>
<head>
<script>
function filledBindings()
{
}
function updateBinding(variableName)
{
}
window.onload = function()
{
document.getElementById('yes').onclick = function()
{
variables.set('dialogResult', 'yes');
variables.set('modalOpened', 0);
}
document.getElementById('no').onclick = function()
{
variables.set('dialogResult', 'no');
variables.set('modalOpened', 0);
}
}
</script>
</head>
<body data-x="0" data-y="0" data-width="372" data-height="422" data-alignment-x="center" data-alignment-y="center" data-cutby="background.png">
<div id="text">
Something wrong?
</div>
<button id="yes">YES</button>
<button id="no">NO</button>
</body>
</html>
As you can see - button "onclick" functions set two variables:
- dialogResult - used in out LUA code
- modalOpened - setting it to 0 will close modal layer.
Modal layer cursor changing
Now I implemented setting new cursor pointer for modal layers.
If you would use it - add "config.ini" with cursor parametrs in layerpath (e.g. "Files/uilayerbank/dialog/config.ini" for "dialog" layer at top example)
Parameters must be some lke next :
[Layer]
cursor=cursor.png
where "cursor" is path (relative to layer path). In this example - it'll be "Files\uilayerbank\dialog\cursor.png"