|
What this is
Other links
The source code/******************************************************************************* * Copyright (c) 2007, 2008 IBM Corporation 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 * Michael Krkoska - initial API and implementation (bug 188333) *******************************************************************************/ package org.eclipse.jface.viewers; import org.eclipse.core.runtime.Assert; import org.eclipse.swt.SWT; import org.eclipse.swt.custom.StyleRange; import org.eclipse.swt.graphics.Color; import org.eclipse.swt.graphics.Font; import org.eclipse.swt.graphics.GC; import org.eclipse.swt.graphics.Image; import org.eclipse.swt.graphics.Rectangle; import org.eclipse.swt.graphics.TextLayout; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Event; import org.eclipse.swt.widgets.Item; import org.eclipse.swt.widgets.TableItem; import org.eclipse.swt.widgets.TreeItem; /** * A {@link SimpleStyledCellLabelProvider} supports styled labels by using owner * draw by preserving native viewer behavior: * <ul> * <li>similar image and label positioning * <li>native drawing of focus and selection * </ul> * * * <p> * For providing the label's styles, create a subclass and overwrite * {@link SimpleStyledCellLabelProvider#getLabelPresentationInfo(Object)} to * return all information needed to render a element. * </p> * <p> * The {@link SimpleStyledCellLabelProvider} will ignore all font settings on * {@link StyleRange}. Different fonts would make labels wider, and the native * selection drawing could not be reused. * </p> * * <p>NOTE: This API is experimental and may be deleted or * changed before 3.4 is released.</p> * * * @deprecated Will be removed before 3.4 M6. Use {@link StyledCellLabelProvider} instead. * * @since 3.4 */ public abstract class SimpleStyledCellLabelProvider extends OwnerDrawLabelProvider { /** * Holds all information used to render a styled element. */ public static class LabelPresentationInfo { private final String text; private final Image image; private final StyleRange[] ranges; private final Font defaultFont; private final Color defaultForegroundColor; private final Color defaultBackgroundColor; /** * Creates a {@link SimpleStyledCellLabelProvider.LabelPresentationInfo}. * * @param text * the text of the current element * @param ranges * the styled ranges for the element * @param image * the image for the element or <code>null * @param defaultFont * the default font for the element or <code>null * @param defaultForegroundColor * the default foreground color for the element or * <code>null * @param defaultBackgroundColor * the default background color for the element or * <code>null */ public LabelPresentationInfo(String text, StyleRange[] ranges, Image image, Font defaultFont, Color defaultForegroundColor, Color defaultBackgroundColor) { Assert.isNotNull(text); Assert.isNotNull(ranges); this.text = text; this.ranges = ranges; this.image = image; this.defaultFont = defaultFont; this.defaultForegroundColor = defaultForegroundColor; this.defaultBackgroundColor = defaultBackgroundColor; } /** * Provides the text of the current element. * * @return returns the text. */ public String getText() { return this.text; } /** * Provides the styled ranges that can be applied to the text provided * by {@link #getText()}. The {@link SimpleStyledCellLabelProvider} * will ignore all font settings. * * @return the styled ranges for the element */ public StyleRange[] getStyleRanges() { return this.ranges; } /** * Provides the image of the current element. * * @return returns the image. */ public Image getImage() { return this.image; } /** * Provides a default background color of the current element, which is * used for the part of the label where no background color is specified * in the StyleRanges provided by {@link #getStyleRanges}. * * @return the background color for the element, or <code>null * to use the default background color */ public Color getDefaultBackground() { return this.defaultBackgroundColor; } /** * Provides a default font of the current element. * * @return the font for the element, or <code>null to use the * default font */ public Font getDefaultFont() { return this.defaultFont; } /** * Provides a default foreground color of the current element, which is * used for the part of the label where no foreground color is specified * in the StyleRanges provided by {@link #getStyleRanges}. * * @return the foreground color for the element, or <code>null * to use the default foreground color */ public Color getDefaultForeground() { return this.defaultForegroundColor; } } private static final String KEY_TEXT_LAYOUT = "styled_label_key_"; //$NON-NLS-1$ /** * Style constant for indicating that the styled colors are to be applied * even it the viewer's item is selected. Default is not to apply colors. */ public static final int COLORS_ON_SELECTION = 1 << 0; /** * Style constant for indicating to draw the focus if requested by the owner * draw event. Default is to draw the focus. */ public static final int NO_FOCUS = 1 << 1; /** * Private constant to indicate if owner draw is enabled for the * label provider's column. */ private static final int OWNER_DRAW_ENABLED = 1 << 4; private int style; private TextLayout cachedTextLayout; // reused text layout for // 'cachedLabelInfo' private LabelPresentationInfo cachedLabelInfo; private boolean cachedWasWithColors; private ColumnViewer viewer; private ViewerColumn column; /** * Creates a new StyledCellLabelProvider. By default, owner draw is enabled, focus is drawn and no * colors are painted on selected elements. */ public SimpleStyledCellLabelProvider() { this(0); } /** * Creates a new StyledCellLabelProvider. By default, owner draw is enabled. * * @param style * the style bits * @see SimpleStyledCellLabelProvider#COLORS_ON_SELECTION * @see SimpleStyledCellLabelProvider#NO_FOCUS */ public SimpleStyledCellLabelProvider(int style) { this.style = style & (COLORS_ON_SELECTION | NO_FOCUS) | OWNER_DRAW_ENABLED; } /** * Returns <code>true is the owner draw rendering is enabled for this label provider. * By default owner draw rendering is enabled. If owner draw rendering is disabled, rending is * done by the viewer and no styled ranges (see {@link LabelPresentationInfo#getStyleRanges()}) * are drawn. * * @return <code>true is the rendering of styles is enabled. */ public boolean isOwnerDrawEnabled() { return (this.style & OWNER_DRAW_ENABLED) != 0; } /** * Specifies whether owner draw rendering is enabled for this label * provider. By default owner draw rendering is enabled. If owner draw * rendering is disabled, rendering is done by the viewer and no styled * ranges (see {@link LabelPresentationInfo#getStyleRanges()}) are drawn. * It is the caller's responsibility to also call * {@link StructuredViewer#refresh()} or similar methods to update the * underlying widget. * * @param enabled * specifies if owner draw rendering is enabled */ public void setOwnerDrawEnabled(boolean enabled) { boolean isEnabled= isOwnerDrawEnabled(); if (isEnabled != enabled) { if (enabled) { this.style |= OWNER_DRAW_ENABLED; } else { this.style &= ~OWNER_DRAW_ENABLED; } if (this.viewer != null) { setOwnerDrawEnabled(this.viewer, this.column, enabled); } } } /** * Returns the viewer on which this label provider is installed on or <code>null if the * label provider is not installed. * * @return the viewer on which this label provider is installed on or <code>null if the * label provider is not installed. */ protected final ColumnViewer getViewer() { return this.viewer; } /** * Returns the column on which this label provider is installed on or <code>null if the * label provider is not installed. * * @return the column on which this label provider is installed on or <code>null if the * label provider is not installed. */ protected final ViewerColumn getColumn() { return this.column; } /** * Returns a {@link LabelPresentationInfo} instance containing the text, * image and style information to use for displaying element. * * @param element * the element to create a presentation info for * @return the presentation info */ protected abstract LabelPresentationInfo getLabelPresentationInfo( Object element); /* (non-Javadoc) * @see org.eclipse.jface.viewers.OwnerDrawLabelProvider#initialize(org.eclipse.jface.viewers.ColumnViewer, org.eclipse.jface.viewers.ViewerColumn) */ public void initialize(ColumnViewer viewer, ViewerColumn column) { Assert.isTrue(this.viewer == null && this.column == null, "Label provider instance already in use"); //$NON-NLS-1$ this.viewer = viewer; this.column = column; super.initialize(viewer, column, isOwnerDrawEnabled()); } /* * (non-Javadoc) * * @see org.eclipse.jface.viewers.BaseLabelProvider#dispose() */ public void dispose() { if (this.cachedTextLayout != null) { cachedTextLayout.dispose(); cachedTextLayout = null; } cachedLabelInfo = null; this.viewer= null; this.column= null; super.dispose(); } /* * (non-Javadoc) * * @see org.eclipse.jface.viewers.OwnerDrawLabelProvider#update(org.eclipse.jface.viewers.ViewerCell) */ public void update(ViewerCell cell) { LabelPresentationInfo info = getLabelPresentationInfo(cell.getElement()); cell.setImage(info.getImage()); cell.setText(info.getText()); cell.setFont(info.getDefaultFont()); cell.setBackground(info.getDefaultBackground()); cell.setForeground(info.getDefaultForeground()); if (isOwnerDrawEnabled()) { // store info in the item to avoid recomputation cell.getItem().setData(KEY_TEXT_LAYOUT + cell.getColumnIndex(), info); } else { // make sure the info is cleared to avoid leaks cell.getItem().setData(KEY_TEXT_LAYOUT + cell.getColumnIndex(), null); } super.update(cell); // calls 'repaint' to trigger the paint listener } private TextLayout getSharedTextLayout(Display display) { if (cachedTextLayout == null) { int orientation = viewer.getControl().getStyle() & (SWT.LEFT_TO_RIGHT | SWT.RIGHT_TO_LEFT); cachedTextLayout = new TextLayout(display); cachedTextLayout.setOrientation(orientation); } return cachedTextLayout; } private boolean useColors(Event event) { return (event.detail & SWT.SELECTED) == 0 || (this.style & COLORS_ON_SELECTION) != 0; } private boolean drawFocus(Event event) { return (event.detail & SWT.FOCUSED) != 0 && (this.style & NO_FOCUS) == 0; } private LabelPresentationInfo getInfo(Event event) { return (LabelPresentationInfo) event.item.getData(KEY_TEXT_LAYOUT + event.index); } /** * Returns a {@link TextLayout} instance for the given * {@link LabelPresentationInfo}. The text layout instance is managed by * the label provider. Caller of the method must not dispose the text * layout. * * @param diplay * the current display * @param labelPresentation * the viewerLabel the label info * * @param applyColors * if set, create colors in the result * @param element * the model element * @param item * the item * @param index * the index * @return a TextLayout instance */ private TextLayout getTextLayoutForInfo(Display display, LabelPresentationInfo labelPresentation, boolean applyColors, Item item, int index) { // can use cache? if (cachedLabelInfo == labelPresentation && applyColors == cachedWasWithColors) { return cachedTextLayout; // use cached layout } TextLayout sharedLayout = getSharedTextLayout(display); applyInfoToLayout(sharedLayout, labelPresentation, applyColors, item, index); cachedLabelInfo = labelPresentation; cachedWasWithColors = applyColors; return sharedLayout; } /** * Fills the given text layout with the styles, text and font of the label * info. * * @param layout * the text layout to fill * @param labelInfo * the viewer label * @param applyColors * if set, colors will be used * @param item * the item * @param index * the index */ private void applyInfoToLayout(TextLayout layout, LabelPresentationInfo labelInfo, boolean applyColors, Item item, int index) { layout.setText(""); // make sure no previous ranges are kept //$NON-NLS-1$ layout.setText(labelInfo.getText()); Font font = labelInfo.getDefaultFont(); if (font == null) { if (item instanceof TableItem) { font = ((TableItem)item).getFont(index); } else if (item instanceof TreeItem) { font = ((TreeItem)item).getFont(index); } } layout.setFont(font); // set also if null to clear previous usages StyleRange[] styleRanges = labelInfo.getStyleRanges(); for (int i = 0; i < styleRanges.length; i++) { StyleRange curr = styleRanges[i]; // if no colors apply or font is set, create a clone and clear the // colors and font if (curr.font != null || !applyColors && (curr.foreground != null || curr.background != null)) { curr = (StyleRange) curr.clone(); curr.font = null; // ignore font settings until bug 168807 is resolved if (!applyColors) { curr.foreground = null; curr.background = null; } } layout.setStyle(curr, curr.start, curr.start + curr.length - 1); } } /** * 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) { // use native erase LabelPresentationInfo labelInfo = getInfo(event); if (labelInfo != null) { // info has been set by 'update': announce that we paint ourselves event.detail &= ~SWT.FOREGROUND; } } /* * (non-Javadoc) * * @see org.eclipse.jface.viewers.OwnerDrawLabelProvider#measure(org.eclipse.swt.widgets.Event, * java.lang.Object) */ protected void measure(Event event, Object element) { // use native measuring } /* * (non-Javadoc) * * @see org.eclipse.jface.viewers.OwnerDrawLabelProvider#paint(org.eclipse.swt.widgets.Event, * java.lang.Object) */ protected void paint(Event event, Object element) { LabelPresentationInfo labelInfo = getInfo(event); if (labelInfo == null) { return; // no info cached: skip this entry, use native painting } boolean applyColors = useColors(event); GC gc = event.gc; Color oldForeground = gc.getForeground(); // remember colors to // restore the GC later Color oldBackground = gc.getBackground(); if (applyColors) { Color foreground = labelInfo.getDefaultForeground(); if (foreground != null) { gc.setForeground(foreground); } Color background = labelInfo.getDefaultBackground(); if (background != null) { gc.setBackground(background); } } Image image = labelInfo.getImage(); if (image != null) { Rectangle imageBounds = getImageBounds(event); Rectangle bounds = image.getBounds(); // center the image in the given space int x = imageBounds.x + Math.max(0, (imageBounds.width - bounds.width) / 2); int y = imageBounds.y + Math.max(0, (imageBounds.height - bounds.height) / 2); gc.drawImage(image, x, y); } TextLayout textLayout = getTextLayoutForInfo(event.display, labelInfo, applyColors, (Item)event.item, event.index); Rectangle layoutBounds = textLayout.getBounds(); Rectangle textBounds = getTextBounds(event); int x = textBounds.x; int y = textBounds.y + Math.max(0, (textBounds.height - layoutBounds.height) / 2); textLayout.draw(gc, x, y); if (drawFocus(event)) { Rectangle focusBounds = getBounds(event); gc.drawFocus(focusBounds.x, focusBounds.y, focusBounds.width, focusBounds.height); } gc.setForeground(oldForeground); gc.setBackground(oldBackground); } private Rectangle getBounds(Event event) { Item item = (Item) event.item; if (item instanceof TreeItem) { return ((TreeItem) item).getBounds(); } else if (item instanceof TableItem) { return ((TableItem) item).getBounds(); } return null; } private Rectangle getImageBounds(Event event) { Item item = (Item) event.item; if (item instanceof TreeItem) { return ((TreeItem) item).getImageBounds(event.index); } else if (item instanceof TableItem) { return ((TableItem) item).getImageBounds(event.index); } return null; } private Rectangle getTextBounds(Event event) { Item item = (Item) event.item; if (item instanceof TreeItem) { return ((TreeItem) item).getTextBounds(event.index); } else if (item instanceof TableItem) { return ((TableItem) item).getTextBounds(event.index); } return null; } } |
... this post is sponsored by my books ... | |
#1 New Release! |
FP Best Seller |
Copyright 1998-2021 Alvin Alexander, alvinalexander.com
All Rights Reserved.
A percentage of advertising revenue from
pages under the /java/jwarehouse
URI on this website is
paid back to open source projects.