use of com.android.launcher3.userevent.nano.LauncherLogProto.Action.Direction in project android_packages_apps_Launcher3 by ArrowOS.
the class CellLayout method addViewsToTempLocation.
private boolean addViewsToTempLocation(ArrayList<View> views, Rect rectOccupiedByPotentialDrop, int[] direction, View dragView, ItemConfiguration currentState) {
if (views.size() == 0)
return true;
boolean success = false;
Rect boundingRect = new Rect();
// We construct a rect which represents the entire group of views passed in
currentState.getBoundingRectForViews(views, boundingRect);
// Mark the occupied state as false for the group of views we want to move.
for (View v : views) {
CellAndSpan c = currentState.map.get(v);
mTmpOccupied.markCells(c, false);
}
GridOccupancy blockOccupied = new GridOccupancy(boundingRect.width(), boundingRect.height());
int top = boundingRect.top;
int left = boundingRect.left;
// for interlocking.
for (View v : views) {
CellAndSpan c = currentState.map.get(v);
blockOccupied.markCells(c.cellX - left, c.cellY - top, c.spanX, c.spanY, true);
}
mTmpOccupied.markCells(rectOccupiedByPotentialDrop, true);
findNearestArea(boundingRect.left, boundingRect.top, boundingRect.width(), boundingRect.height(), direction, mTmpOccupied.cells, blockOccupied.cells, mTempLocation);
// If we successfuly found a location by pushing the block of views, we commit it
if (mTempLocation[0] >= 0 && mTempLocation[1] >= 0) {
int deltaX = mTempLocation[0] - boundingRect.left;
int deltaY = mTempLocation[1] - boundingRect.top;
for (View v : views) {
CellAndSpan c = currentState.map.get(v);
c.cellX += deltaX;
c.cellY += deltaY;
}
success = true;
}
// In either case, we set the occupied array as marked for the location of the views
for (View v : views) {
CellAndSpan c = currentState.map.get(v);
mTmpOccupied.markCells(c, true);
}
return success;
}
use of com.android.launcher3.userevent.nano.LauncherLogProto.Action.Direction in project android_packages_apps_Launcher3 by ArrowOS.
the class CellLayout method pushViewsToTempLocation.
private boolean pushViewsToTempLocation(ArrayList<View> views, Rect rectOccupiedByPotentialDrop, int[] direction, View dragView, ItemConfiguration currentState) {
ViewCluster cluster = new ViewCluster(views, currentState);
Rect clusterRect = cluster.getBoundingRect();
int whichEdge;
int pushDistance;
boolean fail = false;
// the cluster must be shifted.
if (direction[0] < 0) {
whichEdge = ViewCluster.LEFT;
pushDistance = clusterRect.right - rectOccupiedByPotentialDrop.left;
} else if (direction[0] > 0) {
whichEdge = ViewCluster.RIGHT;
pushDistance = rectOccupiedByPotentialDrop.right - clusterRect.left;
} else if (direction[1] < 0) {
whichEdge = ViewCluster.TOP;
pushDistance = clusterRect.bottom - rectOccupiedByPotentialDrop.top;
} else {
whichEdge = ViewCluster.BOTTOM;
pushDistance = rectOccupiedByPotentialDrop.bottom - clusterRect.top;
}
// Break early for invalid push distance.
if (pushDistance <= 0) {
return false;
}
// Mark the occupied state as false for the group of views we want to move.
for (View v : views) {
CellAndSpan c = currentState.map.get(v);
mTmpOccupied.markCells(c, false);
}
// We save the current configuration -- if we fail to find a solution we will revert
// to the initial state. The process of finding a solution modifies the configuration
// in place, hence the need for revert in the failure case.
currentState.save();
// The pushing algorithm is simplified by considering the views in the order in which
// they would be pushed by the cluster. For example, if the cluster is leading with its
// left edge, we consider sort the views by their right edge, from right to left.
cluster.sortConfigurationForEdgePush(whichEdge);
while (pushDistance > 0 && !fail) {
for (View v : currentState.sortedViews) {
// cluster.
if (!cluster.views.contains(v) && v != dragView) {
if (cluster.isViewTouchingEdge(v, whichEdge)) {
LayoutParams lp = (LayoutParams) v.getLayoutParams();
if (!lp.canReorder) {
// The push solution includes the all apps button, this is not viable.
fail = true;
break;
}
cluster.addView(v);
CellAndSpan c = currentState.map.get(v);
// Adding view to cluster, mark it as not occupied.
mTmpOccupied.markCells(c, false);
}
}
}
pushDistance--;
// The cluster has been completed, now we move the whole thing over in the appropriate
// direction.
cluster.shift(whichEdge, 1);
}
boolean foundSolution = false;
clusterRect = cluster.getBoundingRect();
// is to ensure that completed shifted cluster lies completely within the cell layout.
if (!fail && clusterRect.left >= 0 && clusterRect.right <= mCountX && clusterRect.top >= 0 && clusterRect.bottom <= mCountY) {
foundSolution = true;
} else {
currentState.restore();
}
// In either case, we set the occupied array as marked for the location of the views
for (View v : cluster.views) {
CellAndSpan c = currentState.map.get(v);
mTmpOccupied.markCells(c, true);
}
return foundSolution;
}
use of com.android.launcher3.userevent.nano.LauncherLogProto.Action.Direction in project android_packages_apps_Launcher3 by ProtonAOSP.
the class CellLayout method pushViewsToTempLocation.
private boolean pushViewsToTempLocation(ArrayList<View> views, Rect rectOccupiedByPotentialDrop, int[] direction, View dragView, ItemConfiguration currentState) {
ViewCluster cluster = new ViewCluster(views, currentState);
Rect clusterRect = cluster.getBoundingRect();
int whichEdge;
int pushDistance;
boolean fail = false;
// the cluster must be shifted.
if (direction[0] < 0) {
whichEdge = ViewCluster.LEFT;
pushDistance = clusterRect.right - rectOccupiedByPotentialDrop.left;
} else if (direction[0] > 0) {
whichEdge = ViewCluster.RIGHT;
pushDistance = rectOccupiedByPotentialDrop.right - clusterRect.left;
} else if (direction[1] < 0) {
whichEdge = ViewCluster.TOP;
pushDistance = clusterRect.bottom - rectOccupiedByPotentialDrop.top;
} else {
whichEdge = ViewCluster.BOTTOM;
pushDistance = rectOccupiedByPotentialDrop.bottom - clusterRect.top;
}
// Break early for invalid push distance.
if (pushDistance <= 0) {
return false;
}
// Mark the occupied state as false for the group of views we want to move.
for (View v : views) {
CellAndSpan c = currentState.map.get(v);
mTmpOccupied.markCells(c, false);
}
// We save the current configuration -- if we fail to find a solution we will revert
// to the initial state. The process of finding a solution modifies the configuration
// in place, hence the need for revert in the failure case.
currentState.save();
// The pushing algorithm is simplified by considering the views in the order in which
// they would be pushed by the cluster. For example, if the cluster is leading with its
// left edge, we consider sort the views by their right edge, from right to left.
cluster.sortConfigurationForEdgePush(whichEdge);
while (pushDistance > 0 && !fail) {
for (View v : currentState.sortedViews) {
// cluster.
if (!cluster.views.contains(v) && v != dragView) {
if (cluster.isViewTouchingEdge(v, whichEdge)) {
LayoutParams lp = (LayoutParams) v.getLayoutParams();
if (!lp.canReorder) {
// The push solution includes the all apps button, this is not viable.
fail = true;
break;
}
cluster.addView(v);
CellAndSpan c = currentState.map.get(v);
// Adding view to cluster, mark it as not occupied.
mTmpOccupied.markCells(c, false);
}
}
}
pushDistance--;
// The cluster has been completed, now we move the whole thing over in the appropriate
// direction.
cluster.shift(whichEdge, 1);
}
boolean foundSolution = false;
clusterRect = cluster.getBoundingRect();
// is to ensure that completed shifted cluster lies completely within the cell layout.
if (!fail && clusterRect.left >= 0 && clusterRect.right <= mCountX && clusterRect.top >= 0 && clusterRect.bottom <= mCountY) {
foundSolution = true;
} else {
currentState.restore();
}
// In either case, we set the occupied array as marked for the location of the views
for (View v : cluster.views) {
CellAndSpan c = currentState.map.get(v);
mTmpOccupied.markCells(c, true);
}
return foundSolution;
}
use of com.android.launcher3.userevent.nano.LauncherLogProto.Action.Direction in project android_packages_apps_Launcher3 by ProtonAOSP.
the class RecentsView method getSplitSelectTranslation.
/**
* Returns how much additional translation there should be for each of the child TaskViews.
* Note that the translation can be its primary or secondary dimension.
*/
public float getSplitSelectTranslation() {
int splitPosition = getSplitPlaceholder().getActiveSplitStagePosition();
if (!shouldShiftThumbnailsForSplitSelect()) {
return 0f;
}
PagedOrientationHandler orientationHandler = getPagedOrientationHandler();
int direction = orientationHandler.getSplitTranslationDirectionFactor(splitPosition, mActivity.getDeviceProfile());
return mActivity.getResources().getDimension(R.dimen.split_placeholder_size) * direction;
}
use of com.android.launcher3.userevent.nano.LauncherLogProto.Action.Direction in project android_packages_apps_Launcher3 by ProtonAOSP.
the class KeyboardDragAndDropView method getNextSelection.
/**
* Focus finding logic:
* Collect all virtual nodes in reading order (used for forward and backwards).
* Then find the closest view by comparing the distances spatially. Since it is a move
* operation. consider all cell sizes to be approximately of the same size.
*/
private VirtualNodeInfo getNextSelection(int direction) {
// Collect all virtual nodes
mDelegates.clear();
mNodes.clear();
Folder openFolder = Folder.getOpen(mLauncher);
PagedView pv = openFolder == null ? mLauncher.getWorkspace() : openFolder.getContent();
int count = pv.getPageCount();
for (int i = 0; i < count; i++) {
mDelegates.add(((CellLayout) pv.getChildAt(i)).getDragAndDropAccessibilityDelegate());
}
if (openFolder == null) {
mDelegates.add(pv.getNextPage() + 1, mLauncher.getHotseat().getDragAndDropAccessibilityDelegate());
}
mDelegates.forEach(delegate -> {
mIntList.clear();
delegate.getVisibleVirtualViews(mIntList);
mIntList.forEach(id -> mNodes.add(new VirtualNodeInfo(delegate, id)));
});
if (mNodes.isEmpty()) {
return null;
}
int index = mNodes.indexOf(mCurrentSelection);
if (mCurrentSelection == null || index < 0) {
return null;
}
int totalNodes = mNodes.size();
final ToIntBiFunction<Rect, Rect> majorAxis;
final ToIntFunction<Rect> minorAxis;
switch(direction) {
case View.FOCUS_RIGHT:
majorAxis = (source, dest) -> dest.left - source.left;
minorAxis = Rect::centerY;
break;
case View.FOCUS_LEFT:
majorAxis = (source, dest) -> source.left - dest.left;
minorAxis = Rect::centerY;
break;
case View.FOCUS_UP:
majorAxis = (source, dest) -> source.top - dest.top;
minorAxis = Rect::centerX;
break;
case View.FOCUS_DOWN:
majorAxis = (source, dest) -> dest.top - source.top;
minorAxis = Rect::centerX;
break;
case View.FOCUS_FORWARD:
return mNodes.get((index + 1) % totalNodes);
case View.FOCUS_BACKWARD:
return mNodes.get((index + totalNodes - 1) % totalNodes);
default:
// Unknown direction
return null;
}
mCurrentSelection.populate(mTempNodeInfo).getBoundsInScreen(mTempRect);
float minWeight = Float.MAX_VALUE;
VirtualNodeInfo match = null;
for (int i = 0; i < totalNodes; i++) {
VirtualNodeInfo node = mNodes.get(i);
node.populate(mTempNodeInfo).getBoundsInScreen(mTempRect2);
int majorAxisWeight = majorAxis.applyAsInt(mTempRect, mTempRect2);
if (majorAxisWeight <= 0) {
continue;
}
int minorAxisWeight = minorAxis.applyAsInt(mTempRect2) - minorAxis.applyAsInt(mTempRect);
float weight = majorAxisWeight * majorAxisWeight + minorAxisWeight * minorAxisWeight * MINOR_AXIS_WEIGHT;
if (weight < minWeight) {
minWeight = weight;
match = node;
}
}
return match;
}
Aggregations