OSDN Git Service

beb159ace007b8b0908b0afd819091446abd9e44
[jindolf/Jindolf.git] / src / main / java / jp / sourceforge / jindolf / AnchorDraw.java
1 /*\r
2  * アンカー描画\r
3  *\r
4  * Copyright(c) 2008 olyutorskii\r
5  * $Id: AnchorDraw.java 995 2010-03-15 03:54:09Z olyutorskii $\r
6  */\r
7 \r
8 package jp.sourceforge.jindolf;\r
9 \r
10 import java.awt.BasicStroke;\r
11 import java.awt.Color;\r
12 import java.awt.Graphics2D;\r
13 import java.awt.Point;\r
14 import java.awt.Rectangle;\r
15 import java.awt.Stroke;\r
16 import java.awt.image.BufferedImage;\r
17 import java.io.IOException;\r
18 import java.util.regex.Pattern;\r
19 \r
20 /**\r
21  * アンカー描画。\r
22  */\r
23 public class AnchorDraw extends AbstractTextRow{\r
24 \r
25     private static final Color COLOR_ANCHOR = new Color(0xffff99);\r
26     private static final Color COLOR_SIMPLEFG = Color.BLACK;\r
27     private static final int UPPER_MARGIN = 3;\r
28     private static final int UNDER_MARGIN = 3;\r
29 \r
30     private static final Stroke STROKE_DASH;\r
31 \r
32     static{\r
33         float[] dash = {3.0f};\r
34         STROKE_DASH = new BasicStroke(1.0f,\r
35                                       BasicStroke.CAP_SQUARE,\r
36                                       BasicStroke.JOIN_MITER,\r
37                                       10.0f,\r
38                                       dash,\r
39                                       0.0f);\r
40     }\r
41 \r
42     private final Talk talk;\r
43     private final GlyphDraw caption;\r
44     private final GlyphDraw dialog;\r
45     private final BufferedImage faceImage;\r
46     private final Point imageOrigin   = new Point();\r
47     private final Point captionOrigin = new Point();\r
48     private final Point dialogOrigin  = new Point();\r
49 \r
50     private DialogPref dialogPref;\r
51 \r
52     /**\r
53      * コンストラクタ。\r
54      * @param talk 発言\r
55      */\r
56     public AnchorDraw(Talk talk){\r
57         this(talk, new DialogPref(), FontInfo.DEFAULT_FONTINFO);\r
58         return;\r
59     }\r
60 \r
61     /**\r
62      * コンストラクタ。\r
63      * @param talk 発言\r
64      * @param pref 発言表示設定\r
65      * @param fontInfo フォント設定\r
66      */\r
67     public AnchorDraw(Talk talk, DialogPref pref, FontInfo fontInfo){\r
68         super(fontInfo);\r
69 \r
70         this.talk = talk;\r
71         this.caption = new GlyphDraw(getCaptionString(), this.fontInfo);\r
72         this.dialog  = new GlyphDraw(this.talk.getDialog(), this.fontInfo);\r
73         this.dialogPref = pref;\r
74         this.faceImage = getFaceImage();\r
75 \r
76         setColorDesign();\r
77 \r
78         return;\r
79     }\r
80 \r
81     /**\r
82      * 顔アイコンイメージを返す。\r
83      * @return アイコンイメージ\r
84      */\r
85     private BufferedImage getFaceImage(){\r
86         Period period = this.talk.getPeriod();\r
87         Village village = period.getVillage();\r
88 \r
89         BufferedImage image;\r
90         if(this.talk.isGrave()){\r
91             image = village.getGraveImage();\r
92         }else{\r
93             Avatar avatar = this.talk.getAvatar();\r
94             image = village.getAvatarFaceImage(avatar);\r
95         }\r
96 \r
97         return image;\r
98     }\r
99 \r
100     /**\r
101      * 配色を設定する。\r
102      */\r
103     private void setColorDesign(){\r
104         Color fgColor;\r
105         if(this.dialogPref.isSimpleMode()){\r
106             fgColor = COLOR_SIMPLEFG;\r
107         }else{\r
108             fgColor = COLOR_ANCHOR;\r
109         }\r
110         this.caption.setColor(fgColor);\r
111         this.dialog .setColor(fgColor);\r
112         return;\r
113     }\r
114 \r
115     /**\r
116      * キャプション文字列の取得。\r
117      * @return キャプション文字列\r
118      */\r
119     private CharSequence getCaptionString(){\r
120         StringBuilder result = new StringBuilder();\r
121         Avatar avatar = this.talk.getAvatar();\r
122 \r
123         if(this.talk.hasTalkNo()){\r
124             result.append(this.talk.getAnchorNotation_G()).append(' ');\r
125         }\r
126         result.append(avatar.getFullName())\r
127               .append(' ')\r
128               .append(this.talk.getAnchorNotation());\r
129 \r
130         return result;\r
131     }\r
132 \r
133     /**\r
134      * {@inheritDoc}\r
135      * @return {@inheritDoc}\r
136      */\r
137     public Rectangle recalcBounds(){\r
138         int newWidth = getWidth();\r
139 \r
140         int imageWidth  = 0;\r
141         int imageHeight = 0;\r
142         if( ! this.dialogPref.isSimpleMode() ){\r
143             imageWidth  = this.faceImage.getWidth(null);\r
144             imageHeight = this.faceImage.getHeight(null);\r
145         }\r
146 \r
147         this.caption.setWidth(newWidth - imageWidth);\r
148         int captionWidth  = this.caption.getWidth();\r
149         int captionHeight = this.caption.getHeight();\r
150 \r
151         this.dialog.setWidth(newWidth);\r
152         int dialogWidth  = this.dialog.getWidth();\r
153         int dialogHeight = this.dialog.getHeight();\r
154 \r
155         int headerHeight = Math.max(imageHeight, captionHeight);\r
156 \r
157         int totalWidth = Math.max(imageWidth + captionWidth, dialogWidth);\r
158 \r
159         int totalHeight = headerHeight;\r
160         totalHeight += dialogHeight;\r
161 \r
162         int imageYpos;\r
163         int captionYpos;\r
164         if(imageHeight > captionHeight){\r
165             imageYpos = 0;\r
166             captionYpos = (imageHeight - captionHeight) / 2;\r
167         }else{\r
168             imageYpos = (captionHeight - imageHeight) / 2;\r
169             captionYpos = 0;\r
170         }\r
171 \r
172         this.imageOrigin  .setLocation(0,\r
173                                        UPPER_MARGIN + imageYpos);\r
174         this.captionOrigin.setLocation(imageWidth,\r
175                                        UPPER_MARGIN + captionYpos);\r
176         this.dialogOrigin .setLocation(0,\r
177                                        UPPER_MARGIN + headerHeight);\r
178 \r
179         if(this.dialogPref.isSimpleMode()){\r
180             this.bounds.width  = newWidth;\r
181         }else{\r
182             this.bounds.width  = totalWidth;\r
183         }\r
184         this.bounds.height = UPPER_MARGIN + totalHeight + UNDER_MARGIN;\r
185 \r
186         return this.bounds;\r
187     }\r
188 \r
189     /**\r
190      * {@inheritDoc}\r
191      * @param fontInfo {@inheritDoc}\r
192      */\r
193     @Override\r
194     public void setFontInfo(FontInfo fontInfo){\r
195         super.setFontInfo(fontInfo);\r
196 \r
197         this.caption.setFontInfo(this.fontInfo);\r
198         this.dialog .setFontInfo(this.fontInfo);\r
199 \r
200         recalcBounds();\r
201 \r
202         return;\r
203     }\r
204 \r
205     /**\r
206      * 発言設定を更新する。\r
207      * @param pref 発言設定\r
208      */\r
209     public void setDialogPref(DialogPref pref){\r
210         this.dialogPref = pref;\r
211 \r
212         setColorDesign();\r
213         recalcBounds();\r
214 \r
215         return;\r
216     }\r
217 \r
218     /**\r
219      * {@inheritDoc}\r
220      * @param from {@inheritDoc}\r
221      * @param to {@inheritDoc}\r
222      */\r
223     public void drag(Point from, Point to){\r
224         this.caption.drag(from, to);\r
225         this.dialog.drag(from, to);\r
226         return;\r
227     }\r
228 \r
229     /**\r
230      * {@inheritDoc}\r
231      * @param appendable {@inheritDoc}\r
232      * @return {@inheritDoc}\r
233      * @throws java.io.IOException {@inheritDoc}\r
234      */\r
235     public Appendable appendSelected(Appendable appendable)\r
236             throws IOException{\r
237         this.caption.appendSelected(appendable);\r
238         this.dialog.appendSelected(appendable);\r
239         return appendable;\r
240     }\r
241 \r
242     /**\r
243      * {@inheritDoc}\r
244      */\r
245     public void clearSelect(){\r
246         this.caption.clearSelect();\r
247         this.dialog.clearSelect();\r
248         return;\r
249     }\r
250 \r
251     /**\r
252      * 検索文字列パターンを設定する。\r
253      * @param searchRegex パターン\r
254      * @return ヒット数\r
255      */\r
256     public int setRegex(Pattern searchRegex){\r
257         int total = 0;\r
258 \r
259         total += this.dialog.setRegex(searchRegex);\r
260 \r
261         return total;\r
262     }\r
263 \r
264     /**\r
265      * {@inheritDoc}\r
266      * @param g {@inheritDoc}\r
267      */\r
268     public void paint(Graphics2D g){\r
269         final int xPos = this.bounds.x;\r
270         final int yPos = this.bounds.y;\r
271 \r
272         if(this.dialogPref.isSimpleMode()){\r
273             Stroke oldStroke = g.getStroke();\r
274             g.setStroke(STROKE_DASH);\r
275             g.drawLine(xPos,                     this.bounds.y,\r
276                        xPos + this.bounds.width, this.bounds.y );\r
277             g.setStroke(oldStroke);\r
278         }else{\r
279             g.drawImage(this.faceImage,\r
280                         xPos + this.imageOrigin.x,\r
281                         yPos + this.imageOrigin.y,\r
282                         null );\r
283         }\r
284 \r
285         this.caption.setPos(xPos + this.captionOrigin.x,\r
286                             yPos + this.captionOrigin.y );\r
287         this.caption.paint(g);\r
288 \r
289         this.dialog.setPos(xPos + this.dialogOrigin.x,\r
290                            yPos + this.dialogOrigin.y );\r
291         this.dialog.paint(g);\r
292 \r
293         return;\r
294     }\r
295 \r
296 }\r