Package guicomponents

Source Code of guicomponents.G4P$AppletInfo

/*
  Part of the GUI for Processing library
    http://www.lagers.org.uk/g4p/index.html
  http://gui4processing.googlecode.com/svn/trunk/

  Copyright (c) 2008-09 Peter Lager

  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.

  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., 59 Temple Place, Suite 330,
  Boston, MA  02111-1307  USA
*/

package guicomponents;

import java.awt.Font;
import java.awt.GraphicsEnvironment;
import java.util.Collections;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;

import processing.core.PApplet;
import processing.core.PConstants;
import processing.core.PFont;
import processing.core.PGraphics;
import processing.core.PMatrix;
import processing.core.PMatrix2D;
import processing.core.PMatrix3D;
import processing.core.PStyle;

/**
* This class has only static methods. It keeps track of all GComponents created.
* Its primary role is encapsulated in the draw() method which can override
* the default Processing drawing mechanism.
*
* @author Peter Lager
*
*/
public class G4P implements PConstants, GConstants {

  // Keeps info about all applets and their controls
  private static HashMap<PApplet, AppletInfo> applets = new HashMap<PApplet, AppletInfo>();

  // Will be set when and first window is added
  public static PApplet mainWinApp = null;

  public static PStyle g4pStyle = null;

  public static boolean messages = true;

  /**
   * An array of names representing all the available fonts.
   */
  final public static String[] fontFamilies = GraphicsEnvironment.getLocalGraphicsEnvironment().getAvailableFontFamilyNames();

 
  /** INTERNAL USE ONLY  Cursor over changer */
  private static GCursorImageChanger mcd = new GCursorImageChanger();
  public static boolean overControl = false;
  public static boolean cursorChangeEnabled = false;
  public static int mouseOff = ARROW;
  public static int mouseOver = HAND;

  /**
   * See if this font family is available on this user's computer system
   * and return the family name if found. If the font family is unavailable
   * then it returns the name "Dialog"
   * @param family
   * @return
   */
  public static String getFamily(String family){
    for(String f : fontFamilies)
      if(f.equalsIgnoreCase(family))
        return f;
    return "Dialog";
  }


  /**
   * Enables or disables cursor over component change. <br>
   * This method is ignore if an applet or window has not been
   * registered with G4P or the mouse over state is not being changed.
   *
   * This is ignored if no G4P components have been created yet
   * @param enable
   */
  public static void setMouseOverEnabled(boolean enable){
    if(cursorChangeEnabled != enable && mainWinApp != null){
      if(enable == false){
        Set<PApplet> apps = applets.keySet();
        for(PApplet pa : apps)
          pa.cursor(mouseOff);       
      }
      cursorChangeEnabled = enable;
    }
  }

  public static void refresh(){
    Set<PApplet> apps = applets.keySet();
    for(PApplet pa : apps)
      pa.repaint();       
  }

  /**
   * Inform G4P which cursor shapes will be used.
   * Initial values are ARROW (off) and HAND (over)
   *
   * @param cursorOff
   * @param cursorOver
   */
  public static void cursor(int cursorOff, int cursorOver){
    mouseOff = cursorOff;
    mouseOver = cursorOver;
  }

  /**
   * Inform G4P which cursor to use for mouse over.
   *
   * @param cursorOver
   */
  public static void cursor(int cursorOver){
    mouseOver = cursorOver;
  }

  /**
   * INTERNAL USE ONLY <br>
   * This should be called by all ctors in GComponent and since all GUI
   * components inherit from GComponent and are required to call a
   * GComponent ctor then all GUI components will automatically be
   * registered in the set.
   * @param theApplet
   *
   * @param c the component that has been created.
   */
  public static void addComponent(PApplet app, GComponent c){
    if(g4pStyle == null)
      getStyle();
    // info exists for all GWindow objects
    AppletInfo info = applets.get(app);
    // If info == null then this must be the main Processing window and
    // since the matrix may have already been changed e.g. creating
    // a PeaseyCam object will do this, so recalculate the original matrix.
    if(info == null){
      // We have the main applet window so create the AppletInfo for it
      info = addWindow(app);
      if(app.g.is2D())
        info.orgMatrix = new PMatrix2D();
      else
        info.orgMatrix =
          new PMatrix3D(
              1, 0, 0, -0.5f * app.width,
              0, 1, 0, -0.5f * app.height,
              0, 0, 1, -0.5f * app.height / (float)Math.tan(Math.PI / 6.0),
              0, 0, 0, 1
          );
    }
    info.addComponent(c);
  }

