Home | History | Annotate | Download | only in widgets
      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 
     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 
     97     public PlayheadView(Context context, AttributeSet attrs) {
     98         this(context, attrs, 0);
     99     }
    100 
    101     public PlayheadView(Context context) {
    102         this(context, null, 0);
    103     }
    104 
    105     @Override
    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
    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      */
    123     public void setProject(VideoEditorProject project) {
    124         mProject = project;
    125     }
    126 
    127     @Override
    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