• 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.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          */
onMoveBegin(HandleView view)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          */
onMove(HandleView view, int left, int delta)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          */
onMoveEnd(HandleView view, int left, int delta)69         public void onMoveEnd(HandleView view, int left, int delta);
70     }
71 
HandleView(Context context, AttributeSet attrs, int defStyle)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 
HandleView(Context context, AttributeSet attrs)81     public HandleView(Context context, AttributeSet attrs) {
82         this(context, attrs, 0);
83     }
84 
HandleView(Context context)85     public HandleView(Context context) {
86         this(context, null, 0);
87     }
88 
89     /**
90      * @param listener The listener
91      */
setListener(MoveListener listener)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      */
setLimitReached(boolean beginLimitReached, boolean endLimitReached)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      */
endMove()117     public void endMove() {
118         if (mMoveStarted) {
119             endActionMove(mLastMoveX);
120         }
121     }
122 
123     @Override
onTouchEvent(MotionEvent ev)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      */
endActionMove(float eventX)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
onDraw(Canvas canvas)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