Java source code of 'jhplot.jadraw.JaLatexText'

/*

 * Title: japlot.jaxodraw
 * Description: Graphical user interface for drawing Feynman diagrams
 * @author Daniele Binosi 
 * @author Lukas Theussl  

 Copyright (C) 2003-2006,  Daniele Binosi and Lukas Theussl

 See the file LICENSE in the source distribution home directory
 for a full copy of the GPL (GNU General Public License).

    This file is part of japlot.jaxodraw.

    japlot.jaxodraw is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

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


 */
package jhplot.jadraw;


import japlot.jaxodraw.JaxoColor;
import japlot.jaxodraw.JaxoLatexTextOptionsPanel;

import java.awt.BasicStroke;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import org.freehep.graphics2d.VectorGraphics;
import java.awt.geom.AffineTransform;
import java.awt.geom.GeneralPath;
import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;

import javax.swing.BorderFactory;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.border.Border;



/** Defines a JaObject which is just a string. */
public class JaLatexText extends JaObject {
    /**
	 * 
	 */
	private static final long serialVersionUID = 1L;

	/** The text string specifying this JaLatexText object. */
    private String textString;

    /** An integer specifying how the text is alligned with respect to the
     *  current position.
     */
    private int allign;

    /** An integer specifying the LaTeX font size. */
    private int latexfs;
    private JPanel latexPanel = new JPanel();
    private JLabel latexLabel;
    private int rotAngle;

    /** Constructor: sets the width, height, relative width and height to a
     *  default value of 3.
     */
    public JaLatexText() {
        setRelw(2);
        setRelh(2);
    }

    /** Creates a new Panel that display a Label with the String specifying this
     * JaLatexText.
     */
    public final void createLatexPanel() {
        latexLabel = new JLabel(" " + textString + " ");
        latexPanel.setLayout(new BorderLayout());
        latexPanel.add(latexLabel, BorderLayout.CENTER);
        latexPanel.setBackground(new Color(250, 250, 200));

        Border blackline = BorderFactory.createLineBorder(Color.black);
        latexPanel.setBorder(blackline);
    }

    /** Returns the Panel that holds the String specifying this LatexText.
     * @return A JPanel.
     */
    public final JPanel getLatexPanel() {
        return latexPanel;
    }

    /** Sets the Label of this LatexText to str.
     * @param str The string to be set as label.
     */
    public final void setLatexLabel(String str) {
        if (str != null) {
            latexLabel.setText(str);
        }
    }

    // Bean getter and setter methods

    /** Returns the textString property of this text object.
     * @return The textString property of this text object.
     */
    public final String getTextString() {
        return textString;
    }

    /** Sets the textString property of this text object.
     * @param string The textString property of this text object.
     */
    public final void setTextString(String string) {
        this.textString = string;
    }

    /** Returns the allign property of this text object.
     * @return The allign property of this text object.
     */
    public final int getAllign() {
        return allign;
    }

    /** Sets the allign property of this text object.
     * @param newAllign The allign property of this text object.
     */
    public final void setAllign(int newAllign) {
        this.allign = newAllign;
    }

    /** Returns the latexfs property of this text object.
     * @return The latexfs property of this text object.
     */
    public final int getLatexFS() {
        return latexfs;
    }

    /** Sets the latexfs property of this text object.
     * @param newLatexfs The latexfs property of this text object.
     */
    public final void setLatexFS(int newLatexfs) {
        this.latexfs = newLatexfs;
    }

    /** Returns the rotAngle property of this text object.
     * @return The rotAngle property of this text object.
     */
    public final int getRotAngle() {
        return rotAngle;
    }

    /** Sets the rotAngle property of this text object.
     * @param angle The rotAngle property of this text object.
     */
    public final void setRotAngle(int angle) {
        this.rotAngle = angle;
    }

    /** Returns an exact copy of this JaLatexText.
     * @return A copy of this JaLatexText.
     */
    public final JaObject copy() {
        JaLatexText temp = new JaLatexText();
        temp.setX(getX());
        temp.setY(getY());
        temp.setRotAngle(getRotAngle());
        temp.setColor(getColor());
        temp.setTextString(textString);
        temp.setAllign(allign);
        temp.setLatexFS(latexfs);

        return temp;
    }

