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