131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project/* 231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * Copyright (C) 2009 The Android Open Source Project 331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * 431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); 531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * you may not use this file except in compliance with the License. 631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * You may obtain a copy of the License at 731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * 831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * 1031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * Unless required by applicable law or agreed to in writing, software 1131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 1231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * See the License for the specific language governing permissions and 1431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * limitations under the License. 1531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project */ 1631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 17325dc23624160689e59fbac708cf6f222b20d025Daniel Sandlerpackage com.android.launcher3; 1831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 197376faefbbcbe30cc4e3f706ab95c254a4707d98The Android Open Source Projectimport android.appwidget.AppWidgetHostView; 2031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Projectimport android.content.Context; 2131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Projectimport android.view.LayoutInflater; 2231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Projectimport android.view.MotionEvent; 2331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Projectimport android.view.View; 2402dd7aea3d8ac94126a8f8069e6762592ea60326Jason Monkimport android.view.ViewConfiguration; 2597d85d23b013347bead4e2f5fa430a79ce69431eWinson Chungimport android.view.ViewGroup; 2606dff35763bc46884b6464a9bf4406d32cdcaea4Adam Cohenimport android.widget.RemoteViews; 2731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 28b0f3d74815417acc3a9d3dce90cbf34b772847f0Adam Cohenimport com.android.launcher3.DragLayer.TouchCompleteListener; 29b0f3d74815417acc3a9d3dce90cbf34b772847f0Adam Cohen 3031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project/** 3131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * {@inheritDoc} 3231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project */ 33b0f3d74815417acc3a9d3dce90cbf34b772847f0Adam Cohenpublic class LauncherAppWidgetHostView extends AppWidgetHostView implements TouchCompleteListener { 34ff572277112ec3d6a6a8c1be274d6fa1019e3648Sunny Goyal 35ff572277112ec3d6a6a8c1be274d6fa1019e3648Sunny Goyal LayoutInflater mInflater; 36ff572277112ec3d6a6a8c1be274d6fa1019e3648Sunny Goyal 3788f334571fe41df620ba903ced9b2c69b0170d5cWinson Chung private CheckLongPressHelper mLongPressHelper; 3806dff35763bc46884b6464a9bf4406d32cdcaea4Adam Cohen private Context mContext; 3906dff35763bc46884b6464a9bf4406d32cdcaea4Adam Cohen private int mPreviousOrientation; 40b0f3d74815417acc3a9d3dce90cbf34b772847f0Adam Cohen private DragLayer mDragLayer; 4199b6a5b5f7808291e26f98ee8064bd9f288c3febMichael Jurka 4202dd7aea3d8ac94126a8f8069e6762592ea60326Jason Monk private float mSlop; 4302dd7aea3d8ac94126a8f8069e6762592ea60326Jason Monk 447376faefbbcbe30cc4e3f706ab95c254a4707d98The Android Open Source Project public LauncherAppWidgetHostView(Context context) { 4531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project super(context); 4606dff35763bc46884b6464a9bf4406d32cdcaea4Adam Cohen mContext = context; 4788f334571fe41df620ba903ced9b2c69b0170d5cWinson Chung mLongPressHelper = new CheckLongPressHelper(this); 4831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project mInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); 49b0f3d74815417acc3a9d3dce90cbf34b772847f0Adam Cohen mDragLayer = ((Launcher) context).getDragLayer(); 5031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 5141d5d6d0768b467f2c7c47ceb027495e4d3f5effAdam Cohen 5231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project @Override 5331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project protected View getErrorView() { 547376faefbbcbe30cc4e3f706ab95c254a4707d98The Android Open Source Project return mInflater.inflate(R.layout.appwidget_error, this, false); 5531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 5631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 5706dff35763bc46884b6464a9bf4406d32cdcaea4Adam Cohen @Override 5806dff35763bc46884b6464a9bf4406d32cdcaea4Adam Cohen public void updateAppWidget(RemoteViews remoteViews) { 5906dff35763bc46884b6464a9bf4406d32cdcaea4Adam Cohen // Store the orientation in which the widget was inflated 6006dff35763bc46884b6464a9bf4406d32cdcaea4Adam Cohen mPreviousOrientation = mContext.getResources().getConfiguration().orientation; 6106dff35763bc46884b6464a9bf4406d32cdcaea4Adam Cohen super.updateAppWidget(remoteViews); 6206dff35763bc46884b6464a9bf4406d32cdcaea4Adam Cohen } 6306dff35763bc46884b6464a9bf4406d32cdcaea4Adam Cohen 64ff572277112ec3d6a6a8c1be274d6fa1019e3648Sunny Goyal public boolean isReinflateRequired() { 65ff572277112ec3d6a6a8c1be274d6fa1019e3648Sunny Goyal // Re-inflate is required if the orientation has changed since last inflated. 6606dff35763bc46884b6464a9bf4406d32cdcaea4Adam Cohen int orientation = mContext.getResources().getConfiguration().orientation; 6706dff35763bc46884b6464a9bf4406d32cdcaea4Adam Cohen if (mPreviousOrientation != orientation) { 6806dff35763bc46884b6464a9bf4406d32cdcaea4Adam Cohen return true; 6906dff35763bc46884b6464a9bf4406d32cdcaea4Adam Cohen } 7006dff35763bc46884b6464a9bf4406d32cdcaea4Adam Cohen return false; 7106dff35763bc46884b6464a9bf4406d32cdcaea4Adam Cohen } 7206dff35763bc46884b6464a9bf4406d32cdcaea4Adam Cohen 7331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project public boolean onInterceptTouchEvent(MotionEvent ev) { 743798b643cd8a5c7c85864eced90374cf0fb45640Adam Cohen // Just in case the previous long press hasn't been cleared, we make sure to start fresh 753798b643cd8a5c7c85864eced90374cf0fb45640Adam Cohen // on touch down. 763798b643cd8a5c7c85864eced90374cf0fb45640Adam Cohen if (ev.getAction() == MotionEvent.ACTION_DOWN) { 773798b643cd8a5c7c85864eced90374cf0fb45640Adam Cohen mLongPressHelper.cancelLongPress(); 783798b643cd8a5c7c85864eced90374cf0fb45640Adam Cohen } 793798b643cd8a5c7c85864eced90374cf0fb45640Adam Cohen 8031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project // Consume any touch events for ourselves after longpress is triggered 8188f334571fe41df620ba903ced9b2c69b0170d5cWinson Chung if (mLongPressHelper.hasPerformedLongPress()) { 8288f334571fe41df620ba903ced9b2c69b0170d5cWinson Chung mLongPressHelper.cancelLongPress(); 8331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project return true; 8431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 8519072da7441e07d5e90026d9e9e1b38f11245e44Adam Cohen 8631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project // Watch for longpress events at this level to make sure 877376faefbbcbe30cc4e3f706ab95c254a4707d98The Android Open Source Project // users can always pick up this widget 8831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project switch (ev.getAction()) { 8931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project case MotionEvent.ACTION_DOWN: { 9088f334571fe41df620ba903ced9b2c69b0170d5cWinson Chung mLongPressHelper.postCheckForLongPress(); 91b0f3d74815417acc3a9d3dce90cbf34b772847f0Adam Cohen mDragLayer.setTouchCompleteListener(this); 9231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project break; 9331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 9419072da7441e07d5e90026d9e9e1b38f11245e44Adam Cohen 9531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project case MotionEvent.ACTION_UP: 9631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project case MotionEvent.ACTION_CANCEL: 9788f334571fe41df620ba903ced9b2c69b0170d5cWinson Chung mLongPressHelper.cancelLongPress(); 9831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project break; 9902dd7aea3d8ac94126a8f8069e6762592ea60326Jason Monk case MotionEvent.ACTION_MOVE: 10002dd7aea3d8ac94126a8f8069e6762592ea60326Jason Monk if (!Utilities.pointInView(this, ev.getX(), ev.getY(), mSlop)) { 10102dd7aea3d8ac94126a8f8069e6762592ea60326Jason Monk mLongPressHelper.cancelLongPress(); 10202dd7aea3d8ac94126a8f8069e6762592ea60326Jason Monk } 10302dd7aea3d8ac94126a8f8069e6762592ea60326Jason Monk break; 10431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 10519072da7441e07d5e90026d9e9e1b38f11245e44Adam Cohen 10631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project // Otherwise continue letting touch events fall through to children 10731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project return false; 10831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 109d4844c3e731b00547a31f23a00f8bd4a271e2b62Adam Cohen 110e7a852ef1511bc18a87168a0821c901e2600da4bWinson Chung public boolean onTouchEvent(MotionEvent ev) { 111e7a852ef1511bc18a87168a0821c901e2600da4bWinson Chung // If the widget does not handle touch, then cancel 112e7a852ef1511bc18a87168a0821c901e2600da4bWinson Chung // long press when we release the touch 113e7a852ef1511bc18a87168a0821c901e2600da4bWinson Chung switch (ev.getAction()) { 114e7a852ef1511bc18a87168a0821c901e2600da4bWinson Chung case MotionEvent.ACTION_UP: 115e7a852ef1511bc18a87168a0821c901e2600da4bWinson Chung case MotionEvent.ACTION_CANCEL: 116e7a852ef1511bc18a87168a0821c901e2600da4bWinson Chung mLongPressHelper.cancelLongPress(); 117e7a852ef1511bc18a87168a0821c901e2600da4bWinson Chung break; 11802dd7aea3d8ac94126a8f8069e6762592ea60326Jason Monk case MotionEvent.ACTION_MOVE: 11902dd7aea3d8ac94126a8f8069e6762592ea60326Jason Monk if (!Utilities.pointInView(this, ev.getX(), ev.getY(), mSlop)) { 12002dd7aea3d8ac94126a8f8069e6762592ea60326Jason Monk mLongPressHelper.cancelLongPress(); 12102dd7aea3d8ac94126a8f8069e6762592ea60326Jason Monk } 12202dd7aea3d8ac94126a8f8069e6762592ea60326Jason Monk break; 123e7a852ef1511bc18a87168a0821c901e2600da4bWinson Chung } 124e7a852ef1511bc18a87168a0821c901e2600da4bWinson Chung return false; 125e7a852ef1511bc18a87168a0821c901e2600da4bWinson Chung } 126e7a852ef1511bc18a87168a0821c901e2600da4bWinson Chung 12783f111d129fcb8c50b35da789f0d75604b9c0864Jeff Sharkey @Override 12802dd7aea3d8ac94126a8f8069e6762592ea60326Jason Monk protected void onAttachedToWindow() { 12902dd7aea3d8ac94126a8f8069e6762592ea60326Jason Monk super.onAttachedToWindow(); 13002dd7aea3d8ac94126a8f8069e6762592ea60326Jason Monk mSlop = ViewConfiguration.get(getContext()).getScaledTouchSlop(); 13102dd7aea3d8ac94126a8f8069e6762592ea60326Jason Monk } 13202dd7aea3d8ac94126a8f8069e6762592ea60326Jason Monk 13302dd7aea3d8ac94126a8f8069e6762592ea60326Jason Monk @Override 13483f111d129fcb8c50b35da789f0d75604b9c0864Jeff Sharkey public void cancelLongPress() { 13583f111d129fcb8c50b35da789f0d75604b9c0864Jeff Sharkey super.cancelLongPress(); 136b0f3d74815417acc3a9d3dce90cbf34b772847f0Adam Cohen mLongPressHelper.cancelLongPress(); 137b0f3d74815417acc3a9d3dce90cbf34b772847f0Adam Cohen } 13883f111d129fcb8c50b35da789f0d75604b9c0864Jeff Sharkey 139b0f3d74815417acc3a9d3dce90cbf34b772847f0Adam Cohen @Override 140b0f3d74815417acc3a9d3dce90cbf34b772847f0Adam Cohen public void onTouchComplete() { 1413798b643cd8a5c7c85864eced90374cf0fb45640Adam Cohen if (!mLongPressHelper.hasPerformedLongPress()) { 1423798b643cd8a5c7c85864eced90374cf0fb45640Adam Cohen // If a long press has been performed, we don't want to clear the record of that since 1433798b643cd8a5c7c85864eced90374cf0fb45640Adam Cohen // we still may be receiving a touch up which we want to intercept 1443798b643cd8a5c7c85864eced90374cf0fb45640Adam Cohen mLongPressHelper.cancelLongPress(); 1453798b643cd8a5c7c85864eced90374cf0fb45640Adam Cohen } 14683f111d129fcb8c50b35da789f0d75604b9c0864Jeff Sharkey } 14799b6a5b5f7808291e26f98ee8064bd9f288c3febMichael Jurka 14897d85d23b013347bead4e2f5fa430a79ce69431eWinson Chung @Override 14997d85d23b013347bead4e2f5fa430a79ce69431eWinson Chung public int getDescendantFocusability() { 15097d85d23b013347bead4e2f5fa430a79ce69431eWinson Chung return ViewGroup.FOCUS_BLOCK_DESCENDANTS; 15197d85d23b013347bead4e2f5fa430a79ce69431eWinson Chung } 15231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project} 153