com.bdaum.zoom.css.ZColumnLabelProvider.java Source code

Java tutorial

Introduction

Here is the source code for com.bdaum.zoom.css.ZColumnLabelProvider.java

Source

/*
 * This file is part of the ZoRa project: http://www.photozora.org.
 *
 * ZoRa is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * ZoRa is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with ZoRa; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 *
 * (c) 2017 Berthold Daum  
 */
package com.bdaum.zoom.css;

import org.eclipse.jface.resource.JFaceResources;
import org.eclipse.jface.viewers.ColumnViewer;
import org.eclipse.jface.viewers.ILabelProvider;
import org.eclipse.jface.viewers.OwnerDrawLabelProvider;
import org.eclipse.jface.viewers.TableViewerColumn;
import org.eclipse.jface.viewers.TreeViewerColumn;
import org.eclipse.jface.viewers.ViewerColumn;
import org.eclipse.swt.SWT;
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.Point;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Item;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableColumn;
import org.eclipse.swt.widgets.Tree;
import org.eclipse.swt.widgets.TreeColumn;

import com.bdaum.zoom.common.CommonUtilities;
import com.bdaum.zoom.css.internal.CssActivator;
import com.bdaum.zoom.css.internal.IColumnLabelColorModel;
import com.bdaum.zoom.css.internal.IThemeListener;

