-
Notifications
You must be signed in to change notification settings - Fork 3
cc control
cc-control is a flexible control interface that generates ui elements based on your code. cc-control uses javas reflection features to step through your application and generate a ui for marked fields.
To create a control for your code elements you use the CCProperty annotation. Annotations are a java feature that you can use to add metainformation to code elements like variables, methods and classes. cc-control scans through your application and searches for code elements that are marked with a CCProperty annotation and than creates handles to those elements to be able to change them. The handle implements features to read and write an element and to store its content. On top of the handle is the control this is a userinterface implementation to interact with your application with an ui.
So how does it work? Lets start with a simple example. We have an application that contains some values we want to change.
public class QuadRendering extends PApplet {
private float x = 300;
private float y = 300;
private float width = 300;
private float height = 300;
public void setup() {
noStroke();
fill(0, 100);
}
public void draw() {
background(255);
rect(x, y, width, height);
}
public void settings() {
size(800, 600);
}
static public void main(String[] passedArgs) {
String[] appletArgs = new String[] { QuadRendering.class.getName() };
if (passedArgs != null) {
PApplet.main(concat(appletArgs, passedArgs));
} else {
PApplet.main(appletArgs);
}
}
}So as you see in this application we simply drawing a rectangle, we want to change its position and dimension by controlling the x, y, width and height parameters. We do this by adding the CCProperty annotation.
@CCProperty(name = "x")
private float _cX = 300;
@CCProperty(name = "y")
private float _cY = 300;
@CCProperty(name = "width")
private float _cWidth = 300;
@CCProperty(name = "height")
private float _cHeight = 300;The annotation has some optional parameters that you can add, so far you can see the name parameter we will come to other ones soon. To now add the control interface, we have to add the object that actually scans through the application and generates the ui elements. So in setup we add the following.
public void setup() {
_myController = new CCP5Controller(this);
}Now when you start the app you will see the control interface.

So for now you can't see much. Notice the different elements of the control interface.

So far we will only look at the control browser.

The variables you want to control are inside an object your application. So to get to the controls you have to open the object tab by clicking on it.

Now you see number boxes for all the variables you have annotated. You can control them by mouse and keyboard. To do so click in the numberbox you want to control. For control by mouse you simply click and drag draging upwards will increase the value dragging downwards will decrease it.

The amount is dependent on the cursor position. You will always change the digits before the cursor. Control by keyboard works the same click into the numberbox to increase press the up arrow button to decrease the down arrow button. Again the amount is based on the cursor position. You can also simply enter values. Note you can also enter mathematical expressions like 1 / 3 this will be resolved to 0.33

With control ui you can also animate your variables in a timeline. To do so right click on the control in the control browser and click Add To Timeline in the menue.

As you can see a new track appears in the timeline.

Every track has a track control and a track data area. In the track control area you can mute the track output with the mute button. The value range can be set with the minimum and maximum numberboxes they work the same as the variable controls.

We create a track for the x value and change the minimum value to 0 and the maximum value to 500 we can now animate the value between 0 and 500. To animate the value you can create control points by double clicks into to the track data area the x position represents the time the y position the value scaling from the minimum value at the bottom to the maximum value at the top.

There are different controls to control the timeline playback. You start and stop the timeline playback with the play stop button. You can see the current playback time in the time field. You can also enter values directly into the timefield, you have to ensure that you keep the right format. hh:mm:ss:millis The playback speed can be adjusted with the speed field. With the bpm button you can switch to a bpm based ruler in the bpm field you can adjust the bpm field.

To define a loop when playing back click and drag in the upper half of the time ruler and you select the time range to be looped. To move the loop section click in its center and drag. To resize it click and drag at the edges of the loop range. You can define a new loop by clicking and dragging outside of the loop.
To skip through the timeline you can click in the lower half of the time ruler to jump to certain time or click and drag to drag through the timeline. The play header will follow the mouse.

