]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.diagram/src/org/simantics/diagram/elements/Line.java
Option to edit TextNode's text externally
[simantics/platform.git] / bundles / org.simantics.diagram / src / org / simantics / diagram / elements / Line.java
1 /*******************************************************************************
2  * Copyright (c) 2012 Association for Decentralized Information Management
3  * in Industry THTH ry.
4  * All rights reserved. This program and the accompanying materials
5  * are made available under the terms of the Eclipse Public License v1.0
6  * which accompanies this distribution, and is available at
7  * http://www.eclipse.org/legal/epl-v10.html
8  *
9  * Contributors:
10  *     Semantum Oy - initial API and implementation
11  *******************************************************************************/
12 package org.simantics.diagram.elements;
13
14 import java.awt.Graphics2D;
15 import java.awt.Shape;
16 import java.awt.font.TextLayout;
17 import java.awt.geom.Rectangle2D;
18
19 /**
20  * Auxiliary class for drawing positioned and single lines of laid out text.
21  * 
22  * @author Tuukka Lehtonen
23  * 
24  * @see TextNode
25  * @see TextLayout
26  */
27 class Line {
28
29     public interface BoundsProcedure {
30         Rectangle2D getBounds(Line line);
31     }
32
33     public static BoundsProcedure BBOX = new BoundsProcedure() {
34         @Override
35         public Rectangle2D getBounds(Line line) {
36             return line.bbox;
37         }
38     };
39
40     public static BoundsProcedure ABBOX = new BoundsProcedure() {
41         @Override
42         public Rectangle2D getBounds(Line line) {
43             return line.abbox;
44         }
45     };
46
47     public final String document;
48     public final int startOffset;
49     public final int endOffset;
50
51     float drawPosX;
52     float drawPosY;
53     float alignedPosX;
54     float alignedPosY;
55     TextLayout layout;
56     Rectangle2D bbox;
57     Rectangle2D abbox;
58
59     public Line(String document, int startOffset, int endOffset) {
60         int len = document.length();
61         if (endOffset < startOffset)
62             throw new IllegalArgumentException("endOffset (" + endOffset + ") < startOffset (" + startOffset + ")");
63         if (startOffset < 0 || startOffset > len)
64             throw new IllegalArgumentException("startOffset " + startOffset + " out of bounds [0," + len + "]");
65         if (endOffset < 0 || endOffset > len)
66             throw new IllegalArgumentException("endOffset " + endOffset + " out of bounds [0," + len + "]");
67         this.document = document;
68         this.startOffset = startOffset;
69         this.endOffset = endOffset;
70     }
71
72     public void render(Graphics2D g) {
73         if (layout != null)
74             layout.draw(g, alignedPosX, alignedPosY);
75     }
76
77     public String getText() {
78         return document.substring(startOffset, endOffset);
79     }
80
81     public boolean intersectsRange(int start, int end) {
82         return start < endOffset && end > startOffset;
83     }
84
85     public boolean containsRange(int start, int end) {
86         return start >= startOffset && start <= endOffset
87                 && end > startOffset && end <= endOffset;
88     }
89
90     public boolean containsOffset(int caret) {
91         return startOffset <= caret && caret <= endOffset;
92     }
93
94     public Shape getLogicalHighlightShape(int start, int end) {
95         return layout.getLogicalHighlightShape(
96                 Math.max(0, start - startOffset),
97                 Math.min(endOffset - startOffset, end - startOffset));
98     }
99
100     public Shape[] getCaretShapes(int caret) {
101         return layout.getCaretShapes(caret - startOffset);
102     }
103
104     public void translate(Graphics2D g, float xOffset, float yOffset) {
105         g.translate(alignedPosX + xOffset, alignedPosY + yOffset);
106     }
107
108     public void translateInv(Graphics2D g, float xOffset, float yOffset) {
109         g.translate(-alignedPosX - xOffset, - alignedPosY - yOffset);
110     }
111
112     public void alignOffset(double x, double y) {
113         alignedPosX = drawPosX + (float) x;
114         alignedPosY = drawPosY + (float) y;
115         if (abbox == null)
116             abbox = new Rectangle2D.Float();
117         abbox.setFrame(bbox.getX() + x, bbox.getY() + y, bbox.getWidth(), bbox.getHeight());
118         //System.out.println("offset(" + x + ", " + y + "): " + this);
119     }
120
121     @Override
122     public String toString() {
123         return getClass().getSimpleName() + "[startOffset="
124                 + startOffset + ", endOffset=" + endOffset
125                 + ", x=" + drawPosX + ", y=" + drawPosY
126                 + ", ax='" + alignedPosX + ", ay=" + alignedPosY
127                 + ", text='" + getText()
128                 + ", bbox='" + bbox + ", abbox=" + abbox
129                 + "']";
130     }
131
132 }