/* Copyright (c) 2010, Chris Want Please see BSD style licence at the end of this file */ abstract class PlacementElement { float x, y, w, h; boolean visible = true; boolean redraw = true; boolean clickedIn = false; PlacementElement parent=null; ControllerInterface[] controllers=null; PlacementElement(float x, float y, float w, float h) { this.x = x; this.y = y; this.w = w; this.h = h; } void setParent(PlacementElement parent) { // add controllers to child, then run this ... this.parent=parent; if (controllers != null) { for (int i=0; i < controllers.length; ++i) { controllers[i].setPosition(parent.getX(controllers[i].position().x()), parent.getY(controllers[i].position().y())); } } } boolean mouseOver() { return (mouseX>=getScreenX(0) && mouseX<=getScreenX(w) && mouseY>=getScreenY(0) && mouseY<=getScreenY(h)); } float getScreenX(float x0) { // absolute position, for controls/mouse if (parent!=null) { return this.x + parent.getScreenX(x0); } return this.x + x0; } float getScreenY(float y0) { if (parent!=null) { return this.y + parent.getScreenY(y0); } return this.y + y0; } float getX(float x0) { // relative position for drawing return getScreenX(x0); } float getY(float y0) { return getScreenY(y0); } float[] mouseNormalized() { float[] over = new float[2]; over[0] = (mouseX - getScreenX(0)) / w; over[1] = (mouseY - getScreenY(0)) / h; return over; } abstract void draw(PGraphics out); void draw() { if (visible) draw(g); } void flagRedraw() { redraw = true; } void mouseMoved() { } void mousePressed() { if (mouseOver()) clickedIn = true; } void mouseReleased() { clickedIn = false; } void mouseDragged() { } void updateState() { flagRedraw(); } void addController(ControllerInterface controller) { ControllerInterface[] oldControllers; int numControllers; if (controllers == null) { controllers = new ControllerInterface[1]; controllers[0] = controller; return; } numControllers = controllers.length; oldControllers = controllers; controllers = new ControllerInterface[numControllers+1]; for (int i=0; i < numControllers; ++i) { controllers[i] = oldControllers[i]; } controllers[numControllers] = controller; } void disableControllers() { if (controllers == null) return; for (int i=0; i < controllers.length; ++i) { controllers[i].hide(); } } void enableControllers() { if (controllers == null) return; for (int i=0; i < controllers.length; ++i) { controllers[i].show(); } } void updateControllers() { if (controllers != null) { for (int j=0; j < controllers.length; ++j) { if (controllers[j] instanceof Textfield) { Textfield tf; tf = (Textfield) controllers[j]; tf.submit(); } } } } } class ImagePlacementElement extends PlacementElement { PImage pi=null; ImagePlacementElement(float x, float y, float w, float h) { super(x, y, w, h); } ImagePlacementElement(float x, float y, float w, float h, PImage pi) { this(x, y, w, h); setImage(pi); } void setImage(PImage pi) { this.pi = pi; //pi.resize(round(w),round(h)); } void draw(PGraphics out) { if (redraw) { if (pi != null) { out.imageMode(CORNER); // out.image(pi, getCoordX(x), getCoordY(y), w, h); out.image(pi, getX(x), getY(y), w, h); } } redraw = false; } float getX(float x0) { // relative position for drawing return x0; } float getY(float y0) { return y0; } } class GraphicsPlacementElement extends PlacementElement { PGraphics pi=null; GraphicsPlacementElement (float x, float y, float w, float h) { super(x, y, w, h); } GraphicsPlacementElement (float x, float y, float w, float h, String renderer) { super(x, y, w, h); pi = createGraphics(round(w), round(h), renderer); } GraphicsPlacementElement(float x, float y, float w, float h, PGraphics pi) { this(x, y, w, h); setGraphics(pi); } void setGraphics(PGraphics pi) { this.pi = pi; } void draw(PGraphics out) { if (redraw) { if (pi != null) { out.imageMode(CORNER); //out.image(pi, getCoordX(x), getCoordY(y), w, h); out.image(pi, getX(x), getY(y), w, h); } } redraw = false; } float getX(float x0) { // relative position for drawing return x0; } float getY(float y0) { return y0; } } class TabElement { PlacementElement[] panels; String title; TabElement(String title, PlacementElement[] panels) { this.title = title; this.panels = panels; } void draw(PGraphics out) { for (int i=0; i < panels.length; ++i) { panels[i].draw(out); } } void mouseMoved() { for (int i=0; i < panels.length; ++i) { panels[i].mouseMoved(); } } void mousePressed() { for (int i=0; i < panels.length; ++i) { panels[i].mousePressed(); } } void mouseReleased() { for (int i=0; i < panels.length; ++i) { panels[i].mouseReleased(); } } void updateState() { for (int i=0; i < panels.length; ++i) { panels[i].updateState(); } } void disable() { for (int i=0; i < panels.length; ++i) { panels[i].disableControllers(); panels[i].visible = false; } flagRedraw(); } void enable() { for (int i=0; i < panels.length; ++i) { panels[i].enableControllers(); panels[i].visible = true; } flagRedraw(); } void flagRedraw() { for (int i=0; i < panels.length; ++i) { panels[i].flagRedraw(); } } void updateControllers() { // To make sure text values in Textfield controllers have been submitted for (int i=0; i < panels.length; ++i) { panels[i].updateControllers(); } } } class TabPanel extends PlacementElement { TabElement[] tabs=null; int currentTab=0; int tabHeight = 20; PFont font; RadioButton radiob; boolean tabSwitch = true; TabPanel(String radioName, PFont font, float x, float y, float w, float h, ControlP5 controlP5) { super(x, y, w, h); this.font= createFont("Courier",8); addController(radiob = controlP5.addRadioButton(radioName, (int)getX(50), (int)getY(h-15))); radiob.setItemsPerRow(5); radiob.setSpacingColumn(70); radiob.setNoneSelectedAllowed(false); } void addTab(String title, PlacementElement[] panels) { TabElement thisTab; thisTab = new TabElement(title, panels); if (tabs==null) { tabs = new TabElement[1]; tabs[0] = thisTab; } else { TabElement[] oldTabs; oldTabs = tabs; tabs = new TabElement[oldTabs.length+1]; for (int i=0; i < oldTabs.length; ++i) { tabs[i] = oldTabs[i]; } tabs[oldTabs.length] = thisTab; } for (int i=0; i < panels.length; ++i) { panels[i].setParent(this); } radiob.addItem(thisTab.title, tabs.length-1); if (currentTab == (tabs.length-1)) { thisTab.enable(); if (radiob.isVisible()) { radiob.hide(); radiob.activate(currentTab); radiob.show(); } else { radiob.activate(currentTab); } } else { thisTab.disable(); if ( (currentTab+1) == (tabs.length-1)) { } } } void setTab(int nextTab) { tabs[currentTab].disable(); tabs[nextTab].enable(); currentTab = nextTab; updateState(); flagRedraw(); } void flagRedraw() { redraw = true; if (tabs!=null) tabs[currentTab].flagRedraw(); } void draw(PGraphics out) { if (redraw) { out.beginDraw(); out.fill(0); out.stroke(255); out.rectMode(CORNER); out.rect(x,y, w, h); //out.textFont(font,8); //out.textMode(SCREEN); //out.text(tabs[currentTab].title, x+20,y+400); out.endDraw(); redraw = false; } tabs[currentTab].draw(out); } void mouseMoved() { tabs[currentTab].mouseMoved(); } void mousePressed() { tabs[currentTab].mousePressed(); } void mouseReleased() { tabs[currentTab].mouseReleased(); } void updateState() { tabs[currentTab].updateState(); } void updateControllers() { // To make sure text values in Textfield controllers have been submitted for (int i=0; i < tabs.length; ++i) { tabs[i].updateControllers(); } } } /* Copyright (c) 2010, Chris Want, Research Support Group, AICT, University of Alberta. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1) Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2) Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. Contributors: Chris Want (University of Alberta) */