net.certiv.fluentmark.editor.FluentSourceViewerInfoControl.java Source code

Java tutorial

Introduction

Here is the source code for net.certiv.fluentmark.editor.FluentSourceViewerInfoControl.java

Source

/*******************************************************************************
 * Copyright (c) 2016 - 2017 Certiv Analytics 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
 ******************************************************************************/
package net.certiv.fluentmark.editor;

import org.eclipse.core.runtime.Assert;
import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.jface.resource.JFaceResources;
import org.eclipse.jface.text.Document;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.IInformationControl;
import org.eclipse.jface.text.IInformationControlCreator;
import org.eclipse.jface.text.IInformationControlExtension;
import org.eclipse.jface.text.source.ISourceViewer;
import org.eclipse.jface.text.source.SourceViewer;
import org.eclipse.jface.text.source.SourceViewerConfiguration;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.StyledText;
import org.eclipse.swt.events.DisposeEvent;
import org.eclipse.swt.events.DisposeListener;
import org.eclipse.swt.events.FocusListener;
import org.eclipse.swt.events.KeyEvent;
import org.eclipse.swt.events.KeyListener;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.graphics.FontData;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.RGB;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Shell;

import net.certiv.fluentmark.FluentUI;
import net.certiv.fluentmark.preferences.Prefs;

/**
 * Source viewer based implementation of <code>IInformationControl</code>. Displays information in a
 * source viewer.
 */
