001: /*
002: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
003: *
004: * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
005: *
006: * The contents of this file are subject to the terms of either the GNU
007: * General Public License Version 2 only ("GPL") or the Common
008: * Development and Distribution License("CDDL") (collectively, the
009: * "License"). You may not use this file except in compliance with the
010: * License. You can obtain a copy of the License at
011: * http://www.netbeans.org/cddl-gplv2.html
012: * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
013: * specific language governing permissions and limitations under the
014: * License. When distributing the software, include this License Header
015: * Notice in each file and include the License file at
016: * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this
017: * particular file as subject to the "Classpath" exception as provided
018: * by Sun in the GPL Version 2 section of the License file that
019: * accompanied this code. If applicable, add the following below the
020: * License Header, with the fields enclosed by brackets [] replaced by
021: * your own identifying information:
022: * "Portions Copyrighted [year] [name of copyright owner]"
023: *
024: * Contributor(s):
025: *
026: * The Original Software is NetBeans. The Initial Developer of the Original
027: * Software is Sun Microsystems, Inc. Portions Copyright 1997-2007 Sun
028: * Microsystems, Inc. All Rights Reserved.
029: *
030: * If you wish your version of this file to be governed by only the CDDL
031: * or only the GPL Version 2, indicate your decision by adding
032: * "[Contributor] elects to include this software in this distribution
033: * under the [CDDL or GPL Version 2] license." If you do not indicate a
034: * single choice of license, a recipient has the option to distribute
035: * your version of this file under either the CDDL, the GPL Version 2 or
036: * to extend the choice of license to its licensees as provided above.
037: * However, if you add GPL Version 2 code and therefore, elected the GPL
038: * Version 2 license, then the option applies only if the new code is
039: * made subject to such option by the copyright holder.
040: */
041:
042: package org.netbeans.modules.uml.ui.products.ad.compartments.sequencediagram.lifelinepieces;
043:
044: import java.awt.Dimension;
045: import java.awt.Point;
046:
047: import org.netbeans.modules.uml.core.metamodel.diagrams.IDiagram;
048: import org.netbeans.modules.uml.core.support.umlsupport.ETPoint;
049: import org.netbeans.modules.uml.core.support.umlsupport.ETRect;
050: import org.netbeans.modules.uml.core.support.umlsupport.IETPoint;
051: import org.netbeans.modules.uml.core.support.umlsupport.IETRect;
052: import org.netbeans.modules.uml.ui.products.ad.compartments.sequencediagram.ETLifelineCompartment;
053: import org.netbeans.modules.uml.ui.products.ad.compartments.sequencediagram.LifelineConnectorLocation;
054: import org.netbeans.modules.uml.ui.support.archivesupport.IProductArchiveDefinitions;
055: import org.netbeans.modules.uml.ui.support.archivesupport.IProductArchiveElement;
056: import org.netbeans.modules.uml.ui.support.umltsconversions.RectConversions;
057: import org.netbeans.modules.uml.ui.support.viewfactorysupport.IDrawEngine;
058: import org.netbeans.modules.uml.ui.support.viewfactorysupport.IDrawInfo;
059: import org.netbeans.modules.uml.ui.support.viewfactorysupport.TypeConversions; //import com.tomsawyer.util.TSTransform;
060: import com.tomsawyer.editor.TSTransform;
061:
062: /**
063: *
064: * @author Trey Spiva
065: */
066: public abstract class LifelineCompartmentPiece {
067: /** This is the width of all pieces */
068: public static final int PIECE_WIDTH = 10;
069:
070: /** This is the height of all pieces */
071: public static final int PIECE_HEIGHT = 40;
072:
073: /**
074: * Added value when creating an activation bar under a suspension area (logical units).
075: */
076: public static final int ACTIVATION_BAR_BUFFER = 10;
077:
078: /**
079: * added value when creating an activation bar under a suspension area (logical units).
080: */
081: public static final int MIN_SIBLING_SPACE = ACTIVATION_BAR_BUFFER;
082:
083: /** The total number of corner connectors available */
084: public static final int ACTIVATION_CORNER_COUNT = LifelineConnectorLocation.LCL_BOTTOMLEFT + 1;
085:
086: public static final int CHILD_OFFSET = (PIECE_WIDTH / 2);
087:
088: /** The compartment that ownes the piece. */
089: private ETLifelineCompartment m_Parent = null;
090:
091: /** THe owner piece of this lifeline piece. If the piece is a root piece the parent will be null. */
092: private LifelineCompartmentPiece m_ParentPiece = null;
093:
094: /** Distance from the top of the parent piece or compartment to the top of this piece */
095: private IETPoint m_TopLeft = null;
096:
097: /** Distance from the top of this piece to the bottom of this piece. */
098: private int m_Height = -1;
099:
100: public LifelineCompartmentPiece(ETLifelineCompartment parent,
101: LifelineCompartmentPiece parentPiece, IETPoint topLeft,
102: int height) {
103: setParent(parent);
104: setParentPiece(parentPiece);
105: setTopLeft(topLeft);
106: m_Height = height;
107: }
108:
109: //**************************************************
110: // Data Acess Memebers
111: //**************************************************
112:
113: /**
114: * Access to the member parent compartment.
115: */
116: public ETLifelineCompartment getParent() {
117: return m_Parent;
118: }
119:
120: /**
121: * The horizontal offset for the children of this piece.
122: */
123: public int getChildOffset() {
124: return CHILD_OFFSET;
125: }
126:
127: /**
128: * @param compartment
129: */
130: public void setParent(ETLifelineCompartment compartment) {
131: m_Parent = compartment;
132: }
133:
134: /**
135: * Access to the member parent piece
136: */
137: public LifelineCompartmentPiece getParentPiece() {
138: return m_ParentPiece;
139: }
140:
141: /**
142: * Used to set the parent piece for this lifeline piece.
143: */
144: public void setParentPiece(LifelineCompartmentPiece piece) {
145: if ((m_ParentPiece != null) && (piece != null)) {
146: int newY = m_TopLeft.getY()
147: - (piece.getTop() - m_ParentPiece.getTop());
148: m_TopLeft.setY(Math.max(ACTIVATION_BAR_BUFFER, newY));
149: }
150:
151: m_ParentPiece = piece;
152: if ((m_ParentPiece != null) && (m_ParentPiece.getLeft() != 0)) {
153: setLeft(m_ParentPiece.getLeft()
154: + m_ParentPiece.getChildOffset());
155: }
156: }
157:
158: /**
159: * @return
160: */
161: public IETPoint getTopLeft() {
162: return m_TopLeft;
163: }
164:
165: /**
166: * @param point
167: */
168: public void setTopLeft(IETPoint point) {
169: m_TopLeft = point;
170: }
171:
172: /**
173: * Retrieve the height of this piece
174: */
175: public int getHeight() {
176: return m_Height;
177: }
178:
179: /**
180: * Set the height of this piece
181: */
182: public void setHeight(int value) {
183: if (value < 0) {
184: m_Height = value;
185: }
186:
187: m_Height = value;
188: }
189:
190: /**
191: * Get the bottom location (within the lifeline compartment)
192: */
193: public int getBottom() {
194: return (int) getTop() + (int) getHeight();
195: }
196:
197: /**
198: * Sets the bottom location of the piece, by changing the height
199: */
200: public void setBottom(int y) {
201: setHeight(y - getTop());
202: }
203:
204: /**
205: * Sets the logical bottom location of the piece, by changing the height
206: */
207: public void setLogicalBottom(int value) {
208: // Since the Y axis is oriented in such a way that smaller Y values
209: // move down the axis the top should always be a greater number than the
210: // bottom number.
211: setHeight(getLogicalTop() - value);
212: }
213:
214: /**
215: * Get the logical bottom location
216: */
217: public int getLogicalBottom() {
218: int compartmentTop = getCompartmentLogicalBoundingRect()
219: .getTop();
220: return compartmentTop - getBottom();
221: // return getBottom() - compartmentTop;
222: }
223:
224: public void setLeft(int left) {
225: if (m_TopLeft == null) {
226: m_TopLeft = new ETPoint(0, 0);
227: }
228: m_TopLeft.setX(left);
229:
230: getParent().updateSides(left, left + PIECE_WIDTH);
231: }
232:
233: /**
234: * Returns the left offset from the lifeline compartment.
235: */
236: public int getLeft() {
237: return m_TopLeft.getX();
238: }
239:
240: public int getLeftRelativeTo(IETRect rectEngine) {
241: int retVal = getLeft();
242:
243: if (rectEngine != null) {
244: retVal += rectEngine.getTop();
245: }
246:
247: return retVal;
248: }
249:
250: public void moveBy(int delta) {
251: moveBy(delta, true);
252: }
253:
254: public void moveBy(int delta, boolean adjustOthers) {
255: int newPosition = getY() + delta;
256: if (adjustOthers == true) {
257: setY(newPosition);
258: } else {
259: m_TopLeft.setY(newPosition);
260: }
261: }
262:
263: public void setTop(int top) {
264: setY(top - getParentTop());
265: }
266:
267: public int getY() {
268: return m_TopLeft.getY();
269: }
270:
271: /**
272: * Sets the y offset from the parent of the piece, without changing the height.
273: */
274: public void setY(long value) {
275: long yValue = value;
276:
277: long delta = yValue - ACTIVATION_BAR_BUFFER;
278: if (delta < 0) {
279: LifelineCompartmentPiece parent = getParentPiece();
280: if (parent != null) {
281: long newTop = parent.getTop() + delta;
282: parent.setTop((int) newTop);
283: }
284:
285: // It is possible for the parent to change because of a merge.
286: // So, use the current Y if there was a merge
287: if (parent == getParentPiece()) {
288: yValue = ACTIVATION_BAR_BUFFER;
289: } else {
290: yValue = getY();
291: }
292: }
293:
294: m_TopLeft.setY((int) yValue);
295: }
296:
297: /**
298: * Get the top location (within the lifeline compartment)
299: */
300: public int getTop() {
301: return getParentTop() + getY();
302: }
303:
304: /**
305: * Get the parent's top location (within the lifeline compartment).
306: */
307: public int getParentTop() {
308: // default is the top of the compartment
309: int retVal = 0;
310:
311: LifelineCompartmentPiece parent = getParentPiece();
312: if (parent != null) {
313: retVal = parent.getTop();
314: }
315: return retVal;
316: }
317:
318: /**
319: * Get the size of this piece when drawn.
320: */
321: public Dimension getDrawSize() {
322: return new Dimension(PIECE_WIDTH, getHeight());
323: }
324:
325: /**
326: * Get the rectangle, in node coords, for drawing the piece.
327: *
328: * @param zoom The zoom factor used to scale the draw rectangle.
329: * <i><b>Note: </b> currently this parameter is not used.</i>
330: * @return The rectangle that is to be drawned.
331: */
332: public IETRect getDrawRect(double zoom) {
333: Dimension dim = getDrawSize();
334:
335: IETRect engineRect = getEngineLogicalBoundingRect();
336:
337: double xOffset = engineRect.getCenterX();
338: return new ETRect(xOffset + getLeft(), getDETop(), dim
339: .getWidth(), dim.getHeight());
340: }
341:
342: public IETRect getAbsoluteDrawRect(double zoom) {
343: IETRect retVal = getDrawRect(zoom);
344:
345: if (retVal != null) {
346: IETRect engineRect = getEngineLogicalBoundingRect();
347: retVal.setTop(engineRect.getTop() - retVal.getTop());
348: }
349:
350: return retVal;
351: }
352:
353: /**
354: * Retrieves the name of the lifeline piece.
355: */
356: protected abstract String getID();
357:
358: /**
359: * Returns the lifeline pieces kind for this piece.
360: */
361: public abstract int getLifelinePiecesKind();
362:
363: public IProductArchiveElement writeToArchive(
364: IProductArchiveElement pParentElement) {
365: IProductArchiveElement retVal = null;
366: if (pParentElement != null) {
367: retVal = pParentElement.createElement(getID());
368: if (retVal != null) {
369: retVal
370: .addAttributeLong(
371: IProductArchiveDefinitions.ADLIFELINECOMPARTMENTPIECE_LEFT_STRING,
372: getLeft());
373: retVal
374: .addAttributeLong(
375: IProductArchiveDefinitions.ADLIFELINECOMPARTMENTPIECE_DY_STRING,
376: getTop());
377: retVal
378: .addAttributeLong(
379: IProductArchiveDefinitions.ADLIFELINECOMPARTMENTPIECE_HEIGHT_STRING,
380: getHeight());
381: }
382: }
383:
384: return retVal;
385: }
386:
387: public void readFromArchive(IProductArchiveElement pParentElement) {
388: if (pParentElement != null) {
389: long left = pParentElement
390: .getAttributeLong(IProductArchiveDefinitions.ADLIFELINECOMPARTMENTPIECE_LEFT_STRING);
391: long top = pParentElement
392: .getAttributeLong(IProductArchiveDefinitions.ADLIFELINECOMPARTMENTPIECE_DY_STRING);
393: setHeight((int) pParentElement
394: .getAttributeLong(IProductArchiveDefinitions.ADLIFELINECOMPARTMENTPIECE_HEIGHT_STRING));
395:
396: if ((left == 0) && (top == left)) {
397: // When these values are zero, we need to upgrade from the previous
398: // y value
399: top = pParentElement
400: .getAttributeLong(IProductArchiveDefinitions.ADLIFELINECOMPARTMENTPIECE_Y_STRING);
401: }
402: setLeft((int) left);
403: setTop((int) top);
404: }
405: }
406:
407: /**
408: * Retrieves the diagram contianing this piece
409: */
410: public IDiagram getDiagram() {
411: IDiagram retVal = null;
412:
413: IDrawEngine engine = getDrawEngine();
414: if (engine != null) {
415: retVal = TypeConversions.getDiagram(engine);
416: }
417:
418: return retVal;
419: }
420:
421: //**************************************************
422: // Helper Methods
423: //**************************************************
424:
425: /**
426: * Retrieves the draw engine contianing this piece.
427: */
428: protected IDrawEngine getDrawEngine() {
429: IDrawEngine retVal = null;
430:
431: ETLifelineCompartment parent = getParent();
432: if (parent != null) {
433: retVal = parent.getEngine();
434: }
435:
436: return retVal;
437: }
438:
439: /**
440: * Returns the (normalized) logical bounding rect of the draw engine (node)
441: * containing this piece.
442: */
443: protected IETRect getEngineLogicalBoundingRect(boolean normalize) {
444: return getParent().getEngineLogicalBoundingRect(normalize);
445: }
446:
447: /**
448: * Returns the (normalized) logical bounding rect of the draw engine (node)
449: * containing this piece. The rectangle will not be normalized.
450: */
451: protected IETRect getEngineLogicalBoundingRect() {
452: return getParent().getEngineLogicalBoundingRect(false);
453: }
454:
455: /**
456: * Returns the (normalized) logical bounding rect of the draw engine (node)
457: * containing this piece.
458: */
459: protected IETRect getCompartmentLogicalBoundingRect() {
460: // Fix J2573: For some reason the device rect was being passed back
461: // here, but the function name implies that this rect
462: // should be logical. The problem seen was when the
463: // create message feeds back a logical location for
464: // updating the attached "suspension area."
465:
466: return getParent().getLogicalBoundingRect();
467:
468: /// CLEAN IETRect deviceRect = getParent().getBoundingRect();
469: // TSTransform transform = getParent().getTransform();
470: //return new ETRect(transform.boundsToDevice(RectConversions.etRectToTSRect(deviceRect)));
471: // return deviceRect;
472: }
473:
474: /**
475: * Get the distance from the top of the draw engine
476: */
477: public int getDETop() {
478: int drawTop = getParent().getDrawTop();
479: int top = getTop();
480:
481: //ETSystem.out.println("Draw Top = " + drawTop + " Top = " + top);
482: return drawTop + top;
483: //return top;
484:
485: }
486:
487: /**
488: * Get the logical top location
489: */
490: public int getLogicalTop() {
491: int drawEngineTop = getEngineLogicalBoundingRect().getTop();
492: return drawEngineTop - getDETop();
493:
494: }
495:
496: /**
497: * Get the value that is used to restrict the upward movement of the accordion tool
498: */
499: public int getRestrictedY() {
500: return getLogicalTop();
501: }
502:
503: public void setLogicalTop(int value) {
504: int compartmentTop = getCompartmentLogicalBoundingRect()
505: .getTop();
506: if (value > compartmentTop) {
507: value = compartmentTop;
508: }
509:
510: setTop(compartmentTop - value);
511: }
512:
513: /**
514: * Get logical bounding rect for this piece.
515: */
516: public IETRect getLogicalBoundingRect() {
517: IETRect compartmentRect = getCompartmentLogicalBoundingRect();
518:
519: Point logicalToLeft = new Point(compartmentRect.getLeft()
520: + getTop(), compartmentRect.getTop() - getY());
521:
522: return new ETRect(logicalToLeft, getDrawSize());
523: }
524: }
|