Tonegod popup menu

I’ve decided I need to learn the tonegod GUI in addition to Nifty.

So I have this application. On the first update after LMB is pressed, I create a menu, add it to my screen, and show() it. The menu disappears as soon as I release the LMB, before I’ve had a chance to select an item.

What the correct way to keep the menu visible until an item is selected, or at least the next LMB press?

@sgold said: I've decided I need to learn the tonegod GUI in addition to Nifty.

So I have this application. On the first update after LMB is pressed, I create a menu, add it to my screen, and show() it. The menu disappears as soon as I release the LMB, before I’ve had a chance to select an item.

What the correct way to keep the menu visible until an item is selected, or at least the next LMB press?

Menu.showMenu would be the method for handling menu’s properly (there is a bit of juggling that goes on to avoid menu’s hiding otherwise)

I believe it takes 3 params:

parent element (which is usually null… internally this is used to show sub-menus properly)
x coord
y coord - remember this is flipped

Usually you set this from say… a button click… which would look like:

[java]
@Override
public void onButtonMouseLeftUp(MouseButtonEvent evt, boolean isToggled) {
menu.showMenu(null, getAbsoluteX(), getAbsoluteY()-menu.getHeight());
}
[/java]

1 Like

And just for the sake of writing it out:

Sub-menus just need to be added as a param of addMenuItem. If the submenu is not null, everything else is taken care of internally. Menu’s should be smart enough to position themselves to always be on the screen (though I may change how this works slightly), choosing the appropriate side of the menu to display on and repositioning itself if it overhangs the visual area.

And one final note:

I believe I updated how sub-menus appear for Android, using a touch event as apposed to mouse-over.

Ack… there is one final final note :wink:

By default, menu’s use a FadeIn effect. If you decide that this is not what you would like (as the effect is fairly expensive on Android), you can either use Menu.addEffect(EffectEvent evt, Effect effect) to replace them with what you do want. Or, you can remove them using menu.removeEffect(EffectEvent evt);

Thanks for your replies, Chris. And thanks, Paul, for moving this topic to the correct forum section.

I’m using showMenu(null, 0, 0) to display the menu, and it seems to be displayed properly. However, something is causing the menu to disappear as soon as I release the LMB; I don’t know what or why. I want to menu to remain visible until a selection is made, or (perhaps) until I click outside the menu.

I’m testing on Windows 7. There are no submenus yet.

I tried putting a breakpoints in Menu.hideMenu() and Menu.onMouseLeftReleased(), and neither one was hit.

I wonder if my issue might have to do with the fact that I show the menu on an update instead of when LMB is pressed/released. Does showMenu make any assumptions about the state of the LMB?

@sgold said: Thanks for your replies, Chris. And thanks, Paul, for moving this topic to the correct forum section.

I’m using showMenu(null, 0, 0) to display the menu, and it seems to be displayed properly. However, something is causing the menu to disappear as soon as I release the LMB; I don’t know what or why. I want to menu to remain visible until a selection is made, or (perhaps) until I click outside the menu.

I’m testing on Windows 7. There are no submenus yet.

I tried putting a breakpoints in Menu.hideMenu() and Menu.onMouseLeftReleased(), and neither one was hit.

I wonder if my issue might have to do with the fact that I show the menu on an update instead of when LMB is pressed/released. Does showMenu make any assumptions about the state of the LMB?

Let me post an example that should work and check it against what you are doing to see if there is a difference. Out of curiosity, do SelectBox and ComboBox drop-downs display ok? They use menu’s for there drop-down lists.

EDIT: And yes… likely this would be the case (the update issue you mentioned).

[java]
private ButtonAdapter showMenu;
private Menu menu1, menu2, menu;

