Merge "New system bar "shirt pocket", for quickly stashing draggable bits."
This commit is contained in:
committed by
Android (Google) Code Review
commit
10e370c689
BIN
packages/SystemUI/res/drawable-mdpi/ic_sysbar_pocket.png
Normal file
BIN
packages/SystemUI/res/drawable-mdpi/ic_sysbar_pocket.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 509 B |
BIN
packages/SystemUI/res/drawable-mdpi/ic_sysbar_pocket_drag.png
Normal file
BIN
packages/SystemUI/res/drawable-mdpi/ic_sysbar_pocket_drag.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 627 B |
BIN
packages/SystemUI/res/drawable-mdpi/ic_sysbar_pocket_hidden.png
Normal file
BIN
packages/SystemUI/res/drawable-mdpi/ic_sysbar_pocket_hidden.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 696 B |
BIN
packages/SystemUI/res/drawable-mdpi/ic_sysbar_pocket_holding.png
Normal file
BIN
packages/SystemUI/res/drawable-mdpi/ic_sysbar_pocket_holding.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 606 B |
@@ -136,6 +136,27 @@
|
||||
android:layout_alignParentRight="true"
|
||||
android:orientation="horizontal"
|
||||
>
|
||||
<com.android.systemui.statusbar.tablet.ShirtPocket
|
||||
android:id="@+id/pocket"
|
||||
android:layout_width="71dip"
|
||||
android:layout_height="match_parent"
|
||||
android:background="@drawable/ic_sysbar_icon_bg"
|
||||
android:paddingLeft="4dip"
|
||||
android:paddingRight="4dip"
|
||||
android:animateLayoutChanges="true"
|
||||
android:clickable="true"
|
||||
android:descendantFocusability="blocksDescendants"
|
||||
android:gravity="center"
|
||||
>
|
||||
<ImageView
|
||||
android:id="@+id/pocket_icon"
|
||||
android:src="@drawable/ic_sysbar_pocket"
|
||||
android:visibility="invisible"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center"
|
||||
/>
|
||||
</com.android.systemui.statusbar.tablet.ShirtPocket>
|
||||
<com.android.systemui.statusbar.KeyButtonView android:id="@+id/menu"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
|
||||
61
packages/SystemUI/res/layout-xlarge/sysbar_panel_pocket.xml
Normal file
61
packages/SystemUI/res/layout-xlarge/sysbar_panel_pocket.xml
Normal file
@@ -0,0 +1,61 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
/* apps/common/assets/default/default/skins/StatusBar.xml
|
||||
**
|
||||
** Copyright 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.
|
||||
*/
|
||||
-->
|
||||
|
||||
<RelativeLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_width="match_parent"
|
||||
android:background="@*android:drawable/dialog_full_holo_dark"
|
||||
>
|
||||
<TextView
|
||||
android:id="@+id/description"
|
||||
android:textAppearance="@android:style/TextAppearance.Small"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center"
|
||||
android:textStyle="bold"
|
||||
android:maxLines="1"
|
||||
android:layout_alignParentBottom="true"
|
||||
/>
|
||||
|
||||
<FrameLayout
|
||||
android:id="@+id/preview"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_above="@+id/description"
|
||||
android:descendantFocusability="blocksDescendants"
|
||||
>
|
||||
<ImageView
|
||||
android:id="@+id/icon"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:scaleType="centerInside"
|
||||
android:visibility="gone"
|
||||
/>
|
||||
<TextView
|
||||
android:id="@+id/alt"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:textAppearance="@android:style/TextAppearance.Large"
|
||||
android:gravity="center"
|
||||
android:visibility="gone"
|
||||
/>
|
||||
</FrameLayout>
|
||||
</RelativeLayout>
|
||||
@@ -0,0 +1,248 @@
|
||||
/*
|
||||
* 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.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));
|
||||
}
|
||||
|
||||
ShirtPocket.this.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,
|
||||
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
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user