Nifty GUI - Buttons & Focus Effects

From what I understand onFocus situation in Nifty (in buttons case) is used on last clicked button till I click another button. It can be understood as “currently active action” if I use my buttons to build stuff on screen. So for example if I have “Build Barracks” button onFocus it means I will build barracks with my mouse until I click for example “Build Stables” button.
Of course there must be also some logic stuff behind that but it’s not important for now (because I have logic done already).

What I need is:
a) For all buttons to be NOT onFocus at the start of the screen (currently top button in my sidebar is onFocus).
b) To DEFOCUS button after I click it for the second time.
c) For groups of buttons to share same “Focus situation” while others doesn’t. So obviously I can’t build Barracks and Stables at the same time but there should be no problem with having some kind of map overlay activated via button WHILE I am building stuff with build button.

DISCLAIMER: It doesn’t necessarily need to be done via onFocus effect. I just need any way to highlight my buttons using rules mentioned above. For example I tried creating onCustom effect and starting it when I want, but then effect doesn’t persist. It vanishes after about 1.5 second.

We implemented a skillbar which always has one skill active (default is move).
Sounds just like your toolbar.

We use OnCustom instead of OnHover, because our UI also has other buttons in it. (e.g. Menu/Options Button)
In the interact method, we call the following method to stop the OnCustom Effect and then activate the OnCustom Effect on the selected button.
Of course the controller has to have a reference to each button in a collection for this.

Your custom button just needs to have a OnCustom effect now. It can even have an additional OnHover, so players still see when they hover over an active button. I would keep an OnHover effect for Usability :wink:

private void setActiveSkillButton(int buttonNumber) {
    for (Element skillButton : skillButtons) {
        skillButton.stopEffect(EffectEventId.onCustom);
    }
    Element skillButton = skillButtons.get(buttonNumber - 1);
    skillButton.startEffect(EffectEventId.onCustom, new RepeatSkillSelectedEffect(skillButton), NiftyConstants.SELECTED_EFFECT_KEY);
}

By holding different collections of buttons, you also have your “button groups” where only one can be active at a time.

1 Like

For testing purposes I added exactly this line in my initialize method: MyButton.startEffect(EffectEventId.onCustom) and the problem is effect vanishes after about 1.5 second. I tried with colorBox effect, colorPulsate effect, border effect and every time it’s the same - it just doesn’t persist. I did create the effect with java though. Do I need to make it in XML and only activate from java?

You can try using ColorBar.

Small EDIT.
MyButton.startEffect(EffectEventId.onCustom) doesn’t work at all for me. Whenever I change this to “onHover” or anything else (both in XML and in start… method) it works fine. But when I have onCustom it doesn’t work at all.

As for “vanishing after 1.5 sec” I found this parameter neverStopRendering="true", which seems to work.

Anyway: could someone give me proper syntax for onCustom effect (both xml line and java line if needed). Just to start it. No smart method, just to start it in init so it works from there on.

An example how I implemented my onHover effect via Java. It doesn’t make any difference if I use onHover, onFocus or something else. onX → X stands for the certain event / stands for the specific time when the effect should be fired.

public HoverEffectBuilder createColorAction(String color) {

    hoverEffectBuilder = new HoverEffectBuilder("color-hover");
    controlEffectOnHoverAttributes = hoverEffectBuilder.getAttributes();
    controlEffectOnHoverAttributes.setName("colorBar");
    controlEffectOnHoverAttributes.setAttribute("color", color);
    controlEffectOnHoverAttributes.setPost("true");

    return hoverEffectBuilder;
}

via:

createButton.onHoverEffect(effectController.createColorAction("#FFFFFF"));

Of course, if you use the onCustom, you need to define when this event gets fired (as far as I know).

Here’s ours (a single pulse effect. We repeat it via an EventNotifier when calling startAnimation)

        <effect>
            <onCustom customKey="selected" name="pulsate" scaleFactor="0.008" endColor="#ffff"/>
        </effect>

OnCustom are triggered by using

element.startEffect(EffectEventId.onCustom, null, customKey);

customKey is the name of the OnCustom effect (if you have multiple)
the second parameter (here null) is the callback for when the effect has ended.

a) Great Thanks Zanval, it works now!

b) The only difference between Your code and mine is 3 argument Effect call instead of 1 argument Effect call (how are those different? shouldn’t 1 argument call fill other values to defaults like it does with for example onStartScreen and onHover?).

c) Am I the only one seeing the pulsate and colorPulsate effects as little “stuttering” near the beginning of the cycle? It’s like sttutter > smooth to the end > stutter > smooth to the end > stutter > etc.

d) Also multiple effects (different customKeys) being started one after the other seem to be overriding each other. When I hove border first and then pulsate, there is no border at all. Is there a 1 effect at a time limit?

a) glad to hear that :smile:

b) I suppose you could call it with just “EffectEventId.OnCustom”, but that will break as soon as you add a second OnCustom someday. Might be ugly to debug, so I prefer explicitly calling the intended OnCustom effect with its key. I have never tried calling an OnCustom without explicit customKey.

c) It looks smooth for me. Looks very smooth on my end. Heres my “Item-Slot” effect block

            <effect>
                <onActive name="border" post="true" color="#555f" border="2px"/>
                <onHover name="pulsate" scaleFactor="0.008" endColor="#fff5" overlay="true" post="true"/>
                <onHover name="border" post="true" color="999f" border="2px"/>
            </effect>

d) see my xml-block from c). Maybe the post=“true” will help you. We also show a border and have the itemslot pulsate. The onActive here is used for drag and drop purposes (it changes color when you are dragging an item out of it)