Merge "Bringing back the pocket."
This commit is contained in:
committed by
Android (Google) Code Review
commit
b6dd088a3b
BIN
packages/SystemUI/res/drawable-mdpi/pocket_drag_pattern.png
Normal file
BIN
packages/SystemUI/res/drawable-mdpi/pocket_drag_pattern.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 324 B |
21
packages/SystemUI/res/drawable/pocket_drag_bg.xml
Normal file
21
packages/SystemUI/res/drawable/pocket_drag_bg.xml
Normal file
@@ -0,0 +1,21 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Copyright (C) 2011 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.
|
||||
-->
|
||||
|
||||
<bitmap
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:tileMode="repeat"
|
||||
android:src="@drawable/pocket_drag_pattern"
|
||||
/>
|
||||
@@ -91,6 +91,15 @@
|
||||
</RelativeLayout>
|
||||
</FrameLayout>
|
||||
|
||||
<view
|
||||
class="com.android.systemui.statusbar.tablet.ShirtPocket$DropZone"
|
||||
android:id="@+id/drop_target"
|
||||
android:layout_width="512dp"
|
||||
android:layout_height="@*android:dimen/status_bar_height"
|
||||
android:background="@drawable/pocket_drag_bg"
|
||||
android:layout_gravity="right"
|
||||
/>
|
||||
|
||||
<FrameLayout
|
||||
android:id="@+id/bar_shadow_holder"
|
||||
android:layout_width="match_parent"
|
||||
|
||||
@@ -41,6 +41,15 @@
|
||||
android:src="@drawable/ic_sysbar_ime_default"
|
||||
android:visibility="gone"
|
||||
/>
|
||||
|
||||
<com.android.systemui.statusbar.tablet.ShirtPocket
|
||||
android:id="@+id/shirt_pocket"
|
||||
android:layout_width="@*android:dimen/status_bar_height"
|
||||
android:layout_height="@*android:dimen/status_bar_height"
|
||||
android:background="#FFFF0000"
|
||||
android:visibility="gone"
|
||||
/>
|
||||
|
||||
<com.android.systemui.statusbar.tablet.NotificationIconArea
|
||||
android:id="@+id/notificationIcons"
|
||||
android:layout_width="wrap_content"
|
||||
|
||||
@@ -16,26 +16,28 @@
|
||||
|
||||
package com.android.systemui.statusbar.tablet;
|
||||
|
||||
import android.animation.Animator;
|
||||
import android.animation.AnimatorListenerAdapter;
|
||||
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.content.Context;
|
||||
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.Paint;
|
||||
import android.graphics.PixelFormat;
|
||||
import android.graphics.Point;
|
||||
import android.util.AttributeSet;
|
||||
import android.util.Slog;
|
||||
import android.view.DragEvent;
|
||||
import android.view.Gravity;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.View;
|
||||
import android.view.WindowManager;
|
||||
import android.view.WindowManagerImpl;
|
||||
import android.widget.FrameLayout;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.android.systemui.R;
|
||||
|
||||
@@ -45,10 +47,80 @@ public class ShirtPocket extends ImageView {
|
||||
|
||||
private ClipData mClipping = null;
|
||||
|
||||
private View mWindow = null;
|
||||
private ImageView mPreviewIcon;
|
||||
private TextView mDescription;
|
||||
private TextView mAltText;
|
||||
|
||||
public static class DropZone extends View {
|
||||
ShirtPocket mPocket;
|
||||
public DropZone(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
}
|
||||
public void setPocket(ShirtPocket p) {
|
||||
mPocket = p;
|
||||
}
|
||||
|
||||
public void onAttachedToWindow() {
|
||||
super.onAttachedToWindow();
|
||||
if (mPocket.holding()) {
|
||||
show(false);
|
||||
} else {
|
||||
hide(false);
|
||||
}
|
||||
}
|
||||
|
||||
// Drag API notes: we must be visible to receive drag events
|
||||
private void show(boolean animate) {
|
||||
setTranslationY(0f);
|
||||
if (animate) {
|
||||
setAlpha(0f);
|
||||
ObjectAnimator.ofFloat(this, "alpha", 0f, 1f).start();
|
||||
} else {
|
||||
setAlpha(1f);
|
||||
}
|
||||
}
|
||||
|
||||
private void hide(boolean animate) {
|
||||
AnimatorListenerAdapter onEnd = new AnimatorListenerAdapter() {
|
||||
@Override
|
||||
public void onAnimationEnd(Animator _a) {
|
||||
DropZone.this.setTranslationY(getHeight() + 2);
|
||||
DropZone.this.setAlpha(0f);
|
||||
}
|
||||
};
|
||||
if (animate) {
|
||||
Animator a = ObjectAnimator.ofFloat(this, "alpha", getAlpha(), 0f);
|
||||
a.addListener(onEnd);
|
||||
a.start();
|
||||
} else {
|
||||
onEnd.onAnimationEnd(null);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onDragEvent(DragEvent event) {
|
||||
if (DEBUG) Slog.d(TAG, "onDragEvent: " + event);
|
||||
switch (event.getAction()) {
|
||||
// We want to appear whenever a potential drag takes off from anywhere in the UI.
|
||||
case DragEvent.ACTION_DRAG_STARTED:
|
||||
show(true);
|
||||
break;
|
||||
case DragEvent.ACTION_DRAG_ENTERED:
|
||||
if (DEBUG) Slog.d(TAG, "entered!");
|
||||
// XXX: TODO
|
||||
break;
|
||||
case DragEvent.ACTION_DRAG_EXITED:
|
||||
if (DEBUG) Slog.d(TAG, "exited!");
|
||||
break;
|
||||
case DragEvent.ACTION_DROP:
|
||||
if (DEBUG) Slog.d(TAG, "dropped!");
|
||||
mPocket.stash(event.getClipData());
|
||||
break;
|
||||
case DragEvent.ACTION_DRAG_ENDED:
|
||||
hide(true);
|
||||
break;
|
||||
}
|
||||
return true; // we want everything, thank you
|
||||
}
|
||||
}
|
||||
|
||||
public ShirtPocket(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
@@ -58,74 +130,66 @@ public class ShirtPocket extends ImageView {
|
||||
ObjectAnimator mAnimHide, mAnimShow;
|
||||
|
||||
protected void onAttachedToWindow() {
|
||||
// Drag API notes: we must be visible to receive drag events
|
||||
setVisibility(View.VISIBLE);
|
||||
|
||||
refresh();
|
||||
|
||||
setOnClickListener(new View.OnClickListener() {
|
||||
public void onClick(View v) {
|
||||
if (mClipping != null) {
|
||||
if (mWindow.getVisibility() == View.VISIBLE) hideWindow();
|
||||
else showWindow();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void refresh() {
|
||||
setClickable(mClipping != null);
|
||||
// XXX: TODO
|
||||
}
|
||||
|
||||
private void showWindow() {
|
||||
getHandler().post(new Runnable() {
|
||||
public void run() {
|
||||
mWindow.setVisibility(View.VISIBLE);
|
||||
refresh();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void hideWindow() {
|
||||
getHandler().post(new Runnable() {
|
||||
public void run() {
|
||||
mWindow.setVisibility(View.GONE);
|
||||
refresh();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void hideWindowInJustASec() {
|
||||
getHandler().postDelayed(new Runnable() {
|
||||
public void run() {
|
||||
mWindow.setVisibility(View.GONE);
|
||||
refresh();
|
||||
}
|
||||
},
|
||||
250);
|
||||
public boolean holding() {
|
||||
return (mClipping != null);
|
||||
}
|
||||
|
||||
private void stash(ClipData clipping) {
|
||||
mClipping = clipping;
|
||||
if (mClipping != null) {
|
||||
setVisibility(View.VISIBLE);
|
||||
Bitmap icon = mClipping.getIcon();
|
||||
mDescription.setText(mClipping.getDescription().getLabel());
|
||||
// mDescription.setText(mClipping.getDescription().getLabel());
|
||||
if (icon != null) {
|
||||
mPreviewIcon.setImageBitmap(icon);
|
||||
mPreviewIcon.setVisibility(View.VISIBLE);
|
||||
mAltText.setVisibility(View.GONE);
|
||||
setImageBitmap(icon);
|
||||
} 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.getItemAt(0).coerceToText(getContext()));
|
||||
//mAltText.setText(mClipping.getItemAt(0).coerceToText(getContext()));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
setVisibility(View.GONE);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onTouchEvent(MotionEvent ev) {
|
||||
final int action = ev.getAction();
|
||||
if (action == MotionEvent.ACTION_DOWN) {
|
||||
final ClipData clip = mClipping;
|
||||
if (clip != null) {
|
||||
final Bitmap icon = clip.getIcon();
|
||||
DragShadowBuilder shadow;
|
||||
if (icon != null) {
|
||||
shadow = new DragShadowBuilder(this) {
|
||||
public void onProvideShadowMetrics(Point shadowSize, Point shadowTouchPoint) {
|
||||
shadowSize.set(icon.getWidth(), icon.getHeight());
|
||||
shadowTouchPoint.set(shadowSize.x / 2, shadowSize.y / 2);
|
||||
}
|
||||
public void onDrawShadow(Canvas canvas) {
|
||||
canvas.drawBitmap(icon, 0, 0, new Paint());
|
||||
}
|
||||
};
|
||||
} else {
|
||||
// uhhh, what now?
|
||||
shadow = new DragShadowBuilder(this);
|
||||
}
|
||||
|
||||
startDrag(clip, shadow, null, 0);
|
||||
|
||||
// TODO: only discard the clipping if it was accepted
|
||||
stash(null);
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
private boolean isInViewContentArea(View v, int x, int y) {
|
||||
final int l = v.getPaddingLeft();
|
||||
final int r = v.getWidth() - v.getPaddingRight();
|
||||
@@ -167,38 +231,12 @@ public class ShirtPocket extends ImageView {
|
||||
// TODO: only discard the clipping if it was accepted
|
||||
stash(null);
|
||||
|
||||
hideWindowInJustASec(); // will refresh the icon
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
public boolean onDragEvent(DragEvent event) {
|
||||
if (DEBUG) Slog.d(TAG, "onDragEvent: " + event);
|
||||
switch (event.getAction()) {
|
||||
// We want to appear whenever a potential drag takes off from anywhere in the UI.
|
||||
case DragEvent.ACTION_DRAG_STARTED:
|
||||
// XXX: TODO
|
||||
break;
|
||||
case DragEvent.ACTION_DRAG_ENTERED:
|
||||
if (DEBUG) Slog.d(TAG, "entered!");
|
||||
// XXX: TODO
|
||||
break;
|
||||
case DragEvent.ACTION_DRAG_EXITED:
|
||||
if (DEBUG) Slog.d(TAG, "exited!");
|
||||
setVisibility(mClipping == null ? View.GONE : View.VISIBLE);
|
||||
break;
|
||||
case DragEvent.ACTION_DROP:
|
||||
if (DEBUG) Slog.d(TAG, "dropped!");
|
||||
stash(event.getClipData());
|
||||
break;
|
||||
case DragEvent.ACTION_DRAG_ENDED:
|
||||
break;
|
||||
}
|
||||
return true; // we want everything, thank you
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
|
||||
@@ -392,6 +392,11 @@ public class TabletStatusBar extends StatusBar implements
|
||||
// for redirecting errant bar taps to the IME
|
||||
mFakeSpaceBar = sb.findViewById(R.id.fake_space_bar);
|
||||
|
||||
// drag and drop pocket
|
||||
ShirtPocket p = (ShirtPocket) sb.findViewById(R.id.shirt_pocket);
|
||||
ShirtPocket.DropZone z = (ShirtPocket.DropZone) sb.findViewById(R.id.drop_target);
|
||||
z.setPocket(p);
|
||||
|
||||
// "shadows" of the status bar features, for lights-out mode
|
||||
mShadow = sb.findViewById(R.id.bar_shadow);
|
||||
mShadow.setOnTouchListener(
|
||||
|
||||
Reference in New Issue
Block a user