    /** Returns true if all serializable variables of this JaObject
     *  and those of the specified one are equal.
     * @param comp A JaObject to compare with.
     * @return True if the objects are equal, false otherwise.
     */
    public final boolean isCopy(JaObject comp) {
        boolean isCopy = false;

        if (comp instanceof JaLatexText) {
            JaLatexText tmp = (JaLatexText) comp;
            if ((tmp.getX() == getX()) && (tmp.getY() == getY())
                    && (tmp.getRotAngle() == getRotAngle())
                    && tmp.getColor().equals(getColor())
                    && tmp.getTextString().equals(getTextString())
                    && (tmp.getAllign() == getAllign())
                    && (tmp.getLatexFS() == getLatexFS())) {
                isCopy = true;
            }
        }

        return isCopy;

    }

    /** Determines where on this JaObject a mouse click has ocurred.
     * @param clickX The x position of the point where the mouse click ocurred.
     * @param clickY The y position of the point where the mouse click ocurred.
     * @param editmode The current edit mode as defined in JaxoMainPanel.
     * @return An integer specifying whether the click ocurred on one
     * of the handles and if yes, on which.
     */
    public final int getGrabbedHandle(int clickX, int clickY, int editmode) {
        int length = JaObject.LENGTH;

        if ((editmode == MOVE) || (editmode == COPY)) {
            if ((clickX >= (getX() - (length / 2)))
                    && (clickX <= (getX() + (length / 2)))
                    && (clickY >= (getY() - (length / 2)))
                    && (clickY <= (getY() + (length / 2)))) {
                return SELECT_BODY;
            } else {
                return SELECT_NONE;
            }
        } else if (editmode == RESIZE) {
            return SELECT_NONE;
        }

        return SELECT_NONE;
    }

    /** The method that draws this JaxoText.
     * @param g2 The graphics context where the JaxoText has to be drawn.
     * @param drawToScreen A boolean variable that indicates whether
     * the drawing is done on the screen or somewhere else. This is used
     * for exporting/printing, where the object handles should not be painted,
     * even if they are visible on the screen.
     */
    public final void jaxoDraw(VectorGraphics g2, boolean drawToScreen) {
        if (drawToScreen) {
            drawTexVisualAid(g2);
        }
    }

    /** Draws a visual aid for a tex label:
     *  a blu TeX icon.
     * @param g2 The graphics context to draw to
     */
    public final void drawTexVisualAid(VectorGraphics g2) {
        int x = getX();
        int y = getY();
        double theta = Math.toRadians(rotAngle);

        //AffineTransform at = new AffineTransform();
        //at.rotate(theta, x, y);
        char[] ltT = {'T'};
        char[] ltE = {'E'};
        char[] ltX = {'X'};

        Font ltTFont = new Font("Utopia", Font.PLAIN, 18);
        Font ltEFont = new Font("Utopia", Font.PLAIN, 14);
        Font ltXFont = ltTFont;

        g2.rotate(theta, x, y);

        int xOff = 5;
        int yOff = 16;

        if ((allign == 3) || (allign == 4) || (allign == 5)) {
            xOff = -13;
        } else if ((allign == 6) || (allign == 7) || (allign == 8)) {
            xOff = -31;
        }

        if ((allign == 1) || (allign == 4) || (allign == 7)) {
            yOff = 5;
        } else if ((allign == 2) || (allign == 5) || (allign == 8)) {
            yOff = -6;
        }

        g2.setColor(JaxoColor.GRAYSCALE180);
        g2.setFont(ltTFont);
        g2.drawChars(ltT, 0, ltT.length, x + xOff, y + yOff);
        g2.setFont(ltEFont);
        g2.drawChars(ltE, 0, ltE.length, x + xOff + 9, y + yOff + 2);
        g2.setFont(ltXFont);
        g2.drawChars(ltX, 0, ltX.length, x + xOff + 17, y + yOff);
        g2.setColor(JaxoColor.CADET_BLUE);
        g2.setFont(ltTFont);
        g2.drawChars(ltT, 0, ltT.length, (x + xOff) - 1, (y + yOff) - 1);
        g2.setFont(ltEFont);
        g2.drawChars(ltE, 0, ltE.length, x + xOff + 8, y + yOff + 1);
        g2.setFont(ltXFont);
        g2.drawChars(ltX, 0, ltX.length, x + xOff + 18, (y + yOff) - 1);

        g2.rotate(-theta, x, y);

        setBoundingBox(this.getBoundingBox());
    }

