OSDN Git Service

roundタイプの画面表示調整を開始。
[gokigen/JoggingTimer.git] / wear / src / main / java / net / osdn / gokigen / joggingtimer / stopwatch / graphview / LapTimeGraphView.java
1 package net.osdn.gokigen.joggingtimer.stopwatch.graphview;
2
3 import android.content.Context;
4 import android.graphics.Canvas;
5 import android.graphics.Color;
6 import android.graphics.Paint;
7 import android.graphics.Rect;
8 import android.graphics.RectF;
9 import android.util.AttributeSet;
10 import android.view.View;
11
12 import net.osdn.gokigen.joggingtimer.stopwatch.ITimerCounter;
13 import net.osdn.gokigen.joggingtimer.utilities.TimeStringConvert;
14
15 import java.util.ArrayList;
16 import java.util.List;
17
18 /**
19  *
20  *
21  */
22 public class LapTimeGraphView extends View
23 {
24     private Context context = null;
25     private ITimerCounter timerCounter = null;
26     private boolean isStarted = false;
27     private long maxLaptime = 0;
28     private long lastSystemLaptime = 0;
29     private int totalLaptimeCount = 0;
30
31     private List<Long> refTimeList = null;
32     private List<Long> refLapTimeList = null;
33
34     private List<Long> curTimeList = null;
35     private List<Long> curLapTimeList = null;
36
37     /**
38      *   コンストラクタ
39      *
40      */
41     public LapTimeGraphView(Context context)
42     {
43         super(context);
44         initComponent(context);
45     }
46
47     /**
48      *   コンストラクタ
49      *
50      */
51     public LapTimeGraphView(Context context, AttributeSet attrs)
52     {
53         super(context, attrs);
54         initComponent(context);
55     }
56
57     /**
58      *   コンストラクタ
59      *
60      */
61     public LapTimeGraphView(Context context, AttributeSet attrs, int defStyleAttr)
62     {
63         super(context, attrs, defStyleAttr);
64         initComponent(context);
65     }
66
67     /**
68      *   初期化ロジック
69      */
70     private void initComponent(Context context)
71     {
72         this.context = context;
73         setWillNotDraw(false);
74         curLapTimeList = new ArrayList<>();
75     }
76
77     /**
78      *
79      *
80      */
81     public void setITimerCounter(ITimerCounter counter)
82     {
83         timerCounter = counter;
84         parseReferenceTimeList();
85         parseLapTime();
86     }
87
88     /**
89      *
90      *
91      */
92     public void notifyStarted(long startTime)
93     {
94         curLapTimeList.clear();
95         lastSystemLaptime = startTime;
96         isStarted = true;
97     }
98
99     /**
100      *
101      *
102      */
103     public void notifyLapTime()
104     {
105         // ラップタイムの取得
106         parseLapTime();
107         isStarted = true;
108     }
109
110     /**
111      *
112      *
113      */
114     public void notifyStopped()
115     {
116         // ラップタイムの取得
117         parseLapTime();
118         isStarted = false;
119     }
120
121     /**
122      *
123      *
124      */
125     public void notifyReset()
126     {
127         curLapTimeList.clear();
128         isStarted = false;
129     }
130
131     /**
132      *
133      *
134      */
135     @Override
136     protected void onDraw(Canvas canvas)
137     {
138         super.onDraw(canvas);
139
140         try
141         {
142             // 背景の表示
143             drawBackground(canvas);
144
145             // 基準の値表示
146             drawReferenceLap(canvas);
147
148             // 現在の値表示
149             drawCurrentLap(canvas);
150
151             // メッセージの表示
152             drawMessage(canvas);
153         }
154         catch (Exception e)
155         {
156             e.printStackTrace();
157         }
158
159     }
160
161     /**
162      *
163      *
164      */
165     private void drawBackground(Canvas canvas)
166     {
167         int width = canvas.getWidth();
168         int height = canvas.getHeight();
169
170         Rect rect = new Rect(0,0, width, height);
171         Paint paint = new Paint();
172         paint.setColor(Color.BLACK);
173         paint.setStyle(Paint.Style.FILL);
174         canvas.drawRect(rect, paint);
175
176         // Log.v("Canvas", "("+ width + "," + height + ")");
177     }
178
179     /**
180      *
181      *
182      */
183     private void drawReferenceLap(Canvas canvas)
184     {
185         if ((refLapTimeList == null)||(refLapTimeList.size() <= 0))
186         {
187             return;
188         }
189
190         float width = canvas.getWidth();
191         float height = canvas.getHeight();
192
193         Paint paint = new Paint();
194         paint.setColor(Color.BLUE);
195         paint.setStyle(Paint.Style.STROKE);
196         paint.setStyle(Paint.Style.FILL);
197         paint.setStrokeWidth(0.0f);
198         paint.setAntiAlias(true);
199
200         float boxWidthUnit = width / (totalLaptimeCount);
201         float boxHeightUnit = height / (maxLaptime * 1.2f);
202
203         float startX = 0.0f;
204         for (Long time : refLapTimeList)
205         {
206             RectF barRect = new RectF(startX, (height - boxHeightUnit * time), (startX + boxWidthUnit), height);
207             canvas.drawRect(barRect, paint);
208             startX = startX + boxWidthUnit;
209         }
210     }
211
212
213     /**
214      *
215      *
216      */
217     private void drawCurrentLap(Canvas canvas)
218     {
219         if (curLapTimeList == null)
220         {
221             return;
222         }
223
224         float width = canvas.getWidth();
225         float height = canvas.getHeight();
226
227         Paint paint = new Paint();
228         paint.setColor(Color.WHITE);
229         paint.setStyle(Paint.Style.STROKE);
230         paint.setStyle(Paint.Style.FILL);
231         paint.setStrokeWidth(0.0f);
232         paint.setAntiAlias(true);
233
234         int minimumLapTime = 15;
235         float boxWidthUnit = width / (totalLaptimeCount);
236         float boxHeightUnit = height / (maxLaptime * 1.2f);
237         float circleRadius = (totalLaptimeCount > minimumLapTime) ? (boxWidthUnit / 4.0f) : (width / minimumLapTime / 4.0f);
238
239         float startX = 0.0f;
240         if ((curLapTimeList.size() <= 0)&&(isStarted))
241         {
242             long currentLapTime = System.currentTimeMillis() - lastSystemLaptime;
243             canvas.drawCircle((startX + (boxWidthUnit / 2.0f)), (height - boxHeightUnit * currentLapTime), circleRadius, paint);
244             return;
245         }
246
247         for (Long time : curLapTimeList)
248         {
249             canvas.drawCircle((startX + (boxWidthUnit / 2.0f)), (height - boxHeightUnit * time), circleRadius, paint);
250             startX = startX + boxWidthUnit;
251         }
252
253         if (isStarted)
254         {
255             long currentLapTime = System.currentTimeMillis() - lastSystemLaptime;
256             canvas.drawCircle((startX + (boxWidthUnit / 2.0f)), (height - boxHeightUnit * currentLapTime), circleRadius, paint);
257         }
258     }
259
260     /**
261      *
262      *
263      */
264     private void drawMessage(Canvas canvas)
265     {
266         boolean drawTextLeft = false;
267         int width = canvas.getWidth();
268         int height = canvas.getHeight();
269         Paint paint = new Paint();
270
271         paint.setColor(Color.WHITE);
272         paint.setStyle(Paint.Style.STROKE);
273         paint.setStrokeWidth(0.0f);
274         paint.setAntiAlias(true);
275         //canvas.drawRect(rect, paint);
276
277         int lapCount = 0;
278         int refCount = 0;
279         long diffTime = 0;
280         long lapTime = 0;
281         long currTime = 0;
282         try
283         {
284             if (curTimeList != null)
285             {
286                 lapCount = curTimeList.size();
287             }
288
289             if (refTimeList != null)
290             {
291                 refCount = refTimeList.size();
292             }
293
294             if (lapCount > 1)
295             {
296                 long totalTime = curTimeList.get(lapCount - 1) - curTimeList.get(0);
297                 currTime =  curTimeList.get(lapCount - 1) - curTimeList.get(lapCount - 2);
298                 //long currTime =  (lapCount > 2) ? curTimeList.get(lapCount - 1) - curTimeList.get(lapCount - 2) : 0;
299                 if ((lapCount <= refCount)&&(refTimeList != null))
300                 {
301                     diffTime = totalTime - (refTimeList.get(lapCount - 1) - refTimeList.get(0));
302                     lapTime = currTime - (refTimeList.get(lapCount - 1) - refTimeList.get(lapCount - 2));
303                     //lapTime = currTime - ((lapCount > 2) ? refTimeList.get(lapCount - 1) - refTimeList.get(lapCount - 2) : 0);
304                 }
305             }
306         }
307         catch (Exception e)
308         {
309             e.printStackTrace();
310         }
311
312         String textToDraw = "";
313         if ((lapTime == 0)&&(diffTime == 0)&&(lapCount > 1))
314         {
315             textToDraw = "[" + (lapCount - 1) + "] " + TimeStringConvert.getTimeString(currTime).toString();
316             drawTextLeft = true;
317         }
318         else
319         {
320             if (lapTime != 0)
321             {
322                 textToDraw = TimeStringConvert.getDiffTimeString(lapTime).toString();
323             }
324             if (diffTime != 0)
325             {
326                 //  「前回ラップ時間の遅れ・進み / 全体時間の遅れ・進み」
327                 textToDraw = textToDraw + " / " + TimeStringConvert.getDiffTimeString(diffTime).toString();
328             }
329         }
330
331         // 表示する文字の大きさの決定
332         try
333         {
334             float density = context.getResources().getDisplayMetrics().density;
335             paint.setTextSize(density * 20.0f + 0.5f);
336         }
337         catch (Exception e)
338         {
339             e.printStackTrace();
340             paint.setTextSize(32.0f);
341         }
342         paint.setAntiAlias(true);
343         Paint.FontMetrics fm = paint.getFontMetrics();
344         float textHeight = fm.descent - fm.ascent;
345         float textWidth = paint.measureText(textToDraw);
346
347         // 表示位置の調整...
348         float x = (width < textWidth) ? 0.0f : (width - textWidth - 8.0f);
349         float y = (height - textHeight - 2) - fm.ascent;
350         if (drawTextLeft)
351         {
352             x = 0.0f;
353         }
354         canvas.drawText(textToDraw, x , y, paint);
355     }
356
357     /**
358      *
359      *
360      */
361     private void parseReferenceTimeList()
362     {
363         if (timerCounter == null)
364         {
365             return;
366         }
367         refLapTimeList = null;
368
369         refTimeList = timerCounter.getReferenceLapTimeList();
370         if (refTimeList == null)
371         {
372             return;
373         }
374         totalLaptimeCount = refTimeList.size();
375         maxLaptime = 0;
376         if (totalLaptimeCount <= 1)
377         {
378             return;
379         }
380         refLapTimeList = new ArrayList<>();
381         long prevTime = refTimeList.get(0);
382         for (Long time : refTimeList)
383         {
384             long currTime = time - prevTime;
385             if (currTime > 0)
386             {
387                 refLapTimeList.add(currTime);
388             }
389             if (currTime > maxLaptime)
390             {
391                 maxLaptime = currTime;
392             }
393             prevTime = time;
394         }
395     }
396
397     /**
398      *
399      *
400      */
401     private void parseLapTime()
402     {
403         if (timerCounter == null)
404         {
405             return;
406         }
407         curTimeList = timerCounter.getLapTimeList();
408         int lapTimeCount = curTimeList.size();
409         if (lapTimeCount > totalLaptimeCount)
410         {
411             totalLaptimeCount = lapTimeCount;
412         }
413         if (lapTimeCount < 1)
414         {
415             // 開始前の場合...
416             return;
417         }
418         if (lapTimeCount == 1)
419         {
420             lastSystemLaptime = curTimeList.get(0);
421             return;
422         }
423
424         curLapTimeList.clear();
425         long prevTime = curTimeList.get(0);
426         for (Long time : curTimeList)
427         {
428             long currTime = time - prevTime;
429             if (currTime > 0)
430             {
431                 curLapTimeList.add(currTime);
432             }
433             if (currTime > maxLaptime)
434             {
435                 maxLaptime = currTime;
436             }
437             prevTime = time;
438         }
439         lastSystemLaptime = prevTime;
440     }
441
442     @Override
443     public boolean performClick()
444     {
445         return (super.performClick());
446     }
447 }