OSDN Git Service

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