The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 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 | |
| 17 | package android.view; |
| 18 | import android.graphics.Rect; |
| 19 | |
| 20 | /** |
| 21 | * Standard constants and tools for placing an object within a potentially |
| 22 | * larger container. |
| 23 | */ |
| 24 | public class Gravity |
| 25 | { |
| 26 | /** Constant 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 | /** Raw bit controlling whether the right/bottom edge is clipped to its |
| 37 | * container, based on the gravity direction being applied. */ |
| 38 | public static final int AXIS_CLIP = 0x0008; |
| 39 | |
| 40 | /** Bits defining the horizontal axis. */ |
| 41 | public static final int AXIS_X_SHIFT = 0; |
| 42 | /** Bits defining the vertical axis. */ |
| 43 | public static final int AXIS_Y_SHIFT = 4; |
| 44 | |
| 45 | /** Push object to the top of its container, not changing its size. */ |
| 46 | public static final int TOP = (AXIS_PULL_BEFORE|AXIS_SPECIFIED)<<AXIS_Y_SHIFT; |
| 47 | /** Push object to the bottom of its container, not changing its size. */ |
| 48 | public static final int BOTTOM = (AXIS_PULL_AFTER|AXIS_SPECIFIED)<<AXIS_Y_SHIFT; |
| 49 | /** Push object to the left of its container, not changing its size. */ |
| 50 | public static final int LEFT = (AXIS_PULL_BEFORE|AXIS_SPECIFIED)<<AXIS_X_SHIFT; |
| 51 | /** Push object to the right of its container, not changing its size. */ |
| 52 | public static final int RIGHT = (AXIS_PULL_AFTER|AXIS_SPECIFIED)<<AXIS_X_SHIFT; |
| 53 | |
| 54 | /** Place object in the vertical center of its container, not changing its |
| 55 | * size. */ |
| 56 | public static final int CENTER_VERTICAL = AXIS_SPECIFIED<<AXIS_Y_SHIFT; |
| 57 | /** Grow the vertical size of the object if needed so it completely fills |
| 58 | * its container. */ |
| 59 | public static final int FILL_VERTICAL = TOP|BOTTOM; |
| 60 | |
| 61 | /** Place object in the horizontal center of its container, not changing its |
| 62 | * size. */ |
| 63 | public static final int CENTER_HORIZONTAL = AXIS_SPECIFIED<<AXIS_X_SHIFT; |
| 64 | /** Grow the horizontal size of the object if needed so it completely fills |
| 65 | * its container. */ |
| 66 | public static final int FILL_HORIZONTAL = LEFT|RIGHT; |
| 67 | |
| 68 | /** Place the object in the center of its container in both the vertical |
| 69 | * and horizontal axis, not changing its size. */ |
| 70 | public static final int CENTER = CENTER_VERTICAL|CENTER_HORIZONTAL; |
| 71 | |
| 72 | /** Grow the horizontal and vertical size of the object if needed so it |
| 73 | * completely fills its container. */ |
| 74 | public static final int FILL = FILL_VERTICAL|FILL_HORIZONTAL; |
| 75 | |
| 76 | /** Flag to clip the edges of the object to its container along the |
| 77 | * vertical axis. */ |
| 78 | public static final int CLIP_VERTICAL = AXIS_CLIP<<AXIS_Y_SHIFT; |
| 79 | |
| 80 | /** Flag to clip the edges of the object to its container along the |
| 81 | * horizontal axis. */ |
| 82 | public static final int CLIP_HORIZONTAL = AXIS_CLIP<<AXIS_X_SHIFT; |
Fabrice Di Meglio | 6a03640 | 2011-05-23 14:43:23 -0700 | [diff] [blame] | 83 | |
Fabrice Di Meglio | c46f7ff | 2011-06-06 18:23:10 -0700 | [diff] [blame] | 84 | /** Raw bit controlling whether the layout direction is relative or not (START/END instead of |
| 85 | * absolute LEFT/RIGHT). |
| 86 | */ |
| 87 | public static final int RELATIVE_LAYOUT_DIRECTION = 0x00800000; |
Fabrice Di Meglio | 6a03640 | 2011-05-23 14:43:23 -0700 | [diff] [blame] | 88 | |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 89 | /** |
Fabrice Di Meglio | 6a03640 | 2011-05-23 14:43:23 -0700 | [diff] [blame] | 90 | * Binary mask to get the absolute horizontal gravity of a gravity. |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 91 | */ |
| 92 | public static final int HORIZONTAL_GRAVITY_MASK = (AXIS_SPECIFIED | |
| 93 | AXIS_PULL_BEFORE | AXIS_PULL_AFTER) << AXIS_X_SHIFT; |
| 94 | /** |
| 95 | * Binary mask to get the vertical gravity of a gravity. |
| 96 | */ |
| 97 | public static final int VERTICAL_GRAVITY_MASK = (AXIS_SPECIFIED | |
| 98 | AXIS_PULL_BEFORE | AXIS_PULL_AFTER) << AXIS_Y_SHIFT; |
| 99 | |
| 100 | /** Special constant to enable clipping to an overall display along the |
| 101 | * vertical dimension. This is not applied by default by |
| 102 | * {@link #apply(int, int, int, Rect, int, int, Rect)}; you must do so |
| 103 | * yourself by calling {@link #applyDisplay}. |
| 104 | */ |
| 105 | public static final int DISPLAY_CLIP_VERTICAL = 0x10000000; |
| 106 | |
| 107 | /** Special constant to enable clipping to an overall display along the |
| 108 | * horizontal dimension. This is not applied by default by |
| 109 | * {@link #apply(int, int, int, Rect, int, int, Rect)}; you must do so |
| 110 | * yourself by calling {@link #applyDisplay}. |
| 111 | */ |
| 112 | public static final int DISPLAY_CLIP_HORIZONTAL = 0x01000000; |
| 113 | |
Fabrice Di Meglio | 9e3b002 | 2011-06-06 16:30:29 -0700 | [diff] [blame] | 114 | /** Push object to x-axis position at the start of its container, not changing its size. */ |
Fabrice Di Meglio | c46f7ff | 2011-06-06 18:23:10 -0700 | [diff] [blame] | 115 | public static final int START = RELATIVE_LAYOUT_DIRECTION | LEFT; |
Fabrice Di Meglio | 6a03640 | 2011-05-23 14:43:23 -0700 | [diff] [blame] | 116 | |
Fabrice Di Meglio | 9e3b002 | 2011-06-06 16:30:29 -0700 | [diff] [blame] | 117 | /** Push object to x-axis position at the end of its container, not changing its size. */ |
Fabrice Di Meglio | c46f7ff | 2011-06-06 18:23:10 -0700 | [diff] [blame] | 118 | public static final int END = RELATIVE_LAYOUT_DIRECTION | RIGHT; |
Fabrice Di Meglio | 6a03640 | 2011-05-23 14:43:23 -0700 | [diff] [blame] | 119 | |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 120 | /** |
Fabrice Di Meglio | 6a03640 | 2011-05-23 14:43:23 -0700 | [diff] [blame] | 121 | * Binary mask for the horizontal gravity and script specific direction bit. |
| 122 | */ |
Fabrice Di Meglio | 9e3b002 | 2011-06-06 16:30:29 -0700 | [diff] [blame] | 123 | public static final int RELATIVE_HORIZONTAL_GRAVITY_MASK = START | END; |
Fabrice Di Meglio | 6a03640 | 2011-05-23 14:43:23 -0700 | [diff] [blame] | 124 | |
| 125 | /** |
Newton Allen | c502744 | 2013-08-13 11:22:32 -0700 | [diff] [blame] | 126 | * Apply a gravity constant to an object. This supposes that the layout direction is LTR. |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 127 | * |
| 128 | * @param gravity The desired placement of the object, as defined by the |
| 129 | * constants in this class. |
| 130 | * @param w The horizontal size of the object. |
| 131 | * @param h The vertical size of the object. |
| 132 | * @param container The frame of the containing space, in which the object |
| 133 | * will be placed. Should be large enough to contain the |
| 134 | * width and height of the object. |
| 135 | * @param outRect Receives the computed frame of the object in its |
| 136 | * container. |
| 137 | */ |
Fabrice Di Meglio | 6a03640 | 2011-05-23 14:43:23 -0700 | [diff] [blame] | 138 | public static void apply(int gravity, int w, int h, Rect container, Rect outRect) { |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 139 | apply(gravity, w, h, container, 0, 0, outRect); |
| 140 | } |
| 141 | |
| 142 | /** |
Fabrice Di Meglio | 6a03640 | 2011-05-23 14:43:23 -0700 | [diff] [blame] | 143 | * Apply a gravity constant to an object and take care if layout direction is RTL or not. |
| 144 | * |
| 145 | * @param gravity The desired placement of the object, as defined by the |
| 146 | * constants in this class. |
| 147 | * @param w The horizontal size of the object. |
| 148 | * @param h The vertical size of the object. |
| 149 | * @param container The frame of the containing space, in which the object |
| 150 | * will be placed. Should be large enough to contain the |
| 151 | * width and height of the object. |
| 152 | * @param outRect Receives the computed frame of the object in its |
| 153 | * container. |
Fabrice Di Meglio | c005322 | 2011-06-13 12:16:51 -0700 | [diff] [blame] | 154 | * @param layoutDirection The layout direction. |
Fabrice Di Meglio | 6a03640 | 2011-05-23 14:43:23 -0700 | [diff] [blame] | 155 | * |
Fabrice Di Meglio | 49b0a9b | 2012-09-18 12:06:13 -0700 | [diff] [blame] | 156 | * @see View#LAYOUT_DIRECTION_LTR |
| 157 | * @see View#LAYOUT_DIRECTION_RTL |
Fabrice Di Meglio | 6a03640 | 2011-05-23 14:43:23 -0700 | [diff] [blame] | 158 | */ |
| 159 | public static void apply(int gravity, int w, int h, Rect container, |
Fabrice Di Meglio | c005322 | 2011-06-13 12:16:51 -0700 | [diff] [blame] | 160 | Rect outRect, int layoutDirection) { |
| 161 | int absGravity = getAbsoluteGravity(gravity, layoutDirection); |
Fabrice Di Meglio | 6a03640 | 2011-05-23 14:43:23 -0700 | [diff] [blame] | 162 | apply(absGravity, w, h, container, 0, 0, outRect); |
| 163 | } |
| 164 | |
| 165 | /** |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 166 | * Apply a gravity constant to an object. |
| 167 | * |
| 168 | * @param gravity The desired placement of the object, as defined by the |
| 169 | * constants in this class. |
| 170 | * @param w The horizontal size of the object. |
| 171 | * @param h The vertical size of the object. |
| 172 | * @param container The frame of the containing space, in which the object |
| 173 | * will be placed. Should be large enough to contain the |
| 174 | * width and height of the object. |
| 175 | * @param xAdj Offset to apply to the X axis. If gravity is LEFT this |
| 176 | * pushes it to the right; if gravity is RIGHT it pushes it to |
| 177 | * the left; if gravity is CENTER_HORIZONTAL it pushes it to the |
| 178 | * right or left; otherwise it is ignored. |
| 179 | * @param yAdj Offset to apply to the Y axis. If gravity is TOP this pushes |
| 180 | * it down; if gravity is BOTTOM it pushes it up; if gravity is |
| 181 | * CENTER_VERTICAL it pushes it down or up; otherwise it is |
| 182 | * ignored. |
| 183 | * @param outRect Receives the computed frame of the object in its |
| 184 | * container. |
| 185 | */ |
| 186 | public static void apply(int gravity, int w, int h, Rect container, |
Fabrice Di Meglio | 6a03640 | 2011-05-23 14:43:23 -0700 | [diff] [blame] | 187 | int xAdj, int yAdj, Rect outRect) { |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 188 | switch (gravity&((AXIS_PULL_BEFORE|AXIS_PULL_AFTER)<<AXIS_X_SHIFT)) { |
| 189 | case 0: |
| 190 | outRect.left = container.left |
| 191 | + ((container.right - container.left - w)/2) + xAdj; |
| 192 | outRect.right = outRect.left + w; |
| 193 | if ((gravity&(AXIS_CLIP<<AXIS_X_SHIFT)) |
| 194 | == (AXIS_CLIP<<AXIS_X_SHIFT)) { |
| 195 | if (outRect.left < container.left) { |
| 196 | outRect.left = container.left; |
| 197 | } |
| 198 | if (outRect.right > container.right) { |
| 199 | outRect.right = container.right; |
| 200 | } |
| 201 | } |
| 202 | break; |
| 203 | case AXIS_PULL_BEFORE<<AXIS_X_SHIFT: |
| 204 | outRect.left = container.left + xAdj; |
| 205 | outRect.right = outRect.left + w; |
| 206 | if ((gravity&(AXIS_CLIP<<AXIS_X_SHIFT)) |
| 207 | == (AXIS_CLIP<<AXIS_X_SHIFT)) { |
| 208 | if (outRect.right > container.right) { |
| 209 | outRect.right = container.right; |
| 210 | } |
| 211 | } |
| 212 | break; |
| 213 | case AXIS_PULL_AFTER<<AXIS_X_SHIFT: |
| 214 | outRect.right = container.right - xAdj; |
| 215 | outRect.left = outRect.right - w; |
| 216 | if ((gravity&(AXIS_CLIP<<AXIS_X_SHIFT)) |
| 217 | == (AXIS_CLIP<<AXIS_X_SHIFT)) { |
| 218 | if (outRect.left < container.left) { |
| 219 | outRect.left = container.left; |
| 220 | } |
| 221 | } |
| 222 | break; |
| 223 | default: |
| 224 | outRect.left = container.left + xAdj; |
| 225 | outRect.right = container.right + xAdj; |
| 226 | break; |
| 227 | } |
| 228 | |
| 229 | switch (gravity&((AXIS_PULL_BEFORE|AXIS_PULL_AFTER)<<AXIS_Y_SHIFT)) { |
| 230 | case 0: |
| 231 | outRect.top = container.top |
| 232 | + ((container.bottom - container.top - h)/2) + yAdj; |
| 233 | outRect.bottom = outRect.top + h; |
| 234 | if ((gravity&(AXIS_CLIP<<AXIS_Y_SHIFT)) |
| 235 | == (AXIS_CLIP<<AXIS_Y_SHIFT)) { |
| 236 | if (outRect.top < container.top) { |
| 237 | outRect.top = container.top; |
| 238 | } |
| 239 | if (outRect.bottom > container.bottom) { |
| 240 | outRect.bottom = container.bottom; |
| 241 | } |
| 242 | } |
| 243 | break; |
| 244 | case AXIS_PULL_BEFORE<<AXIS_Y_SHIFT: |
| 245 | outRect.top = container.top + yAdj; |
| 246 | outRect.bottom = outRect.top + h; |
| 247 | if ((gravity&(AXIS_CLIP<<AXIS_Y_SHIFT)) |
| 248 | == (AXIS_CLIP<<AXIS_Y_SHIFT)) { |
| 249 | if (outRect.bottom > container.bottom) { |
| 250 | outRect.bottom = container.bottom; |
| 251 | } |
| 252 | } |
| 253 | break; |
| 254 | case AXIS_PULL_AFTER<<AXIS_Y_SHIFT: |
| 255 | outRect.bottom = container.bottom - yAdj; |
| 256 | outRect.top = outRect.bottom - h; |
| 257 | if ((gravity&(AXIS_CLIP<<AXIS_Y_SHIFT)) |
| 258 | == (AXIS_CLIP<<AXIS_Y_SHIFT)) { |
| 259 | if (outRect.top < container.top) { |
| 260 | outRect.top = container.top; |
| 261 | } |
| 262 | } |
| 263 | break; |
| 264 | default: |
| 265 | outRect.top = container.top + yAdj; |
| 266 | outRect.bottom = container.bottom + yAdj; |
| 267 | break; |
| 268 | } |
| 269 | } |
| 270 | |
| 271 | /** |
Fabrice Di Meglio | e8dc07d | 2012-03-09 17:10:19 -0800 | [diff] [blame] | 272 | * Apply a gravity constant to an object. |
| 273 | * |
| 274 | * @param gravity The desired placement of the object, as defined by the |
| 275 | * constants in this class. |
| 276 | * @param w The horizontal size of the object. |
| 277 | * @param h The vertical size of the object. |
| 278 | * @param container The frame of the containing space, in which the object |
| 279 | * will be placed. Should be large enough to contain the |
| 280 | * width and height of the object. |
| 281 | * @param xAdj Offset to apply to the X axis. If gravity is LEFT this |
| 282 | * pushes it to the right; if gravity is RIGHT it pushes it to |
| 283 | * the left; if gravity is CENTER_HORIZONTAL it pushes it to the |
| 284 | * right or left; otherwise it is ignored. |
| 285 | * @param yAdj Offset to apply to the Y axis. If gravity is TOP this pushes |
| 286 | * it down; if gravity is BOTTOM it pushes it up; if gravity is |
| 287 | * CENTER_VERTICAL it pushes it down or up; otherwise it is |
| 288 | * ignored. |
| 289 | * @param outRect Receives the computed frame of the object in its |
| 290 | * container. |
| 291 | * @param layoutDirection The layout direction. |
| 292 | * |
Fabrice Di Meglio | 49b0a9b | 2012-09-18 12:06:13 -0700 | [diff] [blame] | 293 | * @see View#LAYOUT_DIRECTION_LTR |
| 294 | * @see View#LAYOUT_DIRECTION_RTL |
Fabrice Di Meglio | e8dc07d | 2012-03-09 17:10:19 -0800 | [diff] [blame] | 295 | */ |
| 296 | public static void apply(int gravity, int w, int h, Rect container, |
| 297 | int xAdj, int yAdj, Rect outRect, int layoutDirection) { |
| 298 | int absGravity = getAbsoluteGravity(gravity, layoutDirection); |
| 299 | apply(absGravity, w, h, container, xAdj, yAdj, outRect); |
| 300 | } |
| 301 | |
| 302 | /** |
Dianne Hackborn | 935ae46 | 2009-04-13 16:11:55 -0700 | [diff] [blame] | 303 | * Apply additional gravity behavior based on the overall "display" that an |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 304 | * object exists in. This can be used after |
| 305 | * {@link #apply(int, int, int, Rect, int, int, Rect)} to place the object |
| 306 | * within a visible display. By default this moves or clips the object |
| 307 | * to be visible in the display; the gravity flags |
| 308 | * {@link #DISPLAY_CLIP_HORIZONTAL} and {@link #DISPLAY_CLIP_VERTICAL} |
| 309 | * can be used to change this behavior. |
| 310 | * |
| 311 | * @param gravity Gravity constants to modify the placement within the |
| 312 | * display. |
| 313 | * @param display The rectangle of the display in which the object is |
| 314 | * being placed. |
| 315 | * @param inoutObj Supplies the current object position; returns with it |
| 316 | * modified if needed to fit in the display. |
| 317 | */ |
| 318 | public static void applyDisplay(int gravity, Rect display, Rect inoutObj) { |
| 319 | if ((gravity&DISPLAY_CLIP_VERTICAL) != 0) { |
| 320 | if (inoutObj.top < display.top) inoutObj.top = display.top; |
| 321 | if (inoutObj.bottom > display.bottom) inoutObj.bottom = display.bottom; |
| 322 | } else { |
| 323 | int off = 0; |
| 324 | if (inoutObj.top < display.top) off = display.top-inoutObj.top; |
| 325 | else if (inoutObj.bottom > display.bottom) off = display.bottom-inoutObj.bottom; |
| 326 | if (off != 0) { |
| 327 | if (inoutObj.height() > (display.bottom-display.top)) { |
| 328 | inoutObj.top = display.top; |
| 329 | inoutObj.bottom = display.bottom; |
| 330 | } else { |
| 331 | inoutObj.top += off; |
| 332 | inoutObj.bottom += off; |
| 333 | } |
| 334 | } |
| 335 | } |
| 336 | |
| 337 | if ((gravity&DISPLAY_CLIP_HORIZONTAL) != 0) { |
| 338 | if (inoutObj.left < display.left) inoutObj.left = display.left; |
| 339 | if (inoutObj.right > display.right) inoutObj.right = display.right; |
| 340 | } else { |
| 341 | int off = 0; |
| 342 | if (inoutObj.left < display.left) off = display.left-inoutObj.left; |
| 343 | else if (inoutObj.right > display.right) off = display.right-inoutObj.right; |
| 344 | if (off != 0) { |
| 345 | if (inoutObj.width() > (display.right-display.left)) { |
| 346 | inoutObj.left = display.left; |
| 347 | inoutObj.right = display.right; |
| 348 | } else { |
| 349 | inoutObj.left += off; |
| 350 | inoutObj.right += off; |
| 351 | } |
| 352 | } |
| 353 | } |
| 354 | } |
Fabrice Di Meglio | e8dc07d | 2012-03-09 17:10:19 -0800 | [diff] [blame] | 355 | |
| 356 | /** |
| 357 | * Apply additional gravity behavior based on the overall "display" that an |
| 358 | * object exists in. This can be used after |
| 359 | * {@link #apply(int, int, int, Rect, int, int, Rect)} to place the object |
| 360 | * within a visible display. By default this moves or clips the object |
| 361 | * to be visible in the display; the gravity flags |
| 362 | * {@link #DISPLAY_CLIP_HORIZONTAL} and {@link #DISPLAY_CLIP_VERTICAL} |
| 363 | * can be used to change this behavior. |
| 364 | * |
| 365 | * @param gravity Gravity constants to modify the placement within the |
| 366 | * display. |
| 367 | * @param display The rectangle of the display in which the object is |
| 368 | * being placed. |
| 369 | * @param inoutObj Supplies the current object position; returns with it |
| 370 | * modified if needed to fit in the display. |
| 371 | * @param layoutDirection The layout direction. |
| 372 | * |
Fabrice Di Meglio | 49b0a9b | 2012-09-18 12:06:13 -0700 | [diff] [blame] | 373 | * @see View#LAYOUT_DIRECTION_LTR |
| 374 | * @see View#LAYOUT_DIRECTION_RTL |
Fabrice Di Meglio | e8dc07d | 2012-03-09 17:10:19 -0800 | [diff] [blame] | 375 | */ |
| 376 | public static void applyDisplay(int gravity, Rect display, Rect inoutObj, int layoutDirection) { |
| 377 | int absGravity = getAbsoluteGravity(gravity, layoutDirection); |
| 378 | applyDisplay(absGravity, display, inoutObj); |
| 379 | } |
| 380 | |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 381 | /** |
| 382 | * <p>Indicate whether the supplied gravity has a vertical pull.</p> |
| 383 | * |
| 384 | * @param gravity the gravity to check for vertical pull |
| 385 | * @return true if the supplied gravity has a vertical pull |
| 386 | */ |
| 387 | public static boolean isVertical(int gravity) { |
| 388 | return gravity > 0 && (gravity & VERTICAL_GRAVITY_MASK) != 0; |
| 389 | } |
| 390 | |
| 391 | /** |
| 392 | * <p>Indicate whether the supplied gravity has an horizontal pull.</p> |
| 393 | * |
| 394 | * @param gravity the gravity to check for horizontal pull |
| 395 | * @return true if the supplied gravity has an horizontal pull |
| 396 | */ |
| 397 | public static boolean isHorizontal(int gravity) { |
Fabrice Di Meglio | 6a03640 | 2011-05-23 14:43:23 -0700 | [diff] [blame] | 398 | return gravity > 0 && (gravity & RELATIVE_HORIZONTAL_GRAVITY_MASK) != 0; |
| 399 | } |
| 400 | |
| 401 | /** |
| 402 | * <p>Convert script specific gravity to absolute horizontal value.</p> |
| 403 | * |
Fabrice Di Meglio | 9e3b002 | 2011-06-06 16:30:29 -0700 | [diff] [blame] | 404 | * if horizontal direction is LTR, then START will set LEFT and END will set RIGHT. |
| 405 | * if horizontal direction is RTL, then START will set RIGHT and END will set LEFT. |
Fabrice Di Meglio | 6a03640 | 2011-05-23 14:43:23 -0700 | [diff] [blame] | 406 | * |
Fabrice Di Meglio | c005322 | 2011-06-13 12:16:51 -0700 | [diff] [blame] | 407 | * |
Fabrice Di Meglio | 6a03640 | 2011-05-23 14:43:23 -0700 | [diff] [blame] | 408 | * @param gravity The gravity to convert to absolute (horizontal) values. |
Fabrice Di Meglio | c005322 | 2011-06-13 12:16:51 -0700 | [diff] [blame] | 409 | * @param layoutDirection The layout direction. |
Fabrice Di Meglio | 6a03640 | 2011-05-23 14:43:23 -0700 | [diff] [blame] | 410 | * @return gravity converted to absolute (horizontal) values. |
| 411 | */ |
Fabrice Di Meglio | c005322 | 2011-06-13 12:16:51 -0700 | [diff] [blame] | 412 | public static int getAbsoluteGravity(int gravity, int layoutDirection) { |
Fabrice Di Meglio | 6a03640 | 2011-05-23 14:43:23 -0700 | [diff] [blame] | 413 | int result = gravity; |
Fabrice Di Meglio | 9e3b002 | 2011-06-06 16:30:29 -0700 | [diff] [blame] | 414 | // If layout is script specific and gravity is horizontal relative (START or END) |
Fabrice Di Meglio | c46f7ff | 2011-06-06 18:23:10 -0700 | [diff] [blame] | 415 | if ((result & RELATIVE_LAYOUT_DIRECTION) > 0) { |
Fabrice Di Meglio | 9e3b002 | 2011-06-06 16:30:29 -0700 | [diff] [blame] | 416 | if ((result & Gravity.START) == Gravity.START) { |
| 417 | // Remove the START bit |
| 418 | result &= ~START; |
Fabrice Di Meglio | c005322 | 2011-06-13 12:16:51 -0700 | [diff] [blame] | 419 | if (layoutDirection == View.LAYOUT_DIRECTION_RTL) { |
Fabrice Di Meglio | 6a03640 | 2011-05-23 14:43:23 -0700 | [diff] [blame] | 420 | // Set the RIGHT bit |
| 421 | result |= RIGHT; |
| 422 | } else { |
| 423 | // Set the LEFT bit |
| 424 | result |= LEFT; |
| 425 | } |
Fabrice Di Meglio | 9e3b002 | 2011-06-06 16:30:29 -0700 | [diff] [blame] | 426 | } else if ((result & Gravity.END) == Gravity.END) { |
| 427 | // Remove the END bit |
| 428 | result &= ~END; |
Fabrice Di Meglio | c005322 | 2011-06-13 12:16:51 -0700 | [diff] [blame] | 429 | if (layoutDirection == View.LAYOUT_DIRECTION_RTL) { |
Fabrice Di Meglio | 6a03640 | 2011-05-23 14:43:23 -0700 | [diff] [blame] | 430 | // Set the LEFT bit |
| 431 | result |= LEFT; |
| 432 | } else { |
| 433 | // Set the RIGHT bit |
| 434 | result |= RIGHT; |
| 435 | } |
| 436 | } |
| 437 | // Don't need the script specific bit any more, so remove it as we are converting to |
| 438 | // absolute values (LEFT or RIGHT) |
Fabrice Di Meglio | c46f7ff | 2011-06-06 18:23:10 -0700 | [diff] [blame] | 439 | result &= ~RELATIVE_LAYOUT_DIRECTION; |
Fabrice Di Meglio | 6a03640 | 2011-05-23 14:43:23 -0700 | [diff] [blame] | 440 | } |
| 441 | return result; |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 442 | } |
Jorim Jaggi | 484851b | 2017-09-22 16:03:27 +0200 | [diff] [blame] | 443 | |
| 444 | /** |
| 445 | * @hide |
| 446 | */ |
| 447 | public static String toString(int gravity) { |
| 448 | final StringBuilder result = new StringBuilder(); |
Qing Xia | ed80070 | 2017-11-16 10:12:53 -0800 | [diff] [blame] | 449 | if ((gravity & FILL) == FILL) { |
Jorim Jaggi | 484851b | 2017-09-22 16:03:27 +0200 | [diff] [blame] | 450 | result.append("FILL").append(' '); |
| 451 | } else { |
Qing Xia | ed80070 | 2017-11-16 10:12:53 -0800 | [diff] [blame] | 452 | if ((gravity & FILL_VERTICAL) == FILL_VERTICAL) { |
Jorim Jaggi | 484851b | 2017-09-22 16:03:27 +0200 | [diff] [blame] | 453 | result.append("FILL_VERTICAL").append(' '); |
| 454 | } else { |
Qing Xia | ed80070 | 2017-11-16 10:12:53 -0800 | [diff] [blame] | 455 | if ((gravity & TOP) == TOP) { |
Jorim Jaggi | 484851b | 2017-09-22 16:03:27 +0200 | [diff] [blame] | 456 | result.append("TOP").append(' '); |
| 457 | } |
Qing Xia | ed80070 | 2017-11-16 10:12:53 -0800 | [diff] [blame] | 458 | if ((gravity & BOTTOM) == BOTTOM) { |
Jorim Jaggi | 484851b | 2017-09-22 16:03:27 +0200 | [diff] [blame] | 459 | result.append("BOTTOM").append(' '); |
| 460 | } |
| 461 | } |
Qing Xia | ed80070 | 2017-11-16 10:12:53 -0800 | [diff] [blame] | 462 | if ((gravity & FILL_HORIZONTAL) == FILL_HORIZONTAL) { |
Jorim Jaggi | 484851b | 2017-09-22 16:03:27 +0200 | [diff] [blame] | 463 | result.append("FILL_HORIZONTAL").append(' '); |
| 464 | } else { |
Qing Xia | ed80070 | 2017-11-16 10:12:53 -0800 | [diff] [blame] | 465 | if ((gravity & START) == START) { |
Jorim Jaggi | 484851b | 2017-09-22 16:03:27 +0200 | [diff] [blame] | 466 | result.append("START").append(' '); |
Qing Xia | ed80070 | 2017-11-16 10:12:53 -0800 | [diff] [blame] | 467 | } else if ((gravity & LEFT) == LEFT) { |
Jorim Jaggi | 484851b | 2017-09-22 16:03:27 +0200 | [diff] [blame] | 468 | result.append("LEFT").append(' '); |
| 469 | } |
Qing Xia | ed80070 | 2017-11-16 10:12:53 -0800 | [diff] [blame] | 470 | if ((gravity & END) == END) { |
Jorim Jaggi | 484851b | 2017-09-22 16:03:27 +0200 | [diff] [blame] | 471 | result.append("END").append(' '); |
Qing Xia | ed80070 | 2017-11-16 10:12:53 -0800 | [diff] [blame] | 472 | } else if ((gravity & RIGHT) == RIGHT) { |
Jorim Jaggi | 484851b | 2017-09-22 16:03:27 +0200 | [diff] [blame] | 473 | result.append("RIGHT").append(' '); |
| 474 | } |
| 475 | } |
| 476 | } |
Qing Xia | ed80070 | 2017-11-16 10:12:53 -0800 | [diff] [blame] | 477 | if ((gravity & CENTER) == CENTER) { |
Jorim Jaggi | 484851b | 2017-09-22 16:03:27 +0200 | [diff] [blame] | 478 | result.append("CENTER").append(' '); |
| 479 | } else { |
Qing Xia | ed80070 | 2017-11-16 10:12:53 -0800 | [diff] [blame] | 480 | if ((gravity & CENTER_VERTICAL) == CENTER_VERTICAL) { |
Jorim Jaggi | 484851b | 2017-09-22 16:03:27 +0200 | [diff] [blame] | 481 | result.append("CENTER_VERTICAL").append(' '); |
| 482 | } |
Qing Xia | ed80070 | 2017-11-16 10:12:53 -0800 | [diff] [blame] | 483 | if ((gravity & CENTER_HORIZONTAL) == CENTER_HORIZONTAL) { |
Jorim Jaggi | 484851b | 2017-09-22 16:03:27 +0200 | [diff] [blame] | 484 | result.append("CENTER_HORIZONTAL").append(' '); |
| 485 | } |
| 486 | } |
Qing Xia | ed80070 | 2017-11-16 10:12:53 -0800 | [diff] [blame] | 487 | if (result.length() == 0) { |
| 488 | result.append("NO GRAVITY").append(' '); |
| 489 | } |
| 490 | if ((gravity & DISPLAY_CLIP_VERTICAL) == DISPLAY_CLIP_VERTICAL) { |
Jorim Jaggi | 484851b | 2017-09-22 16:03:27 +0200 | [diff] [blame] | 491 | result.append("DISPLAY_CLIP_VERTICAL").append(' '); |
| 492 | } |
Qing Xia | ed80070 | 2017-11-16 10:12:53 -0800 | [diff] [blame] | 493 | if ((gravity & DISPLAY_CLIP_HORIZONTAL) == DISPLAY_CLIP_HORIZONTAL) { |
| 494 | result.append("DISPLAY_CLIP_HORIZONTAL").append(' '); |
Jorim Jaggi | 484851b | 2017-09-22 16:03:27 +0200 | [diff] [blame] | 495 | } |
| 496 | result.deleteCharAt(result.length() - 1); |
| 497 | return result.toString(); |
| 498 | } |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 499 | } |