/* * Copyright (C) 2010 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.launcher2; import android.content.Context; import android.view.Display; import android.view.Surface; import android.view.WindowManager; public class LauncherModelOrientationHelper { static final String TAG = "LauncherModelOrientationHelper"; public class Coordinates { public Coordinates(int newX, int newY) { x = newX; y = newY; } public int x; public int y; } private int mOrientation; private int mLocalDeviceWidth; private int mLocalDeviceHeight; private int mPreviousOrientation; private int mPreviousLocalDeviceWidth; private int mPreviousLocalDeviceHeight; private int mCanonicalDeviceWidth; private int mCanonicalDeviceHeight; protected LauncherModelOrientationHelper(Context ctx) { updateOrientation(ctx); } public int getCurrentOrientation() { return mOrientation; } public int getPreviousOrientationRelativeToCurrent() { int orientationDifference = -(mOrientation - mPreviousOrientation); if (Math.abs(orientationDifference) > 180) { orientationDifference = (int) -Math.signum(orientationDifference) * (360 - Math.abs(orientationDifference)); } return orientationDifference; } private void updateLocalDeviceDimensions() { mPreviousLocalDeviceHeight = mLocalDeviceHeight; mPreviousLocalDeviceWidth = mLocalDeviceWidth; if (mOrientation % 180 != 0) { mLocalDeviceWidth = mCanonicalDeviceHeight; mLocalDeviceHeight = mCanonicalDeviceWidth; } else { mLocalDeviceWidth = mCanonicalDeviceWidth; mLocalDeviceHeight = mCanonicalDeviceHeight; } } public void updateOrientation(Context ctx) { Display display = ((WindowManager) ctx .getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay(); mPreviousOrientation = mOrientation; switch (display.getRotation()) { case Surface.ROTATION_0: mOrientation = 0; break; case Surface.ROTATION_90: mOrientation = 90; break; case Surface.ROTATION_180: mOrientation = 180; break; case Surface.ROTATION_270: mOrientation = 270; break; } updateLocalDeviceDimensions(); } public void updateDeviceDimensions(int deviceWidth, int deviceHeight) { mCanonicalDeviceWidth = deviceWidth; mCanonicalDeviceHeight = deviceHeight; updateLocalDeviceDimensions(); } public Coordinates getLocalCoordinatesFromPreviousLocalCoordinates( int cellX, int cellY, int spanX, int spanY) { return getTransformedLayoutParams(cellX, cellY, spanX, spanY, getPreviousOrientationRelativeToCurrent(), mPreviousLocalDeviceWidth, mPreviousLocalDeviceHeight); } public Coordinates getCanonicalCoordinates(ItemInfo localItem) { return getTransformedLayoutParams(localItem.cellX, localItem.cellY, localItem.spanX, localItem.spanY, mOrientation, mLocalDeviceWidth, mLocalDeviceHeight); } public Coordinates getCanonicalCoordinates(int cellX, int cellY, int spanX, int spanY) { return getTransformedLayoutParams(cellX, cellY, spanX, spanY, mOrientation, mLocalDeviceWidth, mLocalDeviceHeight); } public Coordinates getLocalCoordinates(int cellX, int cellY, int spanX, int spanY) { return getTransformedLayoutParams(cellX, cellY, spanX, spanY, -mOrientation, mCanonicalDeviceWidth, mCanonicalDeviceHeight); } public int getLocalDeviceWidth() { return mLocalDeviceWidth; } public int getLocalDeviceHeight() { return mLocalDeviceHeight; } /** * Transform the coordinates based on the current device rotation */ private Coordinates getTransformedLayoutParams(int cellX, int cellY, int spanX, int spanY, int deviceRotationClockwise, int initialDeviceWidth, int initialDeviceHeight) { if (LauncherApplication.isScreenXLarge()) { int x = cellX; int y = cellY; int width = spanX; int height = spanY; int finalDeviceWidth = initialDeviceWidth; int finalDeviceHeight = initialDeviceHeight; // item rotation is opposite of device rotation to maintain an // absolute // spatial layout double phi = Math.toRadians(-deviceRotationClockwise); double x1 = x + width / 2.0f - initialDeviceWidth / 2.0f; double y1 = y + height / 2.0f - initialDeviceHeight / 2.0f; // multiply x and y by a clockwise rotation matrix double x2 = x1 * Math.cos(phi) + y1 * Math.sin(phi); double y2 = -x1 * Math.sin(phi) + y1 * Math.cos(phi); // Get the rotated device dimensions if (deviceRotationClockwise % 180 != 0) { finalDeviceWidth = initialDeviceHeight; finalDeviceHeight = initialDeviceWidth; } x2 = x2 + finalDeviceWidth / 2.0f - width / 2.0f; y2 = y2 + finalDeviceHeight / 2.0f - height / 2.0f; return new Coordinates((int) Math.round(x2), (int) Math.round(y2)); } else { return new Coordinates(cellX, cellY); } } }