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.view.Gravity.BOTTOM; 20 import static android.view.Gravity.CENTER_VERTICAL; 21 import static android.view.Gravity.END; 22 import static android.view.Gravity.START; 23 import static android.view.Gravity.TOP; 24 25 import static com.android.launcher3.touch.SingleAxisSwipeDetector.HORIZONTAL; 26 import static com.android.launcher3.util.SplitConfigurationOptions.STAGE_POSITION_BOTTOM_OR_RIGHT; 27 import static com.android.launcher3.util.SplitConfigurationOptions.STAGE_POSITION_TOP_OR_LEFT; 28 import static com.android.launcher3.util.SplitConfigurationOptions.STAGE_TYPE_MAIN; 29 30 import android.content.res.Resources; 31 import android.graphics.PointF; 32 import android.graphics.Rect; 33 import android.util.Pair; 34 import android.view.Surface; 35 import android.view.View; 36 import android.widget.FrameLayout; 37 import android.widget.LinearLayout; 38 39 import com.android.launcher3.DeviceProfile; 40 import com.android.launcher3.R; 41 import com.android.launcher3.Utilities; 42 import com.android.launcher3.util.SplitConfigurationOptions.SplitPositionOption; 43 import com.android.launcher3.util.SplitConfigurationOptions.StagedSplitBounds; 44 import com.android.launcher3.views.BaseDragLayer; 45 46 import java.util.Collections; 47 import java.util.List; 48 49 public class SeascapePagedViewHandler extends LandscapePagedViewHandler { 50 51 @Override getSecondaryTranslationDirectionFactor()52 public int getSecondaryTranslationDirectionFactor() { 53 return -1; 54 } 55 56 @Override getSplitTranslationDirectionFactor(int stagePosition, DeviceProfile deviceProfile)57 public int getSplitTranslationDirectionFactor(int stagePosition, DeviceProfile deviceProfile) { 58 if (stagePosition == STAGE_POSITION_BOTTOM_OR_RIGHT) { 59 return -1; 60 } else { 61 return 1; 62 } 63 } 64 65 @Override getRecentsRtlSetting(Resources resources)66 public boolean getRecentsRtlSetting(Resources resources) { 67 return Utilities.isRtl(resources); 68 } 69 70 @Override getDegreesRotated()71 public float getDegreesRotated() { 72 return 270; 73 } 74 75 @Override getRotation()76 public int getRotation() { 77 return Surface.ROTATION_270; 78 } 79 80 @Override adjustFloatingIconStartVelocity(PointF velocity)81 public void adjustFloatingIconStartVelocity(PointF velocity) { 82 float oldX = velocity.x; 83 float oldY = velocity.y; 84 velocity.set(oldY, -oldX); 85 } 86 87 @Override getTaskMenuX(float x, View thumbnailView, int overScroll, DeviceProfile deviceProfile)88 public float getTaskMenuX(float x, View thumbnailView, int overScroll, 89 DeviceProfile deviceProfile) { 90 return x; 91 } 92 93 @Override getTaskMenuY(float y, View thumbnailView, int overScroll)94 public float getTaskMenuY(float y, View thumbnailView, int overScroll) { 95 return y + overScroll + 96 (thumbnailView.getMeasuredHeight() + thumbnailView.getMeasuredWidth()) / 2f; 97 } 98 99 @Override setTaskMenuAroundTaskView(LinearLayout taskView, float margin)100 public void setTaskMenuAroundTaskView(LinearLayout taskView, float margin) { 101 BaseDragLayer.LayoutParams lp = (BaseDragLayer.LayoutParams) taskView.getLayoutParams(); 102 lp.bottomMargin += margin; 103 } 104 105 @Override getAdditionalInsetForTaskMenu(float margin)106 public PointF getAdditionalInsetForTaskMenu(float margin) { 107 return new PointF(-margin, margin); 108 } 109 110 @Override setDwbLayoutParamsAndGetTranslations(int taskViewWidth, int taskViewHeight, StagedSplitBounds splitBounds, DeviceProfile deviceProfile, View[] thumbnailViews, int desiredTaskId, View banner)111 public Pair<Float, Float> setDwbLayoutParamsAndGetTranslations(int taskViewWidth, 112 int taskViewHeight, StagedSplitBounds splitBounds, DeviceProfile deviceProfile, 113 View[] thumbnailViews, int desiredTaskId, View banner) { 114 float translationX = 0; 115 float translationY = 0; 116 FrameLayout.LayoutParams bannerParams = (FrameLayout.LayoutParams) banner.getLayoutParams(); 117 banner.setPivotX(0); 118 banner.setPivotY(0); 119 banner.setRotation(getDegreesRotated()); 120 FrameLayout.LayoutParams snapshotParams = 121 (FrameLayout.LayoutParams) thumbnailViews[0] 122 .getLayoutParams(); 123 bannerParams.gravity = BOTTOM | END; 124 translationX = taskViewWidth - banner.getHeight(); 125 if (splitBounds == null) { 126 // Single, fullscreen case 127 bannerParams.width = taskViewHeight - snapshotParams.topMargin; 128 translationY = banner.getHeight(); 129 return new Pair<>(translationX, translationY); 130 } 131 132 // Set correct width 133 if (desiredTaskId == splitBounds.leftTopTaskId) { 134 bannerParams.width = thumbnailViews[1].getMeasuredHeight(); 135 } else { 136 bannerParams.width = thumbnailViews[0].getMeasuredHeight(); 137 } 138 139 // Set translations 140 if (desiredTaskId == splitBounds.rightBottomTaskId) { 141 translationY = -(taskViewHeight - snapshotParams.topMargin) 142 * (1f - splitBounds.leftTaskPercent) 143 + banner.getHeight(); 144 } 145 if (desiredTaskId == splitBounds.leftTopTaskId) { 146 translationY = banner.getHeight(); 147 } 148 return new Pair<>(translationX, translationY); 149 } 150 151 @Override getDistanceToBottomOfRect(DeviceProfile dp, Rect rect)152 public int getDistanceToBottomOfRect(DeviceProfile dp, Rect rect) { 153 return dp.widthPx - rect.right; 154 } 155 156 @Override getSplitPositionOptions(DeviceProfile dp)157 public List<SplitPositionOption> getSplitPositionOptions(DeviceProfile dp) { 158 // Add "right" option which is actually the top 159 return Collections.singletonList(new SplitPositionOption( 160 R.drawable.ic_split_right, R.string.split_screen_position_right, 161 STAGE_POSITION_TOP_OR_LEFT, STAGE_TYPE_MAIN)); 162 } 163 164 @Override setIconAndSnapshotParams(View mIconView, int taskIconMargin, int taskIconHeight, FrameLayout.LayoutParams snapshotParams, boolean isRtl)165 public void setIconAndSnapshotParams(View mIconView, int taskIconMargin, int taskIconHeight, 166 FrameLayout.LayoutParams snapshotParams, boolean isRtl) { 167 FrameLayout.LayoutParams iconParams = 168 (FrameLayout.LayoutParams) mIconView.getLayoutParams(); 169 iconParams.gravity = (isRtl ? END : START) | CENTER_VERTICAL; 170 iconParams.leftMargin = -taskIconHeight - taskIconMargin / 2; 171 iconParams.rightMargin = 0; 172 iconParams.topMargin = snapshotParams.topMargin / 2; 173 } 174 175 @Override setSplitIconParams(View primaryIconView, View secondaryIconView, int taskIconHeight, int primarySnapshotWidth, int primarySnapshotHeight, boolean isRtl, DeviceProfile deviceProfile, StagedSplitBounds splitConfig)176 public void setSplitIconParams(View primaryIconView, View secondaryIconView, 177 int taskIconHeight, int primarySnapshotWidth, int primarySnapshotHeight, 178 boolean isRtl, DeviceProfile deviceProfile, StagedSplitBounds splitConfig) { 179 super.setSplitIconParams(primaryIconView, secondaryIconView, taskIconHeight, 180 primarySnapshotWidth, primarySnapshotHeight, isRtl, deviceProfile, splitConfig); 181 FrameLayout.LayoutParams primaryIconParams = 182 (FrameLayout.LayoutParams) primaryIconView.getLayoutParams(); 183 FrameLayout.LayoutParams secondaryIconParams = 184 (FrameLayout.LayoutParams) secondaryIconView.getLayoutParams(); 185 186 primaryIconParams.gravity = (isRtl ? END : START) | TOP; 187 secondaryIconParams.gravity = (isRtl ? END : START) | TOP; 188 primaryIconView.setLayoutParams(primaryIconParams); 189 secondaryIconView.setLayoutParams(secondaryIconParams); 190 } 191 192 /* ---------- The following are only used by TaskViewTouchHandler. ---------- */ 193 194 @Override getUpDownSwipeDirection()195 public SingleAxisSwipeDetector.Direction getUpDownSwipeDirection() { 196 return HORIZONTAL; 197 } 198 199 @Override getUpDirection(boolean isRtl)200 public int getUpDirection(boolean isRtl) { 201 return isRtl ? SingleAxisSwipeDetector.DIRECTION_POSITIVE 202 : SingleAxisSwipeDetector.DIRECTION_NEGATIVE; 203 } 204 205 @Override isGoingUp(float displacement, boolean isRtl)206 public boolean isGoingUp(float displacement, boolean isRtl) { 207 return isRtl ? displacement > 0 : displacement < 0; 208 } 209 210 @Override getTaskDragDisplacementFactor(boolean isRtl)211 public int getTaskDragDisplacementFactor(boolean isRtl) { 212 return isRtl ? -1 : 1; 213 } 214 215 /* -------------------- */ 216 } 217