001: package net.xoetrope.builder.editor;
002:
003: import javax.swing.JPanel;
004: import java.awt.Point;
005: import java.awt.Graphics;
006: import java.awt.Color;
007: import java.awt.Dimension;
008: import java.awt.event.MouseMotionListener;
009: import java.awt.event.MouseListener;
010: import java.awt.event.MouseEvent;
011: import java.util.Vector;
012: import java.awt.event.ComponentEvent;
013: import java.awt.AWTEvent;
014: import java.awt.Event;
015: import javax.swing.JButton;
016: import java.awt.event.ActionListener;
017: import java.awt.event.ActionEvent;
018: import javax.swing.JToggleButton;
019: import java.awt.Rectangle;
020: import javax.swing.SwingUtilities;
021: import java.awt.Component;
022: import java.util.prefs.Preferences;
023: import java.awt.SystemColor;
024:
025: /**
026: * <p> Copyright (c) Xoetrope Ltd., 2002-2003</p>
027: * <p> $Revision: 1.7 $</p>
028: * <p> License: see License.txt</p>
029: */
030: public class XGuidePane extends JPanel implements ActionListener {
031: private int left, top, width, height;
032:
033: private static final int NORMAL = 0;
034: private static final int ADD_VERTICAL_GUIDE = 1;
035: private static final int ADD_HORIZONTAL_GUIDE = 2;
036: private static final int MOVE_VERTICAL_GUIDE = 3;
037: private static final int MOVE_HORIZONTAL_GUIDE = 4;
038:
039: private static final int GRID_SNAP_RANGE = 3;
040:
041: private int mode = NORMAL;
042: private int selectedGuideIdx = -1;
043: private Point oldP;
044:
045: private JToggleButton editBtn;
046: private boolean editMode;
047: private boolean paintGuides;
048: private int snapRange;
049:
050: private Vector horzGuides = new Vector();
051: private Vector vertGuides = new Vector();
052:
053: public XGuidePane() {
054: setLayout(null);
055: setOpaque(false);
056: left = top = 10;
057: width = 640;
058: height = 480;
059:
060: snapRange = GRID_SNAP_RANGE;
061: Preferences prefs = Preferences
062: .userNodeForPackage(XuiEditor.class);
063: snapRange = Integer.parseInt(prefs.get("GuideSnapRange",
064: Integer.toString(snapRange)));
065:
066: editBtn = new JToggleButton();
067: editBtn.setBounds(0, 0, 10, 10);
068: editBtn.addActionListener(this );
069: add(editBtn);
070:
071: editMode = false;
072: paintGuides = true;
073: }
074:
075: public void actionPerformed(ActionEvent e) {
076: if (!editMode) {
077: enableEvents(AWTEvent.MOUSE_EVENT_MASK);
078: enableEvents(AWTEvent.MOUSE_MOTION_EVENT_MASK);
079: } else {
080: disableEvents(AWTEvent.MOUSE_EVENT_MASK);
081: disableEvents(AWTEvent.MOUSE_MOTION_EVENT_MASK);
082: }
083: editMode = !editMode;
084: editBtn.setSelected(editMode);
085:
086: int numChildren = getComponentCount();
087: for (int i = 0; i < numChildren; i++) {
088: Component c = (Component) getComponent(i);
089: if (c != editBtn)
090: c.setVisible(!editMode);
091: }
092: }
093:
094: /**
095: * Remove all the children
096: */
097: public void clear() {
098: int numChildren = getComponentCount();
099: Component children[] = getComponents();
100: for (int i = 0; i < numChildren; i++) {
101: if (children[i] != editBtn)
102: remove(children[i]);
103: }
104: }
105:
106: /**
107: * Toggle the painting of the guides and gutters
108: * @param doPaint true to do the painting
109: */
110: public void setPaintGuides(boolean doPaint) {
111: paintGuides = doPaint;
112: editBtn.setVisible(doPaint);
113: }
114:
115: /**
116: * Get the flag indicating painting of the guides and gutters
117: * @param true if the guides are painted
118: */
119: public boolean getPaintGuides() {
120: return paintGuides;
121: }
122:
123: public void paintComponent(Graphics g) {
124: if (paintGuides) {
125: Rectangle clipRect = g.getClipBounds();
126: paintGrid(g, clipRect);
127: paintGutters(g, clipRect);
128: } else
129: super .paintComponent(g);
130: }
131:
132: public void paintGrid(Graphics g, Rectangle clipRect) {
133: g.setColor(new Color(255, 0, 0, 56));
134:
135: int numVertGuides = vertGuides.size();
136: for (int i = 0; i < numVertGuides; i++) {
137: int coord = ((Integer) vertGuides.elementAt(i)).intValue();
138: g.drawLine(left + coord, top, left + coord, top + height);
139: }
140:
141: int numHorzGuides = horzGuides.size();
142: for (int i = 0; i < numHorzGuides; i++) {
143: int coord = ((Integer) horzGuides.elementAt(i)).intValue();
144: g.drawLine(left, top + coord, left + width, top + coord);
145: }
146: }
147:
148: public void paintGutters(Graphics g, Rectangle clipRect) {
149: Dimension d = getSize();
150: int right = Math.min(d.width, clipRect.x + clipRect.width);
151: int startX = clipRect.x;
152: int bottom = Math.min(d.height, clipRect.y + clipRect.height);
153: int startY = clipRect.y;
154: startX -= startX % 5;
155: startY -= startY % 5;
156:
157: int delta = 1;
158:
159: if (startY < top) {
160: // Draw the background
161: g.setColor(SystemColor.control);
162: g.fillRect(startX, 0, right - startX, top);
163:
164: // Draw the edges
165: g.setColor(SystemColor.controlDkShadow);
166: g.drawLine(left, top - 1, d.width - 1, top - 1);
167:
168: // Draw the top minor grid lines
169: int ht = top / 2;
170: for (int x = startX; x < right; x += 5) {
171: g.drawLine(x, ht - delta, x, top - 1);
172: delta = -delta;
173: }
174:
175: // Draw the top major grid lines
176: ht = top / 4;
177: for (int x = startX; x < right; x += 100)
178: g.drawLine(x, ht, x, top - 1);
179: }
180:
181: if (startX < left) {
182: // Draw the background
183: g.setColor(SystemColor.control);
184: g.fillRect(0, startY, left, height - startY);
185:
186: // Draw the edges
187: g.setColor(SystemColor.controlDkShadow);
188: g.drawLine(left - 1, top - 1, left - 1, d.height - 1);
189:
190: // Draw the left hand minor grid lines
191: int wh = left / 2;
192: for (int y = startY; y < bottom; y += 5) {
193: g.drawLine(wh - delta, y, left - 1, y);
194: delta = -delta;
195: }
196:
197: // Draw the left hand major grid lines
198: wh = left / 4;
199: for (int y = startY; y < bottom; y += 100)
200: g.drawLine(wh, y, left - 1, y);
201: }
202: }
203:
204: /**
205: * Set the dimensions of the page container whos grid is being rendered
206: * @param x
207: * @param y
208: * @param w
209: * @param h
210: */
211: public void setPageBounds(int x, int y, int w, int h) {
212: left = x;
213: top = y;
214: width = w;
215: height = h;
216: }
217:
218: public void processMouseEvent(MouseEvent e) {
219: if (e.getID() == MouseEvent.MOUSE_PRESSED)
220: mousePressed(e);
221: else if (e.getID() == MouseEvent.MOUSE_RELEASED)
222: mouseReleased(e);
223:
224: super .processMouseEvent(e);
225: }
226:
227: public void processMouseMotionEvent(MouseEvent e) {
228: if (e.getID() == MouseEvent.MOUSE_DRAGGED)
229: mouseDragged(e);
230:
231: super .processMouseMotionEvent(e);
232: }
233:
234: public void mousePressed(MouseEvent e) {
235: oldP = e.getPoint();
236: if (oldP.y < top) {
237: mode = ADD_HORIZONTAL_GUIDE;
238: } else if (oldP.x < left) {
239: mode = ADD_VERTICAL_GUIDE;
240: } else {
241: int numVertGuides = vertGuides.size();
242: for (int i = 0; i < numVertGuides; i++) {
243: int coord = ((Integer) vertGuides.elementAt(i))
244: .intValue();
245: if (Math.abs(coord - (oldP.x - left)) < 2) {
246: mode = MOVE_VERTICAL_GUIDE;
247: selectedGuideIdx = i;
248: return;
249: }
250: }
251:
252: int numHorzGuides = horzGuides.size();
253: for (int i = 0; i < numHorzGuides; i++) {
254: int coord = ((Integer) horzGuides.elementAt(i))
255: .intValue();
256: if (Math.abs(coord - (oldP.y - top)) < 2) {
257: mode = MOVE_HORIZONTAL_GUIDE;
258: selectedGuideIdx = i;
259: }
260: }
261: }
262: }
263:
264: public void mouseReleased(MouseEvent e) {
265: Point p = e.getPoint();
266: if (mode == ADD_HORIZONTAL_GUIDE) {
267: if ((p.y > left) && (p.y < height + top))
268: horzGuides.add(new Integer(p.y - top));
269: } else if (mode == ADD_VERTICAL_GUIDE) {
270: if ((p.x > top) && (p.x < width + left))
271: vertGuides.add(new Integer(p.x - left));
272: } else if (mode == MOVE_VERTICAL_GUIDE) {
273: if (selectedGuideIdx > -1) {
274: vertGuides.removeElementAt(selectedGuideIdx);
275: if (p.x > left)
276: vertGuides.add(new Integer(p.x - left));
277: }
278: } else if (mode == MOVE_HORIZONTAL_GUIDE) {
279: if (selectedGuideIdx > -1) {
280: horzGuides.removeElementAt(selectedGuideIdx);
281: if (p.y > top)
282: horzGuides.add(new Integer(p.y - top));
283: }
284: } else
285: return;
286:
287: mode = NORMAL;
288: selectedGuideIdx = -1;
289: repaint();
290: }
291:
292: public void mouseDragged(MouseEvent e) {
293: if (mode == NORMAL)
294: return;
295: else {
296: Point p = e.getPoint();
297: Graphics g = getGraphics();
298: Color moveColor = new Color(255, 0, 0, 56);
299: g.setXORMode(moveColor);
300: if ((mode == ADD_HORIZONTAL_GUIDE)
301: || (mode == MOVE_HORIZONTAL_GUIDE)) {
302: if ((p.x > top) && (p.x < width + left)) {
303: g.drawLine(left, oldP.y, left + width, oldP.y);
304: g.drawLine(left, p.y, left + width, p.y);
305: oldP = p;
306: }
307: } else if ((mode == ADD_VERTICAL_GUIDE)
308: || (mode == MOVE_VERTICAL_GUIDE)) {
309: if ((p.y > left) && (p.y < height + top)) {
310: g.drawLine(oldP.x, top, oldP.x, top + height);
311: g.drawLine(p.x, top, p.x, top + height);
312: oldP = p;
313: }
314: }
315: g.dispose();
316: g = null;
317: }
318: }
319:
320: public void alignComponents(Vector selectedComponents) {
321: int numComponents = selectedComponents.size();
322: int numVertGuides = vertGuides.size();
323: int numHorzGuides = horzGuides.size();
324:
325: for (int i = 0; i < numComponents; i++) {
326: XComponentSizer currentSizer = (XComponentSizer) selectedComponents
327: .elementAt(i);
328: Rectangle rect = currentSizer.getBounds();
329:
330: for (int iV = 0; iV < numVertGuides; iV++) {
331: int coord = ((Integer) vertGuides.elementAt(iV))
332: .intValue()
333: + left + 1;
334: Point convertedCoord = SwingUtilities.convertPoint(
335: this , coord, 0, currentSizer.getParent());
336: // Check the left edge and then the right edge
337: if (Math.abs(convertedCoord.x - rect.x) <= snapRange)
338: currentSizer.setLocation(convertedCoord.x, rect.y);
339: else if (Math.abs(convertedCoord.x
340: - (rect.x + rect.width)) <= snapRange)
341: currentSizer.setSize(convertedCoord.x - rect.x,
342: rect.height);
343: }
344:
345: // Refresh the rect as it may have changed
346: rect = currentSizer.getBounds();
347: for (int iH = 0; iH < numHorzGuides; iH++) {
348: int coord = ((Integer) horzGuides.elementAt(iH))
349: .intValue()
350: + top + 1;
351: Point convertedCoord = SwingUtilities.convertPoint(
352: this , 0, coord, currentSizer.getParent());
353: // Check the top edge and then the bottom
354: if (Math.abs(convertedCoord.y - rect.y) <= snapRange)
355: currentSizer.setLocation(rect.x, convertedCoord.y);
356: else if (Math.abs(convertedCoord.y
357: - (rect.y + rect.height)) <= snapRange)
358: currentSizer.setSize(rect.width, convertedCoord.y
359: - rect.y);
360: }
361: }
362: }
363:
364: /**
365: * Get the guide coordinates
366: * @param vert
367: * @return
368: */
369: public Vector getGuideCoords(boolean vert) {
370: if (vert)
371: return vertGuides;
372: else
373: return horzGuides;
374: }
375: }
|