Package org.rsg.lib.chrome

Source Code of org.rsg.lib.chrome.Chrome

package org.rsg.lib.chrome;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Frame;
import java.awt.GraphicsDevice;
import java.awt.GraphicsEnvironment;
import java.awt.Insets;
import java.awt.MouseInfo;
import java.awt.Point;
import java.awt.Toolkit;
import java.awt.event.ComponentEvent;
import java.awt.event.ComponentListener;
import java.awt.event.MouseEvent;
import org.rsg.lib.LibUtilities;
import org.rsg.lib.chrome.button.AbstractButton;
import org.rsg.lib.chrome.button.Header;
import org.rsg.lib.chrome.button.Kill;
import org.rsg.lib.chrome.button.Maximize;
import org.rsg.lib.chrome.button.Minimize;
import org.rsg.lib.chrome.button.Resize;
import org.rsg.lib.color.ColorUtilities;
import processing.core.PApplet;

public class Chrome implements ComponentListener {
  public static boolean shouldWarnAboutLowFrameRate = false;
  private static boolean shouldLockToAspectRatio = false;
  public static boolean shouldAutoHide = false;
 
  private boolean initialized = false;
  private static float originalAspectRatio = 768/1024;
  public static final int MAC_CHROME_HEIGHT = 22;
  public static final int HEIGHT = 33;
  private static final int MINIMUM_WINDOW_WIDTH = 200;
  private static final int MINIMUM_WINDOW_HEIGHT = HEIGHT*2;
  public static PApplet papplet;
  private float mousex = 0.0f;
  private float mousey = 0.0f;
  private float pwidth = 0.0f;
  private float pheight = 0.0f;
  private Point ppointer;
  private boolean isLocked4Movement = false;
  private boolean isLocked4Resize = false;
  private static Dimension APP_SIZE_DEFAULT = new Dimension(800, 600);
  private static Dimension APP_SIZE = APP_SIZE_DEFAULT;
  public static boolean FULL_SCREEN = false;
 
  //  public static boolean WAS_FULL_SCREEN_BEFORE_MINIMIZE = false;
  private static String label = "Application";
  private final static int ALPHA_MAX = 255;
  private final static int ALPHA_MIN = 1;
  private final static int FRAMESPERSEC = 20;
  private final static int TIMEOUTSECS = 10;
  private final static int ALPHA_STEP = 50;
  private final static int alpha_start = ALPHA_MAX + (FRAMESPERSEC * TIMEOUTSECS * ALPHA_STEP);
  private static int _alpha = alpha_start;
  public static AbstractButton minimize = new Minimize();
//  public static AbstractButton maximize = new Maximize();
  public static AbstractButton kill = new Kill();
  public static AbstractButton resize = new Resize();
  public static AbstractButton header = new Header();
 
  //singleton pattern
    public static Chrome instance() { return INSTANCE; }
    private static final Chrome INSTANCE = new Chrome();
  private Chrome() {}
 
  public final static int FRAME_RATE_STARTING = 20;

 
  //DRAW 
  public void draw(PApplet papplet) {
    if(!initialized) { initWithParent(papplet); }
    drawChrome(papplet);
    if(shouldAutoHide)
      updateAlpha();
    Tooltip.run();

    minimize.pick(papplet);
//    maximize.pick(papplet);
    kill.pick(papplet);
    resize.pick(papplet);
//    if(resize.pick(papplet) && isVisible()) {
//      cursor(Cursor.SE_RESIZE_CURSOR);
//    } else {
//      cursor(Cursor.DEFAULT_CURSOR);
//    }
   
   
    //System.out.println("[Chrome] alpha():"+alpha() + " _alpha:"+_alpha);
  }
 
//  //only changes it if different
//  private void cursor(int i) {
//    Cursor c = papplet.getCursor();
//    if(c.getType() != i)
//      papplet.cursor(i);   
//  }
 
  private void updateAlpha() {
    if(_alpha > ALPHA_MIN)
      _alpha -= ALPHA_STEP;
  }
 
  private void drawChrome(PApplet papplet) {
    //TODO: stop drawing if gui is invisible?
   
    //header
    header.draw(papplet);
   
    //buttons
    minimize.draw(papplet);
//    maximize.draw(papplet);
    kill.draw(papplet);   
    resize.draw(papplet);     

    //thin box around whole app
    papplet.noFill();
    papplet.stroke(Color.BLACK.getRGB()); //no alpha for this, it's always visible      
    if(shouldWarnAboutLowFrameRate) {
      int rate = PApplet.constrain(PApplet.ceil(papplet.frameRate), 0, FRAME_RATE_STARTING);
      if(rate < FRAME_RATE_STARTING) {
        papplet.stroke(Color.RED.getRGB()); //no alpha for this, it's always visible
        papplet.strokeWeight(3);
      }
    }
    papplet.rect(0, 0, APP_SIZE.width-1, APP_SIZE.height-1);
  }