  /**
   * INTERNAL USE ONLY <br>
   * Remove a component so that it is permanently unavailable. <br>
   * Do not call this method directly otherwise your program will crash. <br>
   * Use the components dispose method instead.
   *
   * @param c the component to remove
   */
  public static void dumpComponent(GComponent c){
    AppletInfo info = applets.get(c.getPApplet());
    if(info != null)
      info.removeControl(c);
  }

  /**
   * Add the window's PApplet object to G4P if not already there. <br>
   * @param window
   */
  public static void addWindow(GWindow window){
    if(window != null && window.papplet != null)
      addWindow(window.papplet);
  }

  /**
   * Add a PApplet object to G4P if not already there. <br>
   * The only time you might want to use this is when you are mixing
   * G4P and OpenGL. In which case call this method from setup() immediately
   * after the call to size() and before any statements that might alter
   * the initial drawing matrix e.g. <br>
   * <pre>void setup(){</pre> <br>
   * <pre>  size(480, 320);</pre> <br>
   * <pre>  G4P.addWindow(this);</pre> <br>
   * @param app the PApplet object to add
   */
  public static AppletInfo addWindow(PApplet app){
    AppletInfo info = applets.get(app); // avoid duplicates
    if(info == null){
      // If this is the first time then initialise mouse over ability
      if(applets.isEmpty()){
        mainWinApp = app;
        mainWinApp.registerPost(mcd);
      }
      info = new AppletInfo(app);
      applets.put(app, info);
    }
    return info;
  }

  /**
   * INTERNAL USE ONLY <br>
   * Remove control window - called when a ControlWindow is closed
   * for good.
   * 
   * @param window
   */
  public static void removeWindow(GWindow window){
    if(window != null && window.papplet != null)
      applets.remove(window.papplet);
  }

  /**
   * Determines whether a window is still open or has been closed
   * @param window
   * @return true if the window is still open
   */
  public static boolean isWindowActive(GWindow window){
    if(window != null && window.papplet != null)
      return applets.containsKey(window.papplet);
    else
      return false;
  }

  /**
   * INTERNAL USE ONLY
   */
  private static void getStyle(){
    PGraphics temp = new PGraphics();

    g4pStyle = temp.getStyle();

    g4pStyle.rectMode = CORNER;
    g4pStyle.ellipseMode = DIAMETER;
    g4pStyle.imageMode = CORNER;
    g4pStyle.shapeMode = CORNER;

    g4pStyle.colorMode = RGB;
    g4pStyle.colorModeA = 255.0f;
    g4pStyle.colorModeX = 255.0f;
    g4pStyle.colorModeY = 255.0f;
    g4pStyle.colorModeZ = 255.0f;
  }

  /**
   * Set the color scheme to be used by G4P<br>
   * Only reqd if different from the default blue scheme to be
   * global specify before creating GUI components
   *
   * Available schemes:
   * BLUE_SCHEME, GREEN_SCHEME, RED_SCHEME, PURPLE_SCHEME
   * YELLOW_SCHEME, CYAN_SCHEME, GREY_SCHEME
   *
   * @param theApplet
   * @param schemeNo GCScheme.GREEN_SCHEME
   */
  public static void setColorScheme(PApplet theApplet, int schemeNo){
    if(theApplet != null)
      GComponent.globalColor = GCScheme.getColor(theApplet,  schemeNo);
  }

