Project

General

Profile

Download (5.29 KB) Statistics
| Branch: | Tag: | Revision:
1
/*******************************************************************************
2
 * Copyright (c) 2000, 2010 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 *
8
 * Contributors:
9
 *     IBM Corporation - initial API and implementation
10
 *******************************************************************************/
11
package org.eclipse.draw2d.text;
12

    
13
import java.util.ArrayList;
14
import java.util.Iterator;
15
import java.util.List;
16

    
17

    
18
import org.eclipse.draw2d.Border;
19
import org.eclipse.draw2d.ColorConstants;
20
import org.eclipse.draw2d.Graphics;
21
import org.eclipse.draw2d.geometry.Rectangle;
22
import org.eclipse.draw2d.rap.swt.SWT;
23

    
24
/**
25
 * A <code>FlowFigure</code> represented by multiple <code>LineBox</code>
26
 * fragments. An <code>InlineFlow</code>'s parent must be either a
27
 * {@link BlockFlow} or another InlineFlow.
28
 * 
29
 * <P>
30
 * An InlineFlow may contain other InlineFlow figures.
31
 * 
32
 * <P>
33
 * WARNING: This class is not intended to be subclassed by clients.
34
 * 
35
 * @author Randy Hudson
36
 * @since 2.0
37
 */
38
public class InlineFlow extends FlowFigure {
39

    
40
	List fragments = new ArrayList(1);
41

    
42
	/**
43
	 * Iterates over the children to find the width before a line-break is
44
	 * encountered.
45
	 * 
46
	 * @see org.eclipse.draw2d.text.FlowFigure#addLeadingWordRequirements(int[])
47
	 */
48
	public boolean addLeadingWordRequirements(int[] width) {
49
		Iterator iter = getChildren().iterator();
50
		while (iter.hasNext()) {
51
			if (((FlowFigure) iter.next()).addLeadingWordRequirements(width))
52
				return true;
53
		}
54
		return false;
55
	}
56

    
57
	/**
58
	 * Extended to return false if the point is not also contained by at least
59
	 * one fragment.
60
	 * 
61
	 * @return <code>true</code> if a fragment contains the given point
62
	 * @param x
63
	 *            the relative x coordinate
64
	 * @param y
65
	 *            the relative y coordinate
66
	 */
67
	public boolean containsPoint(int x, int y) {
68
		if (super.containsPoint(x, y)) {
69
			List frags = getFragments();
70
			for (int i = 0; i < frags.size(); i++)
71
				if (((FlowBox) frags.get(i)).containsPoint(x, y))
72
					return true;
73
		}
74

    
75
		return false;
76
	}
77

    
78
	/**
79
	 * @see FlowFigure#createDefaultFlowLayout()
80
	 */
81
	protected FlowFigureLayout createDefaultFlowLayout() {
82
		return new InlineFlowLayout(this);
83
	}
84

    
85
	/**
86
	 * Returns the <code>FlowBox</code> fragments contained in this InlineFlow.
87
	 * The returned list should not be modified.
88
	 * 
89
	 * @return The fragments
90
	 */
91
	public List getFragments() {
92
		return fragments;
93
	}
94

    
95
	/**
96
	 * Overridden to paint a {@link FlowBorder} if present, and draw selection.
97
	 * The border is painted first, followed by selection which is generally
98
	 * done in XOR, which still allows the border to be seen.
99
	 * 
100
	 * @param graphics
101
	 *            the graphics
102
	 */
103
	protected void paintBorder(Graphics graphics) {
104
		if (getBorder() != null) {
105
			FlowBorder fb = (FlowBorder) getBorder();
106
			List frags = getFragments();
107
			Rectangle where = new Rectangle();
108
			int sides;
109
			for (int i = 0; i < frags.size(); i++) {
110
				FlowBox box = (FlowBox) frags.get(i);
111

    
112
				where.x = box.getX();
113
				where.width = box.getWidth();
114
				where.y = -box.getAscentWithBorder();
115
				where.height = box.getDescentWithBorder() - where.y;
116
				where.y += box.getBaseline();
117
				sides = 0;
118
				if (i == 0)
119
					sides = SWT.LEAD;
120
				if (i == frags.size() - 1)
121
					sides |= SWT.TRAIL;
122
				fb.paint(this, graphics, where, sides);
123
			}
124
			graphics.restoreState();
125
		}
126
		if (selectionStart != -1)
127
			paintSelection(graphics);
128
	}
129

    
130
	/**
131
	 * Renders the XOR selection rectangles to the graphics.
132
	 * 
133
	 * @param graphics
134
	 *            the graphics to paint on
135
	 * @since 3.1
136
	 */
137
	protected void paintSelection(Graphics graphics) {
138
		graphics.restoreState();
139
		graphics.setXORMode(true);
140
		graphics.setBackgroundColor(ColorConstants.white);
141
		List list = getFragments();
142
		FlowBox box;
143
		for (int i = 0; i < list.size(); i++) {
144
			box = (FlowBox) list.get(i);
145
			int top = box.getLineRoot().getVisibleTop();
146
			int bottom = box.getLineRoot().getVisibleBottom();
147
			graphics.fillRectangle(box.getX(), top, box.getWidth(), bottom
148
					- top);
149
		}
150
	}
151

    
152
	/**
153
	 * @see FlowFigure#postValidate()
154
	 */
155
	public void postValidate() {
156
		List list = getFragments();
157
		FlowBox box;
158
		int left = Integer.MAX_VALUE, top = left;
159
		int right = Integer.MIN_VALUE, bottom = right;
160

    
161
		for (int i = 0; i < list.size(); i++) {
162
			box = (FlowBox) list.get(i);
163
			left = Math.min(left, box.getX());
164
			right = Math.max(right, box.getX() + box.getWidth());
165
			top = Math.min(top, box.getLineRoot().getVisibleTop());
166
			bottom = Math.max(bottom, box.getLineRoot().getVisibleBottom());
167
		}
168

    
169
		setBounds(new Rectangle(left, top, right - left, bottom - top));
170
		repaint();
171
		list = getChildren();
172
		for (int i = 0; i < list.size(); i++)
173
			((FlowFigure) list.get(i)).postValidate();
174
	}
175

    
176
	/**
177
	 * Overridden to assert that only {@link FlowBorder} is used.
178
	 * <code>null</code> is still a valid value as well.
179
	 * 
180
	 * @param border
181
	 *            <code>null</code> or a FlowBorder
182
	 */
183
	public void setBorder(Border border) {
184
		if (border == null || border instanceof FlowBorder)
185
			super.setBorder(border);
186
		else
187
			throw new RuntimeException(
188
					"Border must be an instance of FlowBorder"); //$NON-NLS-1$
189
	}
190

    
191
}
(20-20/31)