  //MOUSE
  public void mouseEvent(MouseEvent e) {
    resetAlpha();//any mouse event makes chrome visible
    int id = e.getID();

    if(!FULL_SCREEN) {
      //LOCK ON MOUSE DOWN
      if (id == MouseEvent.MOUSE_PRESSED) {
        if (resize.isPicked(e)) { //for resize
          isLocked4Resize = true;
          ppointer = MouseInfo.getPointerInfo().getLocation();
          pwidth = APP_SIZE.width;
          pheight = APP_SIZE.height;
        } else if (header.isPicked(e)) { //for move   
          isLocked4Movement = true;
          mousex = papplet.mouseX;
          mousey = papplet.mouseY;
        }
       
      //RESIZE WINDOW
      } else if (isLocked4Resize && (id == MouseEvent.MOUSE_DRAGGED)) {
        Point pointer = MouseInfo.getPointerInfo().getLocation();
        float dx = pointer.x - ppointer.x;
        float dy = pointer.y - ppointer.y;
        int w = (int)(pwidth + dx);
        int h = (int)(pheight + dy);
        Dimension newSize = normalizeScreenSize(w,h);
        papplet.frame.setSize(newSize);
       
      //MOVE WINDOW
      } else if (isLocked4Movement && (id == MouseEvent.MOUSE_DRAGGED)) {
        Point p = MouseInfo.getPointerInfo().getLocation();
        int x = (int) (p.x - mousex);
        int y = (int) (p.y - mousey);
        Point newLocation = magnetizeToScreenEdge(normalizeScreenLocation(x,y));
        papplet.frame.setLocation(newLocation);
       
      //UNLOCK ALL ON MOUSE UP
      } else if (id == MouseEvent.MOUSE_RELEASED) {
        isLocked4Resize = false;
        isLocked4Movement = false;
      }
    }

    //DOUBLE CLICK ON HEADER
    if (header.isPicked(e) && (id == MouseEvent.MOUSE_CLICKED) && (e.getClickCount() > 1)) {
//      System.out.println("[Chrome] DOUBLE CLICK ON HEADER");   
      header.click(papplet);     
    }

  }

//  private boolean highlightButton(AbstractButton button, MouseEvent e) {
//    if (button.isPicked) {
//      if(e.getID() == MouseEvent.MOUSE_CLICKED) {
//        button.click(papplet);
//      }
//      return true;
//    } else {
//      button.isHighlighted = false;   
//      return false;
//    } 
//  }
 

  private Dimension normalizeScreenSize(int w, int h) {
    return normalizeScreenSize(new Dimension(w,h));
  }

  public static Dimension getAPP_SIZE() {
    return APP_SIZE;
  }

  private Dimension normalizeScreenSize(Dimension d) {
      int w = PApplet.max(d.width, MINIMUM_WINDOW_WIDTH);
      int h = PApplet.max(d.height, MINIMUM_WINDOW_HEIGHT);
//      System.out.println("[Chrome] normalizeScreenSize shouldLockToAspectRatio:"+shouldLockToAspectRatio + " " + originalAspectRatio);
      if(shouldLockToAspectRatio)
        h = (int) (w*originalAspectRatio);
      return new Dimension(w,h);
  }

  private Point normalizeScreenLocation(int x, int y) {
    return normalizeScreenLocation(new Point(x,y));
  }

  //turned this off because it was buggy w/ multiple monitors
  private Point normalizeScreenLocation(Point p) {
//      int x = PApplet.constrain(p.x, -(APP_SIZE.width) + HEIGHT, screenSize().width - HEIGHT);
//      int y = PApplet.constrain(p.y, screenInsets().top, screenSize().height - HEIGHT);
//      Point newp = new Point(x,y);
//      //System.out.println("p:"+p + " newp:"+newp);
//      return newp;
    return p;
  }

  private static final int MAGNETIC_RANGE = 15;
  private Point magnetizeToScreenEdge(Point p) {
    //if(!isOnPrimaryScreen(p)) {return p;}
   
    //left
    if((p.x < MAGNETIC_RANGE) && (p.x > -MAGNETIC_RANGE)) {p.x = 0;}
   
    //top
    if(xIsOnPrimaryScreen(p)) {
      if(LibUtilities.isMac()) {
        if(p.y < (MAC_CHROME_HEIGHT + MAGNETIC_RANGE)) {p.y = MAC_CHROME_HEIGHT;}
      } else {
        if(p.y < MAGNETIC_RANGE) {p.y = 0;}     
      }
    }

    //right
    int w = screenSize().width - APP_SIZE.width;
    if((p.x > (w - MAGNETIC_RANGE)) &&
       (p.x < (w + MAGNETIC_RANGE))) {p.x = w;}

    //bottom
    int h = screenSize().height - APP_SIZE.height;
    if((p.y > (h - MAGNETIC_RANGE)) &&
       (p.y < (h + MAGNETIC_RANGE))) {p.y = h;}

      return p;
  }
 
