• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2019 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 static android.widget.ListPopupWindow.WRAP_CONTENT;
20 
21 import static com.android.launcher3.LauncherAnimUtils.VIEW_TRANSLATE_X;
22 import static com.android.launcher3.LauncherAnimUtils.VIEW_TRANSLATE_Y;
23 import static com.android.launcher3.touch.SingleAxisSwipeDetector.HORIZONTAL;
24 import static com.android.launcher3.util.SplitConfigurationOptions.STAGE_POSITION_BOTTOM_OR_RIGHT;
25 import static com.android.launcher3.util.SplitConfigurationOptions.STAGE_POSITION_TOP_OR_LEFT;
26 import static com.android.launcher3.util.SplitConfigurationOptions.STAGE_TYPE_MAIN;
27 
28 import android.content.res.Resources;
29 import android.graphics.PointF;
30 import android.graphics.Rect;
31 import android.graphics.RectF;
32 import android.graphics.drawable.ShapeDrawable;
33 import android.util.FloatProperty;
34 import android.view.MotionEvent;
35 import android.view.Surface;
36 import android.view.VelocityTracker;
37 import android.view.View;
38 import android.view.accessibility.AccessibilityEvent;
39 import android.widget.LinearLayout;
40 
41 import com.android.launcher3.DeviceProfile;
42 import com.android.launcher3.R;
43 import com.android.launcher3.Utilities;
44 import com.android.launcher3.util.SplitConfigurationOptions.SplitPositionOption;
45 import com.android.launcher3.views.BaseDragLayer;
46 
47 import java.util.Collections;
48 import java.util.List;
49 
50 public class LandscapePagedViewHandler implements PagedOrientationHandler {
51 
52     @Override
getPrimaryValue(T x, T y)53     public <T> T getPrimaryValue(T x, T y) {
54         return y;
55     }
56 
57     @Override
getSecondaryValue(T x, T y)58     public <T> T getSecondaryValue(T x, T y) {
59         return x;
60     }
61 
62     @Override
getPrimaryValue(int x, int y)63     public int getPrimaryValue(int x, int y) {
64         return y;
65     }
66 
67     @Override
getSecondaryValue(int x, int y)68     public int getSecondaryValue(int x, int y) {
69         return x;
70     }
71 
72     @Override
getPrimaryValue(float x, float y)73     public float getPrimaryValue(float x, float y) {
74         return y;
75     }
76 
77     @Override
getSecondaryValue(float x, float y)78     public float getSecondaryValue(float x, float y) {
79         return x;
80     }
81 
82     @Override
isLayoutNaturalToLauncher()83     public boolean isLayoutNaturalToLauncher() {
84         return false;
85     }
86 
87     @Override
adjustFloatingIconStartVelocity(PointF velocity)88     public void adjustFloatingIconStartVelocity(PointF velocity) {
89         float oldX = velocity.x;
90         float oldY = velocity.y;
91         velocity.set(-oldY, oldX);
92     }
93 
94     @Override
set(T target, Int2DAction<T> action, int param)95     public <T> void set(T target, Int2DAction<T> action, int param) {
96         action.call(target, 0, param);
97     }
98 
99     @Override
set(T target, Float2DAction<T> action, float param)100     public <T> void set(T target, Float2DAction<T> action, float param) {
101         action.call(target, 0, param);
102     }
103 
104     @Override
setSecondary(T target, Float2DAction<T> action, float param)105     public <T> void setSecondary(T target, Float2DAction<T> action, float param) {
106         action.call(target, param, 0);
107     }
108 
109     @Override
getPrimaryDirection(MotionEvent event, int pointerIndex)110     public float getPrimaryDirection(MotionEvent event, int pointerIndex) {
111         return event.getY(pointerIndex);
112     }
113 
114     @Override
getPrimaryVelocity(VelocityTracker velocityTracker, int pointerId)115     public float getPrimaryVelocity(VelocityTracker velocityTracker, int pointerId) {
116         return velocityTracker.getYVelocity(pointerId);
117     }
118 
119     @Override
getMeasuredSize(View view)120     public int getMeasuredSize(View view) {
121         return view.getMeasuredHeight();
122     }
123 
124     @Override
getPrimarySize(View view)125     public int getPrimarySize(View view) {
126         return view.getHeight();
127     }
128 
129     @Override
getPrimarySize(RectF rect)130     public float getPrimarySize(RectF rect) {
131         return rect.height();
132     }
133 
134     @Override
getStart(RectF rect)135     public float getStart(RectF rect) {
136         return rect.top;
137     }
138 
139     @Override
getEnd(RectF rect)140     public float getEnd(RectF rect) {
141         return rect.bottom;
142     }
143 
144     @Override
getClearAllSidePadding(View view, boolean isRtl)145     public int getClearAllSidePadding(View view, boolean isRtl) {
146         return (isRtl ? view.getPaddingBottom() : - view.getPaddingTop()) / 2;
147     }
148 
149     @Override
getSecondaryDimension(View view)150     public int getSecondaryDimension(View view) {
151         return view.getWidth();
152     }
153 
154     @Override
getPrimaryViewTranslate()155     public FloatProperty<View> getPrimaryViewTranslate() {
156         return VIEW_TRANSLATE_Y;
157     }
158 
159     @Override
getSecondaryViewTranslate()160     public FloatProperty<View> getSecondaryViewTranslate() {
161         return VIEW_TRANSLATE_X;
162     }
163 
164     @Override
getSplitTaskViewDismissDirection(SplitPositionOption splitPosition, DeviceProfile dp)165     public int getSplitTaskViewDismissDirection(SplitPositionOption splitPosition,
166             DeviceProfile dp) {
167         // Don't use device profile here because we know we're in fake landscape, only split option
168         // available is top/left
169         if (splitPosition.mStagePosition == STAGE_POSITION_TOP_OR_LEFT) {
170             // Top (visually left) side
171             return SPLIT_TRANSLATE_PRIMARY_NEGATIVE;
172         }
173         throw new IllegalStateException("Invalid split stage position: " +
174                 splitPosition.mStagePosition);
175     }
176 
177     @Override
getPrimaryScroll(View view)178     public int getPrimaryScroll(View view) {
179         return view.getScrollY();
180     }
181 
182     @Override
getPrimaryScale(View view)183     public float getPrimaryScale(View view) {
184         return view.getScaleY();
185     }
186 
187     @Override
setMaxScroll(AccessibilityEvent event, int maxScroll)188     public void setMaxScroll(AccessibilityEvent event, int maxScroll) {
189         event.setMaxScrollY(maxScroll);
190     }
191 
192     @Override
getRecentsRtlSetting(Resources resources)193     public boolean getRecentsRtlSetting(Resources resources) {
194         return !Utilities.isRtl(resources);
195     }
196 
197     @Override
getDegreesRotated()198     public float getDegreesRotated() {
199         return 90;
200     }
201 
202     @Override
getRotation()203     public int getRotation() {
204         return Surface.ROTATION_90;
205     }
206 
207     @Override
getChildStart(View view)208     public int getChildStart(View view) {
209         return view.getTop();
210     }
211 
212     @Override
getChildStartWithTranslation(View view)213     public float getChildStartWithTranslation(View view) {
214         return view.getTop() + view.getTranslationY();
215     }
216 
217     @Override
getCenterForPage(View view, Rect insets)218     public int getCenterForPage(View view, Rect insets) {
219         return (view.getPaddingLeft() + view.getMeasuredWidth() + insets.left
220             - insets.right - view.getPaddingRight()) / 2;
221     }
222 
223     @Override
getScrollOffsetStart(View view, Rect insets)224     public int getScrollOffsetStart(View view, Rect insets) {
225         return insets.top + view.getPaddingTop();
226     }
227 
228     @Override
getScrollOffsetEnd(View view, Rect insets)229     public int getScrollOffsetEnd(View view, Rect insets) {
230         return view.getHeight() - view.getPaddingBottom() - insets.bottom;
231     }
232 
233     @Override
getPrimaryTranslationDirectionFactor()234     public int getPrimaryTranslationDirectionFactor() {
235         return -1;
236     }
237 
getSecondaryTranslationDirectionFactor()238     public int getSecondaryTranslationDirectionFactor() {
239         return 1;
240     }
241 
242     @Override
getSplitTranslationDirectionFactor(int stagePosition)243     public int getSplitTranslationDirectionFactor(int stagePosition) {
244         if (stagePosition == STAGE_POSITION_BOTTOM_OR_RIGHT) {
245             return -1;
246         } else {
247             return 1;
248         }
249     }
250 
251     @Override
getSplitAnimationTranslation(int translationOffset, DeviceProfile dp)252     public int getSplitAnimationTranslation(int translationOffset, DeviceProfile dp) {
253         return translationOffset;
254     }
255 
256     @Override
getTaskMenuX(float x, View thumbnailView, int overScroll)257     public float getTaskMenuX(float x, View thumbnailView, int overScroll) {
258         return thumbnailView.getMeasuredWidth() + x;
259     }
260 
261     @Override
getTaskMenuY(float y, View thumbnailView, int overScroll)262     public float getTaskMenuY(float y, View thumbnailView, int overScroll) {
263         return y + overScroll;
264     }
265 
266     @Override
getTaskMenuWidth(View view)267     public int getTaskMenuWidth(View view) {
268         return view.getMeasuredHeight();
269     }
270 
271     @Override
setTaskOptionsMenuLayoutOrientation(DeviceProfile deviceProfile, LinearLayout taskMenuLayout, int dividerSpacing, ShapeDrawable dividerDrawable)272     public void setTaskOptionsMenuLayoutOrientation(DeviceProfile deviceProfile,
273             LinearLayout taskMenuLayout, int dividerSpacing,
274             ShapeDrawable dividerDrawable) {
275         taskMenuLayout.setOrientation(LinearLayout.HORIZONTAL);
276         dividerDrawable.setIntrinsicWidth(dividerSpacing);
277         taskMenuLayout.setDividerDrawable(dividerDrawable);
278     }
279 
280     @Override
setLayoutParamsForTaskMenuOptionItem(LinearLayout.LayoutParams lp, LinearLayout viewGroup, DeviceProfile deviceProfile)281     public void setLayoutParamsForTaskMenuOptionItem(LinearLayout.LayoutParams lp,
282             LinearLayout viewGroup, DeviceProfile deviceProfile) {
283         // Phone fake landscape
284         viewGroup.setOrientation(LinearLayout.VERTICAL);
285         lp.width = 0;
286         lp.height = WRAP_CONTENT;
287         lp.weight = 1;
288         Utilities.setStartMarginForView(viewGroup.findViewById(R.id.text), 0);
289         Utilities.setStartMarginForView(viewGroup.findViewById(R.id.icon), 0);
290     }
291 
292     @Override
setTaskMenuAroundTaskView(LinearLayout taskView, float margin)293     public void setTaskMenuAroundTaskView(LinearLayout taskView, float margin) {
294         BaseDragLayer.LayoutParams lp = (BaseDragLayer.LayoutParams) taskView.getLayoutParams();
295         lp.topMargin += margin;
296     }
297 
298     @Override
getAdditionalInsetForTaskMenu(float margin)299     public PointF getAdditionalInsetForTaskMenu(float margin) {
300         return new PointF(margin, 0);
301     }
302 
303     /* ---------- The following are only used by TaskViewTouchHandler. ---------- */
304 
305     @Override
getUpDownSwipeDirection()306     public SingleAxisSwipeDetector.Direction getUpDownSwipeDirection() {
307         return HORIZONTAL;
308     }
309 
310     @Override
getUpDirection(boolean isRtl)311     public int getUpDirection(boolean isRtl) {
312         return isRtl ? SingleAxisSwipeDetector.DIRECTION_NEGATIVE
313                 : SingleAxisSwipeDetector.DIRECTION_POSITIVE;
314     }
315 
316     @Override
isGoingUp(float displacement, boolean isRtl)317     public boolean isGoingUp(float displacement, boolean isRtl) {
318         return isRtl ? displacement < 0 : displacement > 0;
319     }
320 
321     @Override
getTaskDragDisplacementFactor(boolean isRtl)322     public int getTaskDragDisplacementFactor(boolean isRtl) {
323         return isRtl ? 1 : -1;
324     }
325 
326     /* -------------------- */
327 
328     @Override
getChildBounds(View child, int childStart, int pageCenter, boolean layoutChild)329     public ChildBounds getChildBounds(View child, int childStart, int pageCenter,
330         boolean layoutChild) {
331         final int childHeight = child.getMeasuredHeight();
332         final int childBottom = childStart + childHeight;
333         final int childWidth = child.getMeasuredWidth();
334         final int childLeft = pageCenter - childWidth/ 2;
335         if (layoutChild) {
336             child.layout(childLeft, childStart, childLeft + childWidth, childBottom);
337         }
338         return new ChildBounds(childHeight, childWidth, childBottom, childLeft);
339     }
340 
341     @SuppressWarnings("SuspiciousNameCombination")
342     @Override
getDistanceToBottomOfRect(DeviceProfile dp, Rect rect)343     public int getDistanceToBottomOfRect(DeviceProfile dp, Rect rect) {
344         return rect.left;
345     }
346 
347     @Override
getSplitPositionOptions(DeviceProfile dp)348     public List<SplitPositionOption> getSplitPositionOptions(DeviceProfile dp) {
349         // Add "left" side of phone which is actually the top
350         return Collections.singletonList(new SplitPositionOption(
351                 R.drawable.ic_split_screen, R.string.split_screen_position_left,
352                 STAGE_POSITION_TOP_OR_LEFT, STAGE_TYPE_MAIN));
353     }
354 
355     @Override
getSplitSelectTaskOffset(FloatProperty primary, FloatProperty secondary, DeviceProfile deviceProfile)356     public FloatProperty getSplitSelectTaskOffset(FloatProperty primary, FloatProperty secondary,
357             DeviceProfile deviceProfile) {
358         return primary;
359     }
360 }
361