OSDN Git Service

overhaul
[android-x86/packages-apps-Eleven.git] / src / com / andrew / apollo / ui / widgets / RepeatingImageButton.java
1 /*\r
2  * Copyright (C) 2008 The Android Open Source Project\r
3  *\r
4  * Licensed under the Apache License, Version 2.0 (the "License");\r
5  * you may not use this file except in compliance with the License.\r
6  * You may obtain a copy of the License at\r
7  *\r
8  *      http://www.apache.org/licenses/LICENSE-2.0\r
9  *\r
10  * Unless required by applicable law or agreed to in writing, software\r
11  * distributed under the License is distributed on an "AS IS" BASIS,\r
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
13  * See the License for the specific language governing permissions and\r
14  * limitations under the License.\r
15  */\r
16 \r
17 package com.andrew.apollo.ui.widgets;\r
18 \r
19 import android.content.Context;\r
20 import android.os.SystemClock;\r
21 import android.util.AttributeSet;\r
22 import android.view.KeyEvent;\r
23 import android.view.MotionEvent;\r
24 import android.view.View;\r
25 import android.widget.ImageButton;\r
26 \r
27 /**\r
28  * A button that will repeatedly call a 'listener' method as long as the button\r
29  * is pressed.\r
30  */\r
31 public class RepeatingImageButton extends ImageButton {\r
32 \r
33     private long mStartTime;\r
34 \r
35     private int mRepeatCount;\r
36 \r
37     private RepeatListener mListener;\r
38 \r
39     private long mInterval = 500;\r
40 \r
41     public RepeatingImageButton(Context context) {\r
42         this(context, null);\r
43     }\r
44 \r
45     public RepeatingImageButton(Context context, AttributeSet attrs) {\r
46         this(context, attrs, android.R.attr.imageButtonStyle);\r
47     }\r
48 \r
49     public RepeatingImageButton(Context context, AttributeSet attrs, int defStyle) {\r
50         super(context, attrs, defStyle);\r
51         setFocusable(true);\r
52         setLongClickable(true);\r
53     }\r
54 \r
55     /**\r
56      * Sets the listener to be called while the button is pressed and the\r
57      * interval in milliseconds with which it will be called.\r
58      * \r
59      * @param l The listener that will be called\r
60      * @param interval The interval in milliseconds for calls\r
61      */\r
62     public void setRepeatListener(RepeatListener l, long interval) {\r
63         mListener = l;\r
64         mInterval = interval;\r
65     }\r
66 \r
67     @Override\r
68     public boolean performLongClick() {\r
69         mStartTime = SystemClock.elapsedRealtime();\r
70         mRepeatCount = 0;\r
71         post(mRepeater);\r
72         return true;\r
73     }\r
74 \r
75     @Override\r
76     public boolean onTouchEvent(MotionEvent event) {\r
77         if (event.getAction() == MotionEvent.ACTION_UP) {\r
78             // remove the repeater, but call the hook one more time\r
79             removeCallbacks(mRepeater);\r
80             if (mStartTime != 0) {\r
81                 doRepeat(true);\r
82                 mStartTime = 0;\r
83             }\r
84         }\r
85         return super.onTouchEvent(event);\r
86     }\r
87 \r
88     @Override\r
89     public boolean onKeyDown(int keyCode, KeyEvent event) {\r
90         switch (keyCode) {\r
91             case KeyEvent.KEYCODE_DPAD_CENTER:\r
92             case KeyEvent.KEYCODE_ENTER:\r
93                 // need to call super to make long press work, but return\r
94                 // true so that the application doesn't get the down event.\r
95                 super.onKeyDown(keyCode, event);\r
96                 return true;\r
97         }\r
98         return super.onKeyDown(keyCode, event);\r
99     }\r
100 \r
101     @Override\r
102     public boolean onKeyUp(int keyCode, KeyEvent event) {\r
103         switch (keyCode) {\r
104             case KeyEvent.KEYCODE_DPAD_CENTER:\r
105             case KeyEvent.KEYCODE_ENTER:\r
106                 // remove the repeater, but call the hook one more time\r
107                 removeCallbacks(mRepeater);\r
108                 if (mStartTime != 0) {\r
109                     doRepeat(true);\r
110                     mStartTime = 0;\r
111                 }\r
112         }\r
113         return super.onKeyUp(keyCode, event);\r
114     }\r
115 \r
116     private final Runnable mRepeater = new Runnable() {\r
117         @Override\r
118         public void run() {\r
119             doRepeat(false);\r
120             if (isPressed()) {\r
121                 postDelayed(this, mInterval);\r
122             }\r
123         }\r
124     };\r
125 \r
126     private void doRepeat(boolean last) {\r
127         long now = SystemClock.elapsedRealtime();\r
128         if (mListener != null) {\r
129             mListener.onRepeat(this, now - mStartTime, last ? -1 : mRepeatCount++);\r
130         }\r
131     }\r
132 \r
133     public interface RepeatListener {\r
134 \r
135         void onRepeat(View v, long duration, int repeatcount);\r
136     }\r
137 }\r