| /******************************************************************************* |
| * Copyright (c) 2006 Sybase, Inc. 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: |
| * Sybase, Inc. - initial API and implementation |
| *******************************************************************************/ |
| package org.eclipse.jst.pagedesigner.css2.layout; |
| |
| import org.eclipse.draw2d.FigureUtilities; |
| import org.eclipse.draw2d.Graphics; |
| import org.eclipse.draw2d.Label; |
| import org.eclipse.draw2d.geometry.Dimension; |
| import org.eclipse.draw2d.geometry.Rectangle; |
| import org.eclipse.swt.graphics.Font; |
| import org.eclipse.swt.graphics.FontMetrics; |
| |
| public class MultiLineLabel extends Label { |
| private static String ELLIPSIS = "..."; //$NON-NLS-1$ |
| |
| protected void paintFigure(Graphics graphics) { |
| if (isOpaque()) { |
| graphics.fillRectangle(getBounds()); |
| } |
| Rectangle bounds1 = getBounds(); |
| graphics.translate(bounds1.x, bounds1.y); |
| drawText(graphics); |
| graphics.translate(-bounds1.x, -bounds1.y); |
| } |
| |
| private void drawText(Graphics graphics) { |
| String[] strings = splitString(getText()); |
| int y = 0; |
| int lineHeight = FigureUtilities.getFontMetrics(getFont()).getHeight(); |
| for (int i = 0; i < strings.length; i++) { |
| graphics.drawText(getSubStringText(strings[i]), 0, y); |
| y += lineHeight; |
| } |
| |
| } |
| |
| private String[] splitString(String text) { |
| String[] lines = new String[1]; |
| int start = 0, pos; |
| do { |
| pos = text.indexOf('\n', start); |
| if (pos == -1) { |
| lines[lines.length - 1] = text.substring(start); |
| } else { |
| boolean crlf = (pos > 0) && (text.charAt(pos - 1) == '\r'); |
| lines[lines.length - 1] = text.substring(start, pos |
| - (crlf ? 1 : 0)); |
| start = pos + 1; |
| String[] newLines = new String[lines.length + 1]; |
| System.arraycopy(lines, 0, newLines, 0, lines.length); |
| lines = newLines; |
| } |
| } while (pos != -1); |
| return lines; |
| } |
| |
| public String getSubStringText(String text) { |
| String subStringText = text; |
| |
| Font currentFont = getFont(); |
| int textWidth = FigureUtilities.getTextWidth(text, currentFont); |
| if (textWidth - getSize().width <= 0) { |
| return subStringText; |
| } |
| |
| Dimension effectiveSize = new Dimension(getSize().width, 0); |
| |
| int dotsWidth = FigureUtilities.getTextWidth(ELLIPSIS, currentFont); |
| |
| if (effectiveSize.width < dotsWidth) { |
| effectiveSize.width = dotsWidth; |
| } |
| |
| int subStringLength = getLargestSubstringConfinedTo(text, currentFont, |
| effectiveSize.width - dotsWidth); |
| subStringText = new String(text.substring(0, subStringLength) |
| + ELLIPSIS); |
| return subStringText; |
| } |
| |
| int getLargestSubstringConfinedTo(String s, Font f, int availableWidth) { |
| FontMetrics metrics = FigureUtilities.getFontMetrics(f); |
| int min, max; |
| float avg = metrics.getAverageCharWidth(); |
| min = 0; |
| max = s.length() + 1; |
| |
| // The size of the current guess |
| int guess = 0, guessSize = 0; |
| while ((max - min) > 1) { |
| // Pick a new guess size |
| // New guess is the last guess plus the missing width in pixels |
| // divided by the average character size in pixels |
| guess = guess + (int) ((availableWidth - guessSize) / avg); |
| |
| if (guess >= max) { |
| guess = max - 1; |
| } |
| if (guess <= min) { |
| guess = min + 1; |
| } |
| |
| // Measure the current guess |
| guessSize = FigureUtilities |
| .getTextExtents(s.substring(0, guess), f).width; |
| |
| if (guessSize < availableWidth) { |
| // We did not use the available width |
| min = guess; |
| } else { |
| // We exceeded the available width |
| max = guess; |
| } |
| } |
| return min; |
| } |
| } |