tonegodGUI Documentation (Pre-Alpha Release)

Holy balls of shit … I got this to show up in the plugins list >.<

I want to be clear about the existing issues, as well as potential changes that could effect your use of certain controls.

NOTE: I have not added default event consumption as of yet… this is for people to play around with and give feedback on general usability, things they would like to see changed, etc… so, you have been warned =) - This is no longer an issue. Default event consumption should be in place and working correctly.

NOTE: Also wanted to mention that when you are creating controls and placing objects, the Y coord is flipped for you so you don’t have to think upside-down. On the other hand, when manipulating objects remember that the Y coord is flipped on you. A for-instance where you might do this: Showing a menu from a button… if you would like it to show below the button as expected, you would use:

[java]
float y = button.getAbsoluteY()-menu.getHeight()
[/java]

to place it correctly. Cases where you actually need to do this for yourself are rare, but worth the mention!

First, changes that WILL effect usage:

Dial control

Style are NOT implemented on this control and therefore will be subject to change that could effect usage.
Free-float ranges (i.e. percents for non-stepped dials) are NOT being forwarded to the the onChange event.

ChatBox

I’ve disabled the call back for development purposes which, in essence, makes this control non-functional until the next release (which will be very soon… couple days at most) - I had time to fix this due to build fail.
I just want to reserve the right to update this control as needed. The version that is being released in the simple (all text) version

Styles

If you apply your own theme and make a local copy of Common.xml document, there is a chance that new tags will added and will require you to copy/edit any these to your local copy. The two that I am fairly sure are going to happen soon would be the addition of Dropdown Highlight Color and Tab Focus Color. I can see this being updated past this at some point, however… nothing in the foreseeable future past these two.

There are few other controls that are not implementing their own styles yet, but leveraging the super classes instead. This will eventually change.

Now, the changes that will NOT effect usage (outstanding issues):

TextField

The visuals for displaying text ranges does not update properly when you select a range that is larger than the display area of the text field.
The Paste function has been disabled for the time being.

Button

