-
Notifications
You must be signed in to change notification settings - Fork 4
Tutorial: Custom Device UI
By default, all LX pattern and effect devices will have a generic UI constructed which provides knob controls and color pickers for all the relevant device parameters. However, you may wish to implement your own custom UI layout.
Any device class which implements the UIDeviceControls<>
interface will have a method invoked to construct the controls for this device in the bottom pane of the LX Studio UI. Reference the example below.
Many useful helper methods are available in the UIDeviceControls interface.
public class AppPatternWithUI extends LXPattern implements UIDeviceControls<AppPatternWithUI> {
public final DiscreteParameter number =
new DiscreteParameter("Number", 100)
.setDescription("A numeric parameter");
public final ObjectParameter<String> string =
new ObjectParameter<String>("String", new String[] { "One", "Two", "Three" })
.setDescription("A string parameter");
public final CompoundParameter knob =
new CompoundParameter("Knob", 0, 1)
.setDescription("A knob parameter");
public AppPatternWithUI(LX lx) {
super(lx);
addParameter("number", this.number);
addParameter("string", this.string);
addParameter("knob", this.knob);
}
@Override
protected void run(double deltaMs) {
for (LXPoint p : model.points) {
colors[p.index] = LXColor.hsb(240, 100, 100);
}
}
The key method is the buildDeviceControls
method:
/**
* Implement this method from the UIDeviceControls interface to build a custom UI for
* your pattern device, rather than relying upon the in-built default UI.
*/
@Override
public void buildDeviceControls(UI ui, UIDevice uiDevice, AppPatternWithUI pattern) {
uiDevice.setContentWidth(COL_WIDTH);
addColumn(uiDevice, "Custom",
newIntegerBox(pattern.number),
controlLabel(ui, "Number"),
newDropMenu(pattern.string),
controlLabel(ui, "String"),
newKnob(pattern.knob)
);
}
}
If you need more elements than can fit in a single column, elements can be placed in rows using a horizontal container.
import heronarts.p4lx.ui.UI2dContainer;
import heronarts.p4lx.ui.component.UIKnob;
// ...
@Override
public void buildDeviceControls(UI ui, UIDevice uiDevice, AppPatternWithUI pattern) {
uiDevice.setContentWidth(COL_WIDTH * 3);
addColumn(uiDevice, COL_WIDTH * 3,
UI2dContainer.newHorizontalContainer(UIKnob.HEIGHT, 0,
new UIKnob(pattern.knob1),
new UIKnob(pattern.knob2),
new UIKnob(pattern.knob3),
new UIKnob(pattern.knob4)
),
UI2dContainer.newHorizontalContainer(UIKnob.HEIGHT, 0,
new UIKnob(pattern.knob5),
new UIKnob(pattern.knob6)
)
);
}
Don't forget to register these in the constructor, otherwise they won't be mappable.
public AppPatternWithUI(LX lx) {
super(lx);
addParameter("knob1", this.knob1);
addParameter("knob2", this.knob2);
...
}
© 2020 LX Studio — Heron Arts LLC