Download
Getting Started
Members
Projects
Community
Marketplace
Events
Planet Eclipse
Newsletter
Videos
Participate
Report a Bug
Forums
Mailing Lists
Wiki
IRC
How to Contribute
Working Groups
Automotive
Internet of Things
LocationTech
Long-Term Support
PolarSys
Science
OpenMDM
More
Community
Marketplace
Events
Planet Eclipse
Newsletter
Videos
Participate
Report a Bug
Forums
Mailing Lists
Wiki
IRC
How to Contribute
Working Groups
Automotive
Internet of Things
LocationTech
Long-Term Support
PolarSys
Science
OpenMDM
Toggle navigation
Bugzilla – Attachment 72495 Details for
Bug 188333
[Viewers] Label provider for multi-colored TableItems/TreeItems
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
Log In
[x]
|
Terms of Use
|
Copyright Agent
implementation for single line labels
StyledLabelProvider.java (text/plain), 18.61 KB, created by
Michael Chervil
on 2007-06-26 13:06:46 EDT
(
hide
)
Description:
implementation for single line labels
Filename:
MIME Type:
Creator:
Michael Chervil
Created:
2007-06-26 13:06:46 EDT
Size:
18.61 KB
patch
obsolete
>/******************************************************************************* > * Copyright (c) 2007 Michael Krkoska 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: > * Michael Krkoska - initial API and implementation > *******************************************************************************/ > >package org.eclipse.jface.viewers; > >import java.util.HashMap; >import java.util.Iterator; >import java.util.Map; > >import org.eclipse.core.runtime.Assert; >import org.eclipse.jface.resource.JFaceResources; >import org.eclipse.swt.SWT; >import org.eclipse.swt.custom.StyleRange; >import org.eclipse.swt.graphics.Color; >import org.eclipse.swt.graphics.Device; >import org.eclipse.swt.graphics.Font; >import org.eclipse.swt.graphics.FontData; >import org.eclipse.swt.graphics.FontMetrics; >import org.eclipse.swt.graphics.GC; >import org.eclipse.swt.graphics.GlyphMetrics; >import org.eclipse.swt.graphics.Image; >import org.eclipse.swt.graphics.Point; >import org.eclipse.swt.graphics.Rectangle; >import org.eclipse.swt.graphics.TextLayout; >import org.eclipse.swt.graphics.TextStyle; >import org.eclipse.swt.widgets.Display; >import org.eclipse.swt.widgets.Event; >import org.eclipse.swt.widgets.Listener; > > >/** > * An OwnerDrawLabelProvider which applies StyleRanges to the labels provided by a wrapped ILabelProvider or > * ITableLabelProvider. Multi font, multi color labels are supported as well as placing the image anywhere in the label > * text. > * <p> > * To specify the position of the image provided by the label provider, include the IMAGE_PLACEHOLDER char in your > * label. > * </p> > * <p> > * Subclasses must implement either ILabelProvider or ITableLabelProvider to provide the items' labels. > * > * If a subclass implements IFontProvider or IColorProvider or the corresponding table variants, the provided color and > * font information is used as default style for the item. > * </p> > * <p> > * To enable custom draw for your viewer's control, simply call {@link StyledLabelProvider#setUpOwnerDraw(ColumnViewer)} > * after adding all columns and add the StyledLabelProvider to the viewer. > * </p> > * > * @see StyleRange > * @since 3.4 > * @author Michael Krkoska <michael.krkoska@gmail.com> > */ >public abstract class StyledLabelProvider extends BaseLabelProvider { > > /** > * This is the char which can be used as placeholder for an image in the label. > */ > public static final char IMAGE_PLACEHOLDER = '\uFFFC'; > > /** > * Style constant for centering the viewer's items vertically if their heights are less than the maximum vertical > * height. > */ > public static final int CENTER_ITEMS_VERTICALLY = 1; > /** > * Style constant for centering the text of a viewer's item vertically if its height is less than the height of the > * item's image. > */ > public static final int CENTER_TEXT_VERTICALLY = 2; > > /** > * Set up the owner draw callbacks for the viewer. > * <p> > * This method must be called after adding all columns to the viewer. > * </p> > * @param viewer > * the viewer the owner draw is set up > */ > public static void setUpOwnerDraw( final ColumnViewer viewer ) { > /* > * Unfortunately we cannot use OwnerDrawLabelProvider because it uses CellLabelProviders: In > * ColumnViewer.setLabelProvider(.) the StyledLabelProvider might get wrapped, so that the instanceof operation > * fails. > */ > viewer.getControl().addListener(SWT.MeasureItem, new Listener() { > > public void handleEvent( Event event ) { > IBaseLabelProvider provider = viewer.getLabelProvider(); > Object element = event.item.getData(); > if ( provider instanceof StyledLabelProvider ) { > ((StyledLabelProvider)provider).measure(event, element); > } > } > }); > > viewer.getControl().addListener(SWT.PaintItem, new Listener() { > > public void handleEvent( Event event ) { > IBaseLabelProvider provider = viewer.getLabelProvider(); > Object element = event.item.getData(); > if ( provider instanceof StyledLabelProvider ) { > ((StyledLabelProvider)provider).paint(event, element); > } > } > }); > > viewer.getControl().addListener(SWT.EraseItem, new Listener() { > > public void handleEvent( Event event ) { > IBaseLabelProvider provider = viewer.getLabelProvider(); > Object element = event.item.getData(); > if ( provider instanceof StyledLabelProvider ) { > ((StyledLabelProvider)provider).erase(event, element); > } > } > }); > > CellLabelProvider c = new CellLabelProvider() { > > public void update( ViewerCell cell ) { > // Force a redraw > Rectangle cellBounds = cell.getBounds(); > cell.getControl().redraw(cellBounds.x, cellBounds.y, cellBounds.width, cellBounds.height, true); > } > }; > > ViewerColumn column; > int i = 0; > while ( (column = viewer.getViewerColumn(i++)) != null ) { > column.setLabelProvider(c); > } > } > > boolean centerItemsVertically = false; > boolean centerTextVertically = false; > private Map styledFonts = new HashMap(); > private ILabelProvider labelProvider; > private IFontProvider fontProvider = null; > private IColorProvider colorProvider = null; > private ITableLabelProvider tableLabelProvider = null; > > private ITableFontProvider tableFontProvider = null; > private ITableColorProvider tableColorProvider = null; > > /** > * Creates a new StyledLabelProvider. > * > * @param style > * the style bits > * @see StyledLabelProvider#CENTER_ITEMS_VERTICALLY > * @see StyledLabelProvider#CENTER_TEXT_VERTICALLY > */ > public StyledLabelProvider( int style ) { > setLabelProvider(); > if ( (CENTER_ITEMS_VERTICALLY & style) != 0 ) { > centerItemsVertically = true; > } > if ( (CENTER_TEXT_VERTICALLY & style) != 0 ) { > centerTextVertically = true; > } > } > > public void dispose() { > super.dispose(); > for ( Iterator iterator = styledFonts.values().iterator(); iterator.hasNext(); ) { > Font f = (Font)iterator.next(); > f.dispose(); > } > styledFonts.clear(); > } > > /** > * Returns an array of StyleRange instances which are to be applied to the label. > * > * @param element > * The element whose label is going to be displayed > * @param columnIndex > * The column index of the label > * @param label > * The label for which to provide the StyleRanges > * @return An array of StyleRange instances, may be null if no styles are to be applied for this label. > */ > public abstract StyleRange[] getStyleRanges( Object element, int columnIndex, String label ); > > /** > * Creates a TextLayout instance for either measuring or painting the item, using the StyleRanges supplied by > * {@link StyledLabelProvider#getStyleRanges(Object, int, String)}. > * > * Adds an image at the first occurence of {@link StyledLabelProvider#IMAGE_PLACEHOLDER} or at the beginning of the > * label. > * > * @param event > * the measure or paint event for which a TextLayout is needed > * @param label > * the label to display. > * @param image > * the image to display. May be null. > * @param defaultFont > * the default font for the label. If null the system default font is used. > * @param defaultBackground > * the default background color. May be null. > * @param element > * the model element used to obtain label and styles. > * @param columnIndex > * the column index of the label > * @return a TextLayout instance which must be disposed after use. > */ > protected TextLayout createTextLayout( Event event, String label, Image image, Font defaultFont, Color defaultBackground, Object element, int columnIndex ) { > > Display display = event.display; > TextLayout layout = new TextLayout(display); > > int maxFontHeight = 0; > if ( defaultFont != null ) { > layout.setFont(defaultFont); > maxFontHeight = getFontHeight(defaultFont); > } > else { > maxFontHeight = getFontHeight(display.getSystemFont()); > } > > int rangeOffset = 0, imageOffset = 0; > GlyphMetrics imageMetrics = null; > TextStyle imageStyle = null; > if ( image != null ) { > int index = label.indexOf(IMAGE_PLACEHOLDER); > String labelWithImage = label; > if ( index < 0 ) { > labelWithImage = IMAGE_PLACEHOLDER + " " + label; //$NON-NLS-1$ > rangeOffset = 2; > } > layout.setText(labelWithImage); > imageOffset = Math.max(0, index); > Rectangle bounds = image.getBounds(); > imageStyle = new TextStyle(null, null, null); > imageMetrics = new GlyphMetrics(bounds.height, 0, bounds.width); > imageStyle.metrics = imageMetrics; > } > else { > layout.setText(label); > } > > StyleRange[] styleRanges = getStyleRanges(element, columnIndex, label); > if ( styleRanges != null ) { > for ( int i = 0; i < styleRanges.length; i++ ) { > StyleRange styleRange = styleRanges[i]; > checkFont(display, styleRange); > layout.setStyle(styleRange, styleRange.start + rangeOffset, styleRange.start + rangeOffset + styleRange.length - 1); > if ( styleRange.font != null ) { > maxFontHeight = Math.max(maxFontHeight, getFontHeight(styleRange.font)); > } > } > } > > if ( imageStyle != null ) { > layout.setStyle(imageStyle, imageOffset, imageOffset); > } > > if ( centerTextVertically && imageMetrics != null ) { > int lineCount = layout.getLineCount(); > if ( lineCount == 1 && imageMetrics.ascent > maxFontHeight ) { > // vertically center the text if there is an image bigger than the text. > int height = imageMetrics.ascent; > int space = (height - maxFontHeight); > imageMetrics.ascent = (maxFontHeight) + Math.round(space / 2f); > // TODO why does it look better (at least on win xp) with this added pixel? > layout.setDescent(height - imageMetrics.ascent + 1); > } > > } > > if ( defaultBackground != null ) { > int[] ranges = layout.getRanges(); > int oldEnd = -1; > TextStyle[] styles = layout.getStyles(); > for ( int i = 0, length = ranges.length; i < length; i += 2 ) { > int start = ranges[i]; > int end = ranges[i + 1]; > if ( start > oldEnd + 1 ) { > TextStyle style = new TextStyle(null, null, defaultBackground); > layout.setStyle(style, oldEnd + 1, start - 1); > } > > TextStyle style = styles[i >> 1]; > if ( style.background == null ) { > style.background = defaultBackground; > layout.setStyle(style, start, end); > } > > oldEnd = end; > } > if ( layout.getText().length() > oldEnd + 1 ) { > TextStyle style = new TextStyle(null, null, defaultBackground); > layout.setStyle(style, oldEnd + 1, layout.getText().length() - 1); > } > } > > return layout; > } > > /** > * Handle the erase event. The default implementation does nothing to ensure keep native selection highlighting > * working. > * > * @param event > * the erase event > * @param element > * the model object > * @see SWT#EraseItem > */ > protected void erase( Event event, Object element ) { > event.detail &= ~SWT.FOREGROUND; > } > > /** > * @param event > * @param element > */ > protected void measure( Event event, Object element ) { > int columnIndex = event.index; > String label = getLabel(element, columnIndex); > Image image = getImage(element, columnIndex); > Font font = getFont(element, columnIndex); > Color defaultBackground = getBackground(element, columnIndex); > TextLayout textLayout = createTextLayout(event, label, image, font, defaultBackground, element, columnIndex); > Rectangle bounds = textLayout.getBounds(); > event.setBounds(new Rectangle(0, 0, bounds.width, bounds.height)); > textLayout.dispose(); > } > > /** > * @param event > * @param element > */ > protected void paint( Event event, Object element ) { > int columnIndex = event.index; > String label = getLabel(element, columnIndex); > Image image = getImage(element, columnIndex); > Font font = getFont(element, columnIndex); > Color defaultBackground = getBackground(element, event.index); > TextLayout textLayout = createTextLayout(event, label, image, font, defaultBackground, element, columnIndex); > GC gc = event.gc; > Color oldForeground = gc.getForeground(), oldBackground = gc.getBackground(); > Color foreground = getForeground(element, columnIndex); > if ( foreground != null ) { > gc.setForeground(foreground); > } > Color background = getBackground(element, columnIndex); > if ( background != null ) { > gc.setBackground(background); > } > > int heightOffset = 0; > if ( centerItemsVertically ) { > heightOffset = (event.height - textLayout.getBounds().height) / 2; > heightOffset = Math.max(0, heightOffset); > } > > textLayout.draw(gc, event.x, event.y + heightOffset); > > if ( image != null ) { > int imageOffset = Math.max(0, label.indexOf(IMAGE_PLACEHOLDER)); > int lineIndex = textLayout.getLineIndex(imageOffset); > FontMetrics lineMetrics = textLayout.getLineMetrics(lineIndex); > Point point = textLayout.getLocation(imageOffset, false); > GlyphMetrics glyphMetrics = textLayout.getStyle(imageOffset).metrics; > int y = event.y + point.y + lineMetrics.getAscent() - glyphMetrics.ascent + heightOffset; > // Following line is because of a strange incorrect measurement of 3 pixels under win32 in some cases. > y = Math.max(event.y, y); > gc.drawImage(image, event.x + point.x, y); > } > textLayout.dispose(); > > gc.setForeground(oldForeground); > gc.setBackground(oldBackground); > } > > int getFontHeight( Font font ) { > int h = 0; > FontData[] fontData = font.getFontData(); > for ( int i = 0; i < fontData.length; i++ ) { > h = Math.max(h, (int)fontData[i].height); > } > return h; > } > > private void checkFont( Device device, StyleRange styleRange ) { > int fontStyle = styleRange.fontStyle; > if ( fontStyle != SWT.NORMAL ) { > Font font = styleRange.font; > if ( font == null ) { > font = JFaceResources.getDefaultFont(); > } > boolean wrongStyle = false; > FontData[] fontData = font.getFontData(); > for ( int i = 0, length = fontData.length; i < length && !wrongStyle; i++ ) { > if ( fontData[i].getStyle() != fontStyle ) { > wrongStyle = true; > } > } > if ( wrongStyle ) { > fontData = getFontData(font, fontStyle); > // TODO using fontData[0] as cache key might be wrong on motif > Font styledFont = (Font)styledFonts.get(fontData[0]); > if ( styledFont == null ) { > styledFont = new Font(device, fontData); > styledFonts.put(fontData[0], styledFont); > } > } > styleRange.font = font; > } > } > > private Color getBackground( Object element, int columnIndex ) { > if ( tableColorProvider != null ) { > return tableColorProvider.getBackground(element, columnIndex); > } > if ( colorProvider != null && columnIndex == 0 ) { > return colorProvider.getBackground(element); > } > return null; > } > > private Font getFont( Object element, int columnIndex ) { > if ( tableFontProvider != null ) { > return tableFontProvider.getFont(element, columnIndex); > } > if ( fontProvider != null && columnIndex == 0 ) { > return fontProvider.getFont(element); > } > return null; > } > > private FontData[] getFontData( Font font, int style ) { > FontData[] fontDatas = font.getFontData(); > for ( int i = 0; i < fontDatas.length; i++ ) { > fontDatas[i].setStyle(style); > } > return fontDatas; > } > > private Color getForeground( Object element, int columnIndex ) { > if ( tableColorProvider != null ) { > return tableColorProvider.getForeground(element, columnIndex); > } > if ( colorProvider != null && columnIndex == 0 ) { > return colorProvider.getForeground(element); > } > return null; > } > > private Image getImage( Object element, int columnIndex ) { > if ( tableLabelProvider != null ) { > return tableLabelProvider.getColumnImage(element, columnIndex); > } > if ( columnIndex == 0 ) { > return labelProvider.getImage(element); > } > return null; > } > > private String getLabel( Object element, int columnIndex ) { > if ( tableLabelProvider != null ) { > return tableLabelProvider.getColumnText(element, columnIndex); > } > if ( columnIndex == 0 ) { > return labelProvider.getText(element); > } > return ""; //$NON-NLS-1$ > } > > private void setLabelProvider() { > Assert.isTrue(this instanceof ITableLabelProvider || this instanceof ILabelProvider); > if ( this instanceof ILabelProvider ) { > this.labelProvider = (ILabelProvider)this; > } > if ( this instanceof IFontProvider ) { > fontProvider = (IFontProvider)this; > } > if ( this instanceof IColorProvider ) { > colorProvider = (IColorProvider)this; > } > if ( this instanceof ITableLabelProvider ) { > tableLabelProvider = (ITableLabelProvider)this; > } > if ( this instanceof ITableFontProvider ) { > tableFontProvider = (ITableFontProvider)this; > } > if ( this instanceof ITableColorProvider ) { > tableColorProvider = (ITableColorProvider)this; > } > } >}
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Raw
Actions:
View
Attachments on
bug 188333
:
72297
|
72298
|
72299
|
72300
|
72421
|
72422
|
72423
|
72424
|
72495
|
72496
|
72539
|
72542
|
72592
|
73167
|
73272
|
73353
|
73614
|
73626
|
73633
|
73818
|
80884
|
80912
|
82965
|
83672