Package name.abuchen.portfolio.ui

Source Code of name.abuchen.portfolio.ui.Sidebar$Item

package name.abuchen.portfolio.ui;

import java.util.ArrayList;
import java.util.List;

import org.eclipse.core.runtime.Platform;
import org.eclipse.jface.action.Action;
import org.eclipse.jface.action.IMenuListener;
import org.eclipse.jface.action.MenuManager;
import org.eclipse.swt.SWT;
import org.eclipse.swt.dnd.DropTarget;
import org.eclipse.swt.dnd.DropTargetEvent;
import org.eclipse.swt.dnd.DropTargetListener;
import org.eclipse.swt.dnd.Transfer;
import org.eclipse.swt.events.DisposeEvent;
import org.eclipse.swt.events.DisposeListener;
import org.eclipse.swt.events.KeyEvent;
import org.eclipse.swt.events.KeyListener;
import org.eclipse.swt.events.MouseAdapter;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.events.PaintEvent;
import org.eclipse.swt.events.PaintListener;
import org.eclipse.swt.events.TraverseEvent;
import org.eclipse.swt.events.TraverseListener;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.graphics.FontData;
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.layout.FormAttachment;
import org.eclipse.swt.layout.FormData;
import org.eclipse.swt.layout.FormLayout;
import org.eclipse.swt.widgets.Canvas;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Menu;

public final class Sidebar extends Composite
{
    public static final class Entry
    {
        private Sidebar bar;

        private Item item;

        private Action action;

        public Entry(Sidebar sidebar, String label)
        {
            bar = sidebar;
            item = bar.createItem(bar.entries.size(), this, label, 0);
        }

        public Entry(Entry parent, String label)
        {
            this.bar = parent.bar;

            int index = this.bar.entries.indexOf(parent) + 1;
            for (; index < this.bar.entries.size(); index++)
                if (bar.entries.get(index).item.indent == parent.item.indent)
                    break;

            item = bar.createItem(index, this, label, parent.item.indent + STEP);
        }

        public Entry(Entry parent, Action action)
        {
            this(parent, action.getText());
            setAction(action);
        }

        public void setAction(Action action)
        {
            this.action = action;

            if (action.getImageDescriptor() != null)
                item.setImage(action.getImageDescriptor().createImage(true));
        }

        public void setContextMenu(IMenuListener listener)
        {
            item.addContextMenu(listener);
        }

        public void addDropSupport(int operations, Transfer[] transferTypes, final DropTargetListener listener)
        {
            DropTarget dropTarget = new DropTarget(item, operations);
            dropTarget.setTransfer(transferTypes);
            dropTarget.addDropListener(new DropTargetListener()
            {
                @Override
                public void dropAccept(DropTargetEvent event)
                {
                    listener.dropAccept(event);
                }

                @Override
                public void drop(DropTargetEvent event)
                {
                    listener.drop(event);
                }

                @Override
                public void dragOver(DropTargetEvent event)
                {
                    listener.dragOver(event);
                }

                @Override
                public void dragOperationChanged(DropTargetEvent event)
                {
                    listener.dragOperationChanged(event);
                }

                @Override
                public void dragLeave(DropTargetEvent event)
                {
                    listener.dragLeave(event);
                    item.setIsDragTarget(false);
                    item.redraw();
                }

                @Override
                public void dragEnter(DropTargetEvent event)
                {
                    listener.dragEnter(event);
                    item.setIsDragTarget(true);
                    item.redraw();
                }
            });
        }

        private Entry findNeighbor(int direction)
        {
            int index = bar.entries.indexOf(this);

            if (direction == SWT.ARROW_DOWN)
                return index + 1 < bar.entries.size() ? bar.entries.get(index + 1) : null;
            else if (direction == SWT.ARROW_UP)
                return index > 0 ? bar.entries.get(index - 1) : null;

            return null;
        }

        public boolean isSelectable()
        {
            return item != null && item.indent > 0 && action != null;
        }

        public void setLabel(String label)
        {
            item.text = label;
            item.redraw();
        }

        public void dispose()
        {
            Entry down = findNeighbor(SWT.ARROW_DOWN);

            if (down != null)
            {
                FormData data = (FormData) down.item.getLayoutData();

                Entry up = findNeighbor(SWT.ARROW_UP);
                if (up != null)
                    data.top = new FormAttachment(up.item, down.item.indent == 0 ? 20 : 0);
                else
                    data.top = new FormAttachment(0, 5);
            }

            bar.entries.remove(this);

            if (bar.selection == this)
                bar.selection = null;

            item.dispose();
            bar.layout();
        }

        public void select()
        {
            bar.select(this);
        }
    }

    private static final int STEP = 15;

    private Color backgroundColor;
    private Color selectedColor;
    private Color lighterSelectedColor;
    private Color sectionColor;

    private Font regularFont;
    private Font boldFont;
    private Font sectionFont;

