mirror of
https://github.com/LawnchairLauncher/lawnchair.git
synced 2026-02-28 15:56:49 +00:00
Merge "Animate grid tasks to modal state." into tm-qpr-dev
This commit is contained in:
@@ -18,12 +18,12 @@ package com.android.launcher3.uioverrides.states;
|
||||
import static com.android.launcher3.logging.StatsLogManager.LAUNCHER_STATE_OVERVIEW;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.Point;
|
||||
import android.graphics.Rect;
|
||||
|
||||
import com.android.launcher3.BaseDraggingActivity;
|
||||
import com.android.launcher3.Launcher;
|
||||
import com.android.launcher3.LauncherState;
|
||||
import com.android.launcher3.config.FeatureFlags;
|
||||
import com.android.quickstep.views.RecentsView;
|
||||
|
||||
/**
|
||||
@@ -70,13 +70,22 @@ public class OverviewModalTaskState extends OverviewState {
|
||||
}
|
||||
}
|
||||
|
||||
public static float[] getOverviewScaleAndOffsetForModalState(BaseDraggingActivity activity) {
|
||||
Point taskSize = activity.<RecentsView>getOverviewPanel().getSelectedTaskSize();
|
||||
Rect modalTaskSize = new Rect();
|
||||
activity.<RecentsView>getOverviewPanel().getModalTaskSize(modalTaskSize);
|
||||
@Override
|
||||
public boolean isTaskbarStashed(Launcher launcher) {
|
||||
if (FeatureFlags.ENABLE_GRID_ONLY_OVERVIEW.get()) {
|
||||
return true;
|
||||
}
|
||||
return super.isTaskbarStashed(launcher);
|
||||
}
|
||||
|
||||
float scale = Math.min((float) modalTaskSize.height() / taskSize.y,
|
||||
(float) modalTaskSize.width() / taskSize.x);
|
||||
public static float[] getOverviewScaleAndOffsetForModalState(BaseDraggingActivity activity) {
|
||||
RecentsView recentsView = activity.<RecentsView>getOverviewPanel();
|
||||
Rect taskSize = recentsView.getSelectedTaskBounds();
|
||||
Rect modalTaskSize = new Rect();
|
||||
recentsView.getModalTaskSize(modalTaskSize);
|
||||
|
||||
float scale = Math.min((float) modalTaskSize.height() / taskSize.height(),
|
||||
(float) modalTaskSize.width() / taskSize.width());
|
||||
|
||||
return new float[] {scale, NO_OFFSET};
|
||||
}
|
||||
|
||||
@@ -52,6 +52,7 @@ import com.android.launcher3.DeviceProfile;
|
||||
import com.android.launcher3.R;
|
||||
import com.android.launcher3.anim.AnimatorPlaybackController;
|
||||
import com.android.launcher3.anim.PendingAnimation;
|
||||
import com.android.launcher3.config.FeatureFlags;
|
||||
import com.android.launcher3.statehandlers.DepthController;
|
||||
import com.android.launcher3.statehandlers.DesktopVisibilityController;
|
||||
import com.android.launcher3.statemanager.BaseState;
|
||||
@@ -339,12 +340,21 @@ public abstract class BaseActivityInterface<STATE_TYPE extends BaseState<STATE_T
|
||||
*/
|
||||
public final void calculateModalTaskSize(Context context, DeviceProfile dp, Rect outRect) {
|
||||
calculateTaskSize(context, dp, outRect);
|
||||
float maxScale = context.getResources().getFloat(R.dimen.overview_modal_max_scale);
|
||||
boolean isGridOnlyOverview = dp.isTablet && FeatureFlags.ENABLE_GRID_ONLY_OVERVIEW.get();
|
||||
int claimedSpaceBelow = isGridOnlyOverview
|
||||
? dp.overviewActionsTopMarginPx + dp.overviewActionsHeight + dp.stashedTaskbarSize
|
||||
: (dp.heightPx - outRect.bottom - dp.getInsets().bottom);
|
||||
int minimumHorizontalPadding = 0;
|
||||
if (!isGridOnlyOverview) {
|
||||
float maxScale = context.getResources().getFloat(R.dimen.overview_modal_max_scale);
|
||||
minimumHorizontalPadding =
|
||||
Math.round((dp.availableWidthPx - outRect.width() * maxScale) / 2);
|
||||
}
|
||||
calculateTaskSizeInternal(
|
||||
context, dp,
|
||||
dp.overviewTaskMarginPx,
|
||||
dp.heightPx - outRect.bottom - dp.getInsets().bottom,
|
||||
Math.round((dp.availableWidthPx - outRect.width() * maxScale) / 2),
|
||||
claimedSpaceBelow,
|
||||
minimumHorizontalPadding,
|
||||
1f /*maxScale*/,
|
||||
Gravity.CENTER_HORIZONTAL | Gravity.BOTTOM,
|
||||
outRect);
|
||||
|
||||
@@ -80,9 +80,9 @@ public class TaskOverlayFactory implements ResourceBasedOverride {
|
||||
boolean isInLandscape = orientedState.getTouchRotation() != ROTATION_0;
|
||||
boolean isTablet = activity.getDeviceProfile().isTablet;
|
||||
|
||||
boolean isGridOnlyOverview = isTablet && FeatureFlags.ENABLE_GRID_ONLY_OVERVIEW.get();
|
||||
// Add overview actions to the menu when in in-place rotate landscape mode.
|
||||
if ((!canLauncherRotate && isInLandscape)
|
||||
|| (isTablet && FeatureFlags.ENABLE_GRID_ONLY_OVERVIEW.get())) {
|
||||
if ((!canLauncherRotate && isInLandscape) || isGridOnlyOverview) {
|
||||
// Add screenshot action to task menu.
|
||||
List<SystemShortcut> screenshotShortcuts = TaskShortcutFactory.SCREENSHOT
|
||||
.getShortcuts(activity, taskContainer);
|
||||
|
||||
@@ -15,6 +15,8 @@
|
||||
*/
|
||||
package com.android.quickstep.fallback;
|
||||
|
||||
import static android.app.ActivityTaskManager.INVALID_TASK_ID;
|
||||
|
||||
import static com.android.quickstep.GestureState.GestureEndTarget.RECENTS;
|
||||
import static com.android.quickstep.fallback.RecentsState.DEFAULT;
|
||||
import static com.android.quickstep.fallback.RecentsState.HOME;
|
||||
@@ -200,8 +202,9 @@ public class FallbackRecentsView extends RecentsView<RecentsActivity, RecentsSta
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setModalStateEnabled(boolean isModalState, boolean animate) {
|
||||
if (isModalState) {
|
||||
public void setModalStateEnabled(int taskId, boolean animate) {
|
||||
if (taskId != INVALID_TASK_ID) {
|
||||
setSelectedTask(taskId);
|
||||
mActivity.getStateManager().goToState(RecentsState.MODAL_TASK, animate);
|
||||
} else {
|
||||
if (mActivity.isInState(RecentsState.MODAL_TASK)) {
|
||||
|
||||
@@ -15,6 +15,8 @@
|
||||
*/
|
||||
package com.android.quickstep.views;
|
||||
|
||||
import static android.app.ActivityTaskManager.INVALID_TASK_ID;
|
||||
|
||||
import static com.android.launcher3.LauncherState.CLEAR_ALL_BUTTON;
|
||||
import static com.android.launcher3.LauncherState.NORMAL;
|
||||
import static com.android.launcher3.LauncherState.OVERVIEW;
|
||||
@@ -171,8 +173,9 @@ public class LauncherRecentsView extends RecentsView<QuickstepLauncher, Launcher
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setModalStateEnabled(boolean isModalState, boolean animate) {
|
||||
if (isModalState) {
|
||||
public void setModalStateEnabled(int taskId, boolean animate) {
|
||||
if (taskId != INVALID_TASK_ID) {
|
||||
setSelectedTask(taskId);
|
||||
mActivity.getStateManager().goToState(LauncherState.OVERVIEW_MODAL_TASK, animate);
|
||||
} else {
|
||||
if (mActivity.isInState(LauncherState.OVERVIEW_MODAL_TASK)) {
|
||||
|
||||
@@ -303,6 +303,10 @@ public class OverviewActionsView<T extends OverlayUICallbacks> extends FrameLayo
|
||||
return mDp.getOverviewActionsClaimedSpaceBelow();
|
||||
}
|
||||
|
||||
if (mDp.isTablet && FeatureFlags.ENABLE_GRID_ONLY_OVERVIEW.get()) {
|
||||
return mDp.stashedTaskbarSize;
|
||||
}
|
||||
|
||||
// Align to bottom of task Rect.
|
||||
return mDp.heightPx - mTaskSize.bottom - mDp.overviewActionsTopMarginPx
|
||||
- mDp.overviewActionsHeight;
|
||||
|
||||
@@ -453,6 +453,7 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
|
||||
protected final Rect mLastComputedTaskSize = new Rect();
|
||||
protected final Rect mLastComputedGridSize = new Rect();
|
||||
protected final Rect mLastComputedGridTaskSize = new Rect();
|
||||
private TaskView mSelectedTask = null;
|
||||
// How much a task that is directly offscreen will be pushed out due to RecentsView scale/pivot.
|
||||
@Nullable
|
||||
protected Float mLastComputedTaskStartPushOutDistance = null;
|
||||
@@ -1084,6 +1085,16 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
|
||||
super.draw(canvas);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean requestChildRectangleOnScreen(View child, Rect rectangle, boolean immediate) {
|
||||
if (isModal()) {
|
||||
// Do not scroll when clicking on a modal grid task, as it will already be centered
|
||||
// on screen.
|
||||
return false;
|
||||
}
|
||||
return super.requestChildRectangleOnScreen(child, rectangle, immediate);
|
||||
}
|
||||
|
||||
public void addSideTaskLaunchCallback(RunnableList callback) {
|
||||
if (mSideTaskLaunchCallback == null) {
|
||||
mSideTaskLaunchCallback = new RunnableList();
|
||||
@@ -1272,7 +1283,7 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
|
||||
*/
|
||||
@Nullable
|
||||
public TaskView getTaskViewByTaskId(int taskId) {
|
||||
if (taskId == -1) {
|
||||
if (taskId == INVALID_TASK_ID) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -1920,7 +1931,7 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
|
||||
private void onOrientationChanged() {
|
||||
// If overview is in modal state when rotate, reset it to overview state without running
|
||||
// animation.
|
||||
setModalStateEnabled(/* isModalState= */ false, /* animate= */ false);
|
||||
setModalStateEnabled(/* taskId= */ INVALID_TASK_ID, /* animate= */ false);
|
||||
if (isSplitSelectionActive()) {
|
||||
onRotateInSplitSelectionState();
|
||||
}
|
||||
@@ -1993,12 +2004,33 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the size of task selected to enter modal state.
|
||||
* Sets the last TaskView selected.
|
||||
*/
|
||||
public Point getSelectedTaskSize() {
|
||||
mSizeStrategy.calculateTaskSize(mActivity, mActivity.getDeviceProfile(),
|
||||
mTempRect);
|
||||
return new Point(mTempRect.width(), mTempRect.height());
|
||||
public void setSelectedTask(int lastSelectedTaskId) {
|
||||
mSelectedTask = getTaskViewByTaskId(lastSelectedTaskId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the bounds of the task selected to enter modal state.
|
||||
*/
|
||||
public Rect getSelectedTaskBounds() {
|
||||
if (mSelectedTask == null) {
|
||||
return mLastComputedTaskSize;
|
||||
}
|
||||
return getTaskBounds(mSelectedTask);
|
||||
}
|
||||
|
||||
private Rect getTaskBounds(TaskView taskView) {
|
||||
int selectedPage = indexOfChild(taskView);
|
||||
int primaryScroll = mOrientationHandler.getPrimaryScroll(this);
|
||||
int selectedPageScroll = getScrollForPage(selectedPage);
|
||||
boolean isTopRow = taskView != null && mTopRowIdSet.contains(taskView.getTaskViewId());
|
||||
Rect outRect = new Rect(mLastComputedTaskSize);
|
||||
outRect.offset(
|
||||
-(primaryScroll - (selectedPageScroll + getOffsetFromScrollPosition(selectedPage))),
|
||||
(int) (showAsGrid() && ENABLE_GRID_ONLY_OVERVIEW.get() && !isTopRow
|
||||
? mTopBottomRowHeightDiff : 0));
|
||||
return outRect;
|
||||
}
|
||||
|
||||
/** Gets the last computed task size */
|
||||
@@ -4122,8 +4154,13 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
|
||||
|
||||
private void updatePivots() {
|
||||
if (mOverviewSelectEnabled) {
|
||||
setPivotX(mLastComputedTaskSize.centerX());
|
||||
setPivotY(mLastComputedTaskSize.bottom);
|
||||
getModalTaskSize(mTempRect);
|
||||
Rect selectedTaskPosition = getSelectedTaskBounds();
|
||||
|
||||
Utilities.getPivotsForScalingRectToRect(mTempRect, selectedTaskPosition,
|
||||
mTempPointF);
|
||||
setPivotX(mTempPointF.x);
|
||||
setPivotY(mTempPointF.y);
|
||||
} else {
|
||||
getPagedViewOrientedState().getFullScreenScaleAndPivot(mTempRect,
|
||||
mActivity.getDeviceProfile(), mTempPointF);
|
||||
@@ -4136,11 +4173,17 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
|
||||
float offset = mAdjacentPageHorizontalOffset;
|
||||
float modalOffset = ACCEL_0_75.getInterpolation(mTaskModalness);
|
||||
int count = getChildCount();
|
||||
boolean showAsGrid = showAsGrid();
|
||||
|
||||
TaskView runningTask = mRunningTaskViewId == -1 || !mRunningTaskTileHidden
|
||||
? null : getRunningTaskView();
|
||||
int midpoint = runningTask == null ? -1 : indexOfChild(runningTask);
|
||||
int modalMidpoint = getCurrentPage();
|
||||
boolean isModalGridWithoutFocusedTask =
|
||||
showAsGrid && ENABLE_GRID_ONLY_OVERVIEW.get() && mTaskModalness > 0;
|
||||
if (isModalGridWithoutFocusedTask) {
|
||||
modalMidpoint = indexOfChild(mSelectedTask);
|
||||
}
|
||||
|
||||
float midpointOffsetSize = 0;
|
||||
float leftOffsetSize = midpoint - 1 >= 0
|
||||
@@ -4150,7 +4193,6 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
|
||||
? getHorizontalOffsetSize(midpoint + 1, midpoint, offset)
|
||||
: 0;
|
||||
|
||||
boolean showAsGrid = showAsGrid();
|
||||
float modalMidpointOffsetSize = 0;
|
||||
float modalLeftOffsetSize = 0;
|
||||
float modalRightOffsetSize = 0;
|
||||
@@ -4178,23 +4220,34 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
|
||||
: i < midpoint
|
||||
? leftOffsetSize
|
||||
: rightOffsetSize;
|
||||
if (isModalGridWithoutFocusedTask) {
|
||||
gridOffsetSize = getHorizontalOffsetSize(i, modalMidpoint, modalOffset);
|
||||
gridOffsetSize = Math.abs(gridOffsetSize) * (i <= modalMidpoint ? 1 : -1);
|
||||
}
|
||||
float modalTranslation = i == modalMidpoint
|
||||
? modalMidpointOffsetSize
|
||||
: showAsGrid
|
||||
? gridOffsetSize
|
||||
: i < modalMidpoint ? modalLeftOffsetSize : modalRightOffsetSize;
|
||||
float totalTranslation = translation + modalTranslation;
|
||||
float totalTranslationX = translation + modalTranslation;
|
||||
View child = getChildAt(i);
|
||||
FloatProperty translationProperty = child instanceof TaskView
|
||||
FloatProperty translationPropertyX = child instanceof TaskView
|
||||
? ((TaskView) child).getPrimaryTaskOffsetTranslationProperty()
|
||||
: mOrientationHandler.getPrimaryViewTranslate();
|
||||
translationProperty.set(child, totalTranslation);
|
||||
translationPropertyX.set(child, totalTranslationX);
|
||||
if (mEnableDrawingLiveTile && i == getRunningTaskIndex()) {
|
||||
runActionOnRemoteHandles(
|
||||
remoteTargetHandle -> remoteTargetHandle.getTaskViewSimulator()
|
||||
.taskPrimaryTranslation.value = totalTranslation);
|
||||
.taskPrimaryTranslation.value = totalTranslationX);
|
||||
redrawLiveTile();
|
||||
}
|
||||
|
||||
if (showAsGrid && ENABLE_GRID_ONLY_OVERVIEW.get() && child instanceof TaskView) {
|
||||
float totalTranslationY = getVerticalOffsetSize(i, modalOffset);
|
||||
FloatProperty translationPropertyY =
|
||||
((TaskView) child).getSecondaryTaskOffsetTranslationProperty();
|
||||
translationPropertyY.set(child, totalTranslationY);
|
||||
}
|
||||
}
|
||||
updateCurveProperties();
|
||||
}
|
||||
@@ -4292,6 +4345,38 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
|
||||
return distanceToOffscreen * offsetProgress;
|
||||
}
|
||||
|
||||
/**
|
||||
* Computes the vertical distance to offset a given child such that it is completely offscreen.
|
||||
*
|
||||
* @param offsetProgress From 0 to 1 where 0 means no offset and 1 means offset offscreen.
|
||||
*/
|
||||
private float getVerticalOffsetSize(int childIndex, float offsetProgress) {
|
||||
if (offsetProgress == 0 || !(showAsGrid() && ENABLE_GRID_ONLY_OVERVIEW.get())
|
||||
|| mSelectedTask == null) {
|
||||
// Don't bother calculating everything below if we won't offset vertically.
|
||||
return 0;
|
||||
}
|
||||
|
||||
// First, get the position of the task relative to the top row.
|
||||
TaskView child = getTaskViewAt(childIndex);
|
||||
Rect taskPosition = getTaskBounds(child);
|
||||
|
||||
boolean isSelectedTaskTopRow = mTopRowIdSet.contains(mSelectedTask.getTaskViewId());
|
||||
boolean isChildTopRow = mTopRowIdSet.contains(child.getTaskViewId());
|
||||
// Whether the task should be shifted to the top.
|
||||
boolean isTopShift = !isSelectedTaskTopRow && isChildTopRow;
|
||||
boolean isBottomShift = isSelectedTaskTopRow && !isChildTopRow;
|
||||
|
||||
// Next, calculate the distance to move the task off screen at scale = 1.
|
||||
float distanceToOffscreen = 0;
|
||||
if (isTopShift) {
|
||||
distanceToOffscreen = -taskPosition.bottom;
|
||||
} else if (isBottomShift) {
|
||||
distanceToOffscreen = mActivity.getDeviceProfile().heightPx - taskPosition.top;
|
||||
}
|
||||
return distanceToOffscreen * offsetProgress;
|
||||
}
|
||||
|
||||
protected void setTaskViewsResistanceTranslation(float translation) {
|
||||
mTaskViewsSecondaryTranslation = translation;
|
||||
for (int i = 0; i < getTaskViewCount(); i++) {
|
||||
@@ -4391,9 +4476,8 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
|
||||
* Resets the visuals when exit modal state.
|
||||
*/
|
||||
public void resetModalVisuals() {
|
||||
TaskView taskView = getCurrentPageTaskView();
|
||||
if (taskView != null) {
|
||||
taskView.getThumbnail().getTaskOverlay().resetModalVisuals();
|
||||
if (mSelectedTask != null) {
|
||||
mSelectedTask.getThumbnail().getTaskOverlay().resetModalVisuals();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5395,6 +5479,9 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
|
||||
if (mOverviewSelectEnabled != overviewSelectEnabled) {
|
||||
mOverviewSelectEnabled = overviewSelectEnabled;
|
||||
updatePivots();
|
||||
if (!mOverviewSelectEnabled) {
|
||||
setSelectedTask(INVALID_TASK_ID);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5465,7 +5552,9 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
|
||||
private void setTaskModalness(float modalness) {
|
||||
mTaskModalness = modalness;
|
||||
updatePageOffsets();
|
||||
if (getCurrentPageTaskView() != null) {
|
||||
if (mSelectedTask != null) {
|
||||
mSelectedTask.setModalness(modalness);
|
||||
} else if (getCurrentPageTaskView() != null) {
|
||||
getCurrentPageTaskView().setModalness(modalness);
|
||||
}
|
||||
// Only show actions view when it's modal for in-place landscape mode.
|
||||
@@ -5480,7 +5569,7 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
|
||||
}
|
||||
|
||||
/** Enables or disables modal state for RecentsView */
|
||||
public abstract void setModalStateEnabled(boolean isModalState, boolean animate);
|
||||
public abstract void setModalStateEnabled(int taskId, boolean animate);
|
||||
|
||||
public TaskOverlayFactory getTaskOverlayFactory() {
|
||||
return mTaskOverlayFactory;
|
||||
|
||||
@@ -1445,6 +1445,11 @@ public class TaskView extends FrameLayout implements Reusable {
|
||||
TASK_OFFSET_TRANSLATION_X, TASK_OFFSET_TRANSLATION_Y);
|
||||
}
|
||||
|
||||
public FloatProperty<TaskView> getSecondaryTaskOffsetTranslationProperty() {
|
||||
return getPagedOrientationHandler().getSecondaryValue(
|
||||
TASK_OFFSET_TRANSLATION_X, TASK_OFFSET_TRANSLATION_Y);
|
||||
}
|
||||
|
||||
public FloatProperty<TaskView> getTaskResistanceTranslationProperty() {
|
||||
return getPagedOrientationHandler().getSecondaryValue(
|
||||
TASK_RESISTANCE_TRANSLATION_X, TASK_RESISTANCE_TRANSLATION_Y);
|
||||
|
||||
@@ -38,6 +38,7 @@ import android.graphics.LightingColorFilter;
|
||||
import android.graphics.Matrix;
|
||||
import android.graphics.Paint;
|
||||
import android.graphics.Point;
|
||||
import android.graphics.PointF;
|
||||
import android.graphics.Rect;
|
||||
import android.graphics.RectF;
|
||||
import android.graphics.drawable.AdaptiveIconDrawable;
|
||||
@@ -342,6 +343,21 @@ public final class Utilities {
|
||||
return scale;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the x and y pivots for scaling from one Rect to another.
|
||||
*
|
||||
* @param src the source rectangle to scale from.
|
||||
* @param dst the destination rectangle to scale to.
|
||||
* @param outPivot the pivots set for scaling from src to dst.
|
||||
*/
|
||||
public static void getPivotsForScalingRectToRect(Rect src, Rect dst, PointF outPivot) {
|
||||
float pivotXPct = ((float) src.left - dst.left) / ((float) dst.width() - src.width());
|
||||
outPivot.x = dst.left + dst.width() * pivotXPct;
|
||||
|
||||
float pivotYPct = ((float) src.top - dst.top) / ((float) dst.height() - src.height());
|
||||
outPivot.y = dst.top + dst.height() * pivotYPct;
|
||||
}
|
||||
|
||||
/**
|
||||
* Maps t from one range to another range.
|
||||
* @param t The value to map.
|
||||
|
||||
Reference in New Issue
Block a user