    /** Determines whether the curser is currently above the
     * visual aid icon of this LatexText.
     * @param mouseX The current x - coordinate of the cursor
     * @param mouseY The current y - coordinate of the cursor
     * @return A boolean variable
     */
    public final boolean isRolledOver(int mouseX, int mouseY) {
        double[] bbox = getBoundingBox();

        int[] iconbox = {
            (int) bbox[JaObject.BB_MIN_X],
            (int) bbox[JaObject.BB_MIN_Y] - 5,
            (int) bbox[JaObject.BB_MAX_X] + 5,
            (int) bbox[JaObject.BB_MAX_Y] + 2
            };
        boolean isContained = false;

        if ((mouseX > iconbox[0]) && (mouseX < iconbox[2])
                && (mouseY > iconbox[1]) && (mouseY < iconbox[3])) {
            isContained = true;
        }

        return isContained;
    }

    /** Draws the handles of this text object.
     * @param g2 The current graphics context.
     */
    public final void drawHandles(VectorGraphics g2) {
        int length = JaObject.LENGTH;

        g2.setColor(JaxoColor.RED);
        g2.setStroke(new BasicStroke(1.0f));
        g2.drawRect(getX() - (length / 2), getY() - (length / 2), length,
            length);

        if (isMarked()) {
            g2.setColor(JaxoColor.GRAYSCALE150);
            g2.fillRect(getX() - (length / 2) + 1, getY() - (length / 2) + 1,
                length - 1, length - 1);
        }
    }

    /** Returns the bounding box of this latex text object.
     * @return The bounding box.
     */
    public final double[] getBoundingBox() {
        double minX = 0.;
        double maxX = 1.;
        double minY = 0.;
        double maxY = 1.;
        double[] bBox = {minX, minY, maxX, maxY};
        int x = getX();
        int y = getY();
        double theta = Math.toRadians(rotAngle);
        GeneralPath gp = new GeneralPath();
        AffineTransform at = new AffineTransform();
        at.rotate(theta, x, y);

        if (allign == 0) {
            Rectangle2D bb = new Rectangle2D.Double(x, y, 30, 16);
            gp.reset();
            gp.append(bb, false);
            gp.transform(at);
            bb = gp.getBounds();

            double[] bbox =
            {bb.getMinX(), bb.getMinY(), bb.getMaxX(), bb.getMaxY()};

            return bbox;
        } else if (allign == 1) {
            Rectangle2D bb = new Rectangle2D.Double(x, y - 8, 30, 16);
            gp.reset();
            gp.append(bb, false);
            gp.transform(at);
            bb = gp.getBounds();

            double[] bbox =
            {bb.getMinX(), bb.getMinY(), bb.getMaxX(), bb.getMaxY()};

            return bbox;
        } else if (allign == 2) {
            Rectangle2D bb = new Rectangle2D.Double(x, y - 16, 30, 16);
            gp.reset();
            gp.append(bb, false);
            gp.transform(at);
            bb = gp.getBounds();

            double[] bbox =
            {bb.getMinX(), bb.getMinY(), bb.getMaxX(), bb.getMaxY()};

            return bbox;
        } else if (allign == 3) {
            Rectangle2D bb = new Rectangle2D.Double(x - 15, y, 30, 16);
            gp.reset();
            gp.append(bb, false);
            gp.transform(at);
            bb = gp.getBounds();

            double[] bbox =
            {bb.getMinX(), bb.getMinY(), bb.getMaxX(), bb.getMaxY()};

            return bbox;
        } else if (allign == 4) {
            Rectangle2D bb = new Rectangle2D.Double(x - 15, y - 8, 30, 16);
            gp.reset();
            gp.append(bb, false);
            gp.transform(at);
            bb = gp.getBounds();

            double[] bbox =
            {bb.getMinX(), bb.getMinY(), bb.getMaxX(), bb.getMaxY()};

            return bbox;
        } else if (allign == 5) {
            Rectangle2D bb = new Rectangle2D.Double(x - 15, y - 16, 30, 16);
            gp.reset();
            gp.append(bb, false);
            gp.transform(at);
            bb = gp.getBounds();

            double[] bbox =
            {bb.getMinX(), bb.getMinY(), bb.getMaxX(), bb.getMaxY()};

            return bbox;
        } else if (allign == 6) {
            Rectangle2D bb = new Rectangle2D.Double(x - 30, y, 30, 16);
            gp.reset();
            gp.append(bb, false);
            gp.transform(at);
            bb = gp.getBounds();

            double[] bbox =
            {bb.getMinX(), bb.getMinY(), bb.getMaxX(), bb.getMaxY()};

            return bbox;
        } else if (allign == 7) {
            Rectangle2D bb = new Rectangle2D.Double(x - 30, y - 8, 30, 16);
            gp.reset();
            gp.append(bb, false);
            gp.transform(at);
            bb = gp.getBounds();

            double[] bbox =
            {bb.getMinX(), bb.getMinY(), bb.getMaxX(), bb.getMaxY()};

            return bbox;
        } else if (allign == 8) {
            Rectangle2D bb = new Rectangle2D.Double(x - 30, y - 16, 30, 16);
            gp.reset();
            gp.append(bb, false);
            gp.transform(at);
            bb = gp.getBounds();

            double[] bbox =
            {bb.getMinX(), bb.getMinY(), bb.getMaxX(), bb.getMaxY()};

            return bbox;
        }

        return bBox;
    }