    private List<Entry> entries = new ArrayList<Entry>();

    private Entry selection = null;

    public Sidebar(Composite parent, int style)
    {
        super(parent, style);

        setLayout(new FormLayout());

        createColorsAndFonts(parent);
        registerListeners();
    }

    public void select(Entry entry)
    {
        Entry oldSelection = selection;
        selection = entry;

        if (oldSelection != null && oldSelection.item != null)
            oldSelection.item.redraw();

        if (selection.item != null)
            selection.item.redraw();

        entry.action.run();
    }

    //
    // listener implementations
    //

    private void registerListeners()
    {
        addDisposeListener(new DisposeListener()
        {
            public void widgetDisposed(DisposeEvent e)
            {
                Sidebar.this.widgetDisposed();
            }
        });

        addPaintListener(new PaintListener()
        {
            public void paintControl(PaintEvent e)
            {
                Sidebar.this.paintControl(e);
            }
        });

        addKeyListener(new KeyListener()
        {
            @Override
            public void keyReleased(KeyEvent e)
            {}

            @Override
            public void keyPressed(KeyEvent e)
            {
                Sidebar.this.keyPressed(e);
            }
        });

        addTraverseListener(new TraverseListener()
        {
            @Override
            public void keyTraversed(TraverseEvent e)
            {
                Sidebar.this.keyTraversed(e);
            }
        });
    }

    private void widgetDisposed()
    {
        backgroundColor.dispose();
        selectedColor.dispose();
        lighterSelectedColor.dispose();
        sectionColor.dispose();

        regularFont.dispose();
        boldFont.dispose();
        sectionFont.dispose();
    }

    private void paintControl(PaintEvent e)
    {
        GC gc = e.gc;
        gc.setForeground(backgroundColor);
        gc.setBackground(Display.getDefault().getSystemColor(SWT.COLOR_WHITE));
        Rectangle r = getClientArea();
        gc.fillGradientRectangle(0, 0, r.width, r.height, false);
    }

    private void keyPressed(KeyEvent e)
    {
        if (selection != null && (e.keyCode == SWT.ARROW_UP || e.keyCode == SWT.ARROW_DOWN))
        {
            Entry entry = selection.findNeighbor(e.keyCode);
            while (entry != null && !entry.isSelectable())
                entry = entry.findNeighbor(e.keyCode);

            if (entry != null)
                select(entry);
        }
        else
        {
            e.doit = false;
        }
    }

    private void keyTraversed(TraverseEvent e)
    {
        if (e.detail == SWT.TRAVERSE_TAB_NEXT || e.detail == SWT.TRAVERSE_TAB_PREVIOUS)
        {
            e.doit = true;
        }
    }

    //
    // item implementation
    //

    private void createColorsAndFonts(Composite parent)
    {
        backgroundColor = new Color(null, 233, 241, 248);
        selectedColor = new Color(null, 115, 158, 227);
        lighterSelectedColor = new Color(null, 189, 208, 241);
        sectionColor = new Color(null, 149, 165, 180);

        FontData fontData = parent.getFont().getFontData()[0];
        regularFont = new Font(Display.getDefault(), fontData);
        fontData.setStyle(SWT.BOLD);
        boldFont = new Font(Display.getDefault(), fontData);

        if (!Platform.OS_MACOSX.equals(Platform.getOS()))
            fontData.setHeight(fontData.getHeight() - 1);

        sectionFont = new Font(Display.getDefault(), fontData);
    }

    private Item createItem(int index, Entry entry, String label, int indent)
    {
        entries.add(index, entry);

        Item l = new Item(this, entry);
        l.setText(label);
        l.setIndent(indent);

        // fix layout data
        FormData data = new FormData();
        data.left = new FormAttachment(0);
        data.right = new FormAttachment(100);

        if (index == 0)
            data.top = new FormAttachment(0, 5);
        else
            data.top = new FormAttachment(entries.get(index - 1).item, indent == 0 ? 20 : 0);
        l.setLayoutData(data);

        if (index + 1 < entries.size())
        {
            Item item = entries.get(index + 1).item;
            data = (FormData) item.getLayoutData();
            data.top = new FormAttachment(l, item.indent == 0 ? 20 : 0);
        }

        this.setTabList(new Control[0]);

        return l;
    }

    private void action(Entry entry)
    {
        if (entry.action != null)
            entry.action.run();
    }

    //
    // item widget
    //

    private class Item extends Canvas
    {
        private static final int MARGIN_X = 5;
        private static final int MARGIN_Y = 3;

        private final Entry entry;

        private int indent;
        private String text;
        private Image image;

        private Menu contextMenu;

        private boolean isDragTarget;

