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.R;
     20 
     21 import android.content.Context;
     22 import android.content.res.Resources;
     23 import android.graphics.Canvas;
     24 import android.graphics.drawable.Drawable;
     25 import android.util.AttributeSet;
     26 import android.view.MotionEvent;
     27 import android.widget.ImageView;
     28 
     29 /**
     30  * The view that represents a resize handle
     31  */
     32 public class HandleView extends ImageView {
     33     // Instance variables
     34     private final Drawable mIconDragClipLeft;
     35     private final Drawable mIconDragClipRight;
     36     private MoveListener mListener;
     37     private float mStartMoveX, mLastMoveX;
     38     private boolean mMoveStarted;
     39     private boolean mBeginLimitReached, mEndLimitReached;
     40     private int mLastDeltaX;
     41 
     42     /**
     43      * Move listener
     44      */
     45     public interface MoveListener {
     46         /**
     47          * The move begins
     48          *
     49          * @param view The view
     50          */
     51         public void onMoveBegin(HandleView view);
     52 
     53         /**
     54          * Move is in progress
     55          *
     56          * @param view The view
     57          * @param left The left edge left position
     58          * @param delta The offset relative to the left of the view
     59          */
     60         public boolean onMove(HandleView view, int left, int delta);
     61 
     62         /**
     63          * The move ended
     64          *
     65          * @param view The view
     66          * @param left The left edge left position
     67          * @param delta The offset relative to the left of the view
     68          */
     69         public void onMoveEnd(HandleView view, int left, int delta);
     70     }
     71 
     72     public HandleView(Context context, AttributeSet attrs, int defStyle) {
     73         super(context, attrs, defStyle);
     74 
     75         // Prepare the handle arrows
     76         final Resources resources = getResources();
     77         mIconDragClipLeft = resources.getDrawable(R.drawable.ic_drag_clip_left);
     78         mIconDragClipRight = resources.getDrawable(R.drawable.ic_drag_clip_right);
     79     }
     80 
     81     public HandleView(Context context, AttributeSet attrs) {
     82         this(context, attrs, 0);
     83     }
     84 
     85     public HandleView(Context context) {
     86         this(context, null, 0);
     87     }
     88 
     89     /**
     90      * @param listener The listener
     91      */
     92     public void setListener(MoveListener listener) {
     93         mListener = listener;
     94     }
     95 
     96     /**
     97      * Set the movement limits
     98      *
     99      * @param beginLimitReached true if the begin limit was reached
    100      * @param endLimitReached true if the end limit was reached
    101      */
    102     public void setLimitReached(boolean beginLimitReached, boolean endLimitReached) {
    103         // Check if anything has changed
    104         if (beginLimitReached == mBeginLimitReached && endLimitReached == mEndLimitReached) {
    105             return;
    106         }
    107 
    108         mBeginLimitReached = beginLimitReached;
    109         mEndLimitReached = endLimitReached;
    110 
    111         invalidate();
    112     }
    113 
    114     /**
    115      * End the move
    116      */
    117     public void endMove() {
    118         if (mMoveStarted) {
    119             endActionMove(mLastMoveX);
    120         }
    121     }
    122 
    123     @Override
    124     public boolean onTouchEvent(MotionEvent ev) {
    125         super.onTouchEvent(ev);
    126 
    127         switch (ev.getAction()) {
    128             case MotionEvent.ACTION_DOWN: {
    129                 if (isEnabled()) {
    130                     // The ScrollView will not get the touch events
    131                     getParent().requestDisallowInterceptTouchEvent(true);
    132                     if (mListener != null) {
    133                         mListener.onMoveBegin(this);
    134                     }
    135 
    136                     mStartMoveX = ev.getX();
    137                     mMoveStarted = true;
    138                 } else {
    139                     mMoveStarted = false;
    140                 }
    141 
    142                 mLastDeltaX = -10000;
    143                 break;
    144             }
    145 
    146             case MotionEvent.ACTION_MOVE: {
    147                 if (mMoveStarted && isEnabled()) {
    148                     final int deltaX = Math.round((ev.getX() - mStartMoveX));
    149                     if (deltaX != mLastDeltaX) {
    150                         mLastDeltaX = deltaX;
    151 
    152                         if (mListener != null) {
    153                             if (getId() == R.id.handle_left) {
    154                                 mListener.onMove(this, getLeft(), deltaX + getWidth());
    155                             } else {
    156                                 mListener.onMove(this, getLeft(), deltaX);
    157                             }
    158                         }
    159 
    160                         mLastMoveX = ev.getX();
    161                     }
    162                 }
    163                 break;
    164             }
    165 
    166             case MotionEvent.ACTION_CANCEL:
    167             case MotionEvent.ACTION_UP: {
    168                 endActionMove(ev.getX());
    169                 break;
    170             }
    171 
    172             default: {
    173                 break;
    174             }
    175         }
    176 
    177         return true;
    178     }
    179 
    180     /**
    181      * End the move (if it was in progress)
    182      *
    183      * @param eventX The event horizontal position
    184      */
    185     private void endActionMove(float eventX) {
    186         if (mMoveStarted) {
    187             mMoveStarted = false;
    188 
    189             if (mListener != null) {
    190                 final int deltaX = Math.round((eventX - mStartMoveX));
    191                 if (getId() == R.id.handle_left) {
    192                     mListener.onMoveEnd(this, getLeft(), deltaX + getWidth());
    193                 } else {
    194                     mListener.onMoveEnd(this, getLeft(), deltaX);
    195                 }
    196             }
    197         }
    198     }
    199 
    200     @Override
    201     protected void onDraw(Canvas canvas) {
    202         super.onDraw(canvas);
    203 
    204         final int top = (getHeight() - mIconDragClipLeft.getIntrinsicHeight()) / 2;
    205         if (!mBeginLimitReached) {
    206             mIconDragClipLeft.setBounds(0,
    207                     top,
    208                     mIconDragClipLeft.getIntrinsicWidth(),
    209                     top + mIconDragClipLeft.getIntrinsicHeight());
    210             mIconDragClipLeft.draw(canvas);
    211         }
    212 
    213         if (!mEndLimitReached) {
    214             mIconDragClipRight.setBounds(
    215                     mIconDragClipRight.getIntrinsicWidth(),
    216                     top,
    217                     2 * mIconDragClipRight.getIntrinsicWidth(),
    218                     top + mIconDragClipRight.getIntrinsicHeight());
    219             mIconDragClipRight.draw(canvas);
    220         }
    221     }
    222 }
    223