tonegodGUI Documentation (Pre-Alpha Release)

@zarch said: Yeah, ButtonListener interface, ability to add listeners to the button - then empty ButtonAdaptor class that implements all the methods in the interface doing nothing.

Gives everyone best of all worlds :slight_smile:

Ooops… missed the adapter comment. Much better way of handling this. For now, I simply removed the abstract methods and updated the documentation with the override-able event methods since it was an easy update. Once I have default event consumption in place, I’ll revisit this and implement it that way.

Sadly enough, it was the button class alone that was the issue. Most controls have a simple onChange event.

@zarch Thanks so much for this! As soon as I posted the response above, it hit me how stupid it would be to not just implement a simple adapter right away >.<

Done… now all classes with still push their event methods and you can bypass the button spam. You soooo smaaaaart :wink:

I can’t really take credit in this case it’s how Swing handles it :smiley:

In the first few posts you use

[java]@Override
public void onMouseLeftUp(MouseButtonEvent evt, boolean toggled) {
createNewWindow(“New Window ” + winCount);
}[/java]

But it should be:

[java]public void onButtonMouseLeftUp(…);[/java]

@madjack said: In the first few posts you use

[java]@Override
public void onMouseLeftUp(MouseButtonEvent evt, boolean toggled) {
createNewWindow(“New Window ” + winCount);
}[/java]

But it should be:

[java]public void onButtonMouseLeftUp(…);[/java]

Forgot to update this… thanks!

@madjack

Just an FYI, the custom cursor support & OSRViewPort are in tonight’s update.

screen.setUseCustomCursors(true); will error out in the current, as I didn’t put the actual cursors in. >.<

Little more info for anyone using this atm.

Default event consumption is in tonight’s patch.

I’m just summing up controls default state and ensuring there is a way to set values… like such:

ComboBox, SelectBox, Slider & Spinner defaults to index 0 and display appropriately.
You can also call setSelectedIndex(int index) to change this via code at any time and the control will update it’s display appropriately…
Menu’s will be hidden by default, etc, etc.

Will finish up button states for CheckBox & Button/Toggle Button and this should be available by tomorrow.

I’ll be updating the documentation tomorrow(ish) to reflect the changes over the past week.

1 Like

tonegod looks great for a plugin BUT i get the following exception when using the minimum setup code:

    Screen screen = new Screen(this);
    screen.initialize();
    Vector2f v = new Vector2f(15f, 15f);
    Window win = new Window(screen, "win", v,   new Vector2f(400, 300));
    screen.addElement(win);

java.lang.IllegalArgumentException: No enum constant com.jme3.font.LineWrapMode.Clip
at java.lang.Enum.valueOf(Enum.java:236)
at com.jme3.font.LineWrapMode.valueOf(LineWrapMode.java:7)
at tonegod.gui.controls.windows.Window.(Window.java:90)
at tonegod.gui.controls.windows.Window.(Window.java:50)

looks like tonegod is looking for com.jme3.font.LineWrapMode.Clip
which is not part of LineWrapMode.Character, LineWrapMode.NoWrap or LineWrapMode.Word

i update to weekly to the JMonkey Stable classes (not the daily updates). what am i missing?

@ejfuhr said: tonegod looks great for a plugin BUT i get the following exception when using the minimum setup code:
    Screen screen = new Screen(this);
    screen.initialize();
    Vector2f v = new Vector2f(15f, 15f);
    Window win = new Window(screen, "win", v,   new Vector2f(400, 300));
    screen.addElement(win);

java.lang.IllegalArgumentException: No enum constant com.jme3.font.LineWrapMode.Clip
at java.lang.Enum.valueOf(Enum.java:236)
at com.jme3.font.LineWrapMode.valueOf(LineWrapMode.java:7)
at tonegod.gui.controls.windows.Window.(Window.java:90)
at tonegod.gui.controls.windows.Window.(Window.java:50)

looks like tonegod is looking for com.jme3.font.LineWrapMode.Clip
which is not part of LineWrapMode.Character, LineWrapMode.NoWrap or LineWrapMode.Word

