1 /* 2 * Copyright (C) 2020 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 package com.android.launcher3.touch; 18 19 import android.content.res.Resources; 20 import android.graphics.Canvas; 21 import android.graphics.Matrix; 22 import android.graphics.PointF; 23 import android.graphics.Rect; 24 import android.graphics.RectF; 25 import android.graphics.drawable.ShapeDrawable; 26 import android.util.FloatProperty; 27 import android.view.MotionEvent; 28 import android.view.VelocityTracker; 29 import android.view.View; 30 import android.view.accessibility.AccessibilityEvent; 31 import android.widget.LinearLayout; 32 33 import com.android.launcher3.DeviceProfile; 34 import com.android.launcher3.util.SplitConfigurationOptions.SplitPositionOption; 35 import com.android.launcher3.util.SplitConfigurationOptions.StagePosition; 36 37 import java.util.List; 38 39 /** 40 * Abstraction layer to separate horizontal and vertical specific implementations 41 * for {@link com.android.launcher3.PagedView}. Majority of these implementations are (should be) as 42 * simple as choosing the correct X and Y analogous methods. 43 */ 44 public interface PagedOrientationHandler { 45 46 int SPLIT_TRANSLATE_PRIMARY_POSITIVE = 0; 47 int SPLIT_TRANSLATE_PRIMARY_NEGATIVE = 1; 48 int SPLIT_TRANSLATE_SECONDARY_NEGATIVE = 2; 49 50 PagedOrientationHandler PORTRAIT = new PortraitPagedViewHandler(); 51 PagedOrientationHandler LANDSCAPE = new LandscapePagedViewHandler(); 52 PagedOrientationHandler SEASCAPE = new SeascapePagedViewHandler(); 53 54 interface Int2DAction<T> { call(T target, int x, int y)55 void call(T target, int x, int y); 56 } 57 interface Float2DAction<T> { call(T target, float x, float y)58 void call(T target, float x, float y); 59 } 60 Int2DAction<View> VIEW_SCROLL_BY = View::scrollBy; 61 Int2DAction<View> VIEW_SCROLL_TO = View::scrollTo; 62 Float2DAction<Canvas> CANVAS_TRANSLATE = Canvas::translate; 63 Float2DAction<Matrix> MATRIX_POST_TRANSLATE = Matrix::postTranslate; 64 set(T target, Int2DAction<T> action, int param)65 <T> void set(T target, Int2DAction<T> action, int param); set(T target, Float2DAction<T> action, float param)66 <T> void set(T target, Float2DAction<T> action, float param); setSecondary(T target, Float2DAction<T> action, float param)67 <T> void setSecondary(T target, Float2DAction<T> action, float param); getPrimaryDirection(MotionEvent event, int pointerIndex)68 float getPrimaryDirection(MotionEvent event, int pointerIndex); getPrimaryVelocity(VelocityTracker velocityTracker, int pointerId)69 float getPrimaryVelocity(VelocityTracker velocityTracker, int pointerId); getMeasuredSize(View view)70 int getMeasuredSize(View view); getPrimarySize(View view)71 int getPrimarySize(View view); getPrimarySize(RectF rect)72 float getPrimarySize(RectF rect); getStart(RectF rect)73 float getStart(RectF rect); getEnd(RectF rect)74 float getEnd(RectF rect); getClearAllSidePadding(View view, boolean isRtl)75 int getClearAllSidePadding(View view, boolean isRtl); getSecondaryDimension(View view)76 int getSecondaryDimension(View view); getPrimaryViewTranslate()77 FloatProperty<View> getPrimaryViewTranslate(); getSecondaryViewTranslate()78 FloatProperty<View> getSecondaryViewTranslate(); 79 80 /** 81 * @param splitPosition The position where the view to be split will go 82 * @return {@link #SPLIT_TRANSLATE_*} constants to indicate which direction the 83 * dismissal should happen 84 */ getSplitTaskViewDismissDirection(SplitPositionOption splitPosition, DeviceProfile dp)85 int getSplitTaskViewDismissDirection(SplitPositionOption splitPosition, DeviceProfile dp); getPrimaryScroll(View view)86 int getPrimaryScroll(View view); getPrimaryScale(View view)87 float getPrimaryScale(View view); getChildStart(View view)88 int getChildStart(View view); getChildStartWithTranslation(View view)89 float getChildStartWithTranslation(View view); getCenterForPage(View view, Rect insets)90 int getCenterForPage(View view, Rect insets); getScrollOffsetStart(View view, Rect insets)91 int getScrollOffsetStart(View view, Rect insets); getScrollOffsetEnd(View view, Rect insets)92 int getScrollOffsetEnd(View view, Rect insets); getPrimaryTranslationDirectionFactor()93 int getPrimaryTranslationDirectionFactor(); getSecondaryTranslationDirectionFactor()94 int getSecondaryTranslationDirectionFactor(); getSplitTranslationDirectionFactor(@tagePosition int stagePosition)95 int getSplitTranslationDirectionFactor(@StagePosition int stagePosition); getSplitAnimationTranslation(int translationOffset, DeviceProfile dp)96 int getSplitAnimationTranslation(int translationOffset, DeviceProfile dp); getChildBounds(View child, int childStart, int pageCenter, boolean layoutChild)97 ChildBounds getChildBounds(View child, int childStart, int pageCenter, boolean layoutChild); setMaxScroll(AccessibilityEvent event, int maxScroll)98 void setMaxScroll(AccessibilityEvent event, int maxScroll); getRecentsRtlSetting(Resources resources)99 boolean getRecentsRtlSetting(Resources resources); getDegreesRotated()100 float getDegreesRotated(); getRotation()101 int getRotation(); 102 getPrimaryValue(T x, T y)103 <T> T getPrimaryValue(T x, T y); getSecondaryValue(T x, T y)104 <T> T getSecondaryValue(T x, T y); 105 getPrimaryValue(int x, int y)106 int getPrimaryValue(int x, int y); getSecondaryValue(int x, int y)107 int getSecondaryValue(int x, int y); 108 getPrimaryValue(float x, float y)109 float getPrimaryValue(float x, float y); getSecondaryValue(float x, float y)110 float getSecondaryValue(float x, float y); 111 isLayoutNaturalToLauncher()112 boolean isLayoutNaturalToLauncher(); getSplitSelectTaskOffset(FloatProperty primary, FloatProperty secondary, DeviceProfile deviceProfile)113 FloatProperty getSplitSelectTaskOffset(FloatProperty primary, FloatProperty secondary, 114 DeviceProfile deviceProfile); getDistanceToBottomOfRect(DeviceProfile dp, Rect rect)115 int getDistanceToBottomOfRect(DeviceProfile dp, Rect rect); getSplitPositionOptions(DeviceProfile dp)116 List<SplitPositionOption> getSplitPositionOptions(DeviceProfile dp); 117 118 // Overview TaskMenuView methods getTaskMenuX(float x, View thumbnailView, int overScroll)119 float getTaskMenuX(float x, View thumbnailView, int overScroll); getTaskMenuY(float y, View thumbnailView, int overScroll)120 float getTaskMenuY(float y, View thumbnailView, int overScroll); getTaskMenuWidth(View view)121 int getTaskMenuWidth(View view); 122 /** 123 * Sets linear layout orientation for {@link com.android.launcher3.popup.SystemShortcut} items 124 * inside task menu view. 125 */ setTaskOptionsMenuLayoutOrientation(DeviceProfile deviceProfile, LinearLayout taskMenuLayout, int dividerSpacing, ShapeDrawable dividerDrawable)126 void setTaskOptionsMenuLayoutOrientation(DeviceProfile deviceProfile, 127 LinearLayout taskMenuLayout, int dividerSpacing, 128 ShapeDrawable dividerDrawable); 129 /** 130 * Sets layout param attributes for {@link com.android.launcher3.popup.SystemShortcut} child 131 * views inside task menu view. 132 */ setLayoutParamsForTaskMenuOptionItem(LinearLayout.LayoutParams lp, LinearLayout viewGroup, DeviceProfile deviceProfile)133 void setLayoutParamsForTaskMenuOptionItem(LinearLayout.LayoutParams lp, 134 LinearLayout viewGroup, DeviceProfile deviceProfile); 135 /** 136 * Adjusts margins for the entire task menu view itself, which comprises of both app title and 137 * shortcut options. 138 */ setTaskMenuAroundTaskView(LinearLayout taskView, float margin)139 void setTaskMenuAroundTaskView(LinearLayout taskView, float margin); 140 /** 141 * Since the task menu layout is manually positioned on top of recents view, this method returns 142 * additional adjustments to the positioning based on fake land/seascape 143 */ getAdditionalInsetForTaskMenu(float margin)144 PointF getAdditionalInsetForTaskMenu(float margin); 145 146 // The following are only used by TaskViewTouchHandler. 147 /** @return Either VERTICAL or HORIZONTAL. */ getUpDownSwipeDirection()148 SingleAxisSwipeDetector.Direction getUpDownSwipeDirection(); 149 /** @return Given {@link #getUpDownSwipeDirection()}, whether POSITIVE or NEGATIVE is up. */ getUpDirection(boolean isRtl)150 int getUpDirection(boolean isRtl); 151 /** @return Whether the displacement is going towards the top of the screen. */ isGoingUp(float displacement, boolean isRtl)152 boolean isGoingUp(float displacement, boolean isRtl); 153 /** @return Either 1 or -1, a factor to multiply by so the animation goes the correct way. */ getTaskDragDisplacementFactor(boolean isRtl)154 int getTaskDragDisplacementFactor(boolean isRtl); 155 156 /** 157 * Maps the velocity from the coordinate plane of the foreground app to that 158 * of Launcher's (which now will always be portrait) 159 */ adjustFloatingIconStartVelocity(PointF velocity)160 void adjustFloatingIconStartVelocity(PointF velocity); 161 162 class ChildBounds { 163 164 public final int primaryDimension; 165 public final int secondaryDimension; 166 public final int childPrimaryEnd; 167 public final int childSecondaryEnd; 168 ChildBounds(int primaryDimension, int secondaryDimension, int childPrimaryEnd, int childSecondaryEnd)169 ChildBounds(int primaryDimension, int secondaryDimension, int childPrimaryEnd, 170 int childSecondaryEnd) { 171 this.primaryDimension = primaryDimension; 172 this.secondaryDimension = secondaryDimension; 173 this.childPrimaryEnd = childPrimaryEnd; 174 this.childSecondaryEnd = childSecondaryEnd; 175 } 176 } 177 } 178