PDA

View Full Version : Icons-Multistate re-creation.



unimatrixzero
May 16th, 2008, 20:53
Hi all.
I'm playing around with the use of 'icons' within FG2, in particular trying to recreate the 'multistate' function of FG1. At the moment i've just used the change icon script from the weaponslist windowclass, but this is currently limited to cycle between just 2 icons. Is anyone prepared to explain how this code needs to be adapted in order for me to have it cylce thru maybe 9 or 10 different icons?

The other things i would like to know that are possible:
1:can the changing/cycling of icons be disabled on the client/player side?
2:can a button be used/linked to cylce thru the icon as opposed to clicking on the icon itself?

3:On a kinda related issue, can the categoryselectioncontrol be used in different instances? That is, can i use 2 or 3 different sets of icons to cylce thru?

Hopefully someone will have an answer to at least one of these. Here's hoping! :)
Regards
Uni

Foen
May 17th, 2008, 06:30
Here's some code I've used for multistate controls.

control template:


add to common_templates.xml

<template name="multistate">
<genericcontrol>
<stateicons mergerule="resetandadd">
<state>indicator_checkon</state>
<state>indicator_checkoff</state>
</stateicons>
<script file="scripts/template_multistate.lua" />
</genericcontrol>
</template>


The script behind the template:



template_multistate.lua

-- The sourceless value is used if the multistate is used in a window not bound to the database
-- or if the <sourceless /> flag is specifically set

local sourcelessvalue = 0;
local enabled = true;

function setState(state)
if self.beforeStateChanged then
state = self.beforeStateChanged(state);
end
if state == nil or state == false then
state = 1;
end
if source then
source.setValue(state);
else
sourcelessvalue = state;
update();
end
end

function update()
if source then
setIcon(stateicons[1].state[source.getValue()]);
else
setIcon(stateicons[1].state[sourcelessvalue]);
end
if self.onStateChanged then
self.onStateChanged();
end
end

function getState()
if source then
return source.getValue();
else
return sourcelessvalue;
end
end

function onClickDown(button, x, y)
if enabled then
local newstate = getState() + 1;
if newstate > table.getn(stateicons[1].state) then
newstate = 1;
end
setState(newstate);
end
end

function onInit()
if super
and super.onInit then
super.onInit();
end
setIcon(stateicons[1].state[1]);

if not sourceless and window.getDatabaseNode() then
-- Get value from source node
if sourcename then
source = window.getDatabaseNode().createChild(sourcename[1], "number");
else
source = window.getDatabaseNode().createChild(getName(), "number");
end
if source then
source.onUpdate = update;
update();
end
-- Get static flag from database node
if window.getDatabaseNode().isStatic() then
enabled = false;
end
else
-- Use internal value, initialize to state if <state /> is specified
if state then
sourcelessvalue = state[1];
update();
end
end
-- allow <readonly/> to override the database node setting
if readonly then
enabled = false;
end
end

function setEnabled(state)
if not sourceless and window.getDatabaseNode() then
-- Get static flag from database node
if window.getDatabaseNode().isStatic() then
state = false;
end
end
enabled = state;
end


The control in use:


<multistate name='multi'>
<bounds>...</bounds>
<stateicons>
<state>myicon1</state>
<state>myicon2</state>
<state>myicon3</state>
</stateicons>
</multistate>


The behaviour can be disabled (preventing the current value from being changed) if a <readonly/> tag is included in the control. It can also be enabled/disabled in script by using its setEnabled(boolean) method.

The icons can be anything (it defaults to checkboxes if none are specified).

It exposes a getState() method which returns a number between 1 and n (the number of icons), a setState(n) method, a beforeStateChanged(state) event to allow the code to intercept and change the outcome of a click and an onStateChanged() event.

Hope that helps

Stuart

unimatrixzero
May 19th, 2008, 00:05
This is awesome!
I used the following to make it non-editable by players;

if not User.isHost() then
setEnabled(false);
end
this works a treat.
Although i am struggling to figure out what i need to change to simply get my first icon to show when i open the window. it only shows once i click the designated area. I would like it to default to myicon1 somehow.
Am i missing the obvious somewhere?

Regards
Uni

Foen
May 19th, 2008, 06:07
Glad to be of help.

The problem you have is caused by the fact that the control state value defaults to zero when an instance is first created, but the only legal values are 1 to 'n'. The way to trap this is in the onInit function:



change this:
if source then
source.onUpdate = update;
update();
end

to this:
if source then
if source.getValue()==0 then
source.setValue(1);
end
source.onUpdate = update;
update();
end


Cheers,

Stuart