        public Item(Composite parent, Entry entry)
        {
            super(parent, SWT.NO_BACKGROUND | SWT.NO_FOCUS);
            this.entry = entry;

            addDisposeListener(new DisposeListener()
            {
                public void widgetDisposed(DisposeEvent e)
                {
                    Item.this.widgetDisposed();
                }
            });

            addPaintListener(new PaintListener()
            {
                public void paintControl(PaintEvent e)
                {
                    Item.this.paintControl(e);
                }
            });

            addKeyListener(new KeyListener()
            {
                @Override
                public void keyReleased(KeyEvent e)
                {}

                @Override
                public void keyPressed(KeyEvent e)
                {
                    if (e.keyCode == SWT.ARROW_UP || e.keyCode == SWT.ARROW_DOWN)
                        Sidebar.this.keyPressed(e);
                    else
                        e.doit = false;
                }
            });

            addMouseListener(new MouseAdapter()
            {
                public void mouseDown(MouseEvent event)
                {
                    if (event.button == 1)
                    {
                        if (indent > 0)
                        {
                            Sidebar.this.select(Item.this.entry);
                        }
                        else if (indent == 0 && Item.this.entry.action != null)
                        {
                            boolean doIt = true;

                            if (image != null)
                            {
                                Rectangle clientArea = getClientArea();
                                Rectangle imgBounds = image.getBounds();

                                doIt = (event.x >= clientArea.width - imgBounds.width - MARGIN_X)
                                                && (event.x <= clientArea.width - MARGIN_X);
                            }

                            if (doIt)
                                Sidebar.this.action(Item.this.entry);
                        }
                    }
                }
            });
        }

        public void addContextMenu(IMenuListener listener)
        {
            if (contextMenu != null)
                contextMenu.dispose();

            MenuManager menuMgr = new MenuManager("#PopupMenu"); //$NON-NLS-1$
            menuMgr.setRemoveAllWhenShown(true);
            menuMgr.addMenuListener(listener);

            contextMenu = menuMgr.createContextMenu(this);
            setMenu(contextMenu);
        }

        private void widgetDisposed()
        {
            if (image != null)
                image.dispose();

            if (contextMenu != null)
                contextMenu.dispose();
        }

        public void setIsDragTarget(boolean isDragTarget)
        {
            this.isDragTarget = isDragTarget;
        }

        public void setIndent(int indent)
        {
            this.indent = indent;
        }

        public void setText(String text)
        {
            this.text = text;
        }

        public void setImage(Image image)
        {
            this.image = image;
        }

        public Point computeSize(int wHint, int hHint, boolean changed)
        {
            int width = 0, height = 0;
            if (text != null)
            {
                GC gc = new GC(this);
                Point extent = gc.stringExtent(text);
                gc.dispose();
                width += extent.x;
                height = Math.max(height, extent.y);
            }
            if (image != null)
            {
                width += image.getBounds().width + 5;
            }
            return new Point(width + 2 + (2 * MARGIN_X) + indent, height + 2 + (2 * MARGIN_Y));
        }

        private void paintControl(PaintEvent e)
        {
            GC gc = e.gc;

            Color oldBackground = gc.getBackground();
            Color oldForeground = gc.getForeground();

            Rectangle bounds = getClientArea();

            if (Sidebar.this.selection != null && this == Sidebar.this.selection.item)
            {
                gc.setForeground(isDragTarget ? selectedColor : lighterSelectedColor);
                gc.setBackground(selectedColor);
                gc.fillGradientRectangle(bounds.x, bounds.y, bounds.width, bounds.height, true);

                gc.setForeground(getDisplay().getSystemColor(SWT.COLOR_BLACK));
                gc.setFont(boldFont);
            }
            else
            {
                gc.setForeground(backgroundColor);
                gc.setBackground(Display.getDefault().getSystemColor(SWT.COLOR_WHITE));
                gc.fillGradientRectangle(bounds.x, bounds.y, bounds.width, bounds.height, false);

                if (indent > 0)
                {
                    gc.setForeground(getDisplay().getSystemColor(SWT.COLOR_BLACK));
                    gc.setFont(isDragTarget ? boldFont : regularFont);
                }
                else
                {
                    gc.setForeground(isDragTarget ? Display.getDefault().getSystemColor(SWT.COLOR_BLACK) : sectionColor);
                    gc.setFont(sectionFont);
                }
            }

            int x = bounds.x + MARGIN_X + indent;
            if (image != null)
            {
                Rectangle imgBounds = image.getBounds();
                if (indent == 0)
                {
                    gc.drawImage(image, bounds.width - imgBounds.width - MARGIN_X,
                                    (bounds.height - imgBounds.height) / 2);
                }
                else
                {
                    gc.drawImage(image, x, bounds.y + MARGIN_Y);
                    x += imgBounds.width + 5;
                }
            }

            gc.drawText(text, x, bounds.y + MARGIN_Y, true);

            gc.setBackground(oldBackground);
            gc.setForeground(oldForeground);
        }
    }
}
TOP

Related Classes of name.abuchen.portfolio.ui.Sidebar$Item

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.