• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2022 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *
16  */
17 
18 package com.android.wallpaper.picker.customization.ui.section
19 
20 import android.content.Context
21 import android.util.AttributeSet
22 import android.view.MotionEvent
23 import android.view.ViewConfiguration
24 import com.android.wallpaper.picker.SectionView
25 import kotlin.math.pow
26 import kotlin.math.sqrt
27 
28 class ScreenPreviewView(
29     context: Context,
30     attrs: AttributeSet?,
31 ) :
32     SectionView(
33         context,
34         attrs,
35     ) {
36 
37     private var downX = 0f
38     private var downY = 0f
39 
onInterceptTouchEventnull40     override fun onInterceptTouchEvent(event: MotionEvent): Boolean {
41         if (event.actionMasked == MotionEvent.ACTION_DOWN) {
42             downX = event.x
43             downY = event.y
44         }
45 
46         // We want to intercept clicks so the Carousel MotionLayout child doesn't prevent users from
47         // clicking on the screen preview.
48         if (isClick(event, downX, downY)) {
49             return performClick()
50         }
51 
52         return super.onInterceptTouchEvent(event)
53     }
54 
55     companion object {
isClicknull56         private fun isClick(event: MotionEvent, downX: Float, downY: Float): Boolean {
57             return when {
58                 // It's not a click if the event is not an UP action (though it may become one
59                 // later, when/if an UP is received).
60                 event.actionMasked != MotionEvent.ACTION_UP -> false
61                 // It's not a click if too much time has passed between the down and the current
62                 // event.
63                 gestureElapsedTime(event) > ViewConfiguration.getTapTimeout() -> false
64                 // It's not a click if the touch traveled too far.
65                 distanceMoved(event, downX, downY) > ViewConfiguration.getTouchSlop() -> false
66                 // Otherwise, this is a click!
67                 else -> true
68             }
69         }
70 
71         /**
72          * Returns the distance that the pointer traveled in the touch gesture the given event is
73          * part of.
74          */
distanceMovednull75         private fun distanceMoved(event: MotionEvent, downX: Float, downY: Float): Float {
76             val deltaX = event.x - downX
77             val deltaY = event.y - downY
78             return sqrt(deltaX.pow(2) + deltaY.pow(2))
79         }
80 
81         /**
82          * Returns the elapsed time since the touch gesture the given event is part of has begun.
83          */
gestureElapsedTimenull84         private fun gestureElapsedTime(event: MotionEvent): Long {
85             return event.eventTime - event.downTime
86         }
87     }
88 }
89