All Downloads are FREE. Search and download functionalities are using the official Maven repository.

processing.mode.java.pdex.JavaTextAreaPainter Maven / Gradle / Ivy

Go to download

Processing is a programming language, development environment, and online community. This Java Mode package contains the Java mode for Processing IDE.

The newest version!
/* -*- mode: java; c-basic-offset: 2; indent-tabs-mode: nil -*- */

/*
Part of the Processing project - http://processing.org
Copyright (c) 2012-16 The Processing Foundation

This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License version 2
as published by the Free Software Foundation.

This program 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 General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation, Inc.
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/

package processing.mode.java.pdex;

import java.awt.Cursor;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.RenderingHints;
import java.awt.Toolkit;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.image.BufferedImage;
import java.util.List;

import processing.app.SketchCode;
import processing.app.syntax.PdeTextAreaPainter;
import processing.app.syntax.TextAreaDefaults;
import processing.mode.java.JavaEditor;
import processing.mode.java.tweak.ColorControlBox;
import processing.mode.java.tweak.ColorSelector;
import processing.mode.java.tweak.Handle;
import processing.mode.java.tweak.Settings;


/**
 * Customized line painter to handle tweak mode features.
 */
public class JavaTextAreaPainter extends PdeTextAreaPainter {

  public JavaTextAreaPainter(final JavaTextArea textArea, TextAreaDefaults defaults) {
    super(textArea, defaults);

    // TweakMode code
    tweakMode = false;
    cursorType = Cursor.DEFAULT_CURSOR;
  }


  // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

  // TWEAK MODE


	protected int horizontalAdjustment = 0;

	public boolean tweakMode = false;
	public List> handles;
	public List> colorBoxes;

	public Handle mouseHandle = null;
	public ColorSelector colorSelector;

	int cursorType;
	BufferedImage cursorImg = new BufferedImage(16, 16, BufferedImage.TYPE_INT_ARGB);
  Cursor blankCursor;
  // this is a temporary workaround for the CHIP, will be removed
  {
    Dimension cursorSize = Toolkit.getDefaultToolkit().getBestCursorSize(16, 16);
    if (cursorSize.width == 0 || cursorSize.height == 0) {
      blankCursor = Cursor.getDefaultCursor();
    } else {
      blankCursor = Toolkit.getDefaultToolkit().createCustomCursor(cursorImg, new Point(0, 0), "blank cursor");
    }
  }

	@Override
	synchronized public void paint(Graphics gfx) {
		super.paint(gfx);

		if (tweakMode && handles != null) {
			int currentTab = getCurrentCodeIndex();
			// enable anti-aliasing
			Graphics2D g2d = (Graphics2D)gfx;
			g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
                				   RenderingHints.VALUE_ANTIALIAS_ON);

			for (Handle n : handles.get(currentTab)) {
				// update n position and width, and draw it
				int lineStartChar = textArea.getLineStartOffset(n.line);
				int x = textArea.offsetToX(n.line, n.newStartChar - lineStartChar);
				int y = textArea.lineToY(n.line) + fm.getHeight() + 1;
				int end = textArea.offsetToX(n.line, n.newEndChar - lineStartChar);
				n.setPos(x, y);
				n.setWidth(end - x);
				n.draw(g2d, n==mouseHandle);
			}

			// draw color boxes
			for (ColorControlBox cBox: colorBoxes.get(currentTab)) {
				int lineStartChar = textArea.getLineStartOffset(cBox.getLine());
				int x = textArea.offsetToX(cBox.getLine(), cBox.getCharIndex() - lineStartChar);
				int y = textArea.lineToY(cBox.getLine()) + fm.getDescent();
				cBox.setPos(x, y+1);
				cBox.draw(g2d);
			}
		}
	}


	protected void startTweakMode() {
	  addMouseListener(new MouseListener() {

	    @Override
	    public void mouseReleased(MouseEvent e) {
	      if (mouseHandle != null) {
	        mouseHandle.resetProgress();
	        mouseHandle = null;

	        updateCursor(e.getX(), e.getY());
	        repaint();
	      }
	    }

	    @Override
	    public void mousePressed(MouseEvent e) {
	      int currentTab = getCurrentCodeIndex();
	      // check for clicks on number handles
	      for (Handle n : handles.get(currentTab)) {
	        if (n.pick(e.getX(), e.getY())) {
	          cursorType = -1;
	          JavaTextAreaPainter.this.setCursor(blankCursor);
	          mouseHandle = n;
	          mouseHandle.setCenterX(e.getX());
	          repaint();
	          return;
	        }
	      }

	      // check for clicks on color boxes
	      for (ColorControlBox box : colorBoxes.get(currentTab)) {
	        if (box.pick(e.getX(), e.getY())) {
	          if (colorSelector != null) {
	            // we already show a color selector, close it
	            colorSelector.frame.dispatchEvent(new WindowEvent(colorSelector.frame, WindowEvent.WINDOW_CLOSING));
	          }

	          colorSelector = new ColorSelector(box);
	          colorSelector.frame.addWindowListener(new WindowAdapter() {
	            public void windowClosing(WindowEvent e) {
	              colorSelector.frame.setVisible(false);
	              colorSelector = null;
	            }
	          });
	          colorSelector.show(getLocationOnScreen().x + e.getX() + 30,
	                             getLocationOnScreen().y + e.getY() - 130);
	        }
	      }
	    }

      @Override
      public void mouseExited(MouseEvent e) { }

      @Override
      public void mouseEntered(MouseEvent e) { }

      @Override
      public void mouseClicked(MouseEvent e) { }
    });

	  addMouseMotionListener(new MouseMotionListener() {

	    @Override
	    public void mouseMoved(MouseEvent e) {
	      updateCursor(e.getX(), e.getY());

	      if (!Settings.alwaysShowColorBoxes) {
	        showHideColorBoxes(e.getY());
	      }
	    }

	    @Override
	    public void mouseDragged(MouseEvent e) {
	      if (mouseHandle != null) {
	        // set the current drag amount of the arrows
	        mouseHandle.setCurrentX(e.getX());

	        // update code text with the new value
	        updateCodeText();

	        if (colorSelector != null) {
	          colorSelector.refreshColor();
	        }

	        repaint();
	      }
	    }
    });
	  tweakMode = true;
	  setCursor(new Cursor(Cursor.DEFAULT_CURSOR));
		repaint();
	}


	protected void stopTweakMode() {
		tweakMode = false;

		if (colorSelector != null) {
			colorSelector.hide();
			WindowEvent windowEvent =
			  new WindowEvent(colorSelector.frame, WindowEvent.WINDOW_CLOSING);
			colorSelector.frame.dispatchEvent(windowEvent);
		}

		setCursor(new Cursor(Cursor.TEXT_CURSOR));
		repaint();
	}


	protected void updateTweakInterface(List> handles,
	                                    List> colorBoxes) {
		this.handles = handles;
		this.colorBoxes = colorBoxes;

		updateTweakInterfacePositions();
		repaint();
	}


	/**
	* Initialize all the number changing interfaces.
	* synchronize this method to prevent the execution of 'paint' in the middle.
	* (don't paint while we make changes to the text of the editor)
	*/
	private synchronized void updateTweakInterfacePositions() {
		SketchCode[] code = getEditor().getSketch().getCode();
		int prevScroll = textArea.getVerticalScrollPosition();
		String prevText = textArea.getText();

		for (int tab=0; tab




© 2015 - 2024 Weber Informatics LLC | Privacy Policy