    /** The LaTeX command that is necessary to draw the given JaxoText
     * using the axodraw.sty package.
     * @param scale A scale factor to translate Java coordinates to
     * LaTeX coordinates.
     * @param canvasDim The current dimension of the canvas.
     * @return The corresponding axodraw LaTeX command.
     */
    public final String latexCommand(float scale, Dimension canvasDim) {
        // Text(x,y)[mode]{text}
        // r2Text(#1,#2)[#3](#4,#5)#6
        int canvasHeight = canvasDim.height;

        Point2D position = getLaTexPosition(scale, canvasHeight);
        String allignCode = getLaTexAllign(allign);
        String fontSize = getLaTexFontSize(latexfs);
        String color = "\\" + JaxoColor.getColorName(getColor());
        String base;

        //String clk;
        String command;

        base = "\\Text";

        if (getRotAngle() != 0) {
            int ang = -getRotAngle(); //- (int) Math.toDegrees(getRotAngle());

            command =
                base + "(" + D_FORMAT.format(position.getX()) + ","
                + D_FORMAT.format(position.getY()) + ")" + allignCode
                + fontSize + color + "{$" + "\\rput" + allignCode + "{" + ang
                + "}" + "{" + textString + "}" + "$}}}";
        } else {
            command =
                base + "(" + D_FORMAT.format(position.getX()) + ","
                + D_FORMAT.format(position.getY()) + ")" + allignCode
                + fontSize + color + "{$" + textString + "$}}}";
        }

        return command;
    }

    /** Returns the line width of this JaxoText.
     * This is not used for JaxoText.
     * @return Returns "%", corresponding to an empty comment line in LaTeX.
     */
    public final String latexWidth() {
        String lineWidth = "%";

        return lineWidth;
    }

    /** Rescales this JaxoText by the scale factor scale,
     * keeping the point (orx, ory) fixed.
     * @param orx The x - coordinate of the fixed point
     * @param ory The y - coordinate of the fixed point
     * @param scale The scale parameter
     */
    public final void rescaleObject(int orx, int ory, float scale) {
        Point2D newP =
            this.scalePoint(orx, ory, scale, this.getX(), this.getY());

        this.setX((int) Math.round(newP.getX()));
        this.setY((int) Math.round(newP.getY()));
    }

    /////////////////////////////////////////////////////////////////////////
    //
    //   private auxiliary methods  //
    //
    /////////////////////////////////////////////////////////////////////////
    private Point2D getLaTexPosition(float scaleFactor, int canvasHeight) {
        Point2D positionPoint = new Point2D.Float();
        positionPoint.setLocation(getX() / scaleFactor,
            (canvasHeight - getY()) / scaleFactor);

        return positionPoint;
    }

    private String getLaTexAllign(int all) {
        String[] possible =
        {"[lt]", "[l]", "[lb]", "[t]", "[]", "[b]", "[rt]", "[r]", "[rb]"};

        return possible[all];
    }

    private String getLaTexFontSize(int fs) {
        String[] allowed =
        {
            "{\\tiny{", "{\\scriptsize{", "{\\footnotesize{", "{\\small{",
            "{\\normalsize{", "{\\large{", "{\\Large{", "{\\LARGE{", "{\\huge{",
            "{\\Huge{"
        };

        return allowed[fs];
    }

    /** Brings up the edit panel that allows to change the parameters of
     * this object.
     * @return True if the editing actually changed the object, false if
     * the object has not been changed.
     */
    public final boolean editPanel() {
        JaxoLatexTextOptionsPanel latop = new JaxoLatexTextOptionsPanel(this);

        return latop.hasChanged();
    }
}