1:
37:
38:
39: package ;
40:
41: import ;
42:
43: import ;
44: import ;
45: import ;
46: import ;
47:
48: import ;
49: import ;
50: import ;
51: import ;
52: import ;
53: import ;
54: import ;
55:
56:
59: public class BlockView extends BoxView
60: {
61:
62:
66: private static class PositionInfo
67: {
68:
69:
70:
74: static final int STATIC = 0;
75:
76:
80: static final int RELATIVE = 1;
81:
82:
85: static final int ABSOLUTE = 2;
86:
87:
91: static final int FIXED = 3;
92:
93:
96: int type;
97:
98:
101: Length left;
102:
103:
106: Length right;
107:
108:
111: Length top;
112:
113:
116: Length bottom;
117:
118:
127: PositionInfo(int typ, Length l, Length r, Length t, Length b)
128: {
129: type = typ;
130: left = l;
131: right = r;
132: top = t;
133: bottom = b;
134: }
135: }
136:
137:
140: private AttributeSet attributes;
141:
142:
147: StyleSheet.BoxPainter painter;
148:
149:
154: private Length[] cssSpans;
155:
156:
159: private HashMap positionInfo;
160:
161:
168: public BlockView(Element elem, int axis)
169: {
170: super(elem, axis);
171: cssSpans = new Length[2];
172: positionInfo = new HashMap();
173: }
174:
175:
185: public void setParent(View parent)
186: {
187: super.setParent(parent);
188:
189: if (parent != null)
190: setPropertiesFromAttributes();
191: }
192:
193:
203: protected SizeRequirements calculateMajorAxisRequirements(int axis,
204: SizeRequirements r)
205: {
206: if (r == null)
207: r = new SizeRequirements();
208:
209: if (setCSSSpan(r, axis))
210: {
211:
212:
213: SizeRequirements parent = super.calculateMajorAxisRequirements(axis,
214: null);
215: int margin = axis == X_AXIS ? getLeftInset() + getRightInset()
216: : getTopInset() + getBottomInset();
217: r.minimum -= margin;
218: r.preferred -= margin;
219: r.maximum -= margin;
220: constrainSize(axis, r, parent);
221: }
222: else
223: r = super.calculateMajorAxisRequirements(axis, r);
224: return r;
225: }
226:
227:
237: protected SizeRequirements calculateMinorAxisRequirements(int axis,
238: SizeRequirements r)
239: {
240: if (r == null)
241: r = new SizeRequirements();
242:
243: if (setCSSSpan(r, axis))
244: {
245:
246:
247: SizeRequirements parent = super.calculateMinorAxisRequirements(axis,
248: null);
249: int margin = axis == X_AXIS ? getLeftInset() + getRightInset()
250: : getTopInset() + getBottomInset();
251: r.minimum -= margin;
252: r.preferred -= margin;
253: r.maximum -= margin;
254: constrainSize(axis, r, parent);
255: }
256: else
257: r = super.calculateMinorAxisRequirements(axis, r);
258:
259:
260: if (axis == X_AXIS)
261: {
262: Object o = getAttributes().getAttribute(CSS.Attribute.TEXT_ALIGN);
263: if (o != null)
264: {
265: String al = o.toString().trim();
266: if (al.equals("center"))
267: r.alignment = 0.5f;
268: else if (al.equals("right"))
269: r.alignment = 1.0f;
270: else
271: r.alignment = 0.0f;
272: }
273: }
274: return r;
275: }
276:
277:
287: private boolean setCSSSpan(SizeRequirements r, int axis)
288: {
289: boolean ret = false;
290: Length span = cssSpans[axis];
291:
292:
293:
294: if (span != null && ! span.isPercentage())
295: {
296: r.minimum = (int) span.getValue();
297: r.preferred = (int) span.getValue();
298: r.maximum = (int) span.getValue();
299: ret = true;
300: }
301: return ret;
302: }
303:
304:
312: private void constrainSize(int axis, SizeRequirements r,
313: SizeRequirements min)
314: {
315: if (min.minimum > r.minimum)
316: {
317: r.minimum = min.minimum;
318: r.preferred = min.minimum;
319: r.maximum = Math.max(r.maximum, min.maximum);
320: }
321: }
322:
323:
338: protected void layoutMinorAxis(int targetSpan, int axis,
339: int[] offsets, int[] spans)
340: {
341: int viewCount = getViewCount();
342: for (int i = 0; i < viewCount; i++)
343: {
344: View view = getView(i);
345: int min = (int) view.getMinimumSpan(axis);
346: int max;
347:
348: Length length = cssSpans[axis];
349: if (length != null)
350: {
351: min = Math.max((int) length.getValue(targetSpan), min);
352: max = min;
353: }
354: else
355: max = (int) view.getMaximumSpan(axis);
356:
357: if (max < targetSpan)
358: {
359:
360: float align = view.getAlignment(axis);
361: offsets[i] = (int) ((targetSpan - max) * align);
362: spans[i] = max;
363: }
364: else
365: {
366: offsets[i] = 0;
367: spans[i] = Math.max(min, targetSpan);
368: }
369:
370:
371: positionView(targetSpan, axis, i, offsets, spans);
372: }
373: }
374:
375:
379: protected void layoutMajorAxis(int targetSpan, int axis,
380: int[] offsets, int[] spans)
381: {
382: super.layoutMajorAxis(targetSpan, axis, offsets, spans);
383:
384:
385: int viewCount = getViewCount();
386: for (int i = 0; i < viewCount; i++)
387: {
388: positionView(targetSpan, axis, i, offsets, spans);
389: }
390: }
391:
392:
401: private void positionView(int targetSpan, int axis, int i, int[] offsets,
402: int[] spans)
403: {
404: View view = getView(i);
405: PositionInfo pos = (PositionInfo) positionInfo.get(view);
406: if (pos != null)
407: {
408: int p0 = -1;
409: int p1 = -1;
410: if (axis == X_AXIS)
411: {
412: Length l = pos.left;
413: if (l != null)
414: p0 = (int) l.getValue(targetSpan);
415: l = pos.right;
416: if (l != null)
417: p1 = (int) l.getValue(targetSpan);
418: }
419: else
420: {
421: Length l = pos.top;
422: if (l != null)
423: p0 = (int) l.getValue(targetSpan);
424: l = pos.bottom;
425: if (l != null)
426: p1 = (int) l.getValue(targetSpan);
427: }
428: if (pos.type == PositionInfo.ABSOLUTE
429: || pos.type == PositionInfo.FIXED)
430: {
431: if (p0 != -1)
432: {
433: offsets[i] = p0;
434: if (p1 != -1)
435: {
436:
437:
438: spans[i] = targetSpan - p1 - offsets[i];
439: }
440: }
441: else if (p1 != -1)
442: {
443:
444: offsets[i] = targetSpan - p1 - spans[i];
445: }
446: }
447: else if (pos.type == PositionInfo.RELATIVE)
448: {
449: if (p0 != -1)
450: {
451: offsets[i] += p0;
452: if (p1 != -1)
453: {
454:
455:
456: spans[i] = spans[i] - p0 - p1 - offsets[i];
457: }
458: }
459: else if (p1 != -1)
460: {
461:
462: offsets[i] -= p1;
463: }
464: }
465: }
466: }
467:
468:
476: public void paint(Graphics g, Shape a)
477: {
478: Rectangle rect = a instanceof Rectangle ? (Rectangle) a : a.getBounds();
479:
480:
481:
482:
483:
484: painter.paint(g, rect.x, rect.y, rect.width, rect.height, this);
485: super.paint(g, a);
486: }
487:
488:
493: public AttributeSet getAttributes()
494: {
495: if (attributes == null)
496: attributes = getStyleSheet().getViewAttributes(this);
497: return attributes;
498: }
499:
500:
507: public int getResizeWeight(int axis) throws IllegalArgumentException
508: {
509:
510: if (axis == Y_AXIS)
511: return 0;
512: if (axis == X_AXIS)
513: return 1;
514: throw new IllegalArgumentException("Invalid Axis");
515: }
516:
517:
523: public float getAlignment(int axis)
524: {
525: if (axis == X_AXIS)
526: return super.getAlignment(axis);
527: if (axis == Y_AXIS)
528: {
529: if (getViewCount() == 0)
530: return 0.0F;
531: float prefHeight = getPreferredSpan(Y_AXIS);
532: View first = getView(0);
533: float firstRowHeight = first.getPreferredSpan(Y_AXIS);
534: return prefHeight != 0 ? (firstRowHeight * first.getAlignment(Y_AXIS))
535: / prefHeight
536: : 0;
537: }
538: throw new IllegalArgumentException("Invalid Axis");
539: }
540:
541:
549: public void changedUpdate(DocumentEvent ev,
550: Shape a, ViewFactory f)
551: {
552: super.changedUpdate(ev, a, f);
553:
554:
555: int currPos = ev.getOffset();
556: if (currPos <= getStartOffset()
557: && (currPos + ev.getLength()) >= getEndOffset())
558: setPropertiesFromAttributes();
559: }
560:
561:
570: public float getPreferredSpan(int axis) throws IllegalArgumentException
571: {
572: if (axis == X_AXIS || axis == Y_AXIS)
573: return super.getPreferredSpan(axis);
574: throw new IllegalArgumentException("Invalid Axis");
575: }
576:
577:
586: public float getMinimumSpan(int axis) throws IllegalArgumentException
587: {
588: if (axis == X_AXIS || axis == Y_AXIS)
589: return super.getMinimumSpan(axis);
590: throw new IllegalArgumentException("Invalid Axis");
591: }
592:
593:
602: public float getMaximumSpan(int axis) throws IllegalArgumentException
603: {
604: if (axis == X_AXIS || axis == Y_AXIS)
605: return super.getMaximumSpan(axis);
606: throw new IllegalArgumentException("Invalid Axis");
607: }
608:
609:
612: protected void setPropertiesFromAttributes()
613: {
614:
615: StyleSheet ss = getStyleSheet();
616: attributes = ss.getViewAttributes(this);
617:
618:
619: painter = ss.getBoxPainter(attributes);
620:
621:
622: if (attributes != null)
623: {
624: setInsets((short) painter.getInset(TOP, this),
625: (short) painter.getInset(LEFT, this),
626: (short) painter.getInset(BOTTOM, this),
627: (short) painter.getInset(RIGHT, this));
628: }
629:
630:
631: float emBase = ss.getEMBase(attributes);
632: float exBase = ss.getEXBase(attributes);
633: cssSpans[X_AXIS] = (Length) attributes.getAttribute(CSS.Attribute.WIDTH);
634: if (cssSpans[X_AXIS] != null)
635: cssSpans[X_AXIS].setFontBases(emBase, exBase);
636: cssSpans[Y_AXIS] = (Length) attributes.getAttribute(CSS.Attribute.HEIGHT);
637: if (cssSpans[Y_AXIS] != null)
638: cssSpans[Y_AXIS].setFontBases(emBase, exBase);
639: }
640:
641:
646: protected StyleSheet getStyleSheet()
647: {
648: HTMLDocument doc = (HTMLDocument) getDocument();
649: return doc.getStyleSheet();
650: }
651:
652:
655: public void replace(int offset, int length, View[] views)
656: {
657:
658: for (int i = 0; i < length; i++)
659: {
660: View child = getView(i + offset);
661: positionInfo.remove(child);
662: }
663:
664:
665: super.replace(offset, length, views);
666:
667:
668: for (int i = 0; i < views.length; i++)
669: {
670: fetchLayoutInfo(views[i]);
671: }
672: }
673:
674:
679: private void fetchLayoutInfo(View view)
680: {
681: AttributeSet atts = view.getAttributes();
682: Object o = atts.getAttribute(CSS.Attribute.POSITION);
683: if (o != null && o instanceof String && ! o.equals("static"))
684: {
685: int type;
686: if (o.equals("relative"))
687: type = PositionInfo.RELATIVE;
688: else if (o.equals("absolute"))
689: type = PositionInfo.ABSOLUTE;
690: else if (o.equals("fixed"))
691: type = PositionInfo.FIXED;
692: else
693: type = PositionInfo.STATIC;
694:
695: if (type != PositionInfo.STATIC)
696: {
697: StyleSheet ss = getStyleSheet();
698: float emBase = ss.getEMBase(atts);
699: float exBase = ss.getEXBase(atts);
700: Length left = (Length) atts.getAttribute(CSS.Attribute.LEFT);
701: if (left != null)
702: left.setFontBases(emBase, exBase);
703: Length right = (Length) atts.getAttribute(CSS.Attribute.RIGHT);
704: if (right != null)
705: right.setFontBases(emBase, exBase);
706: Length top = (Length) atts.getAttribute(CSS.Attribute.TOP);
707: if (top != null)
708: top.setFontBases(emBase, exBase);
709: Length bottom = (Length) atts.getAttribute(CSS.Attribute.BOTTOM);
710: if (bottom != null)
711: bottom.setFontBases(emBase, exBase);
712: if (left != null || right != null || top != null || bottom != null)
713: {
714: PositionInfo pos = new PositionInfo(type, left, right, top,
715: bottom);
716: positionInfo.put(view, pos);
717: }
718: }
719: }
720: }
721: }