Commits

Karsten Schmidt committed f2f33c2

initial check in

  • Participants

Comments (0)

Files changed (21)

+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry kind="src" path="src"/>
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.5"/>
+	<classpathentry kind="lib" path="lib/core.jar"/>
+	<classpathentry kind="lib" path="lib/toxiclibscore.jar"/>
+	<classpathentry kind="lib" path="lib/controlP5.jar"/>
+	<classpathentry kind="output" path="bin"/>
+</classpath>
+syntax: glob
+
+bin
+dist
+metrics
+
+.DS_Store
+*.class
+
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>controlp5builder</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.jdt.core.javabuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.jdt.core.javanature</nature>
+	</natures>
+</projectDescription>

.settings/org.eclipse.jdt.core.prefs

+#Wed Jul 28 16:59:07 BST 2010
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5
+org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
+org.eclipse.jdt.core.compiler.compliance=1.5
+org.eclipse.jdt.core.compiler.debug.lineNumber=generate
+org.eclipse.jdt.core.compiler.debug.localVariable=generate
+org.eclipse.jdt.core.compiler.debug.sourceFile=generate
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.source=1.5
+<?xml version="1.0" encoding="MacRoman" standalone="no"?>
+<jardesc>
+    <jar path="controlp5builder/dist/cp5utils.jar"/>
+    <options buildIfNeeded="true" compress="true" descriptionLocation="/controlp5builder/dist.jardesc" exportErrors="true" exportWarnings="true" includeDirectoryEntries="false" overwrite="true" saveDescription="true" storeRefactorings="false" useSourceFolders="false"/>
+    <storedRefactorings deprecationInfo="true" structuralOnly="false"/>
+    <selectedProjects/>
+    <manifest generateManifest="true" manifestLocation="" manifestVersion="1.0" reuseManifest="false" saveManifest="false" usesManifest="true">
+        <sealing sealJar="false">
+            <packagesToSeal/>
+            <packagesToUnSeal/>
+        </sealing>
+    </manifest>
+    <selectedElements exportClassFiles="true" exportJavaFiles="false" exportOutputFolder="false">
+        <javaElement handleIdentifier="=controlp5builder/src&lt;toxi.controlp5{FloatRangeBuilder.java"/>
+        <javaElement handleIdentifier="=controlp5builder/src&lt;toxi.controlp5{ButtonBuilder.java"/>
+        <javaElement handleIdentifier="=controlp5builder/src&lt;toxi.controlp5{Range.java"/>
+        <javaElement handleIdentifier="=controlp5builder/src&lt;toxi.controlp5{GUIElement.java"/>
+        <javaElement handleIdentifier="=controlp5builder/src&lt;toxi.controlp5{GUIType.java"/>
+        <javaElement handleIdentifier="=controlp5builder/src&lt;toxi.controlp5{GUIElementBuilder.java"/>
+        <javaElement handleIdentifier="=controlp5builder/src&lt;toxi.controlp5{GUIController.java"/>
+        <javaElement handleIdentifier="=controlp5builder/src&lt;toxi.controlp5{GUIConfiguration.java"/>
+        <javaElement handleIdentifier="=controlp5builder/src&lt;toxi.controlp5{CheckboxBuilder.java"/>
+        <javaElement handleIdentifier="=controlp5builder/src&lt;toxi.controlp5{RadioBuilder.java"/>
+        <javaElement handleIdentifier="=controlp5builder/src&lt;toxi.controlp5{IntegerRangeBuilder.java"/>
+        <javaElement handleIdentifier="=controlp5builder/src&lt;toxi.controlp5{FloatRangeMinMaxBuilder.java"/>
+    </selectedElements>
+</jardesc>

lib/controlP5.jar

Binary file added.

lib/core.jar

Binary file added.

lib/toxiclibscore.jar

Binary file added.

src/toxi/gui/AnnoTest.java

