blob: 2924cc9544540d2b98b2b3ef5ab60d1b9c9a930d [file] [log] [blame]
Daniel Sandler524f5682010-10-13 12:13:33 -04001/*
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
17package com.android.systemui.statusbar.tablet;
18
Daniel Sandler1cfe7532011-02-08 16:33:07 -050019import android.animation.Animator;
20import android.animation.AnimatorListenerAdapter;
Daniel Sandler524f5682010-10-13 12:13:33 -040021import android.animation.ObjectAnimator;
Daniel Sandler524f5682010-10-13 12:13:33 -040022import android.content.ClipData;
23import android.content.ClipDescription;
Daniel Sandler1cfe7532011-02-08 16:33:07 -050024import android.content.Context;
Daniel Sandler524f5682010-10-13 12:13:33 -040025import android.graphics.Bitmap;
26import android.graphics.Canvas;
Daniel Sandler1cfe7532011-02-08 16:33:07 -050027import android.graphics.Paint;
Daniel Sandler524f5682010-10-13 12:13:33 -040028import android.graphics.PixelFormat;
Daniel Sandler1cfe7532011-02-08 16:33:07 -050029import android.graphics.Point;
30import android.util.AttributeSet;
31import android.util.Slog;
32import android.view.DragEvent;
Daniel Sandler524f5682010-10-13 12:13:33 -040033import android.view.Gravity;
Daniel Sandler1cfe7532011-02-08 16:33:07 -050034import android.view.MotionEvent;
35import android.view.View;
36import android.view.WindowManager;
Daniel Sandler1cfe7532011-02-08 16:33:07 -050037import android.widget.FrameLayout;
38import android.widget.ImageView;
39import android.widget.TextView;
Daniel Sandler524f5682010-10-13 12:13:33 -040040
41import com.android.systemui.R;
42
Daniel Sandler0ad460b2010-12-14 12:14:53 -050043public class ShirtPocket extends ImageView {
Daniel Sandler524f5682010-10-13 12:13:33 -040044 private static final boolean DEBUG = false;
45 private static final String TAG = "StatusBar/ShirtPocket";
46
47 private ClipData mClipping = null;
48
Daniel Sandler524f5682010-10-13 12:13:33 -040049 private ImageView mPreviewIcon;
Daniel Sandler1cfe7532011-02-08 16:33:07 -050050
51 public static class DropZone extends View {
52 ShirtPocket mPocket;
53 public DropZone(Context context, AttributeSet attrs) {
54 super(context, attrs);
55 }
56 public void setPocket(ShirtPocket p) {
57 mPocket = p;
58 }
59
60 public void onAttachedToWindow() {
61 super.onAttachedToWindow();
62 if (mPocket.holding()) {
63 show(false);
64 } else {
65 hide(false);
66 }
67 }
68
69 // Drag API notes: we must be visible to receive drag events
70 private void show(boolean animate) {
71 setTranslationY(0f);
72 if (animate) {
73 setAlpha(0f);
74 ObjectAnimator.ofFloat(this, "alpha", 0f, 1f).start();
75 } else {
76 setAlpha(1f);
77 }
78 }
79
80 private void hide(boolean animate) {
81 AnimatorListenerAdapter onEnd = new AnimatorListenerAdapter() {
82 @Override
83 public void onAnimationEnd(Animator _a) {
84 DropZone.this.setTranslationY(getHeight() + 2);
85 DropZone.this.setAlpha(0f);
86 }
87 };
88 if (animate) {
89 Animator a = ObjectAnimator.ofFloat(this, "alpha", getAlpha(), 0f);
90 a.addListener(onEnd);
91 a.start();
92 } else {
93 onEnd.onAnimationEnd(null);
94 }
95 }
96
97 @Override
98 public boolean onDragEvent(DragEvent event) {
99 if (DEBUG) Slog.d(TAG, "onDragEvent: " + event);
100 switch (event.getAction()) {
101 // We want to appear whenever a potential drag takes off from anywhere in the UI.
102 case DragEvent.ACTION_DRAG_STARTED:
103 show(true);
104 break;
105 case DragEvent.ACTION_DRAG_ENTERED:
106 if (DEBUG) Slog.d(TAG, "entered!");
107 // XXX: TODO
108 break;
109 case DragEvent.ACTION_DRAG_EXITED:
110 if (DEBUG) Slog.d(TAG, "exited!");
111 break;
112 case DragEvent.ACTION_DROP:
113 if (DEBUG) Slog.d(TAG, "dropped!");
114 mPocket.stash(event.getClipData());
115 break;
116 case DragEvent.ACTION_DRAG_ENDED:
117 hide(true);
118 break;
119 }
120 return true; // we want everything, thank you
121 }
122 }
Daniel Sandler524f5682010-10-13 12:13:33 -0400123
124 public ShirtPocket(Context context, AttributeSet attrs) {
125 super(context, attrs);
Daniel Sandler524f5682010-10-13 12:13:33 -0400126 }
127
128 // TODO: "pin area" panel, dragging things out
129 ObjectAnimator mAnimHide, mAnimShow;
130
131 protected void onAttachedToWindow() {
Daniel Sandler524f5682010-10-13 12:13:33 -0400132 }
133
Daniel Sandler1cfe7532011-02-08 16:33:07 -0500134 public boolean holding() {
135 return (mClipping != null);
Daniel Sandler524f5682010-10-13 12:13:33 -0400136 }
137
138 private void stash(ClipData clipping) {
139 mClipping = clipping;
140 if (mClipping != null) {
Daniel Sandler1cfe7532011-02-08 16:33:07 -0500141 setVisibility(View.VISIBLE);
Daniel Sandler524f5682010-10-13 12:13:33 -0400142 Bitmap icon = mClipping.getIcon();
Daniel Sandler1cfe7532011-02-08 16:33:07 -0500143// mDescription.setText(mClipping.getDescription().getLabel());
Daniel Sandler524f5682010-10-13 12:13:33 -0400144 if (icon != null) {
Daniel Sandler1cfe7532011-02-08 16:33:07 -0500145 setImageBitmap(icon);
Daniel Sandler524f5682010-10-13 12:13:33 -0400146 } else {
Daniel Sandler524f5682010-10-13 12:13:33 -0400147 if (mClipping.getItemCount() > 0) {
148 // TODO: figure out how to visualize every kind of ClipData!
Daniel Sandler1cfe7532011-02-08 16:33:07 -0500149 //mAltText.setText(mClipping.getItemAt(0).coerceToText(getContext()));
Daniel Sandler524f5682010-10-13 12:13:33 -0400150 }
151 }
Daniel Sandler1cfe7532011-02-08 16:33:07 -0500152 } else {
153 setVisibility(View.GONE);
Daniel Sandler524f5682010-10-13 12:13:33 -0400154 }
155 }
156
Daniel Sandler1cfe7532011-02-08 16:33:07 -0500157 @Override
158 public boolean onTouchEvent(MotionEvent ev) {
159 final int action = ev.getAction();
160 if (action == MotionEvent.ACTION_DOWN) {
161 final ClipData clip = mClipping;
162 if (clip != null) {
163 final Bitmap icon = clip.getIcon();
164 DragShadowBuilder shadow;
165 if (icon != null) {
166 shadow = new DragShadowBuilder(this) {
167 public void onProvideShadowMetrics(Point shadowSize, Point shadowTouchPoint) {
168 shadowSize.set(icon.getWidth(), icon.getHeight());
169 shadowTouchPoint.set(shadowSize.x / 2, shadowSize.y / 2);
170 }
171 public void onDrawShadow(Canvas canvas) {
172 canvas.drawBitmap(icon, 0, 0, new Paint());
173 }
174 };
175 } else {
176 // uhhh, what now?
177 shadow = new DragShadowBuilder(this);
178 }
179
180 startDrag(clip, shadow, null, 0);
181
182 // TODO: only discard the clipping if it was accepted
183 stash(null);
184
185 return true;
186 }
187 }
188 return false;
189 }
190
191 /*
Daniel Sandler524f5682010-10-13 12:13:33 -0400192 private boolean isInViewContentArea(View v, int x, int y) {
193 final int l = v.getPaddingLeft();
194 final int r = v.getWidth() - v.getPaddingRight();
195 final int t = v.getPaddingTop();
196 final int b = v.getHeight() - v.getPaddingBottom();
197 return x >= l && x < r && y >= t && y < b;
198 }
199
200 View.OnTouchListener mWindowTouchListener = new View.OnTouchListener() {
201 public boolean onTouch(View v, MotionEvent ev) {
202 final int action = ev.getAction();
203 if (action == MotionEvent.ACTION_OUTSIDE
204 || (action == MotionEvent.ACTION_DOWN
205 && !isInViewContentArea(mWindow, (int)ev.getX(), (int)ev.getY()))) {
206 hideWindow();
207 return true;
208 } else if (action == MotionEvent.ACTION_DOWN) {
Daniel Sandler524f5682010-10-13 12:13:33 -0400209 final ClipData clip = mClipping;
210 if (clip != null) {
211 final Bitmap icon = clip.getIcon();
Christopher Tate36d4c3f2011-01-07 13:34:24 -0800212 DragShadowBuilder shadow;
Daniel Sandler524f5682010-10-13 12:13:33 -0400213 if (icon != null) {
Christopher Tate36d4c3f2011-01-07 13:34:24 -0800214 shadow = new DragShadowBuilder(v) {
215 public void onProvideShadowMetrics(Point shadowSize, Point shadowTouchPoint) {
216 shadowSize.set(icon.getWidth(), icon.getHeight());
217 shadowTouchPoint.set(shadowSize.x / 2, shadowSize.y / 2);
Daniel Sandler524f5682010-10-13 12:13:33 -0400218 }
Christopher Tate36d4c3f2011-01-07 13:34:24 -0800219 public void onDrawShadow(Canvas canvas) {
Daniel Sandler524f5682010-10-13 12:13:33 -0400220 canvas.drawBitmap(icon, 0, 0, new Paint());
221 }
222 };
223 } else {
224 // uhhh, what now?
Christopher Tate36d4c3f2011-01-07 13:34:24 -0800225 shadow = new DragShadowBuilder(mWindow.findViewById(R.id.preview));
Daniel Sandler524f5682010-10-13 12:13:33 -0400226 }
227
Christopher Tate02d2b3b2011-01-10 20:43:53 -0800228 v.startDrag(clip, shadow, null, 0);
Daniel Sandler524f5682010-10-13 12:13:33 -0400229
230 // TODO: only discard the clipping if it was accepted
231 stash(null);
232
Daniel Sandler524f5682010-10-13 12:13:33 -0400233 return true;
234 }
235 }
236 return false;
237 }
238 };
Daniel Sandler1cfe7532011-02-08 16:33:07 -0500239 */
Daniel Sandler524f5682010-10-13 12:13:33 -0400240}
241