public class FluentSourceViewerInfoControl
        implements IInformationControl, IInformationControlExtension, DisposeListener {

    private Shell shell;
    private StyledText text;
    private SourceViewer viewer;
    private Font textFont;
    private Label statusField;
    private Label separator;
    private Font statusTextFont;
    private int maxWidth = SWT.DEFAULT;
    private int maxHeight = SWT.DEFAULT;
    private final int orientation;

    private Color backgroundColor;
    private boolean isSystemBackgroundColor = true;

    /**
     * Creates a default information control with the given shell as parent. The given information
     * presenter is used to process the information to be displayed. The given styles are applied to the
     * created styled text widget.
     *
     * @param dslUI
     * @param parent the parent shell
     * @param isResizeable
     * @param orientation
     * @param statusFieldText the text to be used in the optional status field or <code>null</code> if
     *            the status field should be hidden
     */
    public FluentSourceViewerInfoControl(Shell parent, boolean isResizable, int orientation,
            String statusFieldText) {

        Assert.isLegal(
                orientation == SWT.RIGHT_TO_LEFT || orientation == SWT.LEFT_TO_RIGHT || orientation == SWT.NONE);
        this.orientation = orientation;

        GridLayout layout;
        GridData gd;

        int shellStyle = SWT.TOOL | SWT.ON_TOP | orientation | (isResizable ? SWT.RESIZE : 0);
        int textStyle = isResizable ? SWT.V_SCROLL | SWT.H_SCROLL : SWT.NONE;

        shell = new Shell(parent, SWT.NO_FOCUS | SWT.ON_TOP | shellStyle);
        Display display = shell.getDisplay();

        initializeColors();

        Composite composite = shell;
        layout = new GridLayout(1, false);
        layout.marginHeight = 0;
        layout.marginWidth = 0;
        composite.setLayout(layout);
        gd = new GridData(GridData.FILL_HORIZONTAL);
        composite.setLayoutData(gd);

        if (statusFieldText != null) {
            composite = new Composite(composite, SWT.NONE);
            layout = new GridLayout(1, false);
            layout.marginHeight = 0;
            layout.marginWidth = 0;
            layout.verticalSpacing = 1;
            composite.setLayout(layout);
            gd = new GridData(GridData.FILL_BOTH);
            composite.setLayoutData(gd);
            composite.setForeground(display.getSystemColor(SWT.COLOR_INFO_FOREGROUND));
            composite.setBackground(backgroundColor);
        }

        // Source viewer
        createViewer(textStyle, composite);
        viewer.setEditable(false);

        text = viewer.getTextWidget();
        gd = new GridData(GridData.BEGINNING | GridData.FILL_BOTH);
        text.setLayoutData(gd);
        text.setForeground(display.getSystemColor(SWT.COLOR_INFO_FOREGROUND));
        text.setBackground(backgroundColor);

        initializeFont();

        text.addKeyListener(new KeyListener() {

            @Override
            public void keyPressed(KeyEvent e) {
                if (e.character == 0x1B) {
                    shell.dispose();
                }
            }

            @Override
            public void keyReleased(KeyEvent e) {
            }
        });

        // Status field
        if (statusFieldText != null) {

            // Horizontal separator line
            separator = new Label(composite, SWT.SEPARATOR | SWT.HORIZONTAL | SWT.LINE_DOT);
            separator.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));

            // Status field label
            statusField = new Label(composite, SWT.RIGHT);
            statusField.setText(statusFieldText);
            Font font = statusField.getFont();
            FontData[] fontDatas = font.getFontData();
            for (FontData fontData : fontDatas) {
                fontData.setHeight(fontData.getHeight() * 9 / 10);
            }
            statusTextFont = new Font(statusField.getDisplay(), fontDatas);
            statusField.setFont(statusTextFont);
            GridData gd2 = new GridData(GridData.FILL_HORIZONTAL | GridData.VERTICAL_ALIGN_BEGINNING);
            statusField.setLayoutData(gd2);

            // Regarding the color see bug 41128
            statusField.setForeground(display.getSystemColor(SWT.COLOR_WIDGET_DARK_SHADOW));
            statusField.setBackground(backgroundColor);
        }

        addDisposeListener(this);
    }

    protected void createViewer(int style, Composite composite) {
        FluentUI mkUI = FluentUI.getDefault();
        FluentTextTools textTools = mkUI.getTextTools();
        IPreferenceStore store = mkUI.getPreferenceStore();
        SourceViewerConfiguration viewerConfig = textTools.createSimpleSourceViewerConfiguration(store);
        viewer = new FluentSourceViewer(composite, null, null, false, style, store);
        viewer.configure(viewerConfig);
    }

    private void initializeColors() {
        RGB bgRGB = getHoverBackgroundColorRGB();
        if (bgRGB != null) {
            backgroundColor = new Color(shell.getDisplay(), bgRGB);
            isSystemBackgroundColor = false;
        } else {
            backgroundColor = shell.getDisplay().getSystemColor(SWT.COLOR_INFO_BACKGROUND);
            isSystemBackgroundColor = true;
        }
    }

    private RGB getHoverBackgroundColorRGB() {
        return null;
    }

    private void initializeFont() {
        textFont = JFaceResources.getFont(Prefs.EDITOR_TEXT_FONT);
        StyledText styledText = getViewer().getTextWidget();
        styledText.setFont(textFont);
    }

    public void setInput(Object input) {
        if (input instanceof String) {
            setInformation((String) input);
        } else {
            setInformation(null);
        }
    }

    @Override
    public void setInformation(String content) {
        if (content == null) {
            viewer.setInput(null);
            return;
        }

        IDocument doc = new Document(content);
        FluentTextTools textTools = FluentUI.getDefault().getTextTools();
        if (textTools != null) {
            textTools.setupDocument(doc);
        }
        viewer.setInput(doc);
    }

    @Override
    public void setVisible(boolean visible) {
        shell.setVisible(visible);
    }

    @Override
    public void widgetDisposed(DisposeEvent event) {
        if (statusTextFont != null && !statusTextFont.isDisposed()) {
            statusTextFont.dispose();
        }

        statusTextFont = null;
        // textFont = null;
        shell = null;
        text = null;
    }

    @Override
    public final void dispose() {
        if (!isSystemBackgroundColor) {
            backgroundColor.dispose();
        }
        if (shell != null && !shell.isDisposed()) {
            shell.dispose();
        } else {
            widgetDisposed(null);
        }
    }

    @Override
    public void setSize(int width, int height) {
        shell.setSize(width, height);
    }

    @Override
    public void setLocation(Point location) {
        shell.setLocation(location);
    }

    @Override
    public void setSizeConstraints(int maxWidth, int maxHeight) {
        this.maxWidth = maxWidth;
        this.maxHeight = maxHeight;
    }

    @Override
    public Point computeSizeHint() {
        // compute the preferred size
        int x = SWT.DEFAULT;
        int y = SWT.DEFAULT;
        Point size = shell.computeSize(x, y);
        if (size.x > maxWidth) {
            x = maxWidth;
        }
        if (size.y > maxHeight) {
            y = maxHeight;
        }

        // recompute using constraints if preferred size is larger than constraints
        if (x != SWT.DEFAULT || y != SWT.DEFAULT) {
            size = shell.computeSize(x, y, false);
        }

        return size;
    }

    @Override
    public void addDisposeListener(DisposeListener listener) {
        shell.addDisposeListener(listener);
    }

    @Override
    public void removeDisposeListener(DisposeListener listener) {
        shell.removeDisposeListener(listener);
    }

    @Override
    public void setForegroundColor(Color foreground) {
        text.setForeground(foreground);
    }

    @Override
    public void setBackgroundColor(Color background) {
        text.setBackground(background);
    }

    @Override
    public boolean isFocusControl() {
        return text.isFocusControl();
    }

    @Override
    public void setFocus() {
        shell.forceFocus();
        text.setFocus();
    }

    @Override
    public void addFocusListener(FocusListener listener) {
        text.addFocusListener(listener);
    }

    @Override
    public void removeFocusListener(FocusListener listener) {
        text.removeFocusListener(listener);
    }

    @Override
    public boolean hasContents() {
        return text.getCharCount() > 0;
    }

    protected ISourceViewer getViewer() {
        return viewer;
    }

    public Rectangle computeTrim() {
        Rectangle trim = shell.computeTrim(0, 0, 0, 0);
        addInternalTrim(trim);
        return trim;
    }

    private void addInternalTrim(Rectangle trim) {
        Rectangle textTrim = text.computeTrim(0, 0, 0, 0);
        trim.x += textTrim.x;
        trim.y += textTrim.y;
        trim.width += textTrim.width;
        trim.height += textTrim.height;

        if (statusField != null) {
            trim.height += separator.computeSize(SWT.DEFAULT, SWT.DEFAULT).y;
            trim.height += statusField.computeSize(SWT.DEFAULT, SWT.DEFAULT).y;
            trim.height += 1; // verticalSpacing
        }
    }

    public Rectangle getBounds() {
        return shell.getBounds();
    }

    public boolean restoresLocation() {
        return false;
    }

    public boolean restoresSize() {
        return false;
    }

    public IInformationControlCreator getInformationPresenterControlCreator() {
        return new IInformationControlCreator() {

            @Override
            public IInformationControl createInformationControl(Shell parent) {
                return new FluentSourceViewerInfoControl(parent, true, orientation, null);
            }
        };
    }

    public boolean containsControl(Control control) {
        do {
            if (control == shell)
                return true;
            if (control instanceof Shell)
                return false;
            control = control.getParent();
        } while (control != null);
        return false;
    }

    public boolean isVisible() {
        return shell != null && !shell.isDisposed() && shell.isVisible();
    }
}