/******************************************************************************* * Copyright (c) 2000, 2010, 2012 IBM Corporation, Gerhardt Informatics Kft. and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * IBM Corporation - initial API and implementation * Gerhardt Informatics Kft. - GEFGWT port *******************************************************************************/ package org.eclipse.draw2d.text; import java.util.Iterator; import org.eclipse.draw2d.Figure; import org.eclipse.draw2d.IFigure; import org.eclipse.draw2d.geometry.Rectangle; /** * The base implementation for text flow figures. A flow figure is used to * render a document in which elements are laid out horizontally within a "line" * until that line is filled. Layout continues on the next line. * * <p> * WARNING: This class is not intended to be subclassed by clients. Future * versions may contain additional abstract methods. * * @author hudsonr * @since 2.1 */ public abstract class FlowFigure extends Figure { /** * integer indicating whether selection should be displayed. */ protected int selectionStart = -1; /** * Constructs a new FlowFigure. */ public FlowFigure() { setLayoutManager(createDefaultFlowLayout()); } /** * If the child is a <code>FlowFigure</code>, its FlowContext is passed to * it. * * @see org.eclipse.draw2d.IFigure#add(IFigure, Object, int) */ public void add(IFigure child, Object constraint, int index) { super.add(child, constraint, index); // If this layout manager is a FlowContext, then the child *must* be a // FlowFigure if (getLayoutManager() instanceof FlowContext) ((FlowFigure) child) .setFlowContext((FlowContext) getLayoutManager()); revalidateBidi(this); } /** * Calculates the width of text before the next line-break is encountered. * <p> * Default implementation treats each FlowFigure as a line-break. It adds no * width and returns <code>true</code>. Sub-classes should override as * needed. * * @param width * the width before the next line-break (if one's found; all the * width, otherwise) will be added on to the first int in the * given array * @return boolean indicating whether or not a line-break was found * @since 3.1 */ public boolean addLeadingWordRequirements(int[] width) { return true; } /** * FlowFigures can contribute text for their block to the given * {@link BidiProcessor}, which will process the contributions to determine * Bidi levels and shaping requirements. * <p> * This method is invoked as part of validating Bidi. * <p> * Sub-classes that cache the BidiInfo and/or the bidi level in ContentBoxes * should clear the cached values when this method is invoked. * * @param proc * the BidiProcessor to which contributions should be made * @see BidiProcessor#add(FlowFigure, String) * @since 3.1 */ protected void contributeBidi(BidiProcessor proc) { for (Iterator iter = getChildren().iterator(); iter.hasNext();) ((FlowFigure) iter.next()).contributeBidi(proc); } /** * Creates the default layout manager * * @return The default layout */ protected abstract FlowFigureLayout createDefaultFlowLayout(); /** * Called after validate has occurred. This is used to update the bounds of * the FlowFigure to encompass its new flow boxed created during validate. */ public abstract void postValidate(); /** * Overridden to revalidateBidi when fragments are removed. * * @see org.eclipse.draw2d.IFigure#remove(org.eclipse.draw2d.IFigure) */ public void remove(IFigure figure) { super.remove(figure); revalidateBidi(this); } /** * This method should be invoked whenever a change that can potentially * affect the Bidi evaluation is made (eg., adding or removing children, * changing text, etc.). * <p> * The default implementation delegates the revalidation task to the parent. * Only {@link BlockFlow#revalidateBidi(IFigure) blocks} perform the actual * revalidation. * <p> * The given IFigure is the one that triggered the revalidation. This can be * used to optimize bidi evaluation. * * @param origin * the figure that was revalidated * @since 3.1 */ protected void revalidateBidi(IFigure origin) { if (getParent() != null) ((FlowFigure) getParent()).revalidateBidi(origin); } /** * Sets the bidi information for this figure. A flow figure contributes bidi * text in {@link #contributeBidi(BidiProcessor)}. If the figure contributes * text associated with it, this method is called back to indicate the bidi * properties for that text within its block. * * @param info * the BidiInfo for this figure * @since 3.1 */ public void setBidiInfo(BidiInfo info) { } /** * FlowFigures override setBounds() to prevent translation of children. * "bounds" is a derived property for FlowFigures, calculated from the * fragments that make up the FlowFigure. * * @see Figure#setBounds(Rectangle) */ public void setBounds(Rectangle r) { if (bounds.equals(r)) return; if (!r.contains(bounds)) erase(); bounds.x = r.x; bounds.y = r.y; bounds.width = r.width; bounds.height = r.height; fireFigureMoved(); if (isCoordinateSystem()) fireCoordinateSystemChanged(); repaint(); } /** * Sets the flow context. * * @param flowContext * the flow context for this flow figure */ public void setFlowContext(FlowContext flowContext) { ((FlowFigureLayout) getLayoutManager()).setFlowContext(flowContext); } /** * Sets the selection or a range of selection. A start value of -1 is used * to indicate no selection. A start value >=0 indicates show selection. A * start and end value can be used to represent a range of offsets which * should render selection. * * @param start * the start offset * @param end * the end offset * @since 3.1 */ public void setSelection(int start, int end) { if (selectionStart == start) return; selectionStart = start; repaint(); } }