• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2010 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.videoeditor.widgets;
18 
19 import com.android.videoeditor.service.VideoEditorProject;
20 import com.android.videoeditor.util.StringUtils;
21 import com.android.videoeditor.R;
22 
23 import android.content.Context;
24 import android.content.res.Resources;
25 import android.graphics.Canvas;
26 import android.graphics.Paint;
27 import android.util.AttributeSet;
28 import android.util.DisplayMetrics;
29 import android.view.Display;
30 import android.view.View;
31 import android.view.WindowManager;
32 
33 /**
34  * The view which displays the scroll position
35  */
36 public class PlayheadView extends View {
37     // Instance variables
38     private final Paint mLinePaint;
39     private final Paint mTextPaint;
40     private final int mTicksHeight;
41     // Timeline text size.
42     private final float mTimeTextSize;
43     private final int mScreenWidth;
44     private final ScrollViewListener mScrollListener;
45     private int mScrollX;
46     private VideoEditorProject mProject;
47 
PlayheadView(Context context, AttributeSet attrs, int defStyle)48     public PlayheadView(Context context, AttributeSet attrs, int defStyle) {
49         super(context, attrs, defStyle);
50 
51         final Resources resources = context.getResources();
52 
53         // Prepare the Paint used to draw the tick marks
54         mLinePaint = new Paint();
55         mLinePaint.setColor(resources.getColor(R.color.playhead_tick_color));
56         mLinePaint.setStrokeWidth(2);
57         mLinePaint.setStyle(Paint.Style.STROKE);
58 
59         // Prepare the Paint used to draw the text
60         mTextPaint = new Paint();
61         mTextPaint.setAntiAlias(true);
62         mTextPaint.setColor(resources.getColor(R.color.playhead_tick_color));
63         mTimeTextSize = resources.getDimension(R.dimen.playhead_layout_text_size);
64         mTextPaint.setTextSize(mTimeTextSize);
65 
66         // The ticks height
67         mTicksHeight = (int)resources.getDimension(R.dimen.playhead_tick_height);
68 
69         // Get the screen width
70         final Display display = ((WindowManager)context.getSystemService(
71                 Context.WINDOW_SERVICE)).getDefaultDisplay();
72         final DisplayMetrics metrics = new DisplayMetrics();
73         display.getMetrics(metrics);
74         mScreenWidth = metrics.widthPixels;
75 
76         // Listen to scroll events and repaint this view as needed
77         mScrollListener = new ScrollViewListener() {
78 
79             @Override
80             public void onScrollBegin(View view, int scrollX, int scrollY, boolean appScroll) {
81             }
82 
83             @Override
84             public void onScrollProgress(View view, int scrollX, int scrollY, boolean appScroll) {
85                 mScrollX = scrollX;
86                 invalidate();
87             }
88 
89             @Override
90             public void onScrollEnd(View view, int scrollX, int scrollY, boolean appScroll) {
91                 mScrollX = scrollX;
92                 invalidate();
93             }
94         };
95     }
96 
PlayheadView(Context context, AttributeSet attrs)97     public PlayheadView(Context context, AttributeSet attrs) {
98         this(context, attrs, 0);
99     }
100 
PlayheadView(Context context)101     public PlayheadView(Context context) {
102         this(context, null, 0);
103     }
104 
105     @Override
onAttachedToWindow()106     protected void onAttachedToWindow() {
107         final TimelineHorizontalScrollView scrollView =
108             (TimelineHorizontalScrollView)((View)getParent()).getParent();
109         mScrollX = scrollView.getScrollX();
110         scrollView.addScrollListener(mScrollListener);
111     }
112 
113     @Override
onDetachedFromWindow()114     protected void onDetachedFromWindow() {
115         final TimelineHorizontalScrollView scrollView =
116             (TimelineHorizontalScrollView)((View)getParent()).getParent();
117         scrollView.removeScrollListener(mScrollListener);
118     }
119 
120     /**
121      * @param project The project
122      */
setProject(VideoEditorProject project)123     public void setProject(VideoEditorProject project) {
124         mProject = project;
125     }
126 
127     @Override
onDraw(Canvas canvas)128     protected void onDraw(Canvas canvas) {
129         super.onDraw(canvas);
130 
131         if (mProject == null) {
132             return;
133         }
134 
135         final long durationMs = mProject.computeDuration();
136         final long durationSec = durationMs / 1000;
137         final int y = (int) -mTextPaint.getFontMetrics().top;
138         // We only draw the origin when there is nothing on the timeline.
139         if (durationMs == 0 || durationSec == 0) {
140             final String timeText = StringUtils.getSimpleTimestampAsString(getContext(), 0);
141             int x = (int) ((getWidth() - mTextPaint.measureText(timeText)) / 2);
142             canvas.drawText(timeText, x, y, mTextPaint);
143             return;
144         }
145 
146         final int width = getWidth() - mScreenWidth;
147         // Compute the number of pixels per second
148         final int pixelsPerSec = (int) (width / durationSec);
149 
150         // Compute the distance between ticks
151         final long tickMs;
152         if (pixelsPerSec < 4) {
153             tickMs = 240000;
154         } else if (pixelsPerSec < 6) {
155             tickMs = 120000;
156         } else if (pixelsPerSec < 10) {
157             tickMs = 60000;
158         } else if (pixelsPerSec < 50) {
159             tickMs = 10000;
160         } else if (pixelsPerSec < 200) {
161             tickMs = 5000;
162         } else {
163             tickMs = 1000;
164         }
165 
166         final float spacing = ((float) (width * tickMs) / (float) durationMs);
167         final float startX = Math.max(mScrollX - (((mScrollX - (mScreenWidth / 2)) % spacing)),
168                 mScreenWidth / 2);
169         float startMs = ((tickMs * (startX - (mScreenWidth / 2))) / spacing);
170         startMs = Math.round(startMs);
171         startMs -= (startMs % tickMs);
172 
173         final Context context = getContext();
174         final float endX = mScrollX + mScreenWidth;
175         for (float i = startX; i <= endX; i += spacing, startMs += tickMs) {
176             final String timeText = StringUtils.getSimpleTimestampAsString(context, (long) startMs);
177             final int x = (int) (i - mTextPaint.measureText(timeText) / 2);
178             canvas.drawText(timeText, x, y, mTextPaint);
179             canvas.drawLine(i, 0, i, mTicksHeight, mLinePaint);
180         }
181     }
182 }
183