Skip to main content
summaryrefslogtreecommitdiffstats
blob: a1aa2bc1621a2bddb855021b4f4803f227891e5b (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
/*******************************************************************************
 * Copyright (c) 2006, 2007 Sybase, Inc. and others.
 *
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License 2.0
 * which accompanies this distribution, and is available at
 * https://www.eclipse.org/legal/epl-2.0/
 *
 * SPDX-License-Identifier: EPL-2.0
 *
 * Contributors:
 *     Sybase, Inc. - initial API and implementation
 *******************************************************************************/
package org.eclipse.jst.pagedesigner.css2.layout;

import org.eclipse.jst.pagedesigner.css2.ICSSStyle;
import org.eclipse.jst.pagedesigner.css2.property.ICSSPropertyID;
import org.eclipse.jst.pagedesigner.css2.value.Length;

/**
 * When doing absolute positioning, we need to create a block. But that block
 * don't have a corresponding figure. So we need a block without corresponding
 * figure.
 * 
 * @author mengbo
 * @version 1.5
 */
public class BlockFlowContext implements FlowContext {
	private LineBox _currentLine;

	private LineBox _previousLine = null;

	BlockBox _blockBox;

	private final FlowContext _originalContext;

	private final ICSSStyle _style;

	/**
	 * @param originalContext 
	 * @param style 
	 */
	public BlockFlowContext(FlowContext originalContext, ICSSStyle style) {
		this._originalContext = originalContext;
		this._style = style;
		setup();
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.jst.pagedesigner.css2.layout.FlowContext#getContainerWidth()
	 */
	public int getContainerWidth() {

		return _originalContext.getContainerWidth();
	}

	/**
	 * Initialize the object
	 */
	private void setup() {
		_blockBox = new BlockBox();
		_blockBox.setRecommendedWidth(getRecommendedWidth());
		_currentLine = this.getCurrentLine();
		_previousLine = null;
	}

	private int getRecommendedWidth() {
		int containerWidth = getContainerWidth();
		Object leftObj = _style.getStyleProperty(ICSSPropertyID.ATTR_LEFT);
		if (leftObj != null && leftObj instanceof Length) {
			Length left = (Length) leftObj;
			int intLeft = left.getValue();
			if (left.isPercentage()) {
				intLeft = containerWidth * intLeft / 100;
			}
			if (intLeft < containerWidth) {
				return containerWidth - intLeft;
			}
		}
		return containerWidth;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.jst.pagedesigner.css2.layout.FlowContext#addToCurrentLine(org.eclipse.jst.pagedesigner.css2.layout.FlowBox)
	 */
	public void addToCurrentLine(FlowBox block) {
		getCurrentLine().add(block);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.jst.pagedesigner.css2.layout.FlowContext#endLine()
	 */
	public void endLine() {
		// this is called from child layouts.
		// If there is no current line, state is equivalent to new line
		if (_currentLine == null)
			return;
		if (_currentLine.isOccupied())
			layoutLine(); // finalize the current line layout
		else
			return;

		LineBox box = _currentLine;
		// _currentLine = _previousLine; //XXX: ???? why (yang)
		_previousLine = box;

		_currentLine = null;
		// setupLine(getCurrentLine());

	}

	/**
	 * @see org.eclipse.jst.pagedesigner.css2.layout.FlowContext#getCurrentLine()
	 */
	public LineBox getCurrentLine() {
		if (_currentLine == null)
			createNewLine();
		return _currentLine;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.jst.pagedesigner.css2.layout.FlowContext#getCurrentLine(int)
	 */
	public LineBox getCurrentLine(int topMargin) {
		if (_currentLine == null)
			createNewLine(topMargin);
		return _currentLine;
	}

	/**
	 * @param topMargin
	 */
	private void createNewLine(int topMargin) {
		createNewLine();
	}

	private void createNewLine() {
		_currentLine = new LineBox();
		setupLine(_currentLine, Integer.MIN_VALUE);
	}

	/**
	 * Override to setup the line's x, remaining, and available width.
	 * 
	 * @param line
	 *            the LineBox to set up
	 * @param topMargin 
	 */
	protected void setupLine(LineBox line, int topMargin) {
		line.clear();

		// the caller of getCurrentLine() may add leftMargin and leftPadding and
		// leftBorder to line.x
		line._x = _blockBox.getBorderInsets().left + _blockBox.getPaddingInsets().left;

		// FIXME: here should check the floating boxes, and minus the width of
		// them from
		// current line.
		// XXX: the RecommendedContentWidth is related with the RecommendedWidth
		// of container that
		// usually larger than it needed.here we do not set the RecommendedWidth
		// for the sake of
		// layouting right absolute position.
		// /shortcoming:the box will break into multi-line after every white
		// space.
		// line.setRecommendedWidth(_blockBox.getRecommendedContentWidth());
		if (_previousLine == null) {
			line._y = _blockBox.getBorderInsets().top
					+ _blockBox.getPaddingInsets().top;
			if (topMargin != Integer.MIN_VALUE)
				line._y += topMargin;
		} else {
			if (topMargin == Integer.MIN_VALUE)
				line._y = _previousLine._y + _previousLine.getHeight()
						+ getLinePadding() + _previousLine.getMarginInsets().bottom; // XXX:
			// should
			// add
			// previous
			// margin
			// bottom?
			else
				line._y = _previousLine._y
						+ _previousLine.getHeight()
						+ Math.max(topMargin,
								_previousLine.getMarginInsets().bottom);
		}
		// line.validate();
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.jst.pagedesigner.css2.layout.FlowContext#getCurrentY()
	 */
	public int getCurrentY() {
		return getCurrentLine()._y; // FIXME: margin of previous block?

	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.jst.pagedesigner.css2.layout.FlowContext#isCurrentLineOccupied()
	 */
	public boolean isCurrentLineOccupied() {
		return _currentLine != null && _currentLine.isOccupied();
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.jst.pagedesigner.css2.layout.FlowContext#getLastMarginRight()
	 */
	public int getLastMarginRight() {
		if (_currentLine == null || !_currentLine.isOccupied()) {
			return 0;
		}
		FlowBox box = (FlowBox) _currentLine.getFragments().get(
				_currentLine.getFragments().size() - 1);
		if (box != null) {
			return box.getMarginInsets().right;
		}
        return 0;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.jst.pagedesigner.css2.layout.FlowContext#isCalculatingMaxWidth()
	 */
	public boolean isCalculatingMaxWidth() {
		return false;
	}

	/**
	 * Adjust all fragments in the current line to have the same baseline. Do
	 * any additional adjustments, such as horizontal alignment.
	 */
	protected void layoutLine() {
		// currentLine.x = 0; //XXX: comment out, don't understand why set to 0,
		// because it has already
		// been set when setupLine(). And if do need, should
		// set to getBorderPaddingInsets().left
		// if (!isInlineBlock() && shouldExpand())
		// {
		// // FIXME: currently we are using getRecommendedContentWidth,
		// // what happen if after adding the new line, the new width is bigger
		// than
		// // recommendedContentWidth? should we use getWidth() instead of
		// // recommendedcontentWidth?
		//
		// Object textalign =
		// (getCSSStyle().getStyleProperty(ICSSPropertyID.ATTR_TEXTALIGN));
		// if (textalign == ICSSPropertyID.VAL_RIGHT)
		// {
		// _currentLine._x = _blockBox.getRecommendedContentWidth() +
		// _blockBox.getBorderPaddingInsets().left - _currentLine.getWidth();
		// }
		// else if (textalign == ICSSPropertyID.VAL_CENTER)
		// {
		//
		// _currentLine._x = _blockBox.getBorderPaddingInsets().left +
		// (_blockBox.getRecommendedContentWidth() - _currentLine.getWidth()) /
		// 2;
		// }
		// if (_currentLine._x < 0)
		// _currentLine._x = 0;
		// }

		// FIXME: should check vertical alignment here?
		_currentLine.commit();
		_blockBox.add(_currentLine);
	}

	void endBlock() {
		endLine();
	}

	int getLinePadding() {
		return 0;
	}
}

Back to the top