i update to weekly to the JMonkey Stable classes (not the daily updates). what am i missing?

Hey you!

One thing I noticed in the code you posted is you’re not adding the screen as a control to the guiNode.

I’m updating the documentation at the moment and may have failed to mention this in the Quick Start portion. though, you’ll want to add:

[java]
guiNode.addControl(screen);
[/java]

after initializing the screen. This is required for certain controls (Buttons using stillPressed events and the OSRViewPort will need this as well.)

Now… about the BitmapText issue. The enum itself is outside of my control directly, however I should be able to remove this and handle the clipping internal to the plugin. Before I update this, let me ask whoever is responsible for maintaining the BitmapText related part of JME.

@normen Sorry to bother you, but the above issue is JME related and outside my control. Do you know why com.jme3.font.LineWrapMode.Clip value would not be present for this person?

@ejfuhr No matter the outcome of the answer about com.jme3.font.LineWrapMode.Clip, I’ll remove all references to this as it is not needed and the update tonight will fix this issue for you.

Don’t know if it influe but it seems you forget the line “this.guiNode.addControl(screen);” before doing everything…reread the quickStart code ;).

[java]//gui
screen = new Screen(this, “Interface/myStyles.xml”);
screen.initialize();
this.guiNode.addControl(screen);[/java]

and then
[java]
Vector2f v = new Vector2f(15f, 15f);
Window win = new Window(screen, “win”, v, new Vector2f(400, 300));
screen.addElement(win);[/java]

EDIT: too late ;).

1 Like

This looks really cool. I’m going through your Quick Start tutorial now: https://wiki.jmonkeyengine.org/legacy/doku.php/jme3:contributions:tonegodgui:quickstart

A small issue I just noticed, maybe it’s already on your bug list:

As per the Quick Start tutorial, I’ve created a Screen, placed a Window, and then placed a Button on the Window. I’m toying around with the Button settings and used setScaleNS(true) and setScaleEW(true) to have the button scale as I moved the Window border. It worked fine when extending the Window to be larger than its original size (the button got larger). When I shrank the Window to be smaller than its original size, the button graphic shrank but then pretty quickly distorted. One half of the button went over the other half and proceeded to move out of the Window.

This can be reproduced by just running the code up through Step 3 in the Quick Start tutorial and adding enabling setScaleXX(true) for the button.

@bolo said: This looks really cool. I'm going through your Quick Start tutorial now: https://wiki.jmonkeyengine.org/legacy/doku.php/jme3:contributions:tonegodgui:quickstart

A small issue I just noticed, maybe it’s already on your bug list:

As per the Quick Start tutorial, I’ve created a Screen, placed a Window, and then placed a Button on the Window. I’m toying around with the Button settings and used setScaleNS(true) and setScaleEW(true) to have the button scale as I moved the Window border. It worked fine when extending the Window to be larger than its original size (the button got larger). When I shrank the Window to be smaller than its original size, the button graphic shrank but then pretty quickly distorted. One half of the button went over the other half and proceeded to move out of the Window.

This can be reproduced by just running the code up through Step 3 in the Quick Start tutorial and adding enabling setScaleXX(true) for the button.

Yes, sorry that this isn’t clarified anywhere. There is a default behavior for minimum size on resize and I have not set this default value in the xml styles in anything BUT the window class. This will be in place soon… just not quite yet. The behavior for resizing works… every object is aware of it, it’s just nothing has a default set yet =)

As for elements moving outside the windows bounds. you can call:

[java]
windowID.setControlClippingLayer(windowID);
[/java]

This will cascade the clipping bounds for all nested elements to the windows bounds.

EDIT: You can find more extensive and up-to-date documentation here:

Documentation

Wow, that was a fast response! No need to be sorry, I’m just playing around with things and seeing what happens–and I know this is still very much under development.

