1 /* 2 * Copyright (C) 2014 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.tv.settings.util; 18 19 import android.graphics.Matrix; 20 import android.graphics.RectF; 21 import android.graphics.drawable.Drawable; 22 import android.view.View; 23 import android.view.ViewParent; 24 import android.widget.ImageView; 25 26 /** 27 * Utility class for View/ImageView locations and clip bounds etc. 28 */ 29 public class WindowLocationUtil { 30 31 private static final float[] sTmpFloat4 = new float[4]; 32 private static final float[] sTmpFloat8 = new float[8]; 33 34 /** 35 * map points inside view into locations of a screen 36 * The function is an extension of {@link View#getLocationInWindow } and can map 37 * multiple points. 38 * 39 * @param points x[0], y[0], x[1], y[1], ... 40 */ getLocationsInWindow(View view, float[] points)41 public static void getLocationsInWindow(View view, float[] points) { 42 43 if (points == null || (points.length & 1) != 0) { 44 throw new IllegalArgumentException(); 45 } 46 int length = points.length; 47 Matrix matrix = view.getMatrix(); 48 if (matrix != null && !matrix.isIdentity()) { 49 matrix.mapPoints(points); 50 } 51 52 int deltax = view.getLeft(); 53 int deltay = view.getTop(); 54 for (int i = 0; i < length; ) { 55 points[i] += deltax; 56 i++; 57 points[i] += deltay; 58 i++; 59 } 60 61 ViewParent viewParent = view.getParent(); 62 while (viewParent instanceof View) { 63 view = (View) viewParent; 64 65 deltax = view.getScrollX(); 66 deltay = view.getScrollY(); 67 for (int i = 0; i < length; ) { 68 points[i] -= deltax; 69 i++; 70 points[i] -= deltay; 71 i++; 72 } 73 74 matrix = view.getMatrix(); 75 if (matrix != null && !matrix.isIdentity()) { 76 matrix.mapPoints(points); 77 } 78 79 deltax = view.getLeft(); 80 deltay = view.getTop(); 81 for (int i = 0; i < length; ) { 82 points[i] += deltax; 83 i++; 84 points[i] += deltay; 85 i++; 86 } 87 88 viewParent = view.getParent(); 89 } 90 } 91 92 /** 93 * get locations of view bounds in Window 94 */ getLocationsInWindow(View view, RectF rect)95 public static void getLocationsInWindow(View view, RectF rect) { 96 sTmpFloat4[0] = rect.left; 97 sTmpFloat4[1] = rect.top; 98 sTmpFloat4[2] = rect.right; 99 sTmpFloat4[3] = rect.bottom; 100 getLocationsInWindow(view, sTmpFloat4); 101 rect.left = sTmpFloat4[0]; 102 rect.top = sTmpFloat4[1]; 103 rect.right = sTmpFloat4[2]; 104 rect.bottom = sTmpFloat4[3]; 105 } 106 107 /** 108 * get clip and unclipped bounds of ImageView inside a window 109 */ getImageLocationsInWindow(ImageView view, RectF clippedBounds, RectF unclippedBitmapRect)110 public static void getImageLocationsInWindow(ImageView view, 111 RectF clippedBounds, RectF unclippedBitmapRect) { 112 // get bounds exclude padding, bitmap will be clipped by this bounds 113 clippedBounds.set(view.getPaddingLeft(), view.getPaddingTop(), 114 view.getWidth() - view.getPaddingRight(), 115 view.getHeight() - view.getPaddingBottom()); 116 Matrix matrix = view.getImageMatrix(); 117 118 Drawable drawable = view.getDrawable(); 119 120 if (drawable != null) { 121 unclippedBitmapRect.set(drawable.getBounds()); 122 matrix.mapRect(unclippedBitmapRect); 123 unclippedBitmapRect.offset(view.getPaddingLeft(), view.getPaddingTop()); 124 sTmpFloat8[0] = clippedBounds.left; 125 sTmpFloat8[1] = clippedBounds.top; 126 sTmpFloat8[2] = clippedBounds.right; 127 sTmpFloat8[3] = clippedBounds.bottom; 128 sTmpFloat8[4] = unclippedBitmapRect.left; 129 sTmpFloat8[5] = unclippedBitmapRect.top; 130 sTmpFloat8[6] = unclippedBitmapRect.right; 131 sTmpFloat8[7] = unclippedBitmapRect.bottom; 132 getLocationsInWindow(view, sTmpFloat8); 133 clippedBounds.left = sTmpFloat8[0]; 134 clippedBounds.top = sTmpFloat8[1]; 135 clippedBounds.right = sTmpFloat8[2]; 136 clippedBounds.bottom = sTmpFloat8[3]; 137 unclippedBitmapRect.left = sTmpFloat8[4]; 138 unclippedBitmapRect.top = sTmpFloat8[5]; 139 unclippedBitmapRect.right = sTmpFloat8[6]; 140 unclippedBitmapRect.bottom = sTmpFloat8[7]; 141 clippedBounds.intersect(unclippedBitmapRect); 142 } else { 143 sTmpFloat4[0] = clippedBounds.left; 144 sTmpFloat4[1] = clippedBounds.top; 145 sTmpFloat4[2] = clippedBounds.right; 146 sTmpFloat4[3] = clippedBounds.bottom; 147 getLocationsInWindow(view, sTmpFloat4); 148 clippedBounds.left = sTmpFloat4[0]; 149 clippedBounds.top = sTmpFloat4[1]; 150 clippedBounds.right = sTmpFloat4[2]; 151 clippedBounds.bottom = sTmpFloat4[3]; 152 unclippedBitmapRect.set(clippedBounds); 153 } 154 } 155 } 156