1 /*
2  * Copyright (C) 2026 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 package com.android.launcher3.celllayout;
17 
18 import static com.android.launcher3.LauncherSettings.Favorites.CONTAINER_DESKTOP;
19 
20 import com.android.launcher3.LauncherSettings.Favorites;
21 import com.android.launcher3.model.data.ItemInfo;
22 
23 import java.util.Objects;
24 
25 /**
26  * Class for mapping between model position and presenter position.
27  */
28 public class CellPosMapper {
29 
30     public static final CellPosMapper DEFAULT = new CellPosMapper(false, -1);
31     private final boolean mHasVerticalHotseat;
32     private final int mNumOfHotseat;
33 
CellPosMapper(boolean hasVerticalHotseat, int numOfHotseat)34     public CellPosMapper(boolean hasVerticalHotseat, int numOfHotseat) {
35         mHasVerticalHotseat = hasVerticalHotseat;
36         mNumOfHotseat = numOfHotseat;
37     }
38 
39     /**
40      * Maps the position in model to the position in view
41      */
mapModelToPresenter(ItemInfo info)42     public CellPos mapModelToPresenter(ItemInfo info) {
43         return new CellPos(info.cellX, info.cellY, info.screenId);
44     }
45 
46     /**
47      * Maps the position in view to the position in model
48      */
mapPresenterToModel(int presenterX, int presenterY, int presenterScreen, int container)49     public CellPos mapPresenterToModel(int presenterX, int presenterY, int presenterScreen,
50             int container) {
51         if (container == Favorites.CONTAINER_HOTSEAT) {
52             presenterScreen = mHasVerticalHotseat
53                     ? mNumOfHotseat - presenterY - 1 : presenterX;
54         }
55         return new CellPos(presenterX, presenterY, presenterScreen);
56     }
57 
58     /**
59      * Cell mapper which maps two panels into a single layout
60      */
61     public static class TwoPanelCellPosMapper extends CellPosMapper {
62 
63         private final int mColumnCount;
64 
TwoPanelCellPosMapper(int columnCount)65         public TwoPanelCellPosMapper(int columnCount) {
66             super(false, -1);
67             mColumnCount = columnCount;
68         }
69 
70         /**
71          * Maps the position in model to the position in view
72          */
mapModelToPresenter(ItemInfo info)73         public CellPos mapModelToPresenter(ItemInfo info) {
74             if (info.container != CONTAINER_DESKTOP || (info.screenId % 2) == 0) {
75                 return super.mapModelToPresenter(info);
76             }
77             return new CellPos(info.cellX + mColumnCount, info.cellY, info.screenId - 1);
78         }
79 
80         @Override
mapPresenterToModel(int presenterX, int presenterY, int presenterScreen, int container)81         public CellPos mapPresenterToModel(int presenterX, int presenterY, int presenterScreen,
82                 int container) {
83             if (container == CONTAINER_DESKTOP && (presenterScreen % 2) == 0
84                     && presenterX >= mColumnCount) {
85                 return new CellPos(presenterX - mColumnCount, presenterY, presenterScreen + 1);
86             }
87             return super.mapPresenterToModel(presenterX, presenterY, presenterScreen, container);
88         }
89     }
90 
91     /**
92      * Utility class to indicate the position of a cell
93      */
94     public static class CellPos {
95         public final int cellX;
96         public final int cellY;
97         public final int screenId;
98 
CellPos(int cellX, int cellY, int screenId)99         public CellPos(int cellX, int cellY, int screenId) {
100             this.cellX = cellX;
101             this.cellY = cellY;
102             this.screenId = screenId;
103         }
104 
105         @Override
equals(Object o)106         public boolean equals(Object o) {
107             if (this == o) return true;
108             if (!(o instanceof CellPos)) return false;
109             CellPos cellPos = (CellPos) o;
110             return cellX == cellPos.cellX && cellY == cellPos.cellY && screenId == cellPos.screenId;
111         }
112 
113         @Override
hashCode()114         public int hashCode() {
115             return Objects.hash(cellX, cellY, screenId);
116         }
117 
118         @Override
toString()119         public String toString() {
120             return "CellPos{"
121                     + "cellX=" + cellX
122                     + ", cellY=" + cellY
123                     + ", screenId=" + screenId + '}';
124         }
125     }
126 }
127