private void initTest() {
	// Create button to display first menu
	showMenu = new ButtonAdapter(screen, new Vector2f(20,20), new Vector2f(100,25)) {
		@Override
		public void onButtonMouseLeftUp(MouseButtonEvent evt, boolean isToggled) {
			menu.showMenu(null, getAbsoluteX(), getAbsoluteY()-menu.getHeight());
		}
	};
	showMenu.setText("Show Menu");
	
	////////////////////////////
	// Create a random submenu
	////////////////////////////
	menu1 = new Menu(screen, "Menu1", new Vector2f(50, 50), new Vector2f(100, 25), false) {
		@Override
		public void onMenuItemClicked(int index, Object value, boolean isToggled) {
			
		}
	};
	menu1.addMenuItem("Create Color Selector", "0", null);
	menu1.addMenuItem("Create new Dialog Box", "1", null);
	menu1.addMenuItem("Create new Alert Box", "2", null);
	menu1.addMenuItem("Enable/Disable Tool Tips", "ToolTips", null, true);
	menu1.addMenuItem("Enable/Disable Audio", "Audio", null, true);
	menu1.addMenuItem("Enable/Disable Custom Cursors", "Cursors", null, true);
	menu1.addMenuItem("Enable/Disable Cursor Effects", "CursorEffects", null, true);
	menu1.getMenuItem(4).setIsToggled(true);
	menu1.getMenuItem(5).setIsToggled(true);
	// Remove default fade effect
	menu1.removeEffect(Effect.EffectEvent.Show);
	
	///////////////////////////////////
	// Create a second random submenu
	///////////////////////////////////
	menu2 = new Menu(screen, "Menu2", new Vector2f(50, 50), new Vector2f(100, 25), false) {
		@Override
		public void onMenuItemClicked(int index, Object value, boolean isToggled) {
			
		}
	};
	menu2.addMenuItem("Enable/Disable Chat Filter", "ChatFilter", null, true);
	menu2.addMenuItem("Enable/Disable Chat Send Button", "ChatSend", null, true);
	menu2.addMenuItem("This is one.", "3", null);
	// Add first menu as a submenu to this menuitem
	menu2.addMenuItem("This is menu item 16 and longer.", "1", menu1);
	menu2.getMenuItem(0).setIsToggled(true);
	// Remove default fade effect
	menu2.removeEffect(Effect.EffectEvent.Show);
	
	////////////////////////
	// Create primary menu
	////////////////////////
	menu = new Menu(screen, "Menu3", new Vector2f(50, 50), new Vector2f(100, 25), false) {
		@Override
		public void onMenuItemClicked(int index, Object value, boolean isToggled) {
			
		}
	};
	menu.addMenuItem("This is a menu.", "1", null);
	menu.addMenuItem("This is another.", "2", null);
	menu.addMenuItem("This is one.", "3", null);
	// Add second menu as a submenu to this menuitem
	menu.addMenuItem("And another.", "4", menu2);
	menu.addMenuItem("This is one", "5", null);
	// Add first menu as a submenu to this menuitem as well
	menu.addMenuItem("This is not.", "6", menu1);
	menu.addMenuItem("This is 3 more.", "7", null);
	menu.addMenuItem("And another.", "4", null);
	menu.addMenuItem("This is one", "5", null);
	menu.addMenuItem("This is not.", "6", null);
	menu.setIsResizable(true);
	menu.setResizeN(false);
	menu.setResizeW(false);
	menu.setResizeE(false);
	menu.setResizeS(true);
	// Remove default fade effect
	menu.removeEffect(Effect.EffectEvent.Show);
	
	screen.addElement(showMenu);
	screen.addElement(menu1);
	screen.addElement(menu2);
	screen.addElement(menu);
}

[/java]

Drop this into your test project and call the method after creating the screen. Let me know if this works ok for you and then we’ll narrow down what was different.

Oh! hey! I just caught that you are displaying the menu on the mouse down not up… this may be the issue. I honestly don’t think I have ever tried that.

1 Like

With some tweaking I got your example code to run. It looks fine. I haven’t tried SelectBox and ComboBox yet.

Here’s an example code that approximates what I’m trying to do. It also illustrates the issue pretty well:
[java]
package mygame;

import com.jme3.app.SimpleApplication;
import com.jme3.input.event.MouseButtonEvent;
import com.jme3.math.Vector2f;
import java.util.logging.Logger;
import tonegod.gui.controls.buttons.ButtonAdapter;
import tonegod.gui.controls.menuing.Menu;
import tonegod.gui.core.Screen;
import tonegod.gui.effects.Effect;