There are two ways to zoom the first is to press alt and than click and dragg the mouse while alt is still pressed. Vertical drag results in zoom horizontal drag in movement. This allows to zoom and move the timeline at once. Alternatively you can use the zoom slider in the timeline controls to zoom and the horizontal scrollbar. Note that the scrollbar does only appear if there are control point outside of the view range.
To save your timeline go to File -> Save in the menue and save the timeline using the appearing file chooser. With File -> Load you can open a timeline document with File -> New you create a new document.
The CCProperty annotation can contain further optional parameters. So you can add the min and max values to predefine the value range for you numeric variables.
Control-ui is flexible in mapping controls to your code it not only scans through the application but recursively through all objects annotated with the CCProperty tag.
public class QuadRendering extends PApplet {
private CCP5Controller _myController;
private class Quad{
@CCProperty(name = "x", min = 0, max = 500)
private float _cX = 300;
@CCProperty(name = "y", min = 0, max = 500)
private float _cY = 100;
@CCProperty(name = "width", min = 0, max = 200)
private float _cWidth = 100;
@CCProperty(name = "height", min = 0, max = 200)
private float _cHeight = 100;
public void draw() {
rect(_cX, _cY, _cWidth, _cHeight);
}
}
@CCProperty(name = "quad")
private Quad _cQuad = new Quad();
public void setup() {
noStroke();
fill(0, 100);
_myController = new CCP5Controller(this);
}
public void draw() {
background(255);
_cQuad.draw();
}
public void settings() {
size(800, 600);
}
static public void main(String[] passedArgs) {
String[] appletArgs = new String[] { QuadRendering.class.getName() };
if (passedArgs != null) {
PApplet.main(concat(appletArgs, passedArgs));
} else {
PApplet.main(appletArgs);
}
}
}We have moved the variables to a new class Quad and added a variable _cQuad that is annotated with CCProperty. Note we also added min max values to the property annotations inside the quad class.

Notice the changes in the control ui. If you double click on app the quick access browser you see the quad instance. The quick access browser helps you navigating through bigger projects by only showing the annotated property objects, by selecting an object in the quick access browser you only see the controls for this object.
In the control browser you do now have the the controls inside the quad tab which is placed inside the app tab.The quad controls are colored red. Controlui automatically colors the control object instances on application level for better overview, also the tracks are colored red.
Because we have added min max values you now also have sliders plus the number box, you can now control the values with the slider or with the number box that is now also limited to the min max values. Note that the min max values in the timeline are also automatically set.
private CCP5Controller _myController;
private class Quad{
@CCProperty(name = "x", min = 0, max = 500)
private float _cX = 300;
@CCProperty(name = "y", min = 0, max = 500)
private float _cY = 100;
@CCProperty(name = "width", min = 0, max = 200)
private float _cWidth = 100;
@CCProperty(name = "height", min = 0, max = 200)
private float _cHeight = 100;
public void draw() {
rect(_cX, _cY, _cWidth, _cHeight);
}
}
@CCProperty(name = "quad 1")
private Quad _cQuad1 = new Quad();
@CCProperty(name = "quad 2")
private Quad _cQuad2 = new Quad();
public void setup() {
noStroke();
fill(0, 100);
_myController = new CCP5Controller(this);
}
public void draw() {
background(255);
_cQuad1.draw();
_cQuad2.draw();
}In the next step we add a second quad to our application.

Again the object is added to the quick access browser and we see one more different colored control tab in the control browser.
private CCP5Controller _myController;
private CCP5Controller _myController;
private class Quad{
@CCProperty(name = "x", min = 0, max = 500)
private float _cX = random(0,500);
@CCProperty(name = "y", min = 0, max = 500)
private float _cY = random(0,500);;
@CCProperty(name = "width", min = 0, max = 200)
private float _cWidth = random(0,200);;
@CCProperty(name = "height", min = 0, max = 200)
private float _cHeight = random(0,200);;
public void draw() {
rect(_cX, _cY, _cWidth, _cHeight);
}
}
@CCProperty(name = "quad list")
private List<Quad> _cQuadList = new ArrayList<>();
@CCProperty(name = "quad map")
private Map<String, Quad> _cQuadMap = new LinkedHashMap<>();
public void setup() {
noStroke();
fill(0, 100);
for(int i = 0; i < 5;i++) {
_cQuadList.add(new Quad());
}
_cQuadMap.put("quad a", new Quad());
_cQuadMap.put("quad b", new Quad());
_cQuadMap.put("quad c", new Quad());
_myController = new CCP5Controller(this);
}
public void draw() {
background(255);
for(Quad myQuad:_cQuadList) {
myQuad.draw();
}
for(Quad myQuad:_cQuadMap.values()) {
myQuad.draw();
}
}Control-ui can also handle javas collection classes List and map so in this example you see how the usage of lists and maps does reflect in the interface.

As you can see we have a couple of more object in the quick access and the control browser. For lists the objects in the ui are named by the list index, for maps they are named by the keys. Note that you have to use LinkedHashMaps to keep the order of insertion for the ui.