  /**
   * Set the font type and size to be used by G4P<br>
   * Only reqd if different from the default "Serif" 11 <br>
   * to be global specify before creating GUI components
   *
   * @param theApplet
   * @param fontName name of font
   * @param fontSize font size
   *
   * @deprecated
   */
  public static void setFont(PApplet theApplet, String fontName, int fontSize){
    if(theApplet != null)
      GComponent.globalFont = GFont.getFont(theApplet, fontName, fontSize);
  }

  /**
   * Set the global font to be used by all controls. <br>
   * You can override the font used by individual controls with
   * the equivalent setFont method for the control.
   *
   * @param fontName font family name
   * @param fontSize font size
   */
  public static void setFont(String fontName, int fontSize){
    setFont(fontName, fontSize, Font.PLAIN);
  }

  /**
   * Set the global font to be used by all controls. <br>
   * You can override the font used by individual controls with
   * the equivalent setFont method for the control. <br>
   *
     * The style argument is an integer bitmask that may
     * be PLAIN, or a bitwise union of BOLD and/or ITALIC
     * (for example, ITALIC or BOLD|ITALIC). If the style is
     * unrecognised it will default to PLAIN.
   *
   * @param fontName font family name
   * @param fontSize font size
   * @param style style e.g. Font.PLAIN
   */
  public static void setFont(String fontName, int fontSize, int style){
    GComponent.fGlobalFont = new Font(fontName, fontSize, style);
  }
 
  /**
   * Set the global font to be used by all controls. <br>
   * You can override the font used by individual controls with
   * the equivalent setFont method for the control. <br>
   *
   * @param font the java.awt.Font to use
   */
  public static void setFont(Font font){
    GComponent.fGlobalFont = font;
  }
 
  /**
   * Set the global font to be used by all controls. <br>
   * You can override the font used by individual controls with
   * the equivalent setFont method for the control. <br>
   *
   * @param pfont the Processing font to use
   */
//  public static void setFont(PFont pfont){
//    GComponent.fGlobalFont = pfont.getFont();
//  }
 
 
 
  /**
   * When you first use G4P(app) it switches off auto draw for the
   * PApplet app.
   *
   */
  public static void draw(PApplet app){
    AppletInfo info = applets.get(app);
    if(info != null && info.paControls.size() > 0){
      // If this method has been called and this applet is still using autodraw
      // then it is time to take over the responsibility for drawing from
      // the applet.
      if(info.autoDrawOn){
        for(GComponent comp : info.paControls){
          if(comp.getParent() == null){
            comp.regDraw = false;
            comp.getPApplet().unregisterDraw(comp);
          }
        }
        info.autoDrawOn = false;
      }
      // Draw the components on the mainWinApp only.
      // Note that GPanels will call the appropriate
      // draw methods for the components on them
      // Now setup for 2D display
      app.noLights();
      app.pushMatrix();
      app.hint(PConstants.DISABLE_DEPTH_TEST);
      app.resetMatrix();
      app.applyMatrix(info.orgMatrix);
      // Draw components
      for(GComponent comp : info.paControls){
        if(comp.getParent() == null && comp.getPApplet() == app)
          comp.draw();
      }
      // Done with drawing components
      app.hint(PConstants.ENABLE_DEPTH_TEST);
      app.popMatrix();
    }
  }

  /**
   * Unregister all GComponents that have no parent from PApplets auto draw
   * mechanism. The G4P.draw() will now be responsible for drawing the
   * components.
   *
   * It is called once on the first call to G4P.draw()
   *
   */
  private static void unregisterFromPAppletDraw(PApplet app) {
    AppletInfo info = applets.get(app);
    if(info != null){
      //    List<GComponent> paControls = info.paControls);
      for(GComponent comp : info.paControls){
        if(comp.getParent() == null){
          comp.regDraw = false;
          comp.getPApplet().unregisterDraw(comp);
        }
      }
      info.autoDrawOn = false;
    }
  }

  /**
   * Is autodraw on for the PApplet app?
   */
  public static boolean isAutoDrawOn(PApplet app){
    AppletInfo info = applets.get(app);
    if(info != null)
      return info.autoDrawOn;
    else
      return false;
  }