public class Main extends SimpleApplication {

final private static Logger logger = Logger.getLogger(Main.class.getName());
private ButtonAdapter showMenu;
private Menu menu;
private Screen screen;
private String savedAction = null;

public static void main(String[] args) {
    Main app = new Main();
    app.start();
}

@Override
public void simpleInitApp() {
    screen = new Screen(this);
    guiNode.addControl(screen);
    flyCam.setEnabled(false);

    initTest();
}

@Override
public void simpleUpdate(float tpf) {
    if (savedAction != null) {
        menu.showMenu(null, 0, 0);
        savedAction = null;
    }
}

private void initTest() {
    // Create button to display first menu
    showMenu = new ButtonAdapter(screen, new Vector2f(20, 20), new Vector2f(100, 25)) {
        @Override
        public void onButtonMouseLeftDown(MouseButtonEvent evt, boolean isToggled) {
            savedAction = "show menu";
        }
    };
    showMenu.setText("Show Menu");

    ////////////////////////
    // Create primary menu
    ////////////////////////
    menu = new Menu(screen, "Menu3", new Vector2f(50, 50), new Vector2f(100, 25), false) {
        @Override
        public void onMenuItemClicked(int index, Object value, boolean isToggled) {
        }
    };
    menu.addMenuItem("This is a menu.", "1", null);
    menu.addMenuItem("This is another.", "2", null);
    menu.addMenuItem("This is one.", "3", null);
    menu.setIsResizable(true);
    menu.setResizeN(false);
    menu.setResizeW(false);
    menu.setResizeE(false);
    menu.setResizeS(true);
    // Remove default fade effect
    menu.removeEffect(Effect.EffectEvent.Show);

    screen.addElement(showMenu);
    screen.addElement(menu);
}

}
[/java]

1 Like

Thanks for this! I’ll try playing around with it once the meds wear off from the surgery.

1 Like

You’re welcome, and I wish you a speedy recovery.

And by the way there’s no rush to address the issue–I’ve worked around it by replacing onButtonMouseLeftDown() with onButtonMouseLeftUp().

1 Like

so I’m having a similar issue. I took your example code, got rid of the “button” and tried to use just “menu.show();” The menu appears at first, but once I click on it, or the scene it’s gone.

I see how you keep adding it to a button, but why do we need to use a button? I want a menu item to be what I click, and then click submenu’s. It’s like we are clciking a button, then a menu, then more menus.

[java] gui.addControl(screen);

Menu subMenu = new Menu(screen, new Vector2f(0,0),false)
{
@Override
public void onMenuItemClicked(int index, Object value, boolean isToggled) { }
};
// Add a menu item
subMenu.addMenuItem(“Some string caption 1”, null, null);
// Add a toggle-able menu item (checkbox)
subMenu.addMenuItem(“Some string caption 2”, null, null, true);
// Add a toggle-able menu item and set the default state of the checkbox to checked
subMenu.addMenuItem(“Some string caption 3”, null, null, true, true);
screen.addElement(subMenu);

final Menu menu = new Menu(
screen,
new Vector2f(0,0),
false
) {
@Override
public void onMenuItemClicked(int index, Object value, boolean isToggled) { }
};
// Add subMenu as a sub-menu to this menu item
menu.addMenuItem(“Some caption”, null, subMenu);
screen.addElement(menu);

    menu.show();
    menu.setIsVisible(true);

[/java]

@KonradZuse said: so I'm having a similar issue. I took your example code, got rid of the "button" and tried to use just "menu.show();" The menu appears at first, but once I click on it, or the scene it's gone.

I see how you keep adding it to a button, but why do we need to use a button? I want a menu item to be what I click, and then click submenu’s. It’s like we are clciking a button, then a menu, then more menus.

[java] gui.addControl(screen);

Menu subMenu = new Menu(screen, new Vector2f(0,0),false)
{
@Override
public void onMenuItemClicked(int index, Object value, boolean isToggled) { }
};
// Add a menu item
subMenu.addMenuItem(“Some string caption 1”, null, null);
// Add a toggle-able menu item (checkbox)
subMenu.addMenuItem(“Some string caption 2”, null, null, true);
// Add a toggle-able menu item and set the default state of the checkbox to checked
subMenu.addMenuItem(“Some string caption 3”, null, null, true, true);
screen.addElement(subMenu);

final Menu menu = new Menu(
screen,
new Vector2f(0,0),
false
) {
@Override
public void onMenuItemClicked(int index, Object value, boolean isToggled) { }
};
// Add subMenu as a sub-menu to this menu item
menu.addMenuItem(“Some caption”, null, subMenu);
screen.addElement(menu);

    menu.show();
    menu.setIsVisible(true);

[/java]

You don’t have to use a button by any means. but you should show the menu using:

[java]
// parent is typically null
Menu.showMenu(Element parent, float coordX, float coordY);
[/java]

@t0neg0d said: You don't have to use a button by any means. but you should show the menu using:

[java]
// parent is typically null
Menu.showMenu(Element parent, float coordX, float coordY);
[/java]

The first thing I did was take the example above and did

[java] menu.showMenu(null, 100, 100-menu.getHeight());[/java]

and it didn’t work, sorry I forgot to mention that I did this as well.

Again I will click the menu, the sub menu will pop up and if I click outside of the menu, or on a menu item it will vanish from the screen.

