1 package org.catacomb.druid.xtext.canvas;
2
3 import org.catacomb.druid.swing.DTextCanvas;
4 import org.catacomb.druid.swing.dnd.Region;
5 import org.catacomb.druid.swing.dnd.RegionBoard;
6 import org.catacomb.druid.xtext.base.*;
7 import org.catacomb.interlish.structure.TextPainter;
8 import org.catacomb.report.E;
9
10
11 import java.awt.Color;
12 import java.awt.Graphics2D;
13
14
15
16 public class TextBoard extends RegionBoard
17 implements TextPainter {
18
19 Block rootBlock;
20
21 FontStore fontStore;
22
23 int width;
24 int height;
25
26 int itxt;
27 int jtxt;
28
29 KeyWriter keyWriter;
30
31 public final static String PUNCTUATION = " .,;:?!\t\n";
32
33
34 private boolean nextIsLinked;
35
36
37
38 public TextBoard(DTextCanvas dtc) {
39 super(dtc);
40
41 canvas.setTextPainter(this);
42
43
44 fontStore = FontStore.instance();
45
46 keyWriter = new KeyWriter(this);
47 canvas.addKeyListener(keyWriter);
48
49
50 canvas.setFocusable(true);
51 requestFocus();
52
53 }
54
55
56 public void setBlock(Block rb) {
57 rootBlock = rb;
58
59 rootBlock.setParent(new BoardRepainterDMItem(this));
60
61 keyWriter.setCaretBlock(firstTextBlock());
62
63 canvas.repaint();
64 }
65
66
67
68 public TextBlock firstTextBlock() {
69 TextBlock ret = null;
70 Block b = rootBlock;
71 while (b.hasNext()) {
72 b = b.next();
73 if (b instanceof TextBlock) {
74 ret = (TextBlock)b;
75 break;
76 }
77 }
78 return ret;
79
80 }
81
82
83
84 public void repaint() {
85 canvas.repaint();
86 }
87
88
89 public void paintText(Graphics2D g) {
90 clearRegions();
91
92 width = canvas.getWidth();
93 height = canvas.getHeight();
94
95 nextIsLinked = false;
96
97 g.setFont(fontStore.getActiveFont());
98 g.setColor(Color.black);
99
100 itxt = 10;
101 jtxt = 30;
102
103 if (rootBlock != null) {
104 paintDoc(g);
105 if (keyWriter.hasCaret()) {
106 paintCaret(g);
107 } else {
108 E.info("not painting caret");
109 }
110 }
111
112 int ofth = fullTextHeight;
113 fullTextHeight = jtxt + 10;
114
115 if (Math.abs(fullTextHeight - ofth) > 10) {
116 canvas.contentSizeChanged();
117 }
118 }
119
120
121
122 private void paintDoc(Graphics2D g) {
123 Block b = rootBlock;
124
125 while (b.hasNext()) {
126 b = b.next();
127 if (b instanceof TextBlock) {
128 paintBlock(g, (TextBlock)b);
129 }
130 }
131 }
132
133
134
135 private void paintCaret(Graphics2D g) {
136
137 TextBlock caretBlock = keyWriter.getCaretBlock();
138 int caretPos = keyWriter.getCaretPos();
139
140 int w = 0;
141 if (caretBlock instanceof NewlineBlock) {
142
143 } else {
144 String txt = caretBlock.getText();
145 String part = txt.substring(0, caretPos);
146 w = fontStore.stringWidth(g, part);
147 }
148
149 int[] xywh = caretBlock.getCachedPosition();
150 g.setColor(Color.black);
151 int xo = xywh[0] + w;
152 int yo = xywh[1];
153 if (caretBlock instanceof NewlineBlock && caretPos > 0) {
154 xo = 10;
155 yo += 16;
156 }
157 g.drawLine(xo, yo, xo, yo - xywh[3]);
158 }
159
160
161
162 private void paintBlock(Graphics2D g, TextBlock b) {
163 if (b instanceof NewlineBlock) {
164 b.setCachedPosition(itxt, jtxt, 0, 16);
165 itxt = 10;
166 jtxt += 16;
167
168 } else {
169 Guise guise = b.getGuise();
170 g.setFont(guise.getFont());
171 g.setColor(guise.getColor());
172
173
174 String txt = b.getText();
175
176 int w = g.getFontMetrics().stringWidth(txt);
177
178 if (itxt + w > width && b instanceof WordBlock) {
179 itxt = 10;
180 jtxt += 16;
181 }
182
183 b.setCachedPosition(itxt, jtxt + 4, w, 16);
184
185 if (b instanceof WordBlock) {
186 g.drawString(txt, itxt, jtxt);
187
188 if (guise.underline()) {
189 g.drawLine(itxt, jtxt + 2, itxt + w, jtxt + 2);
190 }
191
192
193 addDragRegion(b.getCachedPosition(), b, null);
194 nextIsLinked = ((WordBlock)b).hasLinkee();
195
196 } else if (b instanceof PunctuationBlock) {
197 g.drawString(txt, itxt, jtxt);
198 if (nextIsLinked) {
199 g.setColor(Color.blue);
200
201 g.drawLine(itxt-4, jtxt+1, itxt+w+4, jtxt+1);
202
203 nextIsLinked = false;
204 }
205
206 if (txt.trim().equals("")) {
207 addLengthenedRegion(b.getCachedPosition(), b);
208 }
209 }
210
211 itxt += w;
212
213 }
214 }
215
216
217 public void regionClicked(Region reg) {
218 Object src = reg.getRef();
219
220
221 if (src instanceof PunctuationBlock) {
222 PunctuationBlock pb = (PunctuationBlock)src;
223 WordBlock pr = pb.getPreviousWordBlock();
224 WordBlock pn = pb.getNextWordBlock();
225 pr.toggleLink(pn);
226 } else {
227 E.warning("whats this ? " + src);
228 }
229 repaint();
230 }
231 public void dropOn(Object src, String txt, Object tgt, String tag) {
232
233 }
234
235 }