public void setBrushColor(MTColor color) {
   this.brushColor = color;
   if (this.drawShape != null) {
     drawShape.setFillColor(color);
     drawShape.setStrokeColor(color);
   }
 }
  /**
   * Instantiates a new default button click action.
   *
   * @param poly the poly
   */
  public DefaultButtonClickAction(AbstractShape poly) {
    this.polyButton = poly;
    this.sizeChangeValue = 3;

    this.width = polyButton.getWidthXY(TransformSpace.RELATIVE_TO_PARENT);

    this.height = polyButton.getHeightXY(TransformSpace.RELATIVE_TO_PARENT);
  }
 public void setBrush(AbstractShape brush) {
   this.drawShape = brush;
   this.localBrushCenter = drawShape.getCenterPointLocal();
   this.brushWidthHalf = drawShape.getWidthXY(TransformSpace.LOCAL) / 2f;
   this.brushHeightHalf = drawShape.getHeightXY(TransformSpace.LOCAL) / 2f;
   this.stepDistance = brushWidthHalf / 2.8f;
   this.drawShape.setFillColor(this.brushColor);
   this.drawShape.setStrokeColor(this.brushColor);
 }
  public void drawBrush(int steps, Vector3D whatToAdd) {
    int i = 0;
    do {
      i++;
      cPos.addLocal(whatToAdd);
      // Draw new brush into FBO at correct position
      Vector3D diff = cPos.getSubtracted(drawLine.getCenterPointLocal());

      drawApp.pushMatrix();
      drawApp.translate(diff.x, diff.y);
      // Draw brush

      drawLine.setStrokeColor(lineColor);
      drawLine.setFillColor(lineColor);
      drawLine.drawComponent(drawApp.g);

      drawApp.popMatrix();
    } while (i < steps);
  }
 /**
  * Sets the svg options recursive.
  *
  * @param comp the comp
  * @param boundsBehaviour the bounds behaviour
  */
 private void setSvgOptionsRecursive(MTComponent comp, int boundsBehaviour) {
   comp.setGestureAllowance(DragProcessor.class, false);
   comp.setGestureAllowance(RotateProcessor.class, false);
   comp.setGestureAllowance(ScaleProcessor.class, false);
   comp.setGestureAllowance(TapProcessor.class, false);
   //		comp.unregisterAllInputProcessors();
   //		/*
   if (comp instanceof AbstractShape) {
     AbstractShape shape = (AbstractShape) comp;
     if (!shape.isBoundingShapeSet()
         && !(shape.getBoundingShape() instanceof BoundsZPlaneRectangle)) {
       shape.setBoundingShape(new BoundsZPlaneRectangle(shape));
     }
     shape.setBoundsBehaviour(boundsBehaviour);
   }
   //		*/
   for (MTComponent child : comp.getChildren()) {
     setSvgOptionsRecursive(child, boundsBehaviour);
   }
 }
  /** Private method, fiducial has been updated */
  private void updated() {
    AbstractShape component = FiducialRegistry.getInstance().getFiducialComponent(EventID);

    if (component != null) {
      component.setPositionGlobal(event.getPosition());
      float oldAngle = (Float) component.getUserData("angle"); // retrieve the "old" angle
      float newAngle = event.getAngle();
      if (oldAngle != newAngle) {
        float diff = newAngle + oldAngle;
        component.setUserData("angle", newAngle);
        diff = MTApplication.degrees(diff); // our rotation expects degrees (not radians)
        component.rotateZ(component.getCenterPointRelativeToParent(), diff);
      }
    }
  }
  // Global input processor listener implementation (IMTInputEventListener)
  public boolean processInputEvent(MTInputEvent inEvt) {
    if (inEvt instanceof MTFiducialInputEvt) {
      MTFiducialInputEvt fEvt = (MTFiducialInputEvt) inEvt;
      int fID = fEvt.getFiducialId();
      Vector3D position = fEvt.getPosition();

      AbstractShape comp;
      switch (fEvt.getId()) {
        case MTFiducialInputEvt.INPUT_STARTED:
          // Create a new component for the fiducial
          AbstractShape newComp = createComponent(fID, position);
          fiducialIDToComp.put(fID, newComp); // Map id to component
          // Move component to fiducial position
          newComp.setPositionGlobal(position);
          // Save the absolute rotation angle in the component for late
          newComp.setUserData("angle", fEvt.getAngle());
          // Rotate the component
          newComp.rotateZ(
              newComp.getCenterPointRelativeToParent(), MTApplication.degrees(fEvt.getAngle()));
          // Add the component to the canvas to draw it
          getCanvas().addChild(newComp);
          break;
        case MTFiducialInputEvt.INPUT_UPDATED:
          // Retrieve the corresponding component for the fiducial ID from the map
          comp = fiducialIDToComp.get(fID);
          if (comp != null) {
            // Set the new position
            comp.setPositionGlobal(position);
            // Set the rotation (we have to do a little more here because
            // mt4j does incremental rotations instead of specifying an absolute angle)
            float oldAngle = (Float) comp.getUserData("angle"); // retrieve the "old" angle
            float newAngle = fEvt.getAngle();
            if (oldAngle != newAngle) {
              float diff = newAngle - oldAngle;
              comp.setUserData("angle", newAngle);
              diff = MTApplication.degrees(diff); // our rotation expects degrees (not radians)
              comp.rotateZ(comp.getCenterPointRelativeToParent(), diff);
            }
          }
          break;
        case MTFiducialInputEvt.INPUT_ENDED:
          comp = fiducialIDToComp.get(fID);
          if (comp != null) {
            comp.destroy();
            fiducialIDToComp.remove(fID);
          }
          break;
        default:
          break;
      }
    }
    return false;
  }
  /** Private method, handle a new fiducial */
  private void started() {
    AbstractShape roundingcircle =
        new MTEllipse(app, new Vector3D(event.getPosition()), 180, 180, 100);
    roundingcircle.setNoFill(false);
    float r = ToolsMath.getRandom(20, 255);
    float g = ToolsMath.getRandom(20, 255);
    float b = ToolsMath.getRandom(20, 255);
    roundingcircle.setFillColor(new MTColor(r, g, b, 200));
    roundingcircle.setNoStroke(false);
    roundingcircle.setStrokeWeight(1);
    roundingcircle.setStrokeColor(new MTColor(r, g, b, 200));
    roundingcircle.unregisterAllInputProcessors();

    AbstractShape component = new MTEllipse(app, new Vector3D(event.getPosition()), 20, 20, 20);
    component.setNoFill(false);
    float r1 = ToolsMath.getRandom(20, 255);
    float g1 = ToolsMath.getRandom(20, 255);
    float b1 = ToolsMath.getRandom(20, 255);
    component.setFillColor(new MTColor(r1, g1, b1, 200));
    component.setNoStroke(false);
    component.setStrokeWeight(1);
    component.setStrokeColor(new MTColor(r1, g1, b1, 200));
    component.unregisterAllInputProcessors(); // Dont process input/gestures on this component

    roundingcircle.addChild(component);

    MTColor white = new MTColor(255, 255, 255);

    IFont fontArial = FontManager.getInstance().createFont(app, "arial.ttf", 50, white);

    MTTextArea text = new MTTextArea(app, fontArial);
    text.setFillColor(new MTColor(0, 0, 0, 0));
    text.setStrokeColor(new MTColor(0, 0, 0, 0));
    text.unregisterAllInputProcessors();
    roundingcircle.addChild(text);
    text.setPositionRelativeToParent(
        new Vector3D(event.getPosition().x, event.getPosition().y - 120));

    roundingcircle.setUserData("angle", event.getAngle());

    MTKeyboard keys = KeyboardPool.getInstance(app).getKeyboard();
    roundingcircle.addChild(keys);
    keys.setPositionRelativeToParent(
        new Vector3D(event.getPosition().x, event.getPosition().y + 150));
    keys.setUserData("fiducialID", EventID);

    text.setExpandDirection(ExpandDirection.UP);
    text.unregisterAllInputProcessors();
    /*
     * Need to find a way to keep the text centred at all times.
     */
    // text.setEnableCaret(true);

    keys.addTextInputListener(text);
    keys.addInputListener(text);

    FiducialRegistry.getInstance().putFiducialCompoent(EventID, roundingcircle);

    String searchTerm = "Doctor Who";
    TwitterSearch twsearch = new TwitterSearch();
    twsearch.search(searchTerm);

    canvas.addChild(roundingcircle);
  }
 /** Private method, dispose of fiducial */
 private void ended() {
   AbstractShape component = FiducialRegistry.getInstance().getFiducialComponent(EventID);
   component.destroy();
 }
 /**
  * Unhighlight button.
  *
  * @param shape the shape
  * @param opacity the opacity
  */
 private void unhighlightButton(AbstractShape shape, float opacity) {
   MTColor c = shape.getFillColor();
   c.setAlpha(opacity);
   shape.setFillColor(c);
 }
 /**
  * Highlight button.
  *
  * @param shape the shape
  */
 private void highlightButton(AbstractShape shape) {
   MTColor c = shape.getFillColor();
   c.setAlpha(255);
   shape.setFillColor(c);
 }
  /**
   * Inits the.
   *
   * @param x the x
   * @param y the y
   * @param width the width
   * @param height the height
   */
  private void init(float x, float y, float width, float height) {
    this.setNoStroke(true);
    this.setFillColor(new MTColor(255, 255, 255, 150));

    overlayGroup = new MTOverlayContainer(app, "Window Menu Overlay Group");

    if (menuImage == null) {
      menuImage =
          app.loadImage(
              MT4jSettings.getInstance().getDefaultImagesPath() + "blackRoundSolidCorner64sh2.png");
    }

    if (MT4jSettings.getInstance().isOpenGlMode()) {
      GLTextureSettings ts = new GLTextureSettings();
      ts.wrappingHorizontal = WRAP_MODE.CLAMP;
      ts.wrappingVertical = WRAP_MODE.CLAMP;
      GLTexture glTex = new GLTexture(app, menuImage.width, menuImage.height, ts);
      glTex.loadGLTexture(menuImage);
      this.setTexture(glTex);
    } else {
      this.setTexture(menuImage);
    }

    AbstractShape menuShape = this;
    menuShape.unregisterAllInputProcessors();
    menuShape.removeAllGestureEventListeners(DragProcessor.class);
    menuShape.registerInputProcessor(new DragProcessor(app));

    float buttonWidth = 80;
    float buttonHeight = 80;
    final float buttonOpacity = 170;

    // CLOSE BUTTON
    //		Vector3D a = new Vector3D(-width * 1.2f, height/2f);
    Vector3D a = new Vector3D(-width * 1.55f, 0);
    a.rotateZ(PApplet.radians(80));
    final MTRectangle closeButton =
        new MTRectangle(app, x + a.x, y + a.y, buttonWidth, buttonHeight);

    if (closeButtonImage == null) {
      closeButtonImage =
          app.loadImage(MT4jSettings.getInstance().getDefaultImagesPath() + "closeButton64.png");
    }

    closeButton.setTexture(closeButtonImage);
    closeButton.setFillColor(new MTColor(255, 255, 255, buttonOpacity));
    closeButton.setNoStroke(true);
    closeButton.setVisible(false);
    closeButton.removeAllGestureEventListeners(DragProcessor.class);
    closeButton.removeAllGestureEventListeners(RotateProcessor.class);
    closeButton.removeAllGestureEventListeners(ScaleProcessor.class);
    this.addChild(closeButton);

    // Check if this menu belongs to a window Scene (MTSceneWindow)
    // or was added to a normal scene
    // -> if its not a windowed scene we dont display the Restore button
    if (this.windowedScene) {
      // RESTORE BUTTON
      Vector3D b = new Vector3D(-width * 1.55f, 0);
      b.rotateZ(PApplet.radians(10));
      final MTRectangle restoreButton =
          new MTRectangle(app, x + b.x, y + b.y, buttonWidth, buttonHeight);

      if (restoreButtonImage == null) {
        restoreButtonImage =
            app.loadImage(
                MT4jSettings.getInstance().getDefaultImagesPath() + "restoreButton64.png");
      }

      restoreButton.setTexture(restoreButtonImage);
      restoreButton.setFillColor(new MTColor(255, 255, 255, buttonOpacity));
      restoreButton.setNoStroke(true);
      restoreButton.setVisible(false);
      restoreButton.removeAllGestureEventListeners(DragProcessor.class);
      restoreButton.removeAllGestureEventListeners(RotateProcessor.class);
      restoreButton.removeAllGestureEventListeners(ScaleProcessor.class);
      this.addChild(restoreButton);

      menuShape.addGestureListener(
          DragProcessor.class,
          new IGestureEventListener() {
            public boolean processGestureEvent(MTGestureEvent ge) {
              DragEvent de = (DragEvent) ge;
              switch (de.getId()) {
                case MTGestureEvent.GESTURE_STARTED:
                  restoreButton.setVisible(true);
                  closeButton.setVisible(true);
                  unhighlightButton(closeButton, buttonOpacity);
                  unhighlightButton(restoreButton, buttonOpacity);
                  break;
                case MTGestureEvent.GESTURE_UPDATED:
                  // Mouse over effect
                  if (closeButton.containsPointGlobal(de.getTo())) {
                    highlightButton(closeButton);
                  } else {
                    unhighlightButton(closeButton, buttonOpacity);
                  }
                  if (restoreButton.containsPointGlobal(de.getTo())) {
                    highlightButton(restoreButton);
                  } else {
                    unhighlightButton(restoreButton, buttonOpacity);
                  }
                  break;
                case MTGestureEvent.GESTURE_ENDED:
                  unhighlightButton(closeButton, buttonOpacity);
                  unhighlightButton(restoreButton, buttonOpacity);

                  InputCursor cursor = de.getDragCursor();
                  Vector3D restoreButtonIntersection =
                      restoreButton.getIntersectionGlobal(
                          Tools3D.getCameraPickRay(
                              getRenderer(),
                              restoreButton,
                              cursor.getCurrentEvtPosX(),
                              cursor.getCurrentEvtPosY()));
                  if (restoreButtonIntersection != null) {
                    logger.debug("--> RESTORE!");
                    MTSceneMenu.this.sceneTexture.restore();
                  }
                  Vector3D closeButtonIntersection =
                      closeButton.getIntersectionGlobal(
                          Tools3D.getCameraPickRay(
                              getRenderer(),
                              closeButton,
                              cursor.getCurrentEvtPosX(),
                              cursor.getCurrentEvtPosY()));
                  if (closeButtonIntersection != null) {
                    //							if (app.popScene()){
                    //								app.removeScene(scene); //FIXME wont work if the scene has a
                    // transition because we cant remove the still active scene
                    ////								destroy(); //this will be destroyed with the scene
                    //								sceneTexture.destroy(); //destroys also the MTSceneWindow and with it
                    // the scene
                    //								logger.debug("--> CLOSE!");
                    //							}
                    if (sceneTexture.restore()) {
                      //								app.removeScene(scene); //FIXME wont work if the scene has a
                      // transition because we cant remove the still active scene
                      //								destroy(); //this will be destroyed with the scene
                      sceneTexture
                          .destroy(); // destroys also the MTSceneWindow and with it the scene
                      logger.debug("--> CLOSE!");
                    }
                  }

                  restoreButton.setVisible(false);
                  closeButton.setVisible(false);
                  break;
                default:
                  break;
              }
              return false;
            }
          });
    } else {
      if (scene != null) {
        menuShape.addGestureListener(
            DragProcessor.class,
            new IGestureEventListener() {
              public boolean processGestureEvent(MTGestureEvent ge) {
                DragEvent de = (DragEvent) ge;
                switch (de.getId()) {
                  case MTGestureEvent.GESTURE_STARTED:
                    closeButton.setVisible(true);
                    unhighlightButton(closeButton, buttonOpacity);
                    break;
                  case MTGestureEvent.GESTURE_UPDATED:
                    // Mouse over effect
                    if (closeButton.containsPointGlobal(de.getTo())) {
                      highlightButton(closeButton);
                    } else {
                      unhighlightButton(closeButton, buttonOpacity);
                    }
                    break;
                  case MTGestureEvent.GESTURE_ENDED:
                    unhighlightButton(closeButton, buttonOpacity);

                    InputCursor cursor = de.getDragCursor();
                    Vector3D closeButtonIntersection =
                        closeButton.getIntersectionGlobal(
                            Tools3D.getCameraPickRay(
                                getRenderer(),
                                closeButton,
                                cursor.getCurrentEvtPosX(),
                                cursor.getCurrentEvtPosY()));
                    if (closeButtonIntersection != null) {
                      if (app.popScene()) {
                        destroy(); // Destroy this
                        scene.destroy(); // Destroy the scene
                        logger.debug("--> CLOSE!");
                      }
                    }
                    closeButton.setVisible(false);
                    break;
                  default:
                    break;
                }
                return false;
              }
            });
      }
    }
  }