Home | History | Annotate | Download | only in util
      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      */
     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      */
     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      */
    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