setSize(alloc.width, alloc.height); } return super.viewToModel(x, y, a, bias); } /** * Determines the desired alignment for this view along an * axis. This is implemented to give the total alignment * needed to position the children with the alignment points * lined up along the axis orthoginal to the axis that is * being tiled. The axis being tiled will request to be * centered (i.e. 0.5f). * * @param axis may be either <code>View.X_AXIS</code> * or <code>View.Y_AXIS</code> * @return the desired alignment >= 0.0f && <= 1.0f; this should * be a value between 0.0 and 1.0 where 0 indicates alignment at the * origin and 1.0 indicates alignment to the full span * away from the origin; an alignment of 0.5 would be the * center of the view * @exception IllegalArgumentException for an invalid axis */ public float getAlignment(int axis) { checkRequests(axis); if (axis == majorAxis) { return majorRequest.alignment; } else { return minorRequest.alignment; } } /** * Determines the preferred span for this view along an * axis. * * @param axis may be either <code>View.X_AXIS</code> * or <code>View.Y_AXIS</code> * @return the span the view would like to be rendered into >= 0; * typically the view is told to render into the span * that is returned, although there is no guarantee; * the parent may choose to resize or break the view * @exception IllegalArgumentException for an invalid axis type */ public float getPreferredSpan(int axis) { checkRequests(axis); float marginSpan = (axis == X_AXIS) ? getLeftInset() + getRightInset() : getTopInset() + getBottomInset(); if (axis == majorAxis) { return ((float)majorRequest.preferred) + marginSpan; } else { return ((float)minorRequest.preferred) + marginSpan; } } /** * Determines the minimum span for this view along an * axis. * * @param axis may be either <code>View.X_AXIS</code> * or <code>View.Y_AXIS</code> * @return the span the view would like to be rendered into >= 0; * typically the view is told to render into the span * that is returned, although there is no guarantee; * the parent may choose to resize or break the view * @exception IllegalArgumentException for an invalid axis type */ public float getMinimumSpan(int axis) { checkRequests(axis); float marginSpan = (axis == X_AXIS) ? getLeftInset() + getRightInset() : getTopInset() + getBottomInset(); if (axis == majorAxis) { return ((float)majorRequest.minimum) + marginSpan; } else { return ((float)minorRequest.minimum) + marginSpan; } } /** * Determines the maximum span for this view along an * axis. * * @param axis may be either <code>View.X_AXIS</code> * or <code>View.Y_AXIS</code> * @return the span the view would like to be rendered into >= 0; * typically the view is told to render into the span * that is returned, although there is no guarantee; * the parent may choose to resize or break the view * @exception IllegalArgumentException for an invalid axis type */ public float getMaximumSpan(int axis) { checkRequests(axis); float marginSpan = (axis == X_AXIS) ? getLeftInset() + getRightInset() : getTopInset() + getBottomInset(); if (axis == majorAxis) { return ((float)majorRequest.maximum) + marginSpan; } else { return ((float)minorRequest.maximum) + marginSpan; } } // --- local methods ---------------------------------------------------- /** * Are the allocations for the children still * valid? * * @return true if allocations still valid */ protected boolean isAllocationValid() { return (majorAllocValid && minorAllocValid); } /** * Determines if a point falls before an allocated region. * * @param x the X coordinate >= 0 * @param y the Y coordinate >= 0 * @param innerAlloc the allocated region; this is the area * inside of the insets * @return true if the point lies before the region else false */ protected boolean isBefore(int x, int y, Rectangle innerAlloc) { if (majorAxis == View.X_AXIS) { return (x < innerAlloc.x); } else { return (y < innerAlloc.y); } } /** * Determines if a point falls after an allocated region. * * @param x the X coordinate >= 0 * @param y the Y coordinate >= 0 * @param innerAlloc the allocated region; this is the area * inside of the insets * @return true if the point lies after the region else false */ protected boolean isAfter(int x, int y, Rectangle innerAlloc) { if (majorAxis == View.X_AXIS) { return (x > (innerAlloc.width + innerAlloc.x)); } else { return (y > (innerAlloc.height + innerAlloc.y)); } } /** * Fetches the child view at the given coordinates. * * @param x the X coordinate >= 0 * @param y the Y coordinate >= 0 * @param alloc the parents inner allocation on entry, which should * be changed to the childs allocation on exit * @return the view */ protected View getViewAtPoint(int x, int y, Rectangle alloc) { int n = getViewCount(); if (majorAxis == View.X_AXIS) { if (x < (alloc.x + majorOffsets[0])) { childAllocation(0, alloc); return getView(0); } for (int i = 0; i < n; i++) { if (x < (alloc.x + majorOffsets[i])) { childAllocation(i - 1, alloc); return getView(i - 1); } } childAllocation(n - 1, alloc); return getView(n - 1); } else { if (y < (alloc.y + majorOffsets[0])) { childAllocation(0, alloc); return getView(0); } for (int i = 0; i < n; i++) { if (y < (alloc.y + majorOffsets[i])) { childAllocation(i - 1, alloc); return getView(i - 1); } } childAllocation(n - 1, alloc); return getView(n - 1); } } /** * Allocates a region for a child view. * * @param index the index of the child view to * allocate, >= 0 && < getViewCount() * @param alloc the allocated region */ protected void childAllocation(int index, Rectangle alloc) { alloc.x += getOffset(X_AXIS, index); alloc.y += getOffset(Y_AXIS, index); alloc.width = getSpan(X_AXIS, index); alloc.height = getSpan(Y_AXIS, index); } /** * Perform layout on the box * * @param width the width (inside of the insets) >= 0 * @param height the height (inside of the insets) >= 0 */ protected void layout(int width, int height) { setSpanOnAxis(X_AXIS, width); setSpanOnAxis(Y_AXIS, height); } /** * Returns the current width of the box. This is the width that * it was last allocated. * @return the current width of the box */ public int getWidth() { int span; if (majorAxis == X_AXIS) { span = majorSpan; } else { span = minorSpan; } span += getLeftInset() - getRightInset(); return span; } /** * Returns the current height of the box. This is the height that * it was last allocated. * @return the current height of the box */ public int getHeight() { int span; if (majorAxis == Y_AXIS) { span = majorSpan; } else { span = minorSpan; } span += getTopInset() - getBottomInset(); return span; } /** * Performs layout for the major axis of the box (i.e. the * axis that it represents). The results of the layout (the * offset and span for each children) are placed in the given * arrays which represent the allocations to the children * along the major axis. * * @param targetSpan the total span given to the view, which * would be used to layout the children * @param axis the axis being layed out * @param offsets the offsets from the origin of the view for * each of the child views; this is a return value and is * filled in by the implementation of this method * @param spans the span of each child view; this is a return * value and is filled in by the implementation of this method */ protected void layoutMajorAxis(int targetSpan, int axis, int[] offsets, int[] spans) { /* * first pass, calculate the preferred sizes * and the flexibility to adjust the sizes. */ long preferred = 0; int n = getViewCount(); for (int i = 0; i < n; i++) { View v = getView(i); spans[i] = (int) v.getPreferredSpan(axis); preferred += spans[i]; } /* * Second pass, expand or contract by as much as possible to reach * the target span. */ // determine the adjustment to be made long desiredAdjustment = targetSpan - preferred; float adjustmentFactor = 0.0f; int[] diffs = null; if (desiredAdjustment != 0) { long totalSpan = 0; diffs = new int[n]; for (int i = 0; i < n; i++) { View v = getView(i); int tmp; if (desiredAdjustment < 0) { tmp = (int)v.getMinimumSpan(axis); diffs[i] = spans[i] - tmp; } else { tmp = (int)v.getMaximumSpan(axis); diffs[i] = tmp - spans[i]; } totalSpan += tmp; } float maximumAdjustment = Math.abs(totalSpan - preferred); adjustmentFactor = desiredAdjustment / maximumAdjustment; adjustmentFactor = Math.min(adjustmentFactor, 1.0f); adjustmentFactor = Math.max(adjustmentFactor, -1.0f); } // make the adjustments int totalOffset = 0; for (int i = 0; i < n; i++) { offsets[i] = totalOffset; if (desiredAdjustment != 0) { float adjF = adjustmentFactor * diffs[i]; spans[i] += Math.round(adjF); } totalOffset = (int) Math.min((long) totalOffset + (long) spans[i], Integer.MAX_VALUE); } } /** * Performs layout for the minor axis of the box (i.e. the * axis orthoginal to the axis that it represents). The results * of the layout (the offset and span for each children) are * placed in the given arrays which represent the allocations to * the children along the minor axis. * * @param targetSpan the total span given to the view, which * would be used to layout the children * @param axis the axis being layed out * @param offsets the offsets from the origin of the view for * each of the child views; this is a return value and is * filled in by the implementation of this method * @param spans the span of each child view; this is a return * value and is filled in by the implementation of this method */ protected void layoutMinorAxis(int targetSpan, int axis, int[] offsets, int[] spans) { int n = getViewCount(); for (int i = 0; i < n; i++) { View v = getView(i); int max = (int) v.getMaximumSpan(axis); if (max < targetSpan) { // can't make the child this wide, align it float align = v.getAlignment(axis); offsets[i] = (int) ((targetSpan - max) * align); spans[i] = max; } else { // make it the target width, or as small as it can get. int min = (int)v.getMinimumSpan(axis); offsets[i] = 0; spans[i] = Math.max(min, targetSpan); } } } /** * Calculates the size requirements for the major axis * <code>axis</code>. * * @param axis the axis being studied * @param r the <code>SizeRequirements</code> object; * if <code>null</code> one will be created * @return the newly initialized <code>SizeRequirements</code> object * @see javax.swing.SizeRequirements */ protected SizeRequirements calculateMajorAxisRequirements(int axis, SizeRequirements r) { // calculate tiled request float min = 0; float pref = 0; float max = 0; int n = getViewCount(); for (int i = 0; i < n; i++) { View v = getView(i); min += v.getMinimumSpan(axis); pref += v.getPreferredSpan(axis); max += v.getMaximumSpan(axis); } if (r == null) { r = new SizeRequirements(); } r.alignment = 0.5f; r.minimum = (int) min; r.preferred = (int) pref; r.maximum = (int) max; return r; } /** * Calculates the size requirements for the minor axis * <code>axis</code>. * * @param axis the axis being studied * @param r the <code>SizeRequirements</code> object; * if <code>null</code> one will be created * @return the newly initialized <code>SizeRequirements</code> object * @see javax.swing.SizeRequirements */ protected SizeRequirements calculateMinorAxisRequirements(int axis, SizeRequirements r) { int min = 0; long pref = 0; int max = Integer.MAX_VALUE; int n = getViewCount(); for (int i = 0; i < n; i++) { View v = getView(i); min = Math.max((int) v.getMinimumSpan(axis), min); pref = Math.max((int) v.getPreferredSpan(axis), pref); max = Math.max((int) v.getMaximumSpan(axis), max); } if (r == null) { r = new SizeRequirements(); r.alignment = 0.5f; } r.preferred = (int) pref; r.minimum = min; r.maximum = max; return r; } /** * Checks the request cache and update if needed. * @param axis the axis being studied * @exception IllegalArgumentException if <code>axis</code> is * neither <code>View.X_AXIS</code> nor <code>View.Y_AXIS</code> */ void checkRequests(int axis) { if ((axis != X_AXIS) && (axis != Y_AXIS)) { throw new IllegalArgumentException("Invalid axis: " + axis); } if (axis == majorAxis) { if (!majorReqValid) { majorRequest = calculateMajorAxisRequirements(axis, majorRequest); majorReqValid = true; } } else if (! minorReqValid) { minorRequest = calculateMinorAxisRequirements(axis, minorRequest); minorReqValid = true; } } /** * Computes the location and extent of each child view * in this <code>BoxView</code> given the <code>targetSpan</code>, * which is the width (or height) of the region we have to * work with. * * @param targetSpan the total span given to the view, which * would be used to layout the children * @param axis the axis being studied, either * <code>View.X_AXIS</code> or <code>View.Y_AXIS</code> * @param offsets an empty array filled by this method with * values specifying the location of each child view * @param spans an empty array filled by this method with * values specifying the extent of each child view */ protected void baselineLayout(int targetSpan, int axis, int[] offsets, int[] spans) { int totalAscent = (int)(targetSpan * getAlignment(axis)); int totalDescent = targetSpan - totalAscent; int n = getViewCount(); for (int i = 0; i < n; i++) { View v = getView(i); float align = v.getAlignment(axis); float viewSpan; if (v.getResizeWeight(axis) > 0) { // if resizable then resize to the best fit // the smallest span possible float minSpan = v.getMinimumSpan(axis); // the largest span possible float maxSpan = v.getMaximumSpan(axis); if (align == 0.0f) { // if the alignment is 0 then we need to fit into the descent viewSpan = Math.max(Math.min(maxSpan, totalDescent), minSpan); } else if (align == 1.0f) { // if the alignment is 1 then we need to fit into the ascent viewSpan = Math.max(Math.min(maxSpan, totalAscent), minSpan); } else { // figure out the span that we must fit into float fitSpan = Math.min(totalAscent / align, totalDescent / (1.0f - align)); // fit into the calculated span viewSpan = Math.max(Math.min(maxSpan, fitSpan), minSpan); } } else { // otherwise use the preferred spans viewSpan = v.getPreferredSpan(axis); } offsets[i] = totalAscent - (int)(viewSpan * align); spans[i] = (int)viewSpan; } } /** * Calculates the size requirements for this <code>BoxView</code> * by examining the size of each child view. *Lines 501–1000 of 1188. Previous lines Load more
setSize(alloc.width, alloc.height); } return super.viewToModel(x, y, a, bias); } /** * Determines the desired alignment for this view along an * axis. This is implemented to give the total alignment * needed to position the children with the alignment points * lined up along the axis orthoginal to the axis that is * being tiled. The axis being tiled will request to be * centered (i.e. 0.5f). * * @param axis may be either <code>View.X_AXIS</code> * or <code>View.Y_AXIS</code> * @return the desired alignment >= 0.0f && <= 1.0f; this should * be a value between 0.0 and 1.0 where 0 indicates alignment at the * origin and 1.0 indicates alignment to the full span * away from the origin; an alignment of 0.5 would be the * center of the view * @exception IllegalArgumentException for an invalid axis */ public float getAlignment(int axis) { checkRequests(axis); if (axis == majorAxis) { return majorRequest.alignment; } else { return minorRequest.alignment; } } /** * Determines the preferred span for this view along an * axis. * * @param axis may be either <code>View.X_AXIS</code> * or <code>View.Y_AXIS</code> * @return the span the view would like to be rendered into >= 0; * typically the view is told to render into the span * that is returned, although there is no guarantee; * the parent may choose to resize or break the view * @exception IllegalArgumentException for an invalid axis type */ public float getPreferredSpan(int axis) { checkRequests(axis); float marginSpan = (axis == X_AXIS) ? getLeftInset() + getRightInset() : getTopInset() + getBottomInset(); if (axis == majorAxis) { return ((float)majorRequest.preferred) + marginSpan; } else { return ((float)minorRequest.preferred) + marginSpan; } } /** * Determines the minimum span for this view along an * axis. * * @param axis may be either <code>View.X_AXIS</code> * or <code>View.Y_AXIS</code> * @return the span the view would like to be rendered into >= 0; * typically the view is told to render into the span * that is returned, although there is no guarantee; * the parent may choose to resize or break the view * @exception IllegalArgumentException for an invalid axis type */ public float getMinimumSpan(int axis) { checkRequests(axis); float marginSpan = (axis == X_AXIS) ? getLeftInset() + getRightInset() : getTopInset() + getBottomInset(); if (axis == majorAxis) { return ((float)majorRequest.minimum) + marginSpan; } else { return ((float)minorRequest.minimum) + marginSpan; } } /** * Determines the maximum span for this view along an * axis. * * @param axis may be either <code>View.X_AXIS</code> * or <code>View.Y_AXIS</code> * @return the span the view would like to be rendered into >= 0; * typically the view is told to render into the span * that is returned, although there is no guarantee; * the parent may choose to resize or break the view * @exception IllegalArgumentException for an invalid axis type */ public float getMaximumSpan(int axis) { checkRequests(axis); float marginSpan = (axis == X_AXIS) ? getLeftInset() + getRightInset() : getTopInset() + getBottomInset(); if (axis == majorAxis) { return ((float)majorRequest.maximum) + marginSpan; } else { return ((float)minorRequest.maximum) + marginSpan; } } // --- local methods ---------------------------------------------------- /** * Are the allocations for the children still * valid? * * @return true if allocations still valid */ protected boolean isAllocationValid() { return (majorAllocValid && minorAllocValid); } /** * Determines if a point falls before an allocated region. * * @param x the X coordinate >= 0 * @param y the Y coordinate >= 0 * @param innerAlloc the allocated region; this is the area * inside of the insets * @return true if the point lies before the region else false */ protected boolean isBefore(int x, int y, Rectangle innerAlloc) { if (majorAxis == View.X_AXIS) { return (x < innerAlloc.x); } else { return (y < innerAlloc.y); } } /** * Determines if a point falls after an allocated region. * * @param x the X coordinate >= 0 * @param y the Y coordinate >= 0 * @param innerAlloc the allocated region; this is the area * inside of the insets * @return true if the point lies after the region else false */ protected boolean isAfter(int x, int y, Rectangle innerAlloc) { if (majorAxis == View.X_AXIS) { return (x > (innerAlloc.width + innerAlloc.x)); } else { return (y > (innerAlloc.height + innerAlloc.y)); } } /** * Fetches the child view at the given coordinates. * * @param x the X coordinate >= 0 * @param y the Y coordinate >= 0 * @param alloc the parents inner allocation on entry, which should * be changed to the childs allocation on exit * @return the view */ protected View getViewAtPoint(int x, int y, Rectangle alloc) { int n = getViewCount(); if (majorAxis == View.X_AXIS) { if (x < (alloc.x + majorOffsets[0])) { childAllocation(0, alloc); return getView(0); } for (int i = 0; i < n; i++) { if (x < (alloc.x + majorOffsets[i])) { childAllocation(i - 1, alloc); return getView(i - 1); } } childAllocation(n - 1, alloc); return getView(n - 1); } else { if (y < (alloc.y + majorOffsets[0])) { childAllocation(0, alloc); return getView(0); } for (int i = 0; i < n; i++) { if (y < (alloc.y + majorOffsets[i])) { childAllocation(i - 1, alloc); return getView(i - 1); } } childAllocation(n - 1, alloc); return getView(n - 1); } } /** * Allocates a region for a child view. * * @param index the index of the child view to * allocate, >= 0 && < getViewCount() * @param alloc the allocated region */ protected void childAllocation(int index, Rectangle alloc) { alloc.x += getOffset(X_AXIS, index); alloc.y += getOffset(Y_AXIS, index); alloc.width = getSpan(X_AXIS, index); alloc.height = getSpan(Y_AXIS, index); } /** * Perform layout on the box * * @param width the width (inside of the insets) >= 0 * @param height the height (inside of the insets) >= 0 */ protected void layout(int width, int height) { setSpanOnAxis(X_AXIS, width); setSpanOnAxis(Y_AXIS, height); } /** * Returns the current width of the box. This is the width that * it was last allocated. * @return the current width of the box */ public int getWidth() { int span; if (majorAxis == X_AXIS) { span = majorSpan; } else { span = minorSpan; } span += getLeftInset() - getRightInset(); return span; } /** * Returns the current height of the box. This is the height that * it was last allocated. * @return the current height of the box */ public int getHeight() { int span; if (majorAxis == Y_AXIS) { span = majorSpan; } else { span = minorSpan; } span += getTopInset() - getBottomInset(); return span; } /** * Performs layout for the major axis of the box (i.e. the * axis that it represents). The results of the layout (the * offset and span for each children) are placed in the given * arrays which represent the allocations to the children * along the major axis. * * @param targetSpan the total span given to the view, which * would be used to layout the children * @param axis the axis being layed out * @param offsets the offsets from the origin of the view for * each of the child views; this is a return value and is * filled in by the implementation of this method * @param spans the span of each child view; this is a return * value and is filled in by the implementation of this method */ protected void layoutMajorAxis(int targetSpan, int axis, int[] offsets, int[] spans) { /* * first pass, calculate the preferred sizes * and the flexibility to adjust the sizes. */ long preferred = 0; int n = getViewCount(); for (int i = 0; i < n; i++) { View v = getView(i); spans[i] = (int) v.getPreferredSpan(axis); preferred += spans[i]; } /* * Second pass, expand or contract by as much as possible to reach * the target span. */ // determine the adjustment to be made long desiredAdjustment = targetSpan - preferred; float adjustmentFactor = 0.0f; int[] diffs = null; if (desiredAdjustment != 0) { long totalSpan = 0; diffs = new int[n]; for (int i = 0; i < n; i++) { View v = getView(i); int tmp; if (desiredAdjustment < 0) { tmp = (int)v.getMinimumSpan(axis); diffs[i] = spans[i] - tmp; } else { tmp = (int)v.getMaximumSpan(axis); diffs[i] = tmp - spans[i]; } totalSpan += tmp; } float maximumAdjustment = Math.abs(totalSpan - preferred); adjustmentFactor = desiredAdjustment / maximumAdjustment; adjustmentFactor = Math.min(adjustmentFactor, 1.0f); adjustmentFactor = Math.max(adjustmentFactor, -1.0f); } // make the adjustments int totalOffset = 0; for (int i = 0; i < n; i++) { offsets[i] = totalOffset; if (desiredAdjustment != 0) { float adjF = adjustmentFactor * diffs[i]; spans[i] += Math.round(adjF); } totalOffset = (int) Math.min((long) totalOffset + (long) spans[i], Integer.MAX_VALUE); } } /** * Performs layout for the minor axis of the box (i.e. the * axis orthoginal to the axis that it represents). The results * of the layout (the offset and span for each children) are * placed in the given arrays which represent the allocations to * the children along the minor axis. * * @param targetSpan the total span given to the view, which * would be used to layout the children * @param axis the axis being layed out * @param offsets the offsets from the origin of the view for * each of the child views; this is a return value and is * filled in by the implementation of this method * @param spans the span of each child view; this is a return * value and is filled in by the implementation of this method */ protected void layoutMinorAxis(int targetSpan, int axis, int[] offsets, int[] spans) { int n = getViewCount(); for (int i = 0; i < n; i++) { View v = getView(i); int max = (int) v.getMaximumSpan(axis); if (max < targetSpan) { // can't make the child this wide, align it float align = v.getAlignment(axis); offsets[i] = (int) ((targetSpan - max) * align); spans[i] = max; } else { // make it the target width, or as small as it can get. int min = (int)v.getMinimumSpan(axis); offsets[i] = 0; spans[i] = Math.max(min, targetSpan); } } } /** * Calculates the size requirements for the major axis * <code>axis</code>. * * @param axis the axis being studied * @param r the <code>SizeRequirements</code> object; * if <code>null</code> one will be created * @return the newly initialized <code>SizeRequirements</code> object * @see javax.swing.SizeRequirements */ protected SizeRequirements calculateMajorAxisRequirements(int axis, SizeRequirements r) { // calculate tiled request float min = 0; float pref = 0; float max = 0; int n = getViewCount(); for (int i = 0; i < n; i++) { View v = getView(i); min += v.getMinimumSpan(axis); pref += v.getPreferredSpan(axis); max += v.getMaximumSpan(axis); } if (r == null) { r = new SizeRequirements(); } r.alignment = 0.5f; r.minimum = (int) min; r.preferred = (int) pref; r.maximum = (int) max; return r; } /** * Calculates the size requirements for the minor axis * <code>axis</code>. * * @param axis the axis being studied * @param r the <code>SizeRequirements</code> object; * if <code>null</code> one will be created * @return the newly initialized <code>SizeRequirements</code> object * @see javax.swing.SizeRequirements */ protected SizeRequirements calculateMinorAxisRequirements(int axis, SizeRequirements r) { int min = 0; long pref = 0; int max = Integer.MAX_VALUE; int n = getViewCount(); for (int i = 0; i < n; i++) { View v = getView(i); min = Math.max((int) v.getMinimumSpan(axis), min); pref = Math.max((int) v.getPreferredSpan(axis), pref); max = Math.max((int) v.getMaximumSpan(axis), max); } if (r == null) { r = new SizeRequirements(); r.alignment = 0.5f; } r.preferred = (int) pref; r.minimum = min; r.maximum = max; return r; } /** * Checks the request cache and update if needed. * @param axis the axis being studied * @exception IllegalArgumentException if <code>axis</code> is * neither <code>View.X_AXIS</code> nor <code>View.Y_AXIS</code> */ void checkRequests(int axis) { if ((axis != X_AXIS) && (axis != Y_AXIS)) { throw new IllegalArgumentException("Invalid axis: " + axis); } if (axis == majorAxis) { if (!majorReqValid) { majorRequest = calculateMajorAxisRequirements(axis, majorRequest); majorReqValid = true; } } else if (! minorReqValid) { minorRequest = calculateMinorAxisRequirements(axis, minorRequest); minorReqValid = true; } } /** * Computes the location and extent of each child view * in this <code>BoxView</code> given the <code>targetSpan</code>, * which is the width (or height) of the region we have to * work with. * * @param targetSpan the total span given to the view, which * would be used to layout the children * @param axis the axis being studied, either * <code>View.X_AXIS</code> or <code>View.Y_AXIS</code> * @param offsets an empty array filled by this method with * values specifying the location of each child view * @param spans an empty array filled by this method with * values specifying the extent of each child view */ protected void baselineLayout(int targetSpan, int axis, int[] offsets, int[] spans) { int totalAscent = (int)(targetSpan * getAlignment(axis)); int totalDescent = targetSpan - totalAscent; int n = getViewCount(); for (int i = 0; i < n; i++) { View v = getView(i); float align = v.getAlignment(axis); float viewSpan; if (v.getResizeWeight(axis) > 0) { // if resizable then resize to the best fit // the smallest span possible float minSpan = v.getMinimumSpan(axis); // the largest span possible float maxSpan = v.getMaximumSpan(axis); if (align == 0.0f) { // if the alignment is 0 then we need to fit into the descent viewSpan = Math.max(Math.min(maxSpan, totalDescent), minSpan); } else if (align == 1.0f) { // if the alignment is 1 then we need to fit into the ascent viewSpan = Math.max(Math.min(maxSpan, totalAscent), minSpan); } else { // figure out the span that we must fit into float fitSpan = Math.min(totalAscent / align, totalDescent / (1.0f - align)); // fit into the calculated span viewSpan = Math.max(Math.min(maxSpan, fitSpan), minSpan); } } else { // otherwise use the preferred spans viewSpan = v.getPreferredSpan(axis); } offsets[i] = totalAscent - (int)(viewSpan * align); spans[i] = (int)viewSpan; } } /** * Calculates the size requirements for this <code>BoxView</code> * by examining the size of each child view. *