+/*
+ * Copyright (c) 2010 Karsten Schmidt
+ * 
+ * This library is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation; either version 2.1 of the License, or (at your option)
+ * any later version.
+ * 
+ * http://creativecommons.org/licenses/LGPL/2.1/
+ * 
+ * This library is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+package toxi.gui;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+
+import processing.core.PApplet;
+import toxi.util.datatypes.FloatRange;
+import controlP5.ControlEvent;
+import controlP5.ControlP5;
+
+public class AnnoTest extends PApplet {
+
+    public static void main(String[] args) {
+        PApplet.main(new String[] { "toxi.gui.AnnoTest" });
+    }
+
+    @GUIElement(label = "foo")
+    public FloatRange range = new FloatRange(0, 100);
+
+    @GUIElement(label = "enabled", x = 20, y = 300)
+    public boolean isActive = true;
+
+    @GUIElement(label = "file format", x = 20, y = 200)
+    public List<String> options = new ArrayList<String>();
+
+    @GUIElement(label = "hash", x = 220, y = 200)
+    public HashSet<Integer> hash = new HashSet<Integer>();
+
+    @GUIElement
+    public String btRestart = "restart";
+
+    @GUIElement(label = "columns", builder = IntegerRangeBuilder.class)
+    @Range(min = 1, max = 30)
+    public int cols = 10;
+
+    @GUIElement(label = "ratio", builder = FloatRangeBuilder.class)
+    @Range(min = 0.01f, max = 1f)
+    public float ratio = 0.5f;
+
+    @GUIElement(builder = FloatRangeBuilder.class)
+    public FloatRange r2 = new FloatRange(-1, 1);
+    
+    private GUIManager gui;
+
+    public void doRestart(ControlEvent e) {
+        System.out.println("--> " + e.controller().name());
+    }
+
+    public void draw() {
+        background(0);
+    }
+
+    private void initGUI() {
+        ControlP5 cp5 = new ControlP5(this);
+        gui = new GUIManager(cp5);
+        gui.addDefaultMappings();
+        gui.addMapping(toxi.util.datatypes.FloatRange.class,
+                new FloatRangeMinMaxBuilder());
+        gui.createControllers(this, 20, 20,null);        
+        gui.addListenerFor("isActive", "toggleActive", this);
+        gui.addListenerFor("btRestart", "doRestart", this);
+    }
+
+    public void toggleActive(ControlEvent e) {
+        e.controller().setLabel(e.value()>0 ? "enabled" : "disabled");
+    }
+    
+    public void keyPressed() {
+
+    }
+
+    public void setup() {
+        size(400, 400);
+        options.add("png");
+        options.add("tga");
+        options.add("jpg");
+        hash.add(23);
+        hash.add(42);
+        initGUI();
+    }
+}

src/toxi/gui/ButtonBuilder.java

+/*
+ * Copyright (c) 2010 Karsten Schmidt
+ * 
+ * This library is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation; either version 2.1 of the License, or (at your option)
+ * any later version.
+ * 
+ * http://creativecommons.org/licenses/LGPL/2.1/
+ * 
+ * This library is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+package toxi.gui;
+
+import java.lang.reflect.Field;
+import java.util.ArrayList;
+import java.util.List;
+
+import toxi.geom.Vec2D;
+import controlP5.Controller;
+
+public class ButtonBuilder implements GUIElementBuilder {
+
+    public List<Controller> createElementsFor(final Object context,
+            final Field field, GUIElement anno, Vec2D pos, String id,
+            String label, GUIManager gui) throws IllegalArgumentException,
+            IllegalAccessException {
+        int buttonID;
+        if (field.get(context).getClass() == String.class) {
+            label = (String) field.get(context);
+            buttonID = 0;
+        } else {
+            buttonID = field.getInt(context);
+        }
+        Controller ctrl =
+                gui.getGUI().addButton(id, buttonID, (int) pos.x, (int) pos.y,
+                        100, 14);
+        ctrl.setLabel(label);
+        List<Controller> controllers = new ArrayList<Controller>(1);
+        controllers.add(ctrl);
+        return controllers;
+    }
+
+    public int getMinSpacing() {
+        return 20;
+    }
+
+}

src/toxi/gui/CheckboxBuilder.java

+/*
+ * Copyright (c) 2010 Karsten Schmidt
+ * 
+ * This library is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation; either version 2.1 of the License, or (at your option)
+ * any later version.
+ * 
+ * http://creativecommons.org/licenses/LGPL/2.1/
+ * 
+ * This library is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+package toxi.gui;
+
+import java.lang.reflect.Field;
+import java.util.ArrayList;
+import java.util.List;
+
+import toxi.geom.Vec2D;
+import controlP5.ControlEvent;
+import controlP5.ControlListener;
+import controlP5.Controller;
+import controlP5.Toggle;
+
+public class CheckboxBuilder implements GUIElementBuilder {
+
+    public List<Controller> createElementsFor(final Object context,
+            final Field field, GUIElement anno, Vec2D pos, String id,
+            String label, GUIManager gui) throws IllegalArgumentException,
+            IllegalAccessException {
+        boolean state = field.getBoolean(context);
+        Toggle ctrl =
+                gui.getGUI().addToggle(id, state, (int) pos.x, (int) pos.y, 14,
+                        14);
+        ctrl.setLabel(label);
+        ctrl.addListener(new ControlListener() {
+
+            public void controlEvent(ControlEvent e) {
+                try {
+                    field.setBoolean(context, e.value() > 0);
+                } catch (IllegalArgumentException e1) {
+                } catch (IllegalAccessException e1) {
+                }
+            }
+        });
+        List<Controller> controllers = new ArrayList<Controller>(1);
+        controllers.add(ctrl);
+        return controllers;
+    }
+
+    public int getMinSpacing() {
+        return 40;
+    }
+
+}

src/toxi/gui/FloatRangeBuilder.java

+/*
+ * Copyright (c) 2010 Karsten Schmidt
+ * 
+ * This library is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation; either version 2.1 of the License, or (at your option)
+ * any later version.
+ * 
+ * http://creativecommons.org/licenses/LGPL/2.1/
+ * 
+ * This library is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+package toxi.gui;
+
+import java.lang.reflect.Field;
+import java.util.ArrayList;
+import java.util.List;
+
+import toxi.geom.Vec2D;
+import toxi.util.datatypes.FloatRange;
+import controlP5.ControlEvent;
+import controlP5.ControlListener;
+import controlP5.Controller;
+import controlP5.Slider;
+
+public class FloatRangeBuilder implements GUIElementBuilder {
+
+    protected static Slider createSlider(GUIManager gui, String id,
+            float min, float max, float curr, Vec2D pos, String label,
+            ControlListener listener) {
+        Slider s =
+                gui.getGUI().addSlider(id, min, max, curr, (int) pos.x,
+                        (int) pos.y, 100, 14);
+        s.setLabel(label);
+        s.addListener(listener);
+        return s;
+    }
+
+    public List<Controller> createElementsFor(final Object context,
+            final Field field, GUIElement anno, Vec2D pos, String id,
+            String label, GUIManager gui) throws IllegalArgumentException,
+            IllegalAccessException {
+        List<Controller> controllers = new ArrayList<Controller>(1);
+        FloatRange r = null;
+        boolean singleValue = false;
+        if (field.get(context).getClass() == Float.class) {
+            Range ra = field.getAnnotation(Range.class);
+            if (ra != null) {
+                r = new FloatRange(ra.min(), ra.max());
+                r.setCurrent(field.getFloat(context));
+                singleValue = true;
+            }
+        } else {
+            r = (FloatRange) field.get(context);
+        }
+        final FloatRange range = r;
+        final boolean isRange = !singleValue;
+        if (range != null) {
+            Slider s =
+                    createSlider(gui, id, range.min, range.max,
+                            range.currValue, pos, label, new ControlListener() {
+
+                                public void controlEvent(ControlEvent e) {
+                                    try {
+                                        if (isRange) {
+                                            range.setCurrent(e.value());
+                                        } else {
+                                            field.setFloat(context, e.value());
+                                        }
+                                    } catch (IllegalArgumentException e1) {
+                                    } catch (IllegalAccessException e1) {
+                                    }
+                                }
+                            });
+            controllers.add(s);
+        }
+        return controllers;
+    }
+
+    public int getMinSpacing() {
+        return 20;
+    }
+}

src/toxi/gui/FloatRangeMinMaxBuilder.java

+/*
+ * Copyright (c) 2010 Karsten Schmidt
+ * 
+ * This library is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation; either version 2.1 of the License, or (at your option)
+ * any later version.
+ * 
+ * http://creativecommons.org/licenses/LGPL/2.1/
+ * 
+ * This library is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+package toxi.gui;
+
+import java.lang.reflect.Field;
+import java.util.ArrayList;
+import java.util.List;
+
+import toxi.geom.Vec2D;
+import toxi.util.datatypes.FloatRange;
+import controlP5.ControlEvent;
+import controlP5.ControlListener;
+import controlP5.Controller;
+import controlP5.Slider;
+
+public class FloatRangeMinMaxBuilder extends FloatRangeBuilder implements
+        GUIElementBuilder {
+
+    public List<Controller> createElementsFor(final Object context,
+            final Field field, GUIElement anno, Vec2D pos, String id,
+            String label, GUIManager gui) throws IllegalArgumentException,
+            IllegalAccessException {
+        List<Controller> controllers = new ArrayList<Controller>(2);
+        final FloatRange range = (FloatRange) field.get(context);
+        Slider s =
+                createSlider(gui, id + "_min", range.min, range.max, range.min,
+                        pos, "min " + label, new ControlListener() {
+
+                            public void controlEvent(ControlEvent e) {
+                                range.min = e.value();
+                            }
+                        });
+        controllers.add(s);
+        s =
+                createSlider(gui, id + "_max", range.min, range.max, range.max,
+                        pos.add(200, 0), "max " + label, new ControlListener() {
+
+                            public void controlEvent(ControlEvent e) {
+                                range.max = e.value();
+                            }
+                        });
+        controllers.add(s);
+        return controllers;
+    }
+
+    @Override
+    public int getMinSpacing() {
+        return 20;
+    }
+
+}

src/toxi/gui/GUIConfiguration.java

+/*
+ * Copyright (c) 2010 Karsten Schmidt
+ * 
+ * This library is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation; either version 2.1 of the License, or (at your option)
+ * any later version.
+ * 
+ * http://creativecommons.org/licenses/LGPL/2.1/
+ * 
+ * This library is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+package toxi.gui;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+@Target(ElementType.TYPE)
+@Retention(RetentionPolicy.RUNTIME)
+public @interface GUIConfiguration {
+
+    public int x();
+
+    public int y();
+}

src/toxi/gui/GUIElement.java

+/*
+ * Copyright (c) 2010 Karsten Schmidt
+ * 
+ * This library is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation; either version 2.1 of the License, or (at your option)
+ * any later version.
+ * 
+ * http://creativecommons.org/licenses/LGPL/2.1/
+ * 
+ * This library is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+package toxi.gui;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+@Target(ElementType.FIELD)
+@Retention(RetentionPolicy.RUNTIME)
+public @interface GUIElement {
+
+    public static final String NO_LABEL = "<empty>";
+
+    public Class<? extends GUIElementBuilder> builder() default GUIElementBuilder.class;
+
+    public String label() default NO_LABEL;
+
+    public GUIType type() default GUIType.DEFAULT;
+
+    public int x() default -1;
+
+    public int y() default -1;
+}

src/toxi/gui/GUIElementBuilder.java

+/*
+ * Copyright (c) 2010 Karsten Schmidt
+ * 
+ * This library is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation; either version 2.1 of the License, or (at your option)
+ * any later version.
+ * 
+ * http://creativecommons.org/licenses/LGPL/2.1/
+ * 
+ * This library is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+package toxi.gui;
+
+import java.lang.reflect.Field;
+import java.util.List;
+
+import toxi.geom.Vec2D;
+import controlP5.Controller;
+
+public interface GUIElementBuilder {
+
+    public List<Controller> createElementsFor(final Object context,
+            final Field field, GUIElement anno, Vec2D pos, String id,
+            String label, GUIManager gui) throws IllegalArgumentException,
+            IllegalAccessException;
+
+    public int getMinSpacing();
+}

src/toxi/gui/GUIManager.java

+/*
+ * Copyright (c) 2010 Karsten Schmidt
+ * 
+ * This library is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation; either version 2.1 of the License, or (at your option)
+ * any later version.
+ * 
+ * http://creativecommons.org/licenses/LGPL/2.1/
+ * 
+ * This library is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+package toxi.gui;
+
+import java.lang.reflect.Field;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.List;
+
+import toxi.geom.Vec2D;
+import controlP5.ControlEvent;
+import controlP5.ControlListener;
+import controlP5.ControlP5;
+import controlP5.Controller;
+import controlP5.Tab;
+
+public class GUIManager {
+
+    private ControlP5 gui;
+    private Vec2D currPos;
+
+    private HashMap<String, Controller> controllers =
+            new HashMap<String, Controller>();
+
+    private HashMap<Class<?>, GUIElementBuilder> builders =
+            new HashMap<Class<?>, GUIElementBuilder>();
+
+    public GUIManager(ControlP5 gui) {
+        this.gui = gui;
+    }
+
+    public void addDefaultMappings() {
+        addMapping(Boolean.class, new CheckboxBuilder());
+        addMapping(Integer.class, new IntegerRangeBuilder());
+        addMapping(Float.class, new FloatRangeBuilder());
+        addMapping(Collection.class, new RadioBuilder());
+        addMapping(String.class, new ButtonBuilder());
+    }
+
+    public void addListenerFor(String id, final String name,
+            final Object context) {
+        Controller ctrl = getForID(id);
+        if (ctrl != null) {
+            ctrl.addListener(new ControlListener() {
+
+                public void controlEvent(ControlEvent e) {
+                    try {
+                        Method method =
+                                context.getClass().getMethod(name,
+                                        ControlEvent.class);
+                        method.invoke(context, e);
+                    } catch (SecurityException ex) {
+                        ex.printStackTrace();
+                    } catch (NoSuchMethodException ex) {
+                        ex.printStackTrace();
+                    } catch (IllegalArgumentException ex) {
+                        ex.printStackTrace();
+                    } catch (IllegalAccessException ex) {
+                        ex.printStackTrace();
+                    } catch (InvocationTargetException ex) {
+                        ex.printStackTrace();
+                    }
+                }
+            });
+        }
+    }
+
+    public void addMapping(Class<?> c, GUIElementBuilder builder) {
+        builders.put(c, builder);
+    }
+
+    public void createControllers(Object context, int x, int y, Tab tab) {
+        this.currPos = new Vec2D(x, y);
+        try {
+            for (Field f : context.getClass().getFields()) {
+                if (f.isAnnotationPresent(GUIElement.class)) {
+                    Class<?> type = f.get(context).getClass();
+                    GUIElement a = f.getAnnotation(GUIElement.class);
+                    GUIElementBuilder builder = null;
+                    if (a.builder() != GUIElementBuilder.class) {
+                        builder = a.builder().newInstance();
+                    } else {
+                        builder = getMappingForType(type);
+                    }
+                    System.out.println(type+": "+builder);
+                    if (builder != null) {
+                        String label =
+                                !a.label().equals(GUIElement.NO_LABEL) ? a
+                                        .label() : f.getName();
+                        Vec2D pos = getPositionFor(a);
+                        List<Controller> items =
+                                builder.createElementsFor(context, f, a, pos,
+                                        f.getName(), label, this);
+                        for (Controller c : items) {
+                            if (tab != null) {
+                                c.setTab(tab.name());
+                            }
+                            registerController(c.name(), c);
+                        }
+                        if (a.y() == -1) {
+                            currPos.y += builder.getMinSpacing();
+                        }
+                    } else {
+                        System.out.println("no mapping found for: " + type);
+                    }
+                }
+            }
+        } catch (IllegalArgumentException e) {
+            e.printStackTrace();
+        } catch (IllegalAccessException e) {
+            e.printStackTrace();
+        } catch (InstantiationException e) {
+            e.printStackTrace();
+        }
+    }
+
+    public void createControllers(Object context, Tab tab) {
+        int x, y;
+        GUIConfiguration config =
+                context.getClass().getAnnotation(GUIConfiguration.class);
+        if (config != null) {
+            x = config.x();
+            y = config.y();
+        } else {
+            x = 20;
+            y = 20;
+        }
+        createControllers(context, x, y, tab);
+    }
+
+    public Controller getForID(String id) {
+        return controllers.get(id);
+    }
+
+    public ControlP5 getGUI() {
+        return gui;
+    }
+
+    private GUIElementBuilder getMappingForType(Class<?> type) {
+        GUIElementBuilder builder = builders.get(type);
+        if (builder == null) {
+            for (Class<?> c : type.getInterfaces()) {
+                builder = builders.get(c);
+                if (builder != null) {
+                    break;
+                } else {
+                    Class<?> stype = c.getSuperclass();
+                    if (stype != Object.class && stype != null) {
+                        builder = getMappingForType(stype);
+                    }
+                }
+            }
+            if (builder == null) {
+                Class<?> stype = type.getSuperclass();
+                if (stype != Object.class && stype != null) {
+                    builder = getMappingForType(stype);
+                }
+            }
+        }
+        return builder;
+    }
+
+    protected Vec2D getPositionFor(GUIElement a) {
+        float x = a.x() != -1 ? a.x() : currPos.x;
+        float y = a.y() != -1 ? a.y() : currPos.y;
+        return new Vec2D(x, y);
+    }
+
+    protected void registerController(String id, Controller ctrl) {
+        controllers.put(id, ctrl);
+    }
+}

src/toxi/gui/GUIType.java

+/*
+ * Copyright (c) 2010 Karsten Schmidt
+ * 
+ * This library is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation; either version 2.1 of the License, or (at your option)
+ * any later version.
+ * 
+ * http://creativecommons.org/licenses/LGPL/2.1/
+ * 
+ * This library is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+package toxi.gui;
+
+public enum GUIType {
+    SLIDER, DIAL, BUTTON, DEFAULT;
+}

src/toxi/gui/IntegerRangeBuilder.java

+/*
+ * Copyright (c) 2010 Karsten Schmidt
+ * 
+ * This library is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation; either version 2.1 of the License, or (at your option)
+ * any later version.
+ * 
+ * http://creativecommons.org/licenses/LGPL/2.1/
+ * 
+ * This library is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+package toxi.gui;
+
+import java.lang.reflect.Field;
+import java.util.ArrayList;
+import java.util.List;
+
+import toxi.geom.Vec2D;
+import toxi.util.datatypes.IntegerRange;
+import controlP5.ControlEvent;
+import controlP5.ControlListener;
+import controlP5.Controller;
+import controlP5.Slider;
+
+public class IntegerRangeBuilder implements GUIElementBuilder {
+
+    protected static Slider createSlider(GUIManager gui, String id, int min,
+            int max, int curr, Vec2D pos, String label, ControlListener listener) {
+        Slider s =
+                gui.getGUI().addSlider(id, min, max, curr, (int) pos.x,
+                        (int) pos.y, 100, 14);
+        s.setLabel(label);
+        s.addListener(listener);
+        return s;
+    }
+
+    public List<Controller> createElementsFor(final Object context,
+            final Field field, GUIElement anno, Vec2D pos, String id,
+            String label, GUIManager gui) throws IllegalArgumentException,
+            IllegalAccessException {
+        List<Controller> controllers = new ArrayList<Controller>(1);
+        IntegerRange r = null;
+        boolean singleValue = false;
+        if (field.get(context).getClass() == Integer.class) {
+            Range ra = field.getAnnotation(Range.class);
+            if (ra != null) {
+                r = new IntegerRange((int) ra.min(), (int) ra.max());
+                r.setCurrent(field.getInt(context));
+                singleValue = true;
+            }
+        } else {
+            r = (IntegerRange) field.get(context);
+        }
+        final IntegerRange range = r;
+        final boolean isRange = !singleValue;
+        if (range != null) {
+            range.setCurrent(field.getInt(context));
+            Slider s =
+                    createSlider(gui, id, range.min, range.max,
+                            range.currValue, pos, label, new ControlListener() {
+
+                                public void controlEvent(ControlEvent e) {
+                                    try {
+                                        if (isRange) {
+                                            range.setCurrent((int) e.value());
+                                        } else {
+                                            field.setInt(context,
+                                                    (int) e.value());
+                                        }
+                                    } catch (IllegalArgumentException e1) {
+                                    } catch (IllegalAccessException e1) {
+                                    }
+                                }
+                            });
+            controllers.add(s);
+        }
+        return controllers;
+    }
+
+    public int getMinSpacing() {
+        return 20;
+    }
+}

src/toxi/gui/RadioBuilder.java

+/*
+ * Copyright (c) 2010 Karsten Schmidt
+ * 
+ * This library is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation; either version 2.1 of the License, or (at your option)
+ * any later version.
+ * 
+ * http://creativecommons.org/licenses/LGPL/2.1/
+ * 
+ * This library is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+package toxi.gui;
+
+import java.lang.reflect.Field;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+
+import toxi.geom.Vec2D;
+import controlP5.Controller;
+import controlP5.Radio;
+
+public class RadioBuilder implements GUIElementBuilder {
+
+    private int itemCount;
+
+    public List<Controller> createElementsFor(Object context, Field field,
+            GUIElement anno, Vec2D pos, String id, String label,
+            GUIManager gui) throws IllegalArgumentException,
+            IllegalAccessException {
+        Radio r = gui.getGUI().addRadio(id, (int) pos.x, (int) pos.y);
+        r.setBroadcast(false);
+        itemCount = 0;
+        for (Iterator<?> i = ((Collection<?>) field.get(context)).iterator(); i
+                .hasNext();) {
+            r.addItem(i.next().toString(), itemCount++);
+        }
+        r.setBroadcast(true);
+        r.setLabel(label);
+        List<Controller> controllers = new ArrayList<Controller>(1);
+        controllers.add(r);
+        return controllers;
+    }
+
+    public int getMinSpacing() {
+        return itemCount * 16;
+    }
+
+}

src/toxi/gui/Range.java

+/*
+ * Copyright (c) 2010 Karsten Schmidt
+ * 
+ * This library is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation; either version 2.1 of the License, or (at your option)
+ * any later version.
+ * 
+ * http://creativecommons.org/licenses/LGPL/2.1/
+ * 
+ * This library is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+package toxi.gui;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+@Target(ElementType.FIELD)
+@Retention(RetentionPolicy.RUNTIME)
+public @interface Range {
+
+    public float max();
+
+    public float min();
+
+}