View Javadoc

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                     //       g.drawLine(itxt-4, jtxt+2, itxt+w+4, jtxt+2);
201                     g.drawLine(itxt-4, jtxt+1, itxt+w+4, jtxt+1);
202                     //       g.fillOval(itxt + w / 2 - 3, jtxt - 6, 4, 4);
203                     nextIsLinked = false;
204                 }
205 
206                 if (txt.trim().equals("")) {
207                     addLengthenedRegion(b.getCachedPosition(), b);
208                 }
209             }
210 
211             itxt += w;
212             // itxt += 4;
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 }