Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b6dd088a authored by Daniel Sandler's avatar Daniel Sandler Committed by Android (Google) Code Review
Browse files

Merge "Bringing back the pocket."

parents 61eadaa6 1cfe7530
Loading
Loading
Loading
Loading
+324 B
Loading image diff...
+21 −0
Original line number Diff line number Diff line
<?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"
    />
+9 −0
Original line number Diff line number Diff line
@@ -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"
+9 −0
Original line number Diff line number Diff line
@@ -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"
+130 −92
Original line number Diff line number Diff line
@@ -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.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.widget.FrameLayout;
import android.view.WindowManagerImpl;
import android.graphics.PixelFormat;
import android.view.Gravity;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.TextView;

import com.android.systemui.R;

@@ -45,87 +47,149 @@ public class ShirtPocket extends ImageView {

    private ClipData mClipping = null;

    private View mWindow = null;
    private ImageView mPreviewIcon;
    private TextView mDescription;
    private TextView mAltText;

    public ShirtPocket(Context context, AttributeSet attrs) {
    public static class DropZone extends View {
        ShirtPocket mPocket;
        public DropZone(Context context, AttributeSet attrs) {
            super(context, attrs);
        }
        public void setPocket(ShirtPocket p) {
            mPocket = p;
        }

    // TODO: "pin area" panel, dragging things out
    ObjectAnimator mAnimHide, mAnimShow;
        public void onAttachedToWindow() {
            super.onAttachedToWindow();
            if (mPocket.holding()) {
                show(false);
            } else {
                hide(false);
            }
        }

    protected void onAttachedToWindow() {
        // Drag API notes: we must be visible to receive drag events
        setVisibility(View.VISIBLE);

        refresh();
        private void show(boolean animate) {
            setTranslationY(0f);
            if (animate) {
                setAlpha(0f);
                ObjectAnimator.ofFloat(this, "alpha", 0f, 1f).start();
            } else {
                setAlpha(1f);
            }
        }

        setOnClickListener(new View.OnClickListener() {
            public void onClick(View v) {
                if (mClipping != null) {
                    if (mWindow.getVisibility() == View.VISIBLE) hideWindow(); 
                    else showWindow();
        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);
            }
        });
        }

    private void refresh() {
        setClickable(mClipping != 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;
            }
    
    private void showWindow() {
        getHandler().post(new Runnable() {
            public void run() {
                mWindow.setVisibility(View.VISIBLE);
                refresh();
            return true; // we want everything, thank you
        }
        });
    }

    private void hideWindow() {
        getHandler().post(new Runnable() {
            public void run() {
                mWindow.setVisibility(View.GONE);
                refresh();
            }
        });
    public ShirtPocket(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    private void hideWindowInJustASec() {
        getHandler().postDelayed(new Runnable() {
            public void run() {
                mWindow.setVisibility(View.GONE);
                refresh();
    // TODO: "pin area" panel, dragging things out
    ObjectAnimator mAnimHide, mAnimShow;
    
    protected void onAttachedToWindow() {
    }
        },
        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
    }
    */
}
Loading