com.aptana.theme.internal.TextViewerThemer.java Source code

Java tutorial

Introduction

Here is the source code for com.aptana.theme.internal.TextViewerThemer.java

Source

/**
 * Aptana Studio
 * Copyright (c) 2005-2012 by Appcelerator, Inc. All Rights Reserved.
 * Licensed under the terms of the GNU Public License (GPL) v3 (with exceptions).
 * Please see the license.html included with this distribution for details.
 * Any modifications to this file must keep this entire header intact.
 */
package com.aptana.theme.internal;

import org.eclipse.core.runtime.Platform;
import org.eclipse.jface.resource.JFaceResources;
import org.eclipse.jface.text.ITextViewer;
import org.eclipse.swt.custom.StyledText;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.Cursor;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.ImageData;
import org.eclipse.swt.graphics.PaletteData;
import org.eclipse.swt.graphics.RGB;
import org.eclipse.swt.widgets.Caret;
import org.eclipse.swt.widgets.Display;

import com.aptana.theme.ThemePlugin;
import com.aptana.ui.util.UIUtils;

/**
 * Applies theme colors to an ITextViewer's StyledText widget.
 * 
 * @author cwilliams
 */
public class TextViewerThemer extends ControlThemer {

    private static final RGB BLACK = new RGB(0, 0, 0);

    private Image fCaretImage;
    private RGB fCaretColor;
    private Cursor fCursor;

    public TextViewerThemer(ITextViewer viewer) {
        super(viewer.getTextWidget());
    }

    /**
     * Themes always apply to text viewers.
     */
    protected boolean invasiveThemesEnabled() {
        return true;
    }

    /**
     * Always use the editor font.
     */
    protected boolean useEditorFont() {
        return true;
    }

    @Override
    protected void applyTheme() {
        super.applyTheme();

        if (invasiveThemesEnabled() && !controlIsDisposed()) {
            overrideSelectionColor();
            overrideCursor();
            overrideCaretColor();
        }
    }

    /**
     * This is a TextViewer (usually editor contents), so use the text font explicitly, not the view font we set up in
     * parent class.
     */
    protected Font getFont() {
        return JFaceResources.getTextFont();
    }

    private StyledText getTextWidget() {
        return (StyledText) getControl();
    }

    private void overrideSelectionColor() {
        if (getTextWidget() == null) {
            return;
        }

        // Force selection color
        Color existingSelectionBG = getTextWidget().getSelectionBackground();
        RGB selectionRGB = getCurrentTheme().getSelectionAgainstBG();
        if (!existingSelectionBG.getRGB().equals(selectionRGB)) {
            getTextWidget().setSelectionBackground(getColorManager().getColor(selectionRGB));
        }

        if (!Platform.OS_MACOSX.equals(Platform.getOS())) {
            // Linux and windows need selection fg set or we just see a block of color.
            getTextWidget().setSelectionForeground(getForeground());
        }
    }

    private void overrideCursor() {
        if (getTextWidget() == null) {
            return;
        }

        Image cursorImage = null;
        if (getCurrentTheme().hasDarkBG()) {
            cursorImage = UIUtils.getImage(ThemePlugin.getDefault(), ThemePlugin.IBEAM_WHITE);
        } else {
            cursorImage = UIUtils.getImage(ThemePlugin.getDefault(), ThemePlugin.IBEAM_BLACK);
        }

        Display display = getTextWidget().getDisplay();
        Cursor oldCursor = fCursor;

        fCursor = new Cursor(display, cursorImage.getImageData(), 7, 11);
        getTextWidget().setCursor(fCursor);

        if (oldCursor != null) {
            oldCursor.dispose();
        }
    }

    private void overrideCaretColor() {
        if (getTextWidget() == null) {
            return;
        }

        RGB caretColor = getCurrentTheme().getCaret();
        if (caretColor == null) {
            return;
        }

        Caret caret = getTextWidget().getCaret();
        // This is an ugly hack. Setting a black image doesn't work for some reason, but setting no image will cause it
        // to be black.
        if (caretColor.equals(BLACK)) {
            caret.setImage(null);
            return;
        }

        // Shortcut for when color is same, don't do any heavy lifting
        if (this.fCaretImage != null && fCaretColor.equals(caretColor)) {
            return;
        }

        int x = caret.getSize().x;
        int y = caret.getSize().y;
        // Apparently the current caret may have invalid sizings
        // that will cause errors when an attempt to
        // change the color is made. So perform the check and catch
        // errors and exceptions so caret coloring
        // doesn't affect opening the editor.
        if (x > 0 && y > 0) {
            try {
                PaletteData data;
                if (getThemeManager().getCurrentTheme().hasDarkBG()) {
                    data = new PaletteData(new RGB[] { caretColor });
                } else {
                    RGB inverted = new RGB(255 - caretColor.red, 255 - caretColor.green, 255 - caretColor.blue);
                    data = new PaletteData(new RGB[] { inverted });
                }
                ImageData iData = new ImageData(x, y, 1, data);
                caret.setImage(null);
                if (this.fCaretImage != null) {
                    this.fCaretImage.dispose();
                    this.fCaretImage = null;
                }
                this.fCaretImage = new Image(caret.getDisplay(), iData);
                caret.setImage(this.fCaretImage);
                fCaretColor = caretColor;
            } catch (Error e) {
            } catch (Exception e) {
            }
        }
    }

    @Override
    public void dispose() {
        if (fCursor != null) {
            fCursor.dispose();
            fCursor = null;
        }

        if (fCaretImage != null) {
            fCaretImage.dispose();
            fCaretImage = null;
        }
        fCaretColor = null;

        super.dispose();
    }
}