  /**
   * G4P has a range of support messages eg <br>if you create a GUI component
   * without an event handler or, <br>a slider where the visible size of the
   * slider is less than the difference between min and max values.
   *
   * This method allows the user to enable (default) or disable this option. If
   * disable then it should be called before any GUI components are created.
   *
   * @param enable
   */
  public static void messagesEnabled(boolean enable){
    messages = enable;
  }

  /**
   * This will sort the GUI controls in a secondary window.
   * @param window the GWindow object
   */
  public static void setDrawOrder(GWindow window){
    PApplet app = window.papplet;
    setDrawOrder(app);
  }

  /**
   * If you are using GPanel or GCombo it would be useful to call this method in setup
   * or customGUI (if using GUI builder tool). <br>
   * DO NOT CALL this method from inside the draw() method. <br>
   * This will sort the draw order for GUI controls based on their z attribute - note that
   * a control will be drawn before a control with a higher z. If two controls have the
   * same z value, then the controls are ordered by their vertical screen position. This means
   * that controls near the bottom of the display will be drawn before those nearer the top.
   * @param windowApp the PApplet object
   */
  public static void setDrawOrder(PApplet app){
    AppletInfo info = applets.get(app);
    if(info != null && info.autoDrawOn ){
      Collections.sort(info.paControls, new GComponent.Z_Order());
      // Change physical order in PApplet by removing then adding the components
      if(info.autoDrawOn){
        for(GComponent comp : info.paControls){
          if(comp.getParent() == null)
            app.unregisterDraw(comp);
        }
        for(GComponent comp : info.paControls){
          if(comp.getParent() == null)
            app.registerDraw(comp);
       
      }
    }
  }

  /**
   * INTERNAL USE ONLY <br>
   * Used to bring a panel to the front of the display. <br>
   * Do not use this method directly.
   */
  public static void moveToFrontForDraw(GComponent comp){
    PApplet app = comp.getPApplet();
    AppletInfo info = applets.get(app);
    if(info != null && info.paControls.remove(comp)){
      info.paControls.add(comp);
      if(comp.parent == null && app != null && info.autoDrawOn){
        app.unregisterDraw(comp);
        app.registerDraw(comp);
      }
    }
  }

  /**
   * INTERNAL USE ONLY <br>
   * Used to ensure the panel is the last component to be tested for mouse events. <br>
   * Do not use this method.
   */
  public static void moveToFrontForMouse(GComponent comp){
    PApplet app = comp.getPApplet();
    AppletInfo info = applets.get(app);
    if(info != null && info.paControls.remove(comp)){
      info.paControls.add(comp);
      app.unregisterMouseEvent(comp);
      app.registerMouseEvent(comp);
    }
  }

  // Only used inside G4P to keep track of windows and associated applets
  private static class AppletInfo {
    public PMatrix orgMatrix;
    public List<GComponent> paControls;
    public boolean autoDrawOn = true;

    /**
     * @param papplet
     */
    public AppletInfo(PApplet papplet) {
      if(papplet.g.is3D())
        orgMatrix = papplet.getMatrix((PMatrix3D)null);
      else
        orgMatrix = papplet.getMatrix((PMatrix2D)null);
      paControls = new LinkedList<GComponent>();
    }

    /**
     * If the component is not null and has not already been added then
     * add it to the list and return true. Otherwise the operation is
     * ignored and the method returns false;
     * @param comp the component to add
     * @return true if successfully added else false
     */
    public boolean addComponent(GComponent comp){
      if(comp == null)
        return false;
      if(paControls.contains(comp)){
        GMessenger.message(ADD_DUPLICATE, comp ,null);
        return false;
      }
      paControls.add(comp);
      return true;
    }

    /**
     * Removes the component from the
     * @param c
     * @return
     */
    public boolean removeControl(GComponent c){
      return paControls.remove(c);
    }

  }

}
TOP

Related Classes of guicomponents.G4P$AppletInfo

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.