View Javadoc

1   /*
2    *   Magic-Project is a turn based strategy simulator
3    *   Copyright (C) 2003-2007 Fabrice Daugan
4    *
5    *   This program is free software; you can redistribute it and/or modify it 
6    * under the terms of the GNU General Public License as published by the Free 
7    * Software Foundation; either version 2 of the License, or (at your option) any
8    * later version.
9    *
10   *   This program is distributed in the hope that it will be useful, but WITHOUT 
11   * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
12   * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more 
13   * details.
14   *
15   *   You should have received a copy of the GNU General Public License along  
16   * with this program; if not, write to the Free Software Foundation, Inc., 
17   * 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18   */
19  package net.sf.magicproject.ui;
20  
21  import java.awt.AlphaComposite;
22  import java.awt.Color;
23  import java.awt.Graphics;
24  import java.awt.Graphics2D;
25  import java.awt.IllegalComponentStateException;
26  import java.awt.Point;
27  import java.awt.geom.GeneralPath;
28  
29  import javax.swing.JPanel;
30  
31  import net.sf.magicproject.clickable.targetable.TargetableFactory;
32  import net.sf.magicproject.clickable.targetable.card.MCard;
33  import net.sf.magicproject.stack.StackContext;
34  
35  /***
36   * @author <a href="mailto:fabdouglas@users.sourceforge.net">Fabrice Daugan </a>
37   * @since 0.90
38   */
39  public class TargetGlassPane extends JPanel {
40  
41  	/***
42  	 * Composite for all paints of this component.
43  	 */
44  	private final AlphaComposite composite;
45  
46  	/***
47  	 * The active StackElement component. May be <code>null</code>.
48  	 */
49  	private StackContext stackContext;
50  
51  	/***
52  	 * Create a new instance of this class.
53  	 */
54  	public TargetGlassPane() {
55  		setOpaque(false);
56  		setVisible(true);
57  		// targetPicture = Toolkit.getDefaultToolkit().getImage(
58  		// IdConst.IMAGES_DIR + "target.gif");
59  		composite = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.5f);
60  	}
61  
62  	/***
63  	 * @param stackContext
64  	 */
65  	public void setStackContext(StackContext stackContext) {
66  		this.stackContext = stackContext;
67  		MagicUIComponents.magicForm.setGlassPane(this);
68  		setVisible(true);
69  		repaint();
70  	}
71  
72  	@Override
73  	public void paintComponent(Graphics g) {
74  		final StackContext stackContext = this.stackContext;
75  		if (stackContext != null) {
76  			final MCard source = stackContext.getSourceCard();
77  			final Point pSource;
78  			if (source == null)
79  				return;
80  			final Graphics2D g2d = (Graphics2D) g;
81  			g2d.setComposite(composite);
82  			try {
83  				pSource = source.getLocationOnScreen();
84  				if (stackContext.getTargetedList() != null) {
85  					for (int i = 0; i < stackContext.getTargetedList().size(); i++) {
86  						final GeneralPath path = new GeneralPath();
87  						final Point targetI = stackContext.getTargetedList().get(i)
88  								.getLocationOnScreen();
89  						float p1x = pSource.x + 15; // P1.x
90  						float p1y = pSource.y + 15; // P1.y
91  						float p2x = targetI.x + 15; // P2.x
92  						float p2y = targetI.y + 15; // P20y
93  						// Control point of the curve
94  						float cx = Math.abs(p2x - p1x) / 2 - 10;
95  						float cy = p2y - 30;
96  						float arrSize = 20; // Size of the arrow segments
97  						float width = 10;
98  
99  						float adjSize = (float) (arrSize / Math.sqrt(2));
100 						float ex = p2x - cx;
101 						float ey = p2y - cy;
102 						float absE = (float) Math.sqrt(ex * ex + ey * ey);
103 						ex /= absE;
104 						ey /= absE;
105 
106 						// Creating quad arrow
107 						path.moveTo(p1x, p1y);
108 						path.quadTo(cx, cy, p2x, p2y);
109 						path.lineTo(p2x + (-ex + ey) * adjSize, p2y + (-ex - ey) * adjSize);
110 						path.lineTo(p2x + ex * adjSize, p2y + ey * adjSize * 2.0f);
111 						path.lineTo(p2x - ex * adjSize - (ey + ex) * adjSize, p2y + ey
112 								* adjSize + (ex - ey) * adjSize);
113 						path.lineTo(p2x - ex * adjSize, p2y + ey * adjSize);
114 						path.quadTo(cx + width, cy + 2 * width, p1x + width, p1y + width);
115 						path.closePath();
116 
117 						// TODO Should we draw a "target" picture on targeted component?
118 						// g2d.drawImage(targetPicture, targetI.x+5, targetI.y+15, null);
119 						g2d.setColor(TargetableFactory.TARGET_COLOR);
120 						g2d.fill(path);
121 						g2d.setColor(Color.BLACK);
122 						g2d.draw(path);
123 						pSource.translate(0, 15);
124 					}
125 				}
126 			} catch (IllegalComponentStateException e) {
127 				// ignore this error, the source has moved since the target update.
128 			} finally {
129 				g2d.dispose();
130 			}
131 		}
132 	}
133 
134 }