Gravity.java revision 54b6cfa9a9e5b861a9930af873580d6dc20f773c
1/* 2 * Copyright (C) 2006 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 17package android.view; 18import android.graphics.Rect; 19 20/** 21 * Standard constants and tools for placing an object within a potentially 22 * larger container. 23 */ 24public class Gravity 25{ 26 /** Contstant indicating that no gravity has been set **/ 27 public static final int NO_GRAVITY = 0x0000; 28 29 /** Raw bit indicating the gravity for an axis has been specified. */ 30 public static final int AXIS_SPECIFIED = 0x0001; 31 32 /** Raw bit controlling how the left/top edge is placed. */ 33 public static final int AXIS_PULL_BEFORE = 0x0002; 34 /** Raw bit controlling how the right/bottom edge is placed. */ 35 public static final int AXIS_PULL_AFTER = 0x0004; 36 37 /** Bits defining the horizontal axis. */ 38 public static final int AXIS_X_SHIFT = 0; 39 /** Bits defining the vertical axis. */ 40 public static final int AXIS_Y_SHIFT = 4; 41 42 /** Push object to the top of its container, not changing its size. */ 43 public static final int TOP = (AXIS_PULL_BEFORE|AXIS_SPECIFIED)<<AXIS_Y_SHIFT; 44 /** Push object to the bottom of its container, not changing its size. */ 45 public static final int BOTTOM = (AXIS_PULL_AFTER|AXIS_SPECIFIED)<<AXIS_Y_SHIFT; 46 /** Push object to the left of its container, not changing its size. */ 47 public static final int LEFT = (AXIS_PULL_BEFORE|AXIS_SPECIFIED)<<AXIS_X_SHIFT; 48 /** Push object to the right of its container, not changing its size. */ 49 public static final int RIGHT = (AXIS_PULL_AFTER|AXIS_SPECIFIED)<<AXIS_X_SHIFT; 50 51 /** Place object in the vertical center of its container, not changing its 52 * size. */ 53 public static final int CENTER_VERTICAL = AXIS_SPECIFIED<<AXIS_Y_SHIFT; 54 /** Grow the vertical size of the object if needed so it completely fills 55 * its container. */ 56 public static final int FILL_VERTICAL = TOP|BOTTOM; 57 58 /** Place object in the horizontal center of its container, not changing its 59 * size. */ 60 public static final int CENTER_HORIZONTAL = AXIS_SPECIFIED<<AXIS_X_SHIFT; 61 /** Grow the horizontal size of the object if needed so it completely fills 62 * its container. */ 63 public static final int FILL_HORIZONTAL = LEFT|RIGHT; 64 65 /** Place the object in the center of its container in both the vertical 66 * and horizontal axis, not changing its size. */ 67 public static final int CENTER = CENTER_VERTICAL|CENTER_HORIZONTAL; 68 69 /** Grow the horizontal and vertical size of the obejct if needed so it 70 * completely fills its container. */ 71 public static final int FILL = FILL_VERTICAL|FILL_HORIZONTAL; 72 73 /** 74 * Binary mask to get the horizontal gravity of a gravity. 75 */ 76 public static final int HORIZONTAL_GRAVITY_MASK = (AXIS_SPECIFIED | 77 AXIS_PULL_BEFORE | AXIS_PULL_AFTER) << AXIS_X_SHIFT; 78 /** 79 * Binary mask to get the vertical gravity of a gravity. 80 */ 81 public static final int VERTICAL_GRAVITY_MASK = (AXIS_SPECIFIED | 82 AXIS_PULL_BEFORE | AXIS_PULL_AFTER) << AXIS_Y_SHIFT; 83 84 /** 85 * Apply a gravity constant to an object. 86 * 87 * @param gravity The desired placement of the object, as defined by the 88 * constants in this class. 89 * @param w The horizontal size of the object. 90 * @param h The vertical size of the object. 91 * @param container The frame of the containing space, in which the object 92 * will be placed. Should be large enough to contain the 93 * width and height of the object. 94 * @param outRect Receives the computed frame of the object in its 95 * container. 96 */ 97 public static void apply(int gravity, int w, int h, Rect container, 98 Rect outRect) { 99 apply(gravity, w, h, container, 0, 0, outRect); 100 } 101 102 /** 103 * Apply a gravity constant to an object. 104 * 105 * @param gravity The desired placement of the object, as defined by the 106 * constants in this class. 107 * @param w The horizontal size of the object. 108 * @param h The vertical size of the object. 109 * @param container The frame of the containing space, in which the object 110 * will be placed. Should be large enough to contain the 111 * width and height of the object. 112 * @param xAdj Offset to apply to the X axis. If gravity is LEFT this 113 * pushes it to the right; if gravity is RIGHT it pushes it to 114 * the left; if gravity is CENTER_HORIZONTAL it pushes it to the 115 * right or left; otherwise it is ignored. 116 * @param yAdj Offset to apply to the Y axis. If gravity is TOP this pushes 117 * it down; if gravity is BOTTOM it pushes it up; if gravity is 118 * CENTER_VERTICAL it pushes it down or up; otherwise it is 119 * ignored. 120 * @param outRect Receives the computed frame of the object in its 121 * container. 122 */ 123 public static void apply(int gravity, int w, int h, Rect container, 124 int xAdj, int yAdj, Rect outRect) { 125 if ((gravity&((AXIS_PULL_BEFORE|AXIS_PULL_AFTER)<<AXIS_X_SHIFT)) 126 == ((AXIS_PULL_BEFORE|AXIS_PULL_AFTER)<<AXIS_X_SHIFT)) { 127 outRect.left = container.left; 128 outRect.right = container.right; 129 } else { 130 outRect.left = applyMovement( 131 gravity>>AXIS_X_SHIFT, w, container.left, container.right, xAdj); 132 outRect.right = outRect.left + w; 133 } 134 135 if ((gravity&((AXIS_PULL_BEFORE|AXIS_PULL_AFTER)<<AXIS_Y_SHIFT)) 136 == ((AXIS_PULL_BEFORE|AXIS_PULL_AFTER)<<AXIS_Y_SHIFT)) { 137 outRect.top = container.top; 138 outRect.bottom = container.bottom; 139 } else { 140 outRect.top = applyMovement( 141 gravity>>AXIS_Y_SHIFT, h, container.top, container.bottom, yAdj); 142 outRect.bottom = outRect.top + h; 143 } 144 } 145 146 /** 147 * <p>Indicate whether the supplied gravity has a vertical pull.</p> 148 * 149 * @param gravity the gravity to check for vertical pull 150 * @return true if the supplied gravity has a vertical pull 151 */ 152 public static boolean isVertical(int gravity) { 153 return gravity > 0 && (gravity & VERTICAL_GRAVITY_MASK) != 0; 154 } 155 156 /** 157 * <p>Indicate whether the supplied gravity has an horizontal pull.</p> 158 * 159 * @param gravity the gravity to check for horizontal pull 160 * @return true if the supplied gravity has an horizontal pull 161 */ 162 public static boolean isHorizontal(int gravity) { 163 return gravity > 0 && (gravity & HORIZONTAL_GRAVITY_MASK) != 0; 164 } 165 166 private static int applyMovement(int mode, int size, 167 int start, int end, int adj) { 168 if ((mode & AXIS_PULL_BEFORE) != 0) { 169 return start + adj; 170 } 171 172 if ((mode & AXIS_PULL_AFTER) != 0) { 173 return end - size - adj; 174 } 175 176 return start + ((end - start - size)/2) + adj; 177 } 178} 179 180