public abstract class ZColumnLabelProvider extends OwnerDrawLabelProvider
        implements ILabelProvider, IColumnLabelColorModel, IThemeListener {

    private static ZColumnLabelProvider instance;

    public static ZColumnLabelProvider getDefaultInstance() {
        if (instance == null)
            instance = new ZColumnLabelProvider() {
                @Override
                public String getText(Object element) {
                    return element.toString();
                }

            };
        return instance;
    }

    private static final String ELLIPSIS = "..."; //$NON-NLS-1$
    private Item colItem;
    private Composite viewerControl;
    private String tooltip;
    private int maxWidth = 0;
    private Color disabledForegroundColor;
    private Color toolTipBackgroundColor;
    private Color toolTipForegroundColor;
    private Color selectedBackgroundColor;
    private Color selectedForegroundColor;

    @Override
    protected void initialize(ColumnViewer viewer, ViewerColumn column) {
        viewerControl = (Composite) viewer.getControl();
        CssActivator activator = CssActivator.getDefault();
        activator.applyExtendedStyle(viewerControl, this);
        activator.addThemeListener(this);
        if (column instanceof TreeViewerColumn)
            colItem = ((TreeViewerColumn) column).getColumn();
        else if (column instanceof TableViewerColumn)
            colItem = ((TableViewerColumn) column).getColumn();
        super.initialize(viewer, column);
    }

    @Override
    public void dispose() {
        CssActivator.getDefault().removeThemeListener(this);
        super.dispose();
    }

    @Override
    protected void measure(Event event, Object element) {
        Rectangle size = getIconBounds();
        event.height = size == null ? 16 : size.height;
        event.width = getColumnWidth();
    }

    private int getColumnWidth() {
        if (colItem instanceof TreeColumn)
            return ((TreeColumn) colItem).getWidth();
        if (colItem instanceof TableColumn)
            return ((TableColumn) colItem).getWidth();
        return viewerControl.getClientArea().width;
    }

    protected Rectangle getIconBounds() {
        return null;
    }

    @Override
    protected void erase(Event event, Object element) {
        if (maxWidth < event.width)
            maxWidth = event.width;
        event.gc.setBackground(
                (event.detail & SWT.SELECTED) != 0 ? getSelectedBackground(element) : getBackground(element));
        event.gc.fillRectangle(event.x, event.y, maxWidth, event.height);
    }

    protected Color getSelectedBackground(Object element) {
        return selectedBackgroundColor == null ? viewerControl.getDisplay().getSystemColor(SWT.COLOR_LIST_SELECTION)
                : selectedBackgroundColor;
    }

    protected Color getSelectedForeground(Object element) {
        return selectedForegroundColor == null ? viewerControl.getForeground() : selectedForegroundColor;
    }

    protected Color getDisabledForeground(Object element) {
        return disabledForegroundColor == null ? viewerControl.getDisplay().getSystemColor(SWT.COLOR_DARK_GRAY)
                : disabledForegroundColor;
    }

    protected Color getBackground(Object element) {
        return viewerControl.getBackground();
    }

    protected Color getForeground(Object element) {
        return viewerControl.getForeground();
    }

    @Override
    public Color getToolTipBackgroundColor(Object element) {
        return toolTipBackgroundColor;
    }

    @Override
    public Color getToolTipForegroundColor(Object element) {
        return toolTipForegroundColor;
    }

    protected void paint(Event event, Object element) {
        GC gc = event.gc;
        tooltip = null;
        Rectangle iconSize = getIconBounds();
        Image image = getImage(element);
        int iconWidth = iconSize != null ? iconSize.width : -1;
        int iconHeight = iconSize != null ? iconSize.height : -1;
        int rowHeight = Math.max(iconHeight, event.height);
        double fac = 1d;
        if (image != null) {
            if (iconSize == null) {
                iconSize = image.getBounds();
                iconWidth = iconSize.width;
                iconHeight = iconSize.height;
                rowHeight = Math.max(iconHeight, event.height);
            } else {
                Rectangle bounds = image.getBounds();
                fac = Math.min(((double) iconWidth) / bounds.width, ((double) iconHeight) / bounds.height);
                iconSize = bounds;
                iconWidth = iconSize.width;
                iconHeight = iconSize.height;
                rowHeight = Math.max(iconHeight, event.height);
            }
        }
        String text = getText(element);
        if (text != null) {
            Font customFont;
            Color foreground, background;
            if ((event.detail & SWT.SELECTED) != 0) {
                customFont = getSelectionFont(element);
                foreground = getSelectedForeground(element);
                background = getSelectedBackground(element);
            } else {
                customFont = getFont(element);
                foreground = getForeground(element);
                background = getBackground(element);
            }
            if (customFont != null)
                gc.setFont(customFont);
            else if ((event.detail & SWT.SELECTED) != 0)
                gc.setFont(JFaceResources.getFontRegistry().get("com.bdaum.zoom.selectionFont")); //$NON-NLS-1$
            else
                gc.setFont(JFaceResources.getDefaultFont());
            gc.setForeground(foreground);
            gc.setBackground(background);
            Point textExtent = gc.textExtent(text);
            if (iconHeight < 0)
                iconHeight = event.height;
            int x = (int) (event.x + iconWidth * fac + 4);
            int mxWidth = getColumnWidth() - x + getColumnXOrigin();
            String shortened = shortenText(element, text, textExtent.x, gc, mxWidth);
            if (shortened.length() < text.length())
                tooltip = text;
            int ty = event.y + (rowHeight - textExtent.y) / 2;
            if (element instanceof ITitle) {
                Point tx = gc.stringExtent(shortened);
                int len = tx.x;
                if (len < mxWidth)
                    x += (mxWidth - len) / 2;
                int th = ty + tx.y / 2;
                gc.drawLine(0, th, mxWidth, th);
                gc.drawLine(0, th + 2, mxWidth, th + 2);
            }
            gc.drawText(shortened, x, ty, (event.detail & SWT.SELECTED) != 0);
        }
        if (image != null) {
            if (iconSize == null)
                gc.drawImage(image, event.x, (rowHeight - iconHeight) / 2);
            else {
                int w = (int) (iconWidth * fac);
                int h = (int) (iconHeight * fac);
                gc.drawImage(image, 0, 0, iconWidth, iconHeight, event.x + (iconWidth - w) / 2,
                        event.y + (rowHeight - h) / 2, w, h);
            }
        }
        viewerControl.setToolTipText(tooltip);
    }

    protected Font getSelectionFont(Object element) {
        return null;
    }

    private int getColumnXOrigin() {
        int x = 0;
        if (viewerControl instanceof Table) {
            Table table = (Table) viewerControl;
            int[] columnOrder = table.getColumnOrder();
            for (int colIndex : columnOrder) {
                TableColumn column = table.getColumn(colIndex);
                if (column == colItem)
                    return x;
                int width = column.getWidth();
                x += width;
            }
        } else if (viewerControl instanceof Tree) {
            Tree tree = (Tree) viewerControl;
            int[] columnOrder = tree.getColumnOrder();
            for (int colIndex : columnOrder) {
                TreeColumn column = tree.getColumn(colIndex);
                if (column == colItem)
                    return x;
                int width = column.getWidth();
                x += width;
            }
        }
        return x;
    }

    protected String shortenText(Object element, String textValue, int maxExtent, GC gc, int maxWidth) {
        if (maxExtent < maxWidth)
            return textValue;
        int length = textValue.length();
        int charsToClip = Math.min(length - 6, Math.round(0.95f * length * (1 - ((float) maxWidth / maxExtent))));
        int pivot = length / 2;
        int start = pivot - (charsToClip / 2);
        int end = pivot + (charsToClip / 2) + 1;
        StringBuilder sb = new StringBuilder();
        while (start >= 0 && end < length) {
            String s = sb.append(textValue, 0, start).append(ELLIPSIS).append(textValue, end, length).toString();
            if (gc.textExtent(s).x < maxWidth)
                return s;
            sb.setLength(0);
            start--;
            end++;
        }
        return textValue;
    }

    protected Font getFont(Object element) {
        if (element instanceof ITitle)
            return JFaceResources.getBannerFont();
        return null;
    }

    @Override
    public String getToolTipText(Object element) {
        return tooltip;
    }

    @Override
    public int getToolTipTimeDisplayed(Object element) {
        String text = getToolTipText(element);
        return text == null ? 0 : CommonUtilities.computeHoverTime(text.length());
    }

    public String getText(Object element) {
        return null;
    }

    public Image getImage(Object element) {
        return null;
    }

    @Override
    public void setDisabledForegroundColor(Color c) {
        disabledForegroundColor = c;
    }

    @Override
    public void setToolTipBackgroundColor(Color c) {
        toolTipBackgroundColor = c;
    }

    @Override
    public void setToolTipForegroundColor(Color c) {
        toolTipForegroundColor = c;
    }

    @Override
    public void setSelectedBackgroundColor(Color c) {
        selectedBackgroundColor = c;

    }

    @Override
    public void setSelectedForegroundColor(Color c) {
        selectedForegroundColor = c;
    }

    @Override
    public boolean applyColorsTo(Object element) {
        return element instanceof Tree || element instanceof Table;
    }

    @Override
    public void themeChanged() {
        CssActivator.getDefault().applyExtendedStyle(viewerControl, this);
    }

}