  private boolean xIsOnPrimaryScreen(Point p) {
    int w = screenSize().width;
    return  (p.x < w) &&
        ((p.x + w) > 0);
  }
 
  //FULLSCREEN
  public static void toggleFullscreen(PApplet papplet) {
    GraphicsDevice defDevice = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice();             
    if (FULL_SCREEN) {
      defDevice.setFullScreenWindow(null);
    } else {
      defDevice.setFullScreenWindow(papplet.frame);
    }
    FULL_SCREEN = !FULL_SCREEN;
    updateSize(papplet);
    papplet.frame.toFront();
  }

  public static void minimize(PApplet papplet) {
    if(Chrome.FULL_SCREEN) {
      toggleFullscreen(papplet);
    }
    papplet.frame.setState(Frame.ICONIFIED);   
    papplet.mouseX = 0;
    papplet.mouseY = 0;
//    Tooltip.clear(); //have to do this manually for some reason
  }
 
  //UTILITIES
  public static int white() {
    return ColorUtilities.colorWithAlphaAsInt(Color.WHITE, alpha());
  }
 
  public static int black() {
    return ColorUtilities.colorWithAlphaAsInt(Color.BLACK, alpha());
  }

  public static int yellow() {
    return ColorUtilities.colorWithAlphaAsInt(Color.YELLOW, alpha());
  }

  public static int lightYellow() {
    return new Color(255, 255, 202, alpha()).getRGB();
  }

  public static int gray() {
    return ColorUtilities.colorWithAlphaAsInt(Color.GRAY, alpha());
  }

  public static int darkgray() {
    return ColorUtilities.colorWithAlphaAsInt(Color.DARK_GRAY, alpha());
  }

  public static int lightgray() {
    return ColorUtilities.colorWithAlphaAsInt(Color.LIGHT_GRAY, alpha());
  }

  public static Dimension screenSize(){
    return Toolkit.getDefaultToolkit().getScreenSize();
  }
 
  public static Insets screenInsets() {   
//TODO get this more effectively using a Toolkit call like this?
//    return Toolkit.getDefaultToolkit().getScreenInsets(GraphicsConfiguration gc);
    if(LibUtilities.isMac()) {
      return new Insets(MAC_CHROME_HEIGHT, 0, 0, 0);
    } else {
      return new Insets(0, 0, 0, 0);     
    }
  }

  public static void updateSize(PApplet papplet) {
    Dimension d = new Dimension(papplet.frame.getSize())
    updateSize(papplet, d);
  }

  public static void updateSize(PApplet papplet, Dimension d) {
    APP_SIZE = d;
  }
 
 

  private void initWithParent(PApplet papplet) {
    initialized = true;
    Chrome.papplet = papplet;
    papplet.registerMouseEvent(this);   
    papplet.addComponentListener(this);
  }
   
//  private boolean isPicked(Rectangle target, MouseEvent e) {
//    return target.contains(new Point(e.getX(), e.getY()));
//  }

  public int labelWindowWidth() {
    return header.bounds().x - Header.SPACER_LEFT_LABEL;
  }

  public static String getLabel() {
    return label;
  }

  public static void setLabel(String label) {
    Chrome.label = label;
  }

  private static void resetAlpha() {
    _alpha = alpha_start;
  }

  public static boolean isVisible() {
    return !(_alpha == ALPHA_MAX);
  }
 
  public static int alpha() {
    if (_alpha < ALPHA_MIN) {return ALPHA_MIN;}
    if (_alpha > ALPHA_MAX) {return ALPHA_MAX;}
    return _alpha;
  }

  public static void setAPP_SIZE(Dimension app_size) {
//    APP_SIZE_DEFAULT.setSize(app_size);
    originalAspectRatio = (float) app_size.height / app_size.width;
    APP_SIZE.setSize(app_size);
//    System.out.println("[Chrome] setAPP_SIZE("+app_size.width+","+app_size.height+") originalAspectRatio:"+originalAspectRatio);
  }
 
//  private static float getOriginalAspectRatio() {
//    return APP_SIZE_DEFAULT.width / APP_SIZE_DEFAULT.height;
//  }
 
  public static void setShouldLockToAspectRatio(boolean shouldLockToAspectRatio) {
    Chrome.shouldLockToAspectRatio = shouldLockToAspectRatio;
  }

 
  ///////////////////////////////////////////////////////
  //INTERFACE: ComponentListener 
  public void componentHidden(ComponentEvent arg0) {}
  public void componentShown(ComponentEvent arg0) {}
  public void componentMoved(ComponentEvent arg0) {}
  public void componentResized(ComponentEvent arg0) {
//    System.out.println("["+this.getClass().getSimpleName()+"] componentResized("+arg0+")");
    updateSize(papplet, arg0.getComponent().getSize());
    ChromeDispatcher.rescaleWindow();
    papplet.smooth();
  }
}
TOP

Related Classes of org.rsg.lib.chrome.Chrome

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.