Default keyboard usage is not working properly at the moment. The effect varies depending on the type of button (i.e. standard buttons seems to work properly, however toggled buttons including checkboxes do not untoggle properly.

Sliders

Because the sliders thumb can reside within or overhang the track, the eval of percent for free-floating values are not being set by the correct element making it difficult to quickly select value 0 or value 100 while dragging the thumb if the Slider is set to trackContainsThumb when creating the control.

Tab Focus

Controls outside of a form are not losing focus properly when a form element is selected.
Controls with tab focus are not losing focus when you click into the scene (outside the GUI).

Other non-issue related items:

Some new methods have been added to different control and I’ll be updating the documentation here as I can.

You’ll notice a few controls with nothing in the source… these have been held back for dev purposes. They are:

RadioButtonGroup
ColorWheel
LoadScreen - which I don’t think I have started yet, though, the a placeholder may exist.
Ummm… that’s all I can think of off the top of my head.

8 Likes

Quick Start Guide:

For anyone who just wants to jump right in and read as you go, here are the basics for getting a UI up and running in minutes.

The first step is to create the screen control. This can be done one of two ways.

  1. Using the provided default style information:

[java]
// this = any JME Application
Screen screen = new Screen(this);
screen.initialize();
guiNode.addControl(screen);
[/java]

  1. Providing a path to another Style map.

[java]
// this = any JME Application
Screen screen = new Screen(this, “tonegod/gui/style/def/style_map.xml”);
screen.initialize();
guiNode.addControl(screen);
[/java]

NOTE
style_map.xml consists of a list of xml documents containing varied styles for varied use. You can copy the default style map and replace one, many, all with project specific style (Covered later in this tutorial).

Next, we add a control. Might as well start with something interesting as all control contructors follow the same format. Let go with a window and then we’ll add a button to it.

Here are the three contrustor choices for creating the window:

[java]
/** Parameters:

  • Screen screen,
  • String UID,
  • Vector2f position
    */

Window win = new Window(screen, “win”, new Vector2f(15, 15));
screen.addElement(win);
[/java]

And… boom! You have a fancy new resizable, movable window as part of you’re UI. Now, let’s take a look at the two additional constructors.

The second adds a 4th parameter to specify the windows dimensions, like such:

[java]
/** Additional Parameter:

  • Vector2f dimensions */

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

The third option adds 2 more parameters and looks like this:

[java]
/** Additional Parameters:

  • Vector4f resizeBorders,
  • String defaultImg
    */

Window win = new Window(screen, “win”, new Vector2f(15, 15), new Vector2f(400, 300),
new Vector4f(14,14,14,14),
“tonegod/gui/style/def/Window/panel_x.png”
);
screen.addElement(win);
[/java]

Any parameters not specified are derived from the defaults specified in the Window style information.

NOTE:
The occasional control extends this contructor format, adding an additional Orientation parameter or possibly a boolean flag for controls that provide multiple configurable layouts.

So, now lets add a button to the window that will create more windows! The Button class is one of the only GUI control classes that implements

JME’s Control interface. The Control only becomes active if setInterval is called because the Button requires the use of stillPressed events.

This and much more will be cover in later documentation.

Again, you ave the three options above for creating an instance of the button control.

NOTE:
The button control (like many controls) is abstract and provides methods for handling user input.
All events can be consumed by using evt.setConsumed();

First, lets setup a method to create new windows:

[java]
private int winCount = 0;

public final void createNewWindow(String someWindowTitle) {
Window nWin = new Window(
screen,
“Window” + winCount,
new Vector2f( (screen.getWidth()/2)-175, (screen.getHeight()/2)-100 )
);
nWin.setWindowTitle(someWindowTitle);
screen.addElement(nWin);
winCount++;
}
[/java]

Now lets add the button to allow users to create new window:

[java]
/** Parameters:

  • Screen screen,
  • String UID,
  • Vector2f position
    */

ButtonAdapter makeWindow = new ButtonAdapter( screen, “Btn1”, new Vector2f(15, 55) ) {
@Override
public void onButtonMouseLeftUp(MouseButtonEvent evt, boolean toggled) {
createNewWindow("New Window " + winCount);
}
};

// Add it to out initial window
win.addChild(makeWindow);
[/java]

NOTE:
For layout purposes, it is suggested that you add all child Elements toa control PRIOR to adding the control to the screen… so, ceate a window, add a button, add window to screen.

A Bit More Info:
All controls are based on the Element class which has access to all default behaviors.
Behaviors can be enabled disabled on ANY control or primitive Element.

A Few of the Common Behaviors:

[java]
setIsResizable(boolean); // Makes control resizable from defined borders
setIsMovable(boolean); // Makes the control movable
setLockToParentBounds(boolean); // Constrained to parent dimensions
setEffectParent(boolean); // On interaction effects direct parent instead of self
setEffectAbsoluteParent(boolean); // On interaction effects absolute parent (screen lvl) instead of self
setScaleNS(boolean); // allows the control to scale north/south from any encapsulating parent resize
setScaleEW(boolean); // allows the control to scale east/west from any encapsulating parent resize
setDockN(boolean); // also enables/disables dock south
setDockS(boolean); // also enables/disables dock north
setDockE(boolean); // also enables/disables dock west
setDockW(boolean); // also enables/disables dock east
setIgnoreMouse(boolean);
[/java]

NOTE:
There are far more behaviors, however, these are the most critical when creating custom controls to ensure that nested Elements react as you would like when a parent Element is altered.

6 Likes

Quick Start Guide example in full:

[java]
public int winCount = 0;
private Screen screen;

public final void createNewWindow(String someWindowTitle) {
Window nWin = new Window(
screen,
“Window” + winCount,
new Vector2f( (screen.getWidth()/2)-175, (screen.getHeight()/2)-100 )
);
nWin.setWindowTitle(someWindowTitle);
screen.addElement(nWin);
winCount++;
}

public void simpleInitApp() {
screen = new Screen(this, “tonegod/gui/style/def/style_map.xml”);
screen.initialize();
guiNode.addControl(screen);

// Add window
Window win = new Window(screen, “win”, new Vector2f(15, 15));

// create button and add to window
ButtonAdapter makeWindow = new ButtonAdapter( screen, “Btn1″, new Vector2f(15, 55) ) {
    @Override
    public void onButtonMouseLeftUp(MouseButtonEvent evt, boolean toggled) {
        createNewWindow(“New Window ” + winCount);
    }
};

// Add it to out initial window
win.addChild(makeWindow);

// Add window to the screen

screen.addElement(win);
}
[/java]

3 Likes

The Element Class

All controls are extensions of the Element class and thus, provide common methods for handling common features.

Before getting to specific controls, I thought it might be a good idea to cover some of the common methods for changing basic properties… such as: text, etc.

The Element class only provides a single constructor using all 6 of the common parameters:

[java]
/**

  • Parameters:
  • Screen screen
  • String UID
  • Vector2f position
  • Vector2f dimensions
  • Vector4f resizeBorders
  • String defaultImgPath
    */
    Element el = new Element(
    screen,
    “SomeID”,
    new Vector2f(5,5),
    new Vector2f(100,100),
    new Vector4f(5,5,5,5),
    “someImgPath.png”
    );
    [/java]

Note: all setter provide getters

Text/Font related methods:

[java]
setFont(String font path)
setFontSize(float fontSize);
setFontColor(ColorRGBA fontColor);
setTextAlign(BitmapFont.Align textAlign);
setTextVAlign(BitmapFont.VAlign textVAlign);
setTextWrap(LineWrapMode textWrap);
setTextPosition(float x, float y);
setTextPadding(float textPadding);
setText(String text);
[/java]

Element positions/dimensions

[java]
setPosition(Vector2f position);
setPosition(float x, float y);
setX(float x);
setY(float y);
setDimensions(Vector2f dimensions);
setDimensions(float w, float h);
setWidth(float width);
setHeight(float height);
setMinDimensions(new Vector2f(float x, float y));
[/java]

Since position and dimensions are relative to the Element’s parent Element, there are additional getters provided for retrieving absolute X, Y, Width & Height (absolute positions start from screen coords 0, 0)

[java]
getAbsoluteX();
getAbsoluteY();
getAbsoluteWidth();
getAbsoluteHeight();
[/java]

There are additional methods that provide recursive updates to child Elements:

[java]
moveTo(float x, float y);
resize(float diffX, floar diffY, Element.Borders dir);
[/java]

Overridable hooks are provided for default behavoirs:

[java]
controlResizeHook();
controlMoveHook()
[/java]

Clipping will be discussed in detail in the Creating Custom Controls section

3 Likes

Button Class

Button’s have a default state, a hover state and a pressed state.
They implement the tonegodGUI MouseButtonListener & MouseFocusListener interfaces
They provide an optional stillPressed event
Can either consist of text label or icon
They can be set to Toggle mode.
They have default effects set for Hover, Pressed & LoseFocus
Buttons are an abstract class providing methods for handling user input

Again, the same three options for constructor are available (as show in the quick start guide.

Abstract Event Methods:
[java]
public void onButtonMouseLeftDown(MouseButtonEvent evt, boolean toggled) { }
public void onButtonMouseRightDown(MouseButtonEvent evt, boolean toggled) { }
public void onButtonMouseLeftUp(MouseButtonEvent evt, boolean toggled) { }
public void onButtonMouseRightUp(MouseButtonEvent evt, boolean toggled) { }
public void onButtonFocus(MouseMotionEvent evt) { }
public void onButtonLostFocus(MouseMotionEvent evt) { }
public void onButtonStillPressedInterval() { }
[/java]

Methods specific to the Button class
[java]
//Toggle info
setIsToggleButton(boolean isToggleButton); // Also provides a getter
getIsToggleButton();
getIsToggled();

// Additional state info
setButtonHoverInfo(String pathHoverImg, ColorRGBA hoverFontColor);
setButtonPressedInfo(String pathPressedImg, ColorRGBA pressedFontColor);
clearAltImages();

// Adding a button icon
setButtonIcon(float width, float height, String texturePath)

// Enabling/disabling invternal calls
setInterval(float intervalsPerSecond); // 0 deactivates
[/java]

A little info on using effects (This will be covered in more detail in Creating Custom Controls)

[java]
// firing off a default effect from within a control
Effect effect = getEffect(Effect.EffectEvent.Press);
if (effect != null) {
effect.setBlendImage(pressedImg);
screen.getEffectManager().applyEffect(effect);
}
[/java]

Note:
When not otherwise specified, use the primitive Element method for setting the text of a control. For instance, with the Button class, you simply call:

[java]
setText(String text);
[/java]

to set the button text.

Tips for using the Button class:

  1. Create a button
  2. Implement all abstract methods
  3. Write your code for the event handlers you wish to use
  4. Change the Button to a ButtonAdapter
  5. Remove all unused event handler methods
3 Likes

Label Class

Though there was no real need for providing a Label class, as the Element class is a label (as well as everything else), one is provided for two reasons:

  1. Provide the 3 common constructors
  2. Use of styles to allow for global settings for all text using the Label class.

NOTE:
Style information can be overridden by any instance by using the Text/Font setters provided by the Element class

CheckBox Class

CheckBox’s extend the Button class and enable the Toggle setting
They provide a default label (which is only added if the label text is set).
they provide the abstract method onChange for executing code when the CheckBox is altered by the user.

Again, the same three options for constructor are available (as show in the quick start guide.

Abstract Event Methods:
[java]
public void onChange(boolean isChecked);
[/java]

Methods specific to the CheckBox class
[java]
setCheckboxText(String text);
getIsChecked();
[/java]

2 Likes

The next few classes are classified as List controls. They provide methods for adding and removing list values and in the case of Sliders, Spinners & Dials become “notched” when more than 2 step values have been added.

Slider Class

The Slider class provides the same 3 common contrustors with the addition of two extra parameters.

  1. The orientation of the Slider
  2. A boolean flag telling the control whether or not the track should “surround” the thumb.

The additional parameter are appended to the existing parameter list for all 3 constructors, like so:

[java]
/**

  • Parameters:
  • Screen screen
  • String UID
  • Vector2f position
  • Slider.Orientation orientation
  • boolean trackSurroundsThumb
    */
    Slider slider1 = new Slider(
    screen,
    “SomeID”,
    new Vector2f(15, 15),
    Slider.Orientation.HORIZONTAL,
    true
    );
    [/java]

Abstract Event Methods:
[java]
public void onChange(int selectedIndex, String value);
[/java]

Methods specific to the Slider class:
[java]
// Adding/removing step values
addStepValue(String value);
removeStepValue(String value);

// Selected values
setSelectedIndex(int selectedIndex)
getSelectedIndex();
[/java]

2 Likes

Spinner Class

The Spinner class provides:

A display area for the current step value
An increment button
A Decrement button
It can be set to cycle (when it reaches heighest step value it cycles to index 0, and reversed for decrement.

The Spinner class provides the same 3 common contrustors with the addition of two extra parameters.

  1. The orientation of the Spinner
  2. A boolean flag enabling/disabling Spinner cycling.

The additional parameter are appended to the existing parameter list for all 3 constructors, like so:

[java]
/**

  • Parameters:
  • Screen screen
  • String UID
  • Vector2f position
  • Spinner.Orientation orientation
  • boolean cycle
    */
    Spinner spinner1 = new Spinner(
    screen,
    “SomeID”,
    new Vector2f(15, 15),
    Spinner.Orientation.HORIZONTAL,
    true
    );
    [/java]

Abstract Event Methods:
[java]
public void onChange(int selectedIndex, String value);
[/java]

Methods specific to the Spinner class:
[java]
// Quickly set interval info for both button
setInterval(float callsPerSecond);

// Adding removing list info
addStepValue(String value);
removeStepValue(String value);

// Quickly populate step values with integers/floats
setStepIntegerRange(int min, int max, int inc);
setStepFloatRange(float min, float max, float inc);

// Retrieval of current selected step
setSelectedIndex(int selectedIndex);
getSelectedIndex();
[/java]

2 Likes

Dial Class

The Dial class provides:

A rotating knob for selecting step values

The Dial class provides the standard 3 common contrustors

Abstract Event Methods:
[java]
public void onChange(int selectedIndex, String value);
[/java]

Methods specific to the Dial class:
[java]
// Adding removing list info
addStepValue(String value);
removeStepValue(String value);

// Retrieval of current selected step
getSelectedIndex();
[/java]

2 Likes

SelectBox & ComboBox

The combo box and select box works exactly like any other combo box or select box:

They both provides the standard 3 constructors
The only difference between the two is the SelectBox’s text field is disabled.
The SelectBox still allows for arrow key navigation and enter select, though other key input is disabled.

Usage is as follows:
[java]
ComboBox combo = new ComboBox(
screen,
“SomeID”,
new Vector2f(5,5)
);
combo.addListItem(“Some caption”, “Some value”);
combo.addListItem(“Some caption”, “Some value”);
combo.addListItem(“Some caption”, “Some value”);
combo.addListItem(“Some caption”, “Some value”);
combo.addListItem(“Some caption”, “Some value”);
combo.addListItem(“Some caption”, “Some value”);
combo.pack();
[/java]

Abstract Event Methods:
[java]
public void onChange(int selectedIndex, String value);
[/java]

Methods specific to the ComboBox
[java]
// Adding a drop-down list item
addListItem(String caption, String value);

// Call after list is complete
pack();

// Selected Index
setSelectedIndex(int selectedIndex);
getSelectedIndex();

// Overridable hook for keyboard input events
controlKeyPressHook(KeyInputEvent evt, String text);
[/java]

NOTE:
This control WILL be updated with a change that will effect use. The need to call pack() will eventually be dropped and the addition of instertListItem() and removeListItem() will be added to allow for dynamically updatable drop-down lists.

TextField Class

TextFields provide the standard 3 constructors.

Textfields are single line text input fields, that provide the following functionality:
Caret & Text Range
Mouse select
Keyboard nav using:

  • arrows (nav by letter)
  • SHIFT+arrows (text range by latter)
  • CTRL+arrows (nav by word)
  • SHIFT+CTRL+arrows (text range by word)
  • etc.
    Cut & Paste

This control is still a work in progress and will be updated as either time permits or issues arise.
There is a known issue with the Cut & Paste function as of right now.

Methods specific to the TextField class:
[java]
// Get & set the TextField text
getTextFieldText();
setTextFieldText(String s);

// Force the current caret position - used by arrow key nav
setCaretPositionByX(float x);

// Tab key focus
setTabFocus();
resetTabFocus();

// Overridable hook for keyboard input
controlKeyPressHook(KeyInputEvent evt, String text);
[/java]

Note: Tab focus is a state of the screen class and is not implemented on either the screen level, or control level. I’ll be adding a form class for managing complete lists of related controls, as well as the addition of enforcing input criteria.

Password Class

The password class extends TextField and adds the ability to set a mask character.

Password specific methods:
[java]
setMask(char mask);
getMask(); // Returns mask character as a String
[/java]

Menu Class

The Menu class extends ScrollArea as Menu’s can be resizable and scrollable if the behaviors are enabled.

Menu’s contain a list of MenuItems, which provide mapping for sub-menus. This implementation of menu’s negates the need for any form of Menu Manager as the Screen, by default, handles delegating Mouse Events and therefore is (in a sense) a Menu Manager. Menus utilize a single text element with separate highlight element, to keep the rendered meshes to count of 3 for any length menu.

Features:
Unlimited menu item list
Unlimited sub-menu mapping
MenuItem toggle states (semi-work-in-progress here)

Menu utilizes the standard 3 constructors with the addition of a single boolean:
isScrollable - appended to the end of the parameter list in each constructor

Sample usage:
[java]
Menu subMenu = new Menu(
screen,
“SomeID”
new Vector2f(0,0),
false
);
subMenu.addMenuItem(“Some string caption”, “Some string value” null);
subMenu.addMenuItem(“Some string caption”, “Some string value” null);
subMenu.addMenuItem(“Some string caption”, “Some string value” null);
subMenu.pack();

screen.addElement(subMenu);

Menu menu = new Menu(
screen,
“SomeOtherID”
new Vector2f(0,0),
false
);
menu.addMenuItem(“Some caption”, “Some value”, subMenu); // adds first menu as a submenu to this menu item
menu.pack();

screen.addElement(menu);
[/java]

Abstract Event Methods:
[java]
public void onMenuItemClicked(int index, String value);
[/java]

Methods specific to the Menu Class:
[java]
// Mneu manipulation
addMenuItem(String caption, String value, Menu subMenu); // null if no sub-menu
insertMenuItem(int index, String caption, String value, Menu subMenu); // null if no sub-menu
removeMenuItem(int index);
pack();

// Configuration related methods
setMenuOverhang(float menuOverhang);
getMenuOverhang();
getMenuItemHeight();
getMenuPadding();

//Menu item related methods
getMenuItems(); // point to menu item list
getMenuItem(int index);

// Hide/show methods
showMenu(Menu caller, float x, float y); // Caller is null if not show by another menu
hideMenu();

// Overridable hook method for hide event
controlHideHook();
[/java]

ScrollArea class

Utilizes the standard 3 constructors + the addition of a single boolean:
isTextOnly - appended to the end of the param list for each constructor

Note:
The scrollArea implement Vertical Scrolling only. Why? Because I was lazy. Eventually I will add Horizontal scrolling as well.

ScrollArea s can be implemented in two ways: Text Only, or an inner element that can contain nested Elements.

The text only version uses the Element setText() method for adding to the scrollable content.
The inner Element method uses addScrollableChild() as well as setText() to add scrollable content

When using a scroll area for building Custom Controls, consider the potential uses of the ScrollArea to alleviate unnecessary overhead. If the text only version will suffice… USE IT! No reason to create the extra Element if it will not be used.

Methods specific to the ScrollArea class:
[java]
// Config methods
getIsTextOnly();
setPadding(float padding);
getPadding();
getScrollableHeight();

// Pointer to VScrollBar
getVScrollBar();

//Scrolling methods
scrollYTo(float y);
scrollYBy(float yInc);
scrollToTop();
scrollToBottom();
[/java]

RadioButtonGroup

Will add this on first update as it needs a once over for styles implementation. For initial release, I’ll be replacing the existing with a blank placeholder class. You can expect this soon after initial release.

Panel

The Panel class extends Element and, like the Label class, it’s only purpose is to provide:

The 3 standard constructors
Default style information

To produce a resizable, movable panel (window) without a dragbar. Instead, the entire window is clickable for moving unless otherwise covered by added child Elements that have not called setIgnoreMouse(true).

Window Class

The window class provides a movable, resizable window with a Drag Bar.

It provides the 3 standard contructors

NOTE:
Once again, default behaviors, such as moving, and resizing can be disabled calling the appropriate setters from the Element class.

Methods specific to the Window Class:
[java]
getDragBar(); // returns a pointer to the dragbar Element
getDragBarHeight(); // returns the height of the dragbar
setWindowTitle(String title); // Sets the title displayed in the dragbar
[/java]

AlertBox Class

The AlertBox class extends Window, adding a scroll area for displaying messages, as well as a configurable button for closing the AlertBox.

It utilizes the 3 standard constructors

Abstract Event Methods:
[java]
public void onButtonOkPressed(MouseButtonEvent evt, boolean toggled)
[/java]

AlertBox specific methods:
[java]
setMsg(String text); // Set the alert message
setButtonOkText(String text); // Sets the text for the ok button of the AlertBox
[/java]

DialogBox Class

The DialogBox extends AlertBox adding a Cancel button with event handlers.

It utilizes the 3 standard constructors

Abstract Event Methods:
[java]
public void onButtonOkPressed(MouseButtonEvent evt, boolean toggled)
public void onButtonCencelPressed(MouseButtonEvent evt, boolean toggled)
[/java]

Methods specific to the DialogBox class:
[java]
setButtonCancelText(String text);
[/java]