OSDN Git Service

00938d1ed9eabb1c67903ac3aaccb3cd1700d7b2
[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         // 背景の表示
141         drawBackground(canvas);
142
143         // 基準の値表示
144         drawReferenceLap(canvas);
145
146         // 現在の値表示
147         drawCurrentLap(canvas);
148
149         // メッセージの表示
150         drawMessage(canvas);
151
152     }
153
154     /**
155      *
156      *
157      */
158     private void drawBackground(Canvas canvas)
159     {
160         int width = canvas.getWidth();
161         int height = canvas.getHeight();
162
163         Rect rect = new Rect(0,0, width, height);
164         Paint paint = new Paint();
165         paint.setColor(Color.BLACK);
166         paint.setStyle(Paint.Style.FILL);
167         canvas.drawRect(rect, paint);
168     }
169
170     /**
171      *
172      *
173      */
174     private void drawReferenceLap(Canvas canvas)
175     {
176         if ((refLapTimeList == null)||(refLapTimeList.size() <= 0))
177         {
178             return;
179         }
180
181         float width = canvas.getWidth();
182         float height = canvas.getHeight();
183
184         Paint paint = new Paint();
185         paint.setColor(Color.BLUE);
186         paint.setStyle(Paint.Style.STROKE);
187         paint.setStyle(Paint.Style.FILL);
188         paint.setStrokeWidth(0.0f);
189         paint.setAntiAlias(true);
190
191         float boxWidthUnit = width / (totalLaptimeCount);
192         float boxHeightUnit = height / (maxLaptime * 1.2f);
193
194         float startX = 0.0f;
195         for (Long time : refLapTimeList)
196         {
197             RectF barRect = new RectF(startX, (height - boxHeightUnit * time), (startX + boxWidthUnit), height);
198             canvas.drawRect(barRect, paint);
199             startX = startX + boxWidthUnit;
200         }
201     }
202
203
204     /**
205      *
206      *
207      */
208     private void drawCurrentLap(Canvas canvas)
209     {
210         if (curLapTimeList == null)
211         {
212             return;
213         }
214
215         float width = canvas.getWidth();
216         float height = canvas.getHeight();
217
218         Paint paint = new Paint();
219         paint.setColor(Color.WHITE);
220         paint.setStyle(Paint.Style.STROKE);
221         paint.setStyle(Paint.Style.FILL);
222         paint.setStrokeWidth(0.0f);
223         paint.setAntiAlias(true);
224
225         int minimumLapTime = 15;
226         float boxWidthUnit = width / (totalLaptimeCount);
227         float boxHeightUnit = height / (maxLaptime * 1.2f);
228         float circleRadius = (totalLaptimeCount > minimumLapTime) ? (boxWidthUnit / 4.0f) : (width / minimumLapTime / 4.0f);
229
230         float startX = 0.0f;
231         if ((curLapTimeList.size() <= 0)&&(isStarted))
232         {
233             long currentLapTime = System.currentTimeMillis() - lastSystemLaptime;
234             canvas.drawCircle((startX + (boxWidthUnit / 2.0f)), (height - boxHeightUnit * currentLapTime), circleRadius, paint);
235             return;
236         }
237
238         for (Long time : curLapTimeList)
239         {
240             canvas.drawCircle((startX + (boxWidthUnit / 2.0f)), (height - boxHeightUnit * time), circleRadius, paint);
241             startX = startX + boxWidthUnit;
242         }
243
244         if (isStarted)
245         {
246             long currentLapTime = System.currentTimeMillis() - lastSystemLaptime;
247             canvas.drawCircle((startX + (boxWidthUnit / 2.0f)), (height - boxHeightUnit * currentLapTime), circleRadius, paint);
248         }
249     }
250
251     /**
252      *
253      *
254      */
255     private void drawMessage(Canvas canvas)
256     {
257         int width = canvas.getWidth();
258         int height = canvas.getHeight();
259         Paint paint = new Paint();
260
261         paint.setColor(Color.WHITE);
262         paint.setStyle(Paint.Style.STROKE);
263         paint.setStrokeWidth(0.0f);
264         paint.setAntiAlias(true);
265         //canvas.drawRect(rect, paint);
266
267         int lapCount = 0;
268         int refCount = 0;
269         long diffTime = 0;
270         long lapTime = 0;
271         try
272         {
273             if (curTimeList != null)
274             {
275                 lapCount = curTimeList.size();
276             }
277
278             if (refTimeList != null)
279             {
280                 refCount = refTimeList.size();
281             }
282
283             if (lapCount > 1)
284             {
285                 long totalTime = curTimeList.get(lapCount - 1) - curTimeList.get(0);
286                 long currTime =  curTimeList.get(lapCount - 1) - curTimeList.get(lapCount - 2);
287                 //long currTime =  (lapCount > 2) ? curTimeList.get(lapCount - 1) - curTimeList.get(lapCount - 2) : 0;
288                 if ((lapCount <= refCount)&&(refTimeList != null))
289                 {
290                     diffTime = totalTime - (refTimeList.get(lapCount - 1) - refTimeList.get(0));
291                     lapTime = currTime - (refTimeList.get(lapCount - 1) - refTimeList.get(lapCount - 2));
292                     //lapTime = currTime - ((lapCount > 2) ? refTimeList.get(lapCount - 1) - refTimeList.get(lapCount - 2) : 0);
293                 }
294             }
295         }
296         catch (Exception e)
297         {
298             e.printStackTrace();
299         }
300
301
302         String ovearll = "";
303         if (diffTime != 0)
304         {
305             ovearll = "T:" + TimeStringConvert.getDiffTimeString(diffTime).toString();
306         }
307         String lap = "";
308         if (lapTime != 0)
309         {
310             lap = TimeStringConvert.getDiffTimeString(lapTime).toString();
311         }
312
313         // 表示する文字の大きさの決定
314         try
315         {
316             float density = context.getResources().getDisplayMetrics().density;
317             paint.setTextSize(density * 20.0f + 0.5f);  //
318         }
319         catch (Exception e)
320         {
321             e.printStackTrace();
322             paint.setTextSize(32.0f);
323         }
324         paint.setAntiAlias(true);
325         Paint.FontMetrics fm = paint.getFontMetrics();
326         float textHeight = fm.descent - fm.ascent;
327         float textWidth = paint.measureText(ovearll);
328
329         // 表示位置の調整...
330         float x = (width < textWidth) ? 0.0f : (width - textWidth - 8.0f);
331         float y = (height - textHeight - 2) - fm.ascent;
332
333         canvas.drawText(ovearll, x , y, paint);     // 全体時間の遅れ・進み
334         canvas.drawText(lap, 0.0f , y, paint);  // 前回ラップ時間の遅れ・進み
335     }
336
337     /**
338      *
339      *
340      */
341     private void parseReferenceTimeList()
342     {
343         if (timerCounter == null)
344         {
345             return;
346         }
347         refLapTimeList = null;
348
349         refTimeList = timerCounter.getReferenceLapTimeList();
350         if (refTimeList == null)
351         {
352             return;
353         }
354         totalLaptimeCount = refTimeList.size();
355         maxLaptime = 0;
356         if (totalLaptimeCount <= 1)
357         {
358             return;
359         }
360         refLapTimeList = new ArrayList<>();
361         long prevTime = refTimeList.get(0);
362         for (Long time : refTimeList)
363         {
364             long currTime = time - prevTime;
365             if (currTime > 0)
366             {
367                 refLapTimeList.add(currTime);
368             }
369             if (currTime > maxLaptime)
370             {
371                 maxLaptime = currTime;
372             }
373             prevTime = time;
374         }
375     }
376
377     /**
378      *
379      *
380      */
381     private void parseLapTime()
382     {
383         if (timerCounter == null)
384         {
385             return;
386         }
387         curTimeList = timerCounter.getLapTimeList();
388         int lapTimeCount = curTimeList.size();
389         if (lapTimeCount > totalLaptimeCount)
390         {
391             totalLaptimeCount = lapTimeCount;
392         }
393         if (lapTimeCount < 1)
394         {
395             // 開始前の場合...
396             return;
397         }
398         if (lapTimeCount == 1)
399         {
400             lastSystemLaptime = curTimeList.get(0);
401             return;
402         }
403
404         curLapTimeList.clear();
405         long prevTime = curTimeList.get(0);
406         for (Long time : curTimeList)
407         {
408             long currTime = time - prevTime;
409             if (currTime > 0)
410             {
411                 curLapTimeList.add(currTime);
412             }
413             if (currTime > maxLaptime)
414             {
415                 maxLaptime = currTime;
416             }
417             prevTime = time;
418         }
419         lastSystemLaptime = prevTime;
420     }
421
422     @Override
423     public boolean performClick()
424     {
425         return (super.performClick());
426     }
427 }