One other thing I noticed: I made the Button setIsMovable(true) and setlockToParentBounds(true). This lets me move the button but prevents it from going outside the parent Window. However, I can resize the parent Window in such a way that it’s pulled out from under the button and the button is left floating. I’d guess desired behavior would instead be to either (1) have the button disappear when the parent window edge is pulled over it, (2) have the button act as a barrier to resize that the parent window cannot shrink past, or (3) have the button move with the shrinking parent until some minimum window size is reached (in this case, where the parent window is just barely big enough to contain the button).

Let me know if you want me to keep reporting any odd behaviors–if you already know all this stuff and it’s on your ToDo list then I don’t want to clog up your thread :slight_smile:

@bolo said: Wow, that was a fast response! No need to be sorry, I'm just playing around with things and seeing what happens--and I know this is still very much under development.

One other thing I noticed: I made the Button setIsMovable(true) and setlockToParentBounds(true). This lets me move the button but prevents it from going outside the parent Window. However, I can resize the parent Window in such a way that it’s pulled out from under the button and the button is left floating. I’d guess desired behavior would instead be to either (1) have the button disappear when the parent window edge is pulled over it, (2) have the button act as a barrier to resize that the parent window cannot shrink past, or (3) have the button move with the shrinking parent until some minimum window size is reached (in this case, where the parent window is just barely big enough to contain the button).

Let me know if you want me to keep reporting any odd behaviors–if you already know all this stuff and it’s on your ToDo list then I don’t want to clog up your thread :slight_smile:

Please do!

to prevent anything being seen outside a windows bounds, use the

windowInstance.setControlClippingLayer(windowInstance);

method from the outter-most container. If you want to handle control clipping individually, you can set it on the button itself

setCliipingLayer(windowInstance);

For the time being… I think option 1 is the way to go (using the above). Once the standard controls are flea-less, I’ll revisit this… mostly because I am curious to see how difficult it would be to implement option 2. The barrier idea is neat =) Not to mention, all of these are valid possibilities and would be great to have as configuration options.

I may (for now), enforce clipping automatically to elements added to the screen level… since it can be changed/disabled at/before run-time.

