Skip to content

Commit

Permalink
Merge pull request #1659 from ayeung/timob-7836
Browse files Browse the repository at this point in the history
TIMOB-7836: Allow fill behavior for horiztonal and veritcal layouts
  • Loading branch information
vishalduggal committed Mar 15, 2012
2 parents 2be304c + c2fd9eb commit eea3f63
Show file tree
Hide file tree
Showing 6 changed files with 84 additions and 52 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ private int calculateAbsoluteRight(View child)
int contentWidth = getContentProperty(TiC.PROPERTY_CONTENT_WIDTH);
if (contentWidth == AUTO) {
int childMeasuredWidth = child.getMeasuredWidth();
if (!p.autoWidth && p.optionWidth != null) {
if (!p.sizeOrFillWidthEnabled && p.optionWidth != null) {
childMeasuredWidth = getDimensionValue(p.optionWidth, parentWidth);
}
if (p.optionLeft != null) {
Expand All @@ -137,7 +137,7 @@ private int calculateAbsoluteBottom(View child)

if (contentHeight == AUTO) {
int childMeasuredHeight = child.getMeasuredHeight();
if (!p.autoHeight && p.optionHeight != null) {
if (!p.sizeOrFillHeightEnabled && p.optionHeight != null) {
childMeasuredHeight = getDimensionValue(p.optionHeight, parentHeight);
}
if (p.optionTop != null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -411,14 +411,14 @@ private View layoutHeaderOrFooter(TiViewProxy viewProxy)

int width = AbsListView.LayoutParams.WRAP_CONTENT;
int height = AbsListView.LayoutParams.WRAP_CONTENT;
if (params.autoHeight) {
if (params.sizeOrFillHeightEnabled) {
if (params.autoFillsHeight) {
height = AbsListView.LayoutParams.FILL_PARENT;
}
} else if (params.optionHeight != null) {
height = params.optionHeight.getAsPixels(listView);
}
if (params.autoWidth) {
if (params.sizeOrFillWidthEnabled) {
if (params.autoFillsWidth) {
width = AbsListView.LayoutParams.FILL_PARENT;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -175,9 +175,10 @@ public static boolean fillLayout(HashMap<String, Object> hashMap, LayoutParams l
Object width = null;
Object height = null;

// Set auto width/height to false to trigger undefined behavior
layoutParams.autoWidth = false;
layoutParams.autoHeight = false;
// Don't use fill or size by default to trigger the undefined behavior. When we have undefined behavior, we try
// to calculate the height/width from the pins if possible.
layoutParams.sizeOrFillWidthEnabled = false;
layoutParams.sizeOrFillHeightEnabled = false;

if (hashMap.containsKey(TiC.PROPERTY_SIZE)) {
HashMap<String, Object> size = (HashMap<String, Object>) hashMap.get(TiC.PROPERTY_SIZE);
Expand Down Expand Up @@ -217,26 +218,26 @@ public static boolean fillLayout(HashMap<String, Object> hashMap, LayoutParams l

if (width == null) {
layoutParams.optionWidth = null;
layoutParams.autoWidth = false;
layoutParams.sizeOrFillWidthEnabled = false;

} else if (width.equals(TiC.SIZE_AUTO)) {
layoutParams.optionWidth = null;
layoutParams.autoWidth = true;
layoutParams.sizeOrFillWidthEnabled = true;

} else if (width.equals(TiC.LAYOUT_FILL)) {
// fill
layoutParams.optionWidth = null;
layoutParams.autoWidth = true;
layoutParams.sizeOrFillWidthEnabled = true;
layoutParams.autoFillsWidth = true;

} else if (width.equals(TiC.LAYOUT_SIZE)) {
// size
layoutParams.optionWidth = null;
layoutParams.autoWidth = true;
layoutParams.sizeOrFillWidthEnabled = true;
layoutParams.autoFillsWidth = false;
} else {
layoutParams.optionWidth = toTiDimension(width, TiDimension.TYPE_WIDTH);
layoutParams.autoWidth = false;
layoutParams.sizeOrFillWidthEnabled = false;
}
dirty = true;
}
Expand All @@ -248,26 +249,26 @@ public static boolean fillLayout(HashMap<String, Object> hashMap, LayoutParams l

if (height == null) {
layoutParams.optionHeight = null;
layoutParams.autoHeight = false;
layoutParams.sizeOrFillHeightEnabled = false;

} else if (height.equals(TiC.SIZE_AUTO)) {
layoutParams.optionHeight = null;
layoutParams.autoHeight = true;
layoutParams.sizeOrFillHeightEnabled = true;

} else if (height.equals(TiC.LAYOUT_FILL)) {
// fill
layoutParams.optionHeight = null;
layoutParams.autoHeight = true;
layoutParams.sizeOrFillHeightEnabled = true;
layoutParams.autoFillsHeight = true;

} else if (height.equals(TiC.LAYOUT_SIZE)) {
// size
layoutParams.optionHeight = null;
layoutParams.autoHeight = true;
layoutParams.sizeOrFillHeightEnabled = true;
layoutParams.autoFillsHeight = false;
} else {
layoutParams.optionHeight = toTiDimension(height, TiDimension.TYPE_HEIGHT);
layoutParams.autoHeight = false;
layoutParams.sizeOrFillHeightEnabled = false;
}
dirty = true;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -190,15 +190,17 @@ protected boolean checkLayoutParams(ViewGroup.LayoutParams p) {
@Override
protected LayoutParams generateDefaultLayoutParams()
{
// Default is fill view
// Default behavior is size since optionWidth/optionHeight is null, and autoFillsWidth/autoFillsHeight is false.
// Some classes such as ViewProxy will set autoFillsWidth/autoFillsHeight to true in order to trigger the fill
// behavior by default.
LayoutParams params = new LayoutParams();
params.optionLeft = null;
params.optionRight = null;
params.optionTop = null;
params.optionBottom = null;
params.optionZIndex = NOT_SET;
params.autoHeight = true;
params.autoWidth = true;
params.sizeOrFillHeightEnabled = true;
params.sizeOrFillWidthEnabled = true;

return params;
}
Expand Down Expand Up @@ -308,6 +310,7 @@ protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec)
protected void constrainChild(View child, int width, int wMode, int height, int hMode)
{
LayoutParams p = (LayoutParams) child.getLayoutParams();
// If autoFillsWidth is false, and optionWidth is null, then we use size behavior.
int childDimension = LayoutParams.WRAP_CONTENT;
if (p.optionWidth != null) {
if (p.optionWidth.isUnitPercent() && width > 0) {
Expand All @@ -316,14 +319,15 @@ protected void constrainChild(View child, int width, int wMode, int height, int
childDimension = p.optionWidth.getAsPixels(this);
}
} else {
if (p.autoFillsWidth && !isHorizontalArrangement()) {
if (p.autoFillsWidth) {
childDimension = LayoutParams.FILL_PARENT;
}
}

int widthPadding = getViewWidthPadding(child, width);
int widthSpec = ViewGroup.getChildMeasureSpec(MeasureSpec.makeMeasureSpec(width, wMode), widthPadding,
childDimension);
// If autoFillsHeight is false, and optionHeight is null, then we use size behavior.
childDimension = LayoutParams.WRAP_CONTENT;
if (p.optionHeight != null) {
if (p.optionHeight.isUnitPercent() && height > 0) {
Expand All @@ -332,7 +336,7 @@ protected void constrainChild(View child, int width, int wMode, int height, int
childDimension = p.optionHeight.getAsPixels(this);
}
} else {
if (p.autoFillsHeight && !isVerticalArrangement()) {
if (p.autoFillsHeight) {
childDimension = LayoutParams.FILL_PARENT;
}
}
Expand All @@ -347,11 +351,14 @@ protected void constrainChild(View child, int width, int wMode, int height, int
// int childHeight = child.getMeasuredHeight();
}

private int getUndefinedWidth(LayoutParams params, int parentLeft, int parentRight, int parentWidth)
// Try to calculate width from pins, if we couldn't calculate from pins or we don't need to, then return the
// measured width
private int calculateWidthFromPins(LayoutParams params, int parentLeft, int parentRight, int parentWidth,
int measuredWidth)
{
int width = -1;
int width = measuredWidth;

if (params.optionWidth != null || params.autoWidth) {
if (params.optionWidth != null || params.sizeOrFillWidthEnabled) {
return width;
}

Expand All @@ -371,12 +378,15 @@ private int getUndefinedWidth(LayoutParams params, int parentLeft, int parentRig
return width;
}

private int getUndefinedHeight(LayoutParams params, int parentTop, int parentBottom, int parentHeight)
// Try to calculate height from pins, if we couldn't calculate from pins or we don't need to, then return the
// measured height
private int calculateHeightFromPins(LayoutParams params, int parentTop, int parentBottom, int parentHeight,
int measuredHeight)
{
int height = -1;
int height = measuredHeight;

// Return if we don't need undefined behavior
if (params.optionHeight != null || params.autoHeight) {
if (params.optionHeight != null || params.sizeOrFillHeightEnabled) {
return height;
}

Expand Down Expand Up @@ -451,18 +461,11 @@ protected void onLayout(boolean changed, int l, int t, int r, int b)
(TiCompositeLayout.LayoutParams) child.getLayoutParams();
if (child.getVisibility() != View.GONE) {
// Dimension is required from Measure. Positioning is determined here.

// Try using undefined behavior first
int childMeasuredHeight = getUndefinedHeight(params, top, bottom, getHeight());
int childMeasuredWidth = getUndefinedWidth(params, left, right, getWidth());

if (childMeasuredWidth == -1) {
childMeasuredWidth = child.getMeasuredWidth();
}

if (childMeasuredHeight == -1) {
childMeasuredHeight = child.getMeasuredHeight();
}
// Try to calculate width/height from pins, and default to measured width/height. We have to do this in
// onLayout since we can't get the correct top, bottom, left, and right values inside constrainChild().
int childMeasuredHeight = calculateHeightFromPins(params, top, bottom, getHeight(), child.getMeasuredHeight());
int childMeasuredWidth = calculateWidthFromPins(params, left, right, getWidth(), child.getMeasuredWidth());

if (isHorizontalArrangement()) {
if (i == 0) {
Expand All @@ -486,8 +489,8 @@ protected void onLayout(boolean changed, int l, int t, int r, int b)

int newWidth = horizontal[1] - horizontal[0];
int newHeight = vertical[1] - vertical[0];
// If the old child measurements do not match the new measurements that we calculated,
// then update the child measurements accordingly
// If the old child measurements do not match the new measurements that we calculated, then update the
// child measurements accordingly
if (newWidth != child.getMeasuredWidth()
|| newHeight != child.getMeasuredHeight()) {
int newWidthSpec = MeasureSpec.makeMeasureSpec(newWidth, MeasureSpec.EXACTLY);
Expand Down Expand Up @@ -552,8 +555,8 @@ private void computeVerticalLayoutPosition(int currentHeight,
if (optionTop != null) {
top += optionTop.getAsPixels(this);
}
//cap the bottom to make sure views don't go off-screen when user supplies a height value that is >= screen height and this view is
//below another view in vertical layout.
// cap the bottom to make sure views don't go off-screen when user supplies a height value that is >= screen
// height and this view is below another view in vertical layout.
int bottom = Math.min(top + measuredHeight, maxBottom);
pos[0] = top;
pos[1] = bottom;
Expand Down Expand Up @@ -610,22 +613,30 @@ public static class LayoutParams extends ViewGroup.LayoutParams {
public TiDimension optionHeight = null;
public Ti2DMatrix optionTransform = null;

public boolean autoHeight = true;
public boolean autoWidth = true;
// This are flags to determine whether we are using fill or size behavior
public boolean sizeOrFillHeightEnabled = true;
public boolean sizeOrFillWidthEnabled = true;

/**
* If this is true, and {@link #autoWidth} is true, then the current view will fill available parent width.
* If this is true, and {@link #sizeOrFillWidthEnabled} is true, then the current view will follow the fill
* behavior, which fills available parent width. If this value is false and {@link #sizeOrFillWidthEnabled} is
* true, then we use the size behavior, which constrains the view width to fit the width of its contents.
*
* @module.api
*/
public boolean autoFillsWidth = false;

/**
* If this is true, and {@link #autoHeight} is true, then the current view will fill available parent height.
* If this is true, and {@link #sizeOrFillHeightEnabled} is true, then the current view will follow fill
* behavior, which fills available parent height. If this value is false and {@link #sizeOrFillHeightEnabled} is
* true, then we use the size behavior, which constrains the view height to fit the height of its contents.
*
* @module.api
*/
public boolean autoFillsHeight = false;

public LayoutParams() {
public LayoutParams()
{
super(WRAP_CONTENT, WRAP_CONTENT);

index = Integer.MIN_VALUE;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -381,10 +381,10 @@ public void propertyChanged(String key, Object oldValue, Object newValue, KrollP
if (newValue != null) {
if (!newValue.equals(TiC.SIZE_AUTO)) {
layoutParams.optionHeight = TiConvert.toTiDimension(TiConvert.toString(newValue), TiDimension.TYPE_HEIGHT);
layoutParams.autoHeight = false;
layoutParams.sizeOrFillHeightEnabled = false;
} else {
layoutParams.optionHeight = null;
layoutParams.autoHeight = true;
layoutParams.sizeOrFillHeightEnabled = true;
}
} else {
layoutParams.optionHeight = null;
Expand All @@ -394,10 +394,10 @@ public void propertyChanged(String key, Object oldValue, Object newValue, KrollP
if (newValue != null) {
if (!newValue.equals(TiC.SIZE_AUTO)) {
layoutParams.optionWidth = TiConvert.toTiDimension(TiConvert.toString(newValue), TiDimension.TYPE_WIDTH);
layoutParams.autoWidth = false;
layoutParams.sizeOrFillWidthEnabled = false;
} else {
layoutParams.optionWidth = null;
layoutParams.autoWidth = true;
layoutParams.sizeOrFillWidthEnabled = true;
}
} else {
layoutParams.optionWidth = null;
Expand Down
20 changes: 20 additions & 0 deletions drillbit/tests/ui.layout/ui.layout.js
Original file line number Diff line number Diff line change
Expand Up @@ -631,6 +631,26 @@ describe("Ti.UI Layout tests", {
win.add(view1);
win.open();
}),
fillInVerticalLayout: asyncTest(function() {
var win = Ti.UI.createWindow({
});
var parent = Ti.UI.createView({
height: 50,
width: 40,
layout: 'vertical',
});
var child = Ti.UI.createView({
});
parent.add(child);
win.add(parent);
win.addEventListener("open", this.async(function(e) {
valueOf(parent.size.width).shouldBe(40);
valueOf(parent.size.height).shouldBe(50);
valueOf(child.size.width).shouldBe(40);
valueOf(child.size.height).shouldBe(50);
}));
win.open();
}),
fourPins: asyncTest(function() {
var win = Ti.UI.createWindow({
width: 100, height: 100
Expand Down

0 comments on commit eea3f63

Please sign in to comment.