Skip to content

GUI API Home

thecodewarrior edited this page Jul 16, 2016 · 2 revisions

Gui Framework

Main Concepts

  • Components
  • Handlers
  • Options
  • Mixins
  • Templates

Handlers

Handlers are the event system of components, and in my opinion, one of the API's most powerful and difficult to fully utilize feature. Handlers allow you to run code when an event happens, much akin to Forge's event bus.

HandlerList

The HandlerList is one event for one component. They are typically initialized like so:
public final HandlerList<HandlerInterface> handlerName = new HandlerList<>()

To call the handler you can use one of three methods:

  • .fireAll(caller) which fires all of the handlers and doesn't require a return value from the caller - caller: (handler) -> void
  • .fire(caller) which fires all the handlers until the caller returns true (this is often just the return value from an interface with a boolean return value) and returns true if it was canceled in this way - caller: (handler) -> boolean
  • .fire(value, caller) which fires all the handlers and allows each to modify the value. The caller must return the modified value, this is often just a method in the handler interface that is returned by a lambda. - caller: (handler, T value) -> T

Here are some example caller implementations:

public final HandlerList<IClickEventHandler> click = new HandlerList<>();

// h is an IClickEventHandler
click.fireAll( (h) -> h.handle(/* params */) );
// IPreDrawEventHandler.handle(T component) returns true if the
// component shouldn't be drawn
public final HandlerList<IPreDrawEventHandler<T>> click = new HandlerList<>();

// h is an IPreDrawEventHandler<T>
// h.handle returns a boolean, the first time the lambda returns true
// (lambdas automatically return if they need to and are only one statement)
// the handling will stop and click.fire() will return true
// if none of the handlers return true, it will return false and
// the draw method won't return prematurely
if( click.fire( (h) -> h.handle(/* params */) ) )
    return;
// IModifyBobEvent.handle(String bob) returns a modified version of bob
public final HandlerList<IModifyBobEvent<String>> bob = new HandlerList<>();

String bobsName = "bob";

// h is an IModifyBobEvent<String>
bobsName = bob.fire( bobsName, (h, v) -> h.handle(/* params */));

Options

Options are values used by a component that can be either a fixed value or a lambda to produce a value. Options have an input type and an output type.

public final Option<MyComponentClass, List<String>> myopt =
        new Option<>(ImmutableList.of() /* default value */);

To set the value of an option you can either call .setValue(val) to set it to a static value, or use .func(lambda) to dynamically generate the value. In order to get the value you call .getValue(parameter) with whatever parameter class you specified. Most of the time the parameter should be your component.

// comp has a <MyComponentClass, List<String>> option called "bob"
comp.bob.setValue("bob's name is bob");
comp.bob.getValue(comp); // -> "bob's name is bob"

comp.bob.func( (c) -> "obj " + c );
comp.bob.getValue(comp); // -> "obj MyComponentClass@12345"

Mixins

Mixins are a name for anything that adds functionality through events. A mixin theoretically could be added to any component. Some mixins only make sense to be applied once, so the mixin should add a tag to the component and not apply itself if the component has that tag.

public class DragMixin {
    public static final String TAG = "mixinDrag";
    
    private boolean dragging = false;
    
    public DragMixin(GuiComponent component) {
        component.mouseDown.add( (c, pos, button) -> {
            if(c.mouseOverThisFrame) {
                dragging = true;
            }
        });
        component.mouseUp.add( (c, pos, button) -> {
            dragging = false;
        } );
        
        component.preDraw.add( (c, mousePos, partialTicks) -> {
            c.setPos(mousePos);
        } );
    }
}

Templates

Templates are methods that generate a component in a DRY style. Instead of having complicated code in multiple places, you put it in one resuable place.

Examples of templates: Basic text buttons, Sliders (Book GUI), Modules (Worktable GUI), etc.

Clone this wiki locally