Wow. With this GUI, it’s very quick and easy to create new stuff. I didn’t see anything about tabbed menus (a la Nifty: http://sourceforge.net/apps/mediawiki/nifty-gui/index.php?title=Standard_Controls_Tabs), so I constructed an example tabbed menu system using just a few buttons and panels:

[java]
Screen screen = new Screen(app);

	float height = screen.getHeight();
	float width = screen.getWidth();
	
	float pad = 15.0f;
	
	//Step 1:  Create overlapping, non-movable panels for each tab
	Panel graphicsPanel = new Panel(screen, "gPanel", new Vector2f(pad, height/2), new Vector2f(width-2*pad, height/2-pad));
	graphicsPanel.setIsMovable(false);
	graphicsPanel.setIsResizable(false);
	graphicsPanel.setText("This is the Graphics Panel!");
	graphicsPanel.setTextPadding(10.0f);
	
	Panel audioPanel = new Panel(screen, "aPanel", new Vector2f(pad, height/2), new Vector2f(width-2*pad, height/2-pad));
	audioPanel.setIsMovable(false);
	audioPanel.setIsResizable(false);
	audioPanel.setText("This is the Audio Panel!");
	audioPanel.setTextPadding(10.0f);
	
	Panel inputPanel = new Panel(screen, "iPanel", new Vector2f(pad, height/2), new Vector2f(width-2*pad, height/2-pad));
	inputPanel.setIsMovable(false);
	inputPanel.setIsResizable(false);
	inputPanel.setText("This is the Input Panel!");
	inputPanel.setTextPadding(10.0f);
	
	Panel miscPanel = new Panel(screen, "mPanel", new Vector2f(pad, height/2), new Vector2f(width-2*pad, height/2-pad));
	miscPanel.setIsMovable(false);
	miscPanel.setIsResizable(false);
	miscPanel.setText("This is the Miscellaneous Panel!");
	miscPanel.setTextPadding(10.0f);
	
	//Step 2:  Create separate panel above the tab panels, to host the navigation buttons
	Panel buttonPanel = new Panel(screen, "buttonPanel", new Vector2f(pad, height/2-2*pad), new Vector2f(width-2*pad, 2*pad));
	buttonPanel.setIsMovable(false);
	buttonPanel.setIsResizable(false);
	buttonPanel.setGlobalAlpha(0); //make the panel itself invisible, only showing buttons
	
	//Step 3:  Create buttons.  Left click hides/shows appropriate panels.
	ButtonAdapter graphicsButton = new ButtonAdapter(screen, "gButton", new Vector2f(0, 0)) {
		@Override
		public void onButtonMouseLeftDown(MouseButtonEvent event, boolean toggled) {
			screen.getElementById("aPanel").hide();
			screen.getElementById("iPanel").hide();
			screen.getElementById("mPanel").hide();
			screen.getElementById("gPanel").show();				
		}
	};
	graphicsButton.setText("Graphics");				
	
	ButtonAdapter audioButton = new ButtonAdapter(screen, "aButton", new Vector2f(100, 0)) {
		@Override
		public void onButtonMouseLeftDown(MouseButtonEvent event, boolean toggled) {
			screen.getElementById("aPanel").show();
			screen.getElementById("iPanel").hide();
			screen.getElementById("mPanel").hide();
			screen.getElementById("gPanel").hide();				
		}
	};
	audioButton.setText("Audio");				
	
	ButtonAdapter inputButton = new ButtonAdapter(screen, "iButton", new Vector2f(200, 0)) {
		@Override
		public void onButtonMouseLeftDown(MouseButtonEvent event, boolean toggled) {
			screen.getElementById("aPanel").hide();
			screen.getElementById("iPanel").show();
			screen.getElementById("mPanel").hide();
			screen.getElementById("gPanel").hide();				
		}
	};
	inputButton.setText("Input");				
	
	ButtonAdapter miscButton = new ButtonAdapter(screen, "mButton", new Vector2f(300, 0)) {
		@Override
		public void onButtonMouseLeftDown(MouseButtonEvent event, boolean toggled) {
			screen.getElementById("aPanel").hide();
			screen.getElementById("iPanel").hide();
			screen.getElementById("mPanel").show();
			screen.getElementById("gPanel").hide();				
		}
	};
	miscButton.setText("Misc");
	
	//Step 4:  Add buttons to the button panel, set initial panel hide/show stats, then add all panels to the screen	
	buttonPanel.addChild(graphicsButton);
	buttonPanel.addChild(audioButton);
	buttonPanel.addChild(inputButton);
	buttonPanel.addChild(miscButton);
	
	audioPanel.hide();
	inputPanel.hide();
	miscPanel.hide();
	graphicsPanel.show();
	
	screen.addElement(buttonPanel);
	screen.addElement(graphicsPanel);
	screen.addElement(audioPanel);
	screen.addElement(inputPanel);
	screen.addElement(miscPanel);
	
	screen.initialize();
	guiNode.addControl(screen);

[/java]

Edit: Quick view of it in action. Note this is not very fancy at this point!
[video]http://www.youtube.com/watch?v=0onCXmdqnsM&feature=youtu.be[/video]

3 Likes

Would’ve been nice to see what that looked like immediately though. :confused:

Ask and ye shall receive. Forgot that I had screen capture software :slight_smile:

I also needed tabs for my own chat implementation (multiple tabs, multiple filters) as chris didn’t seem very excited to integrate a tab element, I also implement mine … . a bit more generic that one above, however. Utilization is identical to all the other components of the library.

It includes a ZOrder for the content panel and a button system suitable for clinging to the tabs as shown above with the addition of a small system that hides tabs dynamically (when parent resizing event) which are out of compsant; Those will remain accessible via a small “more” button which list them.
For now it needs a little cleaning and its own style.xml (for easy customization) but I will share it with pleasure as soon as I finish. I’ll try to do a little video to illustrate pending.

Nice!