blob: 09c8cd2f864da36e4f7003a9816c8fd79622bc12 [file] [log] [blame]
/*
* Copyright (C) 2010 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.systemui.statusbar.tablet;
import android.animation.ObjectAnimator;
import android.content.Context;
import android.util.Slog;
import android.view.View;
import android.util.AttributeSet;
import android.widget.ImageView;
import android.widget.TextView;
import android.view.DragEvent;
import android.view.MotionEvent;
import android.content.ClipData;
import android.content.ClipDescription;
import android.graphics.Paint;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Point;
import android.view.WindowManager;
import android.widget.FrameLayout;
import android.view.WindowManagerImpl;
import android.graphics.PixelFormat;
import android.view.Gravity;
import com.android.systemui.R;
public class ShirtPocket extends FrameLayout {
private static final boolean DEBUG = false;
private static final String TAG = "StatusBar/ShirtPocket";
private ClipData mClipping = null;
private View mWindow = null;
private ImageView mIcon;
private ImageView mPreviewIcon;
private TextView mDescription;
private TextView mAltText;
public ShirtPocket(Context context, AttributeSet attrs) {
super(context, attrs);
setupWindow();
}
// TODO: "pin area" panel, dragging things out
ObjectAnimator mAnimHide, mAnimShow;
protected void onAttachedToWindow() {
// Drag API notes: we must be visible to receive drag events
setVisibility(View.VISIBLE);
mIcon = (ImageView) findViewById(R.id.pocket_icon);
refreshStatusIcon();
setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
if (mClipping != null) {
if (mWindow.getVisibility() == View.VISIBLE) hideWindow();
else showWindow();
}
}
});
}
private void refreshStatusIcon() {
setClickable(mClipping != null);
mIcon.setImageResource(mClipping == null
? R.drawable.ic_sysbar_pocket_hidden
: R.drawable.ic_sysbar_pocket_holding);
mIcon.setVisibility(mClipping == null ? View.INVISIBLE : View.VISIBLE);
}
private void showWindow() {
getHandler().post(new Runnable() {
public void run() {
mWindow.setVisibility(View.VISIBLE);
refreshStatusIcon();
}
});
}
private void hideWindow() {
getHandler().post(new Runnable() {
public void run() {
mWindow.setVisibility(View.GONE);
refreshStatusIcon();
}
});
}
private void hideWindowInJustASec() {
getHandler().postDelayed(new Runnable() {
public void run() {
mWindow.setVisibility(View.GONE);
refreshStatusIcon();
}
},
250);
}
private void stash(ClipData clipping) {
mClipping = clipping;
if (mClipping != null) {
Bitmap icon = mClipping.getIcon();
mDescription.setText(mClipping.getDescription().getLabel());
if (icon != null) {
mPreviewIcon.setImageBitmap(icon);
mPreviewIcon.setVisibility(View.VISIBLE);
mAltText.setVisibility(View.GONE);
} else {
mPreviewIcon.setVisibility(View.GONE);
mAltText.setVisibility(View.VISIBLE);
if (mClipping.getItemCount() > 0) {
// TODO: figure out how to visualize every kind of ClipData!
mAltText.setText(mClipping.getItem(0).coerceToText(getContext()));
}
}
}
}
private boolean isInViewContentArea(View v, int x, int y) {
final int l = v.getPaddingLeft();
final int r = v.getWidth() - v.getPaddingRight();
final int t = v.getPaddingTop();
final int b = v.getHeight() - v.getPaddingBottom();
return x >= l && x < r && y >= t && y < b;
}
View.OnTouchListener mWindowTouchListener = new View.OnTouchListener() {
public boolean onTouch(View v, MotionEvent ev) {
final int action = ev.getAction();
if (action == MotionEvent.ACTION_OUTSIDE
|| (action == MotionEvent.ACTION_DOWN
&& !isInViewContentArea(mWindow, (int)ev.getX(), (int)ev.getY()))) {
hideWindow();
return true;
} else if (action == MotionEvent.ACTION_DOWN) {
Slog.d(TAG, "ACTION_DOWN");
final ClipData clip = mClipping;
if (clip != null) {
final Bitmap icon = clip.getIcon();
DragThumbnailBuilder thumb;
if (icon != null) {
thumb = new DragThumbnailBuilder(v) {
public void onProvideThumbnailMetrics(Point thumbnailSize, Point thumbnailTouchPoint) {
thumbnailSize.set(icon.getWidth(), icon.getHeight());
thumbnailTouchPoint.set(thumbnailSize.x / 2, thumbnailSize.y / 2);
}
public void onDrawThumbnail(Canvas canvas) {
canvas.drawBitmap(icon, 0, 0, new Paint());
}
};
} else {
// uhhh, what now?
thumb = new DragThumbnailBuilder(mWindow.findViewById(R.id.preview));
}
v.startDrag(clip, thumb, false);
// TODO: only discard the clipping if it was accepted
stash(null);
hideWindowInJustASec(); // will refresh the icon
return true;
}
}
return false;
}
};
private void setupWindow() {
mWindow = View.inflate(getContext(), R.layout.sysbar_panel_pocket, null);
mPreviewIcon = (ImageView) mWindow.findViewById(R.id.icon);
mDescription = (TextView) mWindow.findViewById(R.id.description);
mAltText = (TextView) mWindow.findViewById(R.id.alt);
mWindow.setVisibility(View.GONE);
mWindow.setOnTouchListener(mWindowTouchListener);
WindowManager.LayoutParams lp = new WindowManager.LayoutParams(
400,
250,
WindowManager.LayoutParams.TYPE_STATUS_BAR_PANEL,
WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
| WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM
| WindowManager.LayoutParams.FLAG_SPLIT_TOUCH,
PixelFormat.TRANSLUCENT);
lp.gravity = Gravity.BOTTOM | Gravity.RIGHT;
// int pos[] = new int[2];
// getLocationOnScreen(pos);
// lp.x = pos[1];
// lp.y = 0;
lp.setTitle("ShirtPocket");
lp.windowAnimations = com.android.internal.R.style.Animation_SlidingCard;
WindowManagerImpl.getDefault().addView(mWindow, lp);
}
public boolean onDragEvent(DragEvent event) {
if (DEBUG) Slog.d(TAG, "onDragEvent: " + event);
if (mIcon != null) {
switch (event.getAction()) {
// We want to appear whenever a potential drag takes off from anywhere in the UI.
case DragEvent.ACTION_DRAG_STARTED:
mIcon.setImageResource(mClipping == null
? R.drawable.ic_sysbar_pocket
: R.drawable.ic_sysbar_pocket_holding);
mIcon.setVisibility(View.VISIBLE);
break;
case DragEvent.ACTION_DRAG_ENTERED:
if (DEBUG) Slog.d(TAG, "entered!");
mIcon.setImageResource(R.drawable.ic_sysbar_pocket_drag);
break;
case DragEvent.ACTION_DRAG_EXITED:
if (DEBUG) Slog.d(TAG, "exited!");
mIcon.setImageResource(mClipping == null
? R.drawable.ic_sysbar_pocket
: R.drawable.ic_sysbar_pocket_holding);
break;
case DragEvent.ACTION_DROP:
if (DEBUG) Slog.d(TAG, "dropped!");
stash(event.getClipData());
refreshStatusIcon();
break;
case DragEvent.ACTION_DRAG_ENDED:
refreshStatusIcon();
break;
}
}
return true; // we want everything, thank you
}
}