/*
* Open Source Physics software is free software as described near the bottom of this code file.
*
* For additional information and documentation on Open Source Physics please see:
* <http://www.opensourcephysics.org/>
*/
package org.opensourcephysics.display;
import java.awt.Color;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Shape;
public class InteractiveLabel extends MeasuredCircle implements Interactive {
public static final int TOP_LEFT_LOCATION = 0;
public static final int CENTER_LOCATION = 1;
public static final int TOP_CENTER_LOCATION = 2;
public int connection_location = CENTER_LOCATION;
boolean enabled = true;
protected String text = null;
protected Font font;
protected String fontname = "TimesRoman"; // The logical name of the font to use //$NON-NLS-1$
protected int fontsize = 14; // The font size
protected int fontstyle = Font.PLAIN; // The font style
Box box = new Box();
/**
* Constructor InteractiveLabel
*/
public InteractiveLabel() {
super(0, 0);
color = Color.YELLOW;
pixRadius = 1;
font = new Font(fontname, fontstyle, fontsize);
}
/**
* Constructor InteractiveLabel
* @param str
*/
public InteractiveLabel(String str) {
this();
text = TeXParser.parseTeX(str);
}
public void setXY(double _x, double _y) {
x = _x;
y = _y;
}
public void setText(String _text) {
text = TeXParser.parseTeX(_text);
}
public void setText(String _text, double _x, double _y) {
x = _x;
y = _y;
text = TeXParser.parseTeX(_text);
}
public void resetBoxSize() {
box.boxHeight = 0;
box.boxWidth = 0;
}
/**
* Sets the location of the connection point.
* Location values are:TOP_LEFT_LOCATION, TOP_CENTER_LOCATION
*
* @param location int
*/
public void setConnectionPoint(int location) {
connection_location = location;
}
/**
* Sets the label's offset in the x direction.
* @param offset int
*/
public void setOffsetX(int offset) {
box.xoffset = offset;
}
/**
* Gets the label's offset in the x direction.
* @param offset int
*/
public int getOffsetX() {
return box.xoffset;
}
/**
* Sets the label's offset in the y direction.
* @param offset int
*/
public void setOffsetY(int offset) {
box.yoffset = offset;
}
/**
* Gets the label's offset in the y direction.
* @param offset int
*/
public int getOffsetY() {
return box.yoffset;
}
public void draw(DrawingPanel panel, Graphics g) {
String tempText = text; // local reference for thread safety
if(tempText==null) {
return;
}
super.draw(panel, g);
box.computeBoxMetrics(panel, g);
int xpix = panel.xToPix(x);
int ypix = panel.yToPix(y);
g.setColor(Color.YELLOW);
g.drawLine(xpix, ypix, box.connectX, box.connectY);
g.setColor(Color.BLACK);
box.draw(panel, g);
}
public Interactive findInteractive(DrawingPanel panel, int xpix, int ypix) {
if(box.isInside(panel, xpix, ypix)) {
return box;
}
return null;
}
/**
* Checks to see if this object is enabled and if the pixel coordinates are inside the drawable.
*
* @param panel
* @param xpix
* @param ypix
* @return true if the pixel coordinates are inside; false otherwise
*/
public boolean isInside(DrawingPanel panel, int xpix, int ypix) {
return box.isInside(panel, xpix, ypix);
}
/**
* Enables mouse interactions
* @param enabled boolean
*/
public void setEnabled(boolean enabled) {
this.enabled = enabled;
box.setEnabled(enabled);
}
/**
* Gets the mouse interaction enabled property.
* @return boolean
*/
public boolean isEnabled() {
return enabled;
}
class Box extends AbstractInteractive {
int leftPix, topPix;
int boxHeight = 0, boxWidth = 0; // the box width and height
int xpix = 0, ypix = 0;
int xoffset = 0, yoffset = 0;
int connectX, connectY;
DrawingPanel panel;
/**
* Draws the box and the text.
*
* @param panel DrawingPanel
* @param g Graphics
*/
public void draw(DrawingPanel panel, Graphics g) {
this.panel = panel;
String tempText = text; // local reference for thread safety
if(tempText==null) {
return;
}
Graphics2D g2 = (Graphics2D) g;
g2.setColor(color);
Font oldFont = g2.getFont();
g2.setFont(font);
Shape clipShape = g2.getClip();
g2.setClip(0, 0, panel.getWidth(), panel.getHeight());
g2.setColor(Color.YELLOW);
g2.fillRect(leftPix, topPix, boxWidth, boxHeight);
g2.setColor(Color.BLACK);
g2.drawRect(leftPix, topPix, boxWidth, boxHeight);
g2.drawString(tempText, leftPix+3, topPix+boxHeight-2);
g2.setFont(oldFont);
g2.setClip(clipShape);
}
void computeBoxMetrics(DrawingPanel panel, Graphics g) {
String tempText = text; // local reference for thread safety
if((tempText==null)||(panel==null)) {
return;
}
Graphics2D g2 = (Graphics2D) g;
Font oldFont = g2.getFont();
g2.setFont(font);
FontMetrics fm = g2.getFontMetrics();
int sh = fm.getAscent()+2; // current string height
int sw = fm.stringWidth(tempText)+6; // current string width
boxHeight = Math.max(boxHeight, sh);
boxWidth = Math.max(boxWidth, sw);
xpix = panel.xToPix(InteractiveLabel.this.x);
ypix = panel.yToPix(InteractiveLabel.this.y);
connectX = leftPix = xpix+xoffset;
connectY = topPix = ypix+yoffset;
if(InteractiveLabel.this.connection_location==TOP_CENTER_LOCATION) {
connectX += boxWidth/2;
} else if(InteractiveLabel.this.connection_location==CENTER_LOCATION) {
connectX += boxWidth/2;
connectY += boxHeight/2;
}
g2.setFont(oldFont);
}
public void setXY(double x, double y) {
if(panel==null) {
return;
}
int x1 = panel.xToPix(InteractiveLabel.this.x);
int x2 = panel.xToPix(x);
xoffset = x2-x1;
int y1 = panel.yToPix(InteractiveLabel.this.y);
int y2 = panel.yToPix(y);
yoffset = y2-y1;
}
public boolean isInside(DrawingPanel panel, int xpix, int ypix) {
if((xpix>=leftPix)&&(xpix<=leftPix+boxWidth)&&(ypix>=topPix)&&(ypix<=topPix+boxHeight)) {
return true;
}
return false;
}
}
}
/*
* Open Source Physics software is free software; you can redistribute
* it and/or modify it under the terms of the GNU General Public License (GPL) as
* published by the Free Software Foundation; either version 2 of the License,
* or(at your option) any later version.
*
* Code that uses any portion of the code in the org.opensourcephysics package
* or any subpackage (subdirectory) of this package must must also be be released
* under the GNU GPL license.
*
* This software 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; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston MA 02111-1307 USA
* or view the license online at http://www.gnu.org/copyleft/gpl.html
*
* Copyright (c) 2007 The Open Source Physics project
* http://www.opensourcephysics.org
*/