Thanks T0neg0d! I hope you’re feeling better as well!

@KonradZuse said: The first thing I did was take the example above and did

[java] menu.showMenu(null, 100, 100-menu.getHeight());[/java]

and it didn’t work, sorry I forgot to mention that I did this as well.

Again I will click the menu, the sub menu will pop up and if I click outside of the menu, or on a menu item it will vanish from the screen.

Thanks T0neg0d! I hope you’re feeling better as well!

Are you showing the menu on mouse button down or button up?

EDIT: And thank you! I am not yet… but that will soon be resolved… finally!

Oh! I just caught how you are showing this… interesting. I actually never thought about showing a menu in this way before. I think at the moment, it has to be fired off from some event… keyboard, mouse, touch, etc to flag states properly to ensure the menu doesn’t just disappear.

@t0neg0d said: Oh! I just caught how you are showing this... interesting. I actually never thought about showing a menu in this way before. I *think* at the moment, it has to be fired off from some event... keyboard, mouse, touch, etc to flag states properly to ensure the menu doesn't just disappear.

Crap poo forum didn’t notify me of replies…

[java]
Menu subMenu = new Menu(screen, new Vector2f(0,0),false)
{
@Override
public void onMenuItemClicked(int index, Object value, boolean isToggled) { }
};
// Add a menu item
subMenu.addMenuItem(“Some string caption 1”, null, null);
// Add a toggle-able menu item (checkbox)
subMenu.addMenuItem(“Some string caption 2”, null, null, true);
// Add a toggle-able menu item and set the default state of the checkbox to checked
subMenu.addMenuItem(“Some string caption 3”, null, null, true, true);
screen.addElement(subMenu);

final Menu menu = new Menu(
screen,
new Vector2f(0,0),
false
) {
@Override
public void onMenuItemClicked(int index, Object value, boolean isToggled) { }
};
// Add subMenu as a sub-menu to this menu item
menu.addMenuItem(“Some caption”, null, subMenu);
screen.addElement(menu);

    menu.showMenu(null, 100, 100-menu.getHeight());

[/java]

yeah, I find it interesting we have to use the “onMenuItemClicked” for everything.

Technically nothing should happen at all with this code, but when you scroll over the menu, the secondary menu pops up. I realize now that I don’t need to click anything, but that doesn’t mean that my menu should poof out of nowhere?

Shouldn’t the top level menu be shown always unless we hide it ourselves? If we click a submenu, then the entire menu will collapse as it does now. The thing is, it’s thinking that the top level menu, is the same as the sub level, and everything is poofing.

Thus in your example, the button is considered the top level, it’s clicked, then you can go to the “menu item” and then it’s sub-menu.

@KonradZuse said: Crap poo forum didn't notify me of replies...

[java]
Menu subMenu = new Menu(screen, new Vector2f(0,0),false)
{
@Override
public void onMenuItemClicked(int index, Object value, boolean isToggled) { }
};
// Add a menu item
subMenu.addMenuItem(“Some string caption 1”, null, null);
// Add a toggle-able menu item (checkbox)
subMenu.addMenuItem(“Some string caption 2”, null, null, true);
// Add a toggle-able menu item and set the default state of the checkbox to checked
subMenu.addMenuItem(“Some string caption 3”, null, null, true, true);
screen.addElement(subMenu);

final Menu menu = new Menu(
screen,
new Vector2f(0,0),
false
) {
@Override
public void onMenuItemClicked(int index, Object value, boolean isToggled) { }
};
// Add subMenu as a sub-menu to this menu item
menu.addMenuItem(“Some caption”, null, subMenu);
screen.addElement(menu);

    menu.showMenu(null, 100, 100-menu.getHeight());

[/java]

yeah, I find it interesting we have to use the “onMenuItemClicked” for everything.

Technically nothing should happen at all with this code, but when you scroll over the menu, the secondary menu pops up. I realize now that I don’t need to click anything, but that doesn’t mean that my menu should poof out of nowhere?

Shouldn’t the top level menu be shown always unless we hide it ourselves? If we click a submenu, then the entire menu will collapse as it does now. The thing is, it’s thinking that the top level menu, is the same as the sub level, and everything is poofing.

Thus in your example, the button is considered the top level, it’s clicked, then you can go to the “menu item” and then it’s sub-menu.

Yeah… in my example (and the assumption I went off of when writing this was) a Menu Bar would be a different control (or some other clickable/right-clickable item… be it scene spatial or other ui component).

Since this is a very easy thing to put together, I never added a menu bar type control, as there are so many different configs the user could want.