|
3 | 3 | import br.nullexcept.mux.app.Context; |
4 | 4 | import br.nullexcept.mux.graphics.Point; |
5 | 5 | import br.nullexcept.mux.graphics.Rect; |
| 6 | +import br.nullexcept.mux.graphics.Size; |
6 | 7 | import br.nullexcept.mux.input.MotionEvent; |
7 | 8 | import br.nullexcept.mux.input.MouseEvent; |
8 | 9 | import br.nullexcept.mux.res.AttributeList; |
@@ -32,57 +33,62 @@ public void requestLayout() { |
32 | 33 | invalidate(); |
33 | 34 | } else { |
34 | 35 | measure(); |
35 | | - measureBounds(); |
36 | 36 | } |
37 | 37 | } |
38 | 38 |
|
39 | | - private void measureChildren(){ |
40 | | - for (View child : children) { |
41 | | - child.measure(); |
| 39 | + protected int measureSpec(int parent, int spec, int wrap, int padding) { |
| 40 | + if (spec == LayoutParams.WRAP_CONTENT) { |
| 41 | + return wrap + padding; |
| 42 | + } else if (spec == LayoutParams.MATCH_PARENT) { |
| 43 | + return Math.max(parent, 0); |
| 44 | + } else { |
| 45 | + return spec; |
| 46 | + } |
| 47 | + } |
| 48 | + |
| 49 | + protected boolean measureChild(View child) { |
| 50 | + LayoutParams params = child.getLayoutParams(); |
| 51 | + Size size = child.onMeasureContent(); |
| 52 | + Point pos = getChildLocation(child); |
| 53 | + |
| 54 | + int left = pos.x - getPaddingLeft(); |
| 55 | + int top = pos.y - getPaddingTop(); |
| 56 | + |
| 57 | + int w = measureSpec(getMeasuredWidth()-getPaddingLeft()-getPaddingRight()-left, params.width, size.width, child.getPaddingLeft() + child.getPaddingRight()); |
| 58 | + int h = measureSpec(getMeasuredHeight()-getPaddingTop()-getPaddingBottom()-top, params.height, size.height, child.getPaddingTop() + child.getPaddingBottom()); |
| 59 | + if (w != child.getMeasuredWidth() || h != child.getMeasuredHeight()) { |
| 60 | + child.onMeasure(w,h); |
| 61 | + return true; |
42 | 62 | } |
| 63 | + return false; |
| 64 | + } |
| 65 | + |
| 66 | + protected boolean measureChildren(){ |
| 67 | + if (children == null) |
| 68 | + return false; |
| 69 | + |
| 70 | + boolean changed = false; |
43 | 71 | for (View child : children) { |
| 72 | + changed |= measureChild(child); |
| 73 | + } |
| 74 | + |
| 75 | + for (View child: children) { |
44 | 76 | child.measureBounds(); |
45 | 77 | } |
| 78 | + return changed; |
46 | 79 | } |
47 | 80 |
|
48 | 81 | @Override |
49 | 82 | public void measure() { |
50 | | - LayoutParams params = getLayoutParams(); |
51 | 83 | ViewGroup parent = getParent(); |
52 | 84 | if (parent == null) |
53 | 85 | return; |
54 | 86 |
|
55 | | - parent.getInternalSize(rect); |
56 | | - |
57 | | - int ow = getMeasuredWidth(); |
58 | | - int oh = getMeasuredHeight(); |
59 | | - Point location = parent.getChildLocation(this); |
60 | | - int width, height; |
61 | | - if (params.hasWrap()) { |
62 | | - measureChildren(); |
63 | | - if (params.width == LayoutParams.WRAP_CONTENT) { |
64 | | - width = calculateWidth(); |
65 | | - } else { |
66 | | - width = params.width == LayoutParams.MATCH_PARENT ? rect.width() - location.x : params.width; |
67 | | - } |
68 | | - if (params.height == LayoutParams.WRAP_CONTENT) { |
69 | | - height = calculateHeight(); |
70 | | - } else { |
71 | | - height = params.height == LayoutParams.MATCH_PARENT ? rect.height() - location.y : params.height; |
72 | | - } |
73 | | - } else { |
74 | | - width = params.width == LayoutParams.MATCH_PARENT ? rect.width() - location.x : params.width; |
75 | | - height = params.height == LayoutParams.MATCH_PARENT ? rect.height() - location.y : params.height; |
76 | | - width = Math.max(0, width); |
77 | | - height = Math.max(0, height); |
78 | | - } |
79 | | - |
80 | | - measureChildren(); |
81 | | - if (width != ow || height != oh) { |
82 | | - onMeasure(width, height); |
| 87 | + parent.measureChild(this); |
| 88 | + while (measureChildren()) { |
83 | 89 | measure(); |
84 | | - invalidate(); |
85 | 90 | } |
| 91 | + measureBounds(); |
86 | 92 | } |
87 | 93 |
|
88 | 94 | @Override |
@@ -124,23 +130,15 @@ public final View getChildAt(int x,int y){ |
124 | 130 | } |
125 | 131 |
|
126 | 132 | @Override |
127 | | - protected int calculateWidth() { |
128 | | - int width = 0; |
| 133 | + protected Size onMeasureContent() { |
| 134 | + Size size = new Size(); |
129 | 135 | for (View child: children){ |
130 | 136 | int x = Math.max(0, getChildLocation(child).x - getPaddingLeft()); |
131 | | - width = Math.max(x+child.getMeasuredWidth(), width); |
132 | | - } |
133 | | - return width + getPaddingLeft() + getPaddingRight(); |
134 | | - } |
135 | | - |
136 | | - @Override |
137 | | - protected int calculateHeight() { |
138 | | - int height = 0; |
139 | | - for (View child: children){ |
| 137 | + size.width = Math.max(x + child.getMeasuredWidth(), size.width); |
140 | 138 | int y = Math.max(0, getChildLocation(child).y - getPaddingTop()); |
141 | | - height = Math.max(y+child.getMeasuredHeight(), height); |
| 139 | + size.height = Math.max(y+child.getMeasuredHeight(), size.height); |
142 | 140 | } |
143 | | - return height + getPaddingTop() + getPaddingBottom(); |
| 141 | + return size; |
144 | 142 | } |
145 | 143 |
|
146 | 144 | public int getChildrenCount(){ |
|
0 commit comments