All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.eclipse.ui.internal.FastViewPane Maven / Gradle / Ivy

Go to download

This plug-in contains the bulk of the Workbench implementation, and depends on JFace, SWT, and Core Runtime. It cannot be used independently from org.eclipse.ui. Workbench client plug-ins should not depend directly on this plug-in.

The newest version!
/*******************************************************************************
 * Copyright (c) 2004, 2007 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
 *     Chris Gross [email protected] Bug 107443
 *******************************************************************************/
package org.eclipse.ui.internal;

import org.eclipse.jface.action.ContributionItem;
import org.eclipse.jface.action.IMenuManager;
import org.eclipse.jface.util.Geometry;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.FocusAdapter;
import org.eclipse.swt.events.FocusEvent;
import org.eclipse.swt.events.KeyAdapter;
import org.eclipse.swt.events.KeyEvent;
import org.eclipse.swt.events.KeyListener;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Sash;
import org.eclipse.swt.widgets.ToolBar;
import org.eclipse.ui.ISizeProvider;
import org.eclipse.ui.IViewReference;
import org.eclipse.ui.IWorkbenchPartReference;
import org.eclipse.ui.internal.dnd.DragUtil;
import org.eclipse.ui.internal.presentations.PresentablePart;
import org.eclipse.ui.internal.presentations.SystemMenuFastView;
import org.eclipse.ui.internal.presentations.SystemMenuFastViewOrientation;
import org.eclipse.ui.internal.presentations.SystemMenuSizeFastView;
import org.eclipse.ui.internal.presentations.UpdatingActionContributionItem;
import org.eclipse.ui.presentations.AbstractPresentationFactory;
import org.eclipse.ui.presentations.IPresentablePart;
import org.eclipse.ui.presentations.IStackPresentationSite;
import org.eclipse.ui.presentations.StackPresentation;

/**
 * Handles the presentation of an active fastview. A fast view pane docks to one side of a
 * parent composite, and is capable of displaying a single view. The view may be resized.
 * Displaying a new view will hide any view currently being displayed in the pane. 
 * 
 * Currently, the fast view pane does not own or contain the view. It only controls the view's 
 * position and visibility.  
 * 
 * @see org.eclipse.ui.internal.FastViewBar
 */
public class FastViewPane {
    private int side = SWT.LEFT;

    private PresentablePart currentPane;

    private Composite clientComposite;
    
    private static final int SASH_SIZE = 3;

    private int minSize = 10;

    private int size;

    private Sash sash;

    // Traverse listener -- listens to ESC and closes the active fastview 
    private Listener escapeListener = new Listener() {
        public void handleEvent(Event event) {
            if (event.character == SWT.ESC) {
                if (currentPane != null) {
                    currentPane.getPane().getPage().hideFastView();
                }
            }
        }
    };

    private DefaultStackPresentationSite site = new DefaultStackPresentationSite() {
        /* (non-Javadoc)
         * @see org.eclipse.ui.internal.skins.IPresentationSite#setState(int)
         */
        public void setState(int newState) {
            super.setState(newState);
            PartPane pane = currentPane.getPane();
            switch (newState) {
            case IStackPresentationSite.STATE_MINIMIZED:
                
                pane.getPage().hideFastView();
                break;
            case IStackPresentationSite.STATE_MAXIMIZED:
                pane.setZoomed(true);
                sash.setVisible(false);
                this.getPresentation().setBounds(getBounds());
                break;
            case IStackPresentationSite.STATE_RESTORED:
                pane.setZoomed(false);
                sash.setVisible(true);
                this.getPresentation().setBounds(getBounds());
                break;
            default:
            }
        }

        public void flushLayout() {
        	
        }
        
        public void close(IPresentablePart part) {
            if (!isCloseable(part)) {
                return;
            }
            IWorkbenchPartReference ref = currentPane.getPane().getPartReference();
            if (ref instanceof IViewReference) {
                currentPane.getPane().getPage().hideView((IViewReference)ref);
            }
        }

        public void close(IPresentablePart[] parts) {
            for (int idx = 0; idx < parts.length; idx++) {
                close(parts[idx]);
            }
        }

        /* (non-Javadoc)
         * @see org.eclipse.ui.internal.skins.IPresentationSite#dragStart(org.eclipse.ui.internal.skins.IPresentablePart, boolean)
         */
        public void dragStart(IPresentablePart beingDragged,
                Point initialPosition, boolean keyboard) {
            dragStart(initialPosition, keyboard);
        }

        /* (non-Javadoc)
         * @see org.eclipse.ui.internal.skins.IPresentationSite#dragStart(boolean)
         */
        public void dragStart(Point initialPosition, boolean keyboard) {
            if (!isPartMoveable()) {
				return;
			}

            PartPane pane = currentPane.getPane();

            Control control = this.getPresentation().getControl();

            Rectangle bounds = Geometry.toDisplay(clientComposite, control
                    .getBounds());

            WorkbenchPage page = pane.getPage();

            page.hideFastView();
            if (page.isZoomed()) {
                page.zoomOut();
            }

            DragUtil.performDrag(pane, bounds, initialPosition, !keyboard);
        }

        public IPresentablePart getSelectedPart() {
            return currentPane;
        }

        public void addSystemActions(IMenuManager menuManager) {
        	ViewStackTrimToolBar vstt = getTrim();
        	
            appendToGroupIfPossible(menuManager,
                    "misc", new SystemMenuFastViewOrientation(currentPane.getPane(), vstt)); //$NON-NLS-1$

            // Only add the 'Fast View' menu entry if the
        	// pane is showing a 'legacy' fast view
        	if (vstt == null) {
	            appendToGroupIfPossible(menuManager,
	                    "misc", new UpdatingActionContributionItem(fastViewAction)); //$NON-NLS-1$
        	}
        	
            appendToGroupIfPossible(menuManager,
                    "size", new SystemMenuSizeFastView(FastViewPane.this)); //$NON-NLS-1$
        }

        /**
         * Returns the ViewStackTrimToolBar which has caused the FV to be shown. If
         * null then we can assume it was the legacy FastViewBar.
         */
        private ViewStackTrimToolBar getTrim() {
        	if (currentPane == null || currentPane.getPane() == null)
        		return null;

            ViewStackTrimToolBar trim = null;

        	PartPane pane = currentPane.getPane();
        	if (pane instanceof ViewPane) {
        		ViewPane vp = (ViewPane) pane;
                Perspective persp = vp.getPage().getActivePerspective();
                IViewReference viewRef = vp.getViewReference();
                FastViewManager fvm = persp.getFastViewManager();
                
                String trimId = null;
                if (fvm != null)
                	trimId = fvm.getIdForRef(viewRef);

                if (trimId != null && !trimId.equals(FastViewBar.FASTVIEWBAR_ID))
                	trim = fvm.getViewStackTrimToolbar(trimId);
        	}
        	
        	return trim;
        }
        
        public boolean isPartMoveable(IPresentablePart toMove) {
            return isPartMoveable();
        }

        public boolean isStackMoveable() {
            // a fast view stack is moveable iff its part is moveable
            return isPartMoveable();
        }

        private boolean isPartMoveable() {
            if (currentPane == null) {
				return false;
			}
            Perspective perspective = currentPane.getPane().getPage()
                    .getActivePerspective();
            if (perspective == null) {
                // Shouldn't happen -- can't have a FastViewPane without a perspective
                return false;
            }
            
            IWorkbenchPartReference ref = currentPane.getPane().getPartReference();
            
            if (ref instanceof IViewReference) {
                return perspective.isMoveable((IViewReference)ref);
            }
            return true;
        }

        public boolean supportsState(int newState) {
            if (currentPane == null) {
				return false;
			}
            if (currentPane.getPane().getPage().isFixedLayout()) {
				return false;
			}
            return true;
        }

        public IPresentablePart[] getPartList() {
            return new IPresentablePart[] {getSelectedPart()};
        }

        /* (non-Javadoc)
         * @see org.eclipse.ui.presentations.IStackPresentationSite#getProperty(java.lang.String)
         */
        public String getProperty(String id) {
            // fast views stacks do not get arbitrary user properties.
            return null;
        }
    };

    private SystemMenuFastView fastViewAction = new SystemMenuFastView(site);

    private static void appendToGroupIfPossible(IMenuManager m, String groupId,
            ContributionItem item) {
        try {
            m.appendToGroup(groupId, item);
        } catch (IllegalArgumentException e) {
            m.add(item);
        }
    }

    private Listener mouseDownListener = new Listener() {
        public void handleEvent(Event event) {
            if (event.widget instanceof Control) {
                Control control = (Control) event.widget;

                if (control.getShell() != clientComposite.getShell()) {
                    return;
                }

                if (event.widget instanceof ToolBar) {
                    // Ignore mouse down on actual tool bar buttons
                    Point pt = new Point(event.x, event.y);
                    ToolBar toolBar = (ToolBar) event.widget;
                    if (toolBar.getItem(pt) != null) {
						return;
					}
                }

                Point loc = DragUtil.getEventLoc(event);

            	// 'Extrude' the rect -before- converting to Display coords
            	// to avoid Right-to-Left issues
                Rectangle bounds = clientComposite.getBounds();
                if (site.getState() != IStackPresentationSite.STATE_MAXIMIZED) {
                    bounds = Geometry.getExtrudedEdge(bounds, size + SASH_SIZE, side);
                }
                
                // Now map the bounds to display coords
                bounds = clientComposite.getDisplay().map(clientComposite, null, bounds);

                if (!bounds.contains(loc)) {
                    site.setState(IStackPresentationSite.STATE_MINIMIZED);
                }
            }
        }
    };

    public void moveSash() {
        final KeyListener listener = new KeyAdapter() {
            public void keyPressed(KeyEvent e) {
                if (e.character == SWT.ESC || e.character == '\r') {
                    currentPane.setFocus();
                }
            }
        };
        sash.addFocusListener(new FocusAdapter() {
            public void focusGained(FocusEvent e) {
                sash.setBackground(sash.getDisplay().getSystemColor(
                        SWT.COLOR_LIST_SELECTION));
                sash.addKeyListener(listener);
            }

            public void focusLost(FocusEvent e) {
                sash.setBackground(null);
                sash.removeKeyListener(listener);
            }
        });
        sash.setFocus();
    }

    private Listener resizeListener = new Listener() {
        public void handleEvent(Event event) {
            if (event.type == SWT.Resize && currentPane != null) {
                setSize(size);
            }
        }
    };

    private SelectionAdapter selectionListener = new SelectionAdapter() {
        public void widgetSelected(SelectionEvent e) {

            if (currentPane != null) {
                Rectangle bounds = clientComposite.getClientArea();
                Point location = new Point(e.x, e.y);
                int distanceFromEdge = Geometry.getDistanceFromEdge(bounds,
                        location, side);

                if (!(side == SWT.TOP || side == SWT.LEFT)) {
                    distanceFromEdge -= SASH_SIZE;
                }

                setSize(distanceFromEdge);

                if (e.detail != SWT.DRAG) {
                    updateFastViewSashBounds();
                    //					getPresentation().getControl().moveAbove(null);
                    //					currentPane.moveAbove(null); 
                    //					sash.moveAbove(null);
                    //currentPane.getControl().redraw();
                    sash.redraw();
                }
            }
        }
    };

    private void setSize(int size) {

        if (size < minSize) {
            size = minSize;
        }
        this.size = size;

        StackPresentation presentation = getPresentation();
        if (presentation == null || presentation.getControl().isDisposed()) {
            return;
        }
        getPresentation().setBounds(getBounds());
        updateFastViewSashBounds();
    }

    /**
     * Returns the current fastview size ratio. Returns 0.0 if there is no fastview visible.
     */
    public float getCurrentRatio() {
        if (currentPane == null) {
            return 0.0f;
        }

        boolean isVertical = !Geometry.isHorizontal(side);
        Rectangle clientArea = clientComposite.getClientArea();

        int clientSize = Geometry.getDimension(clientArea, isVertical);

        return (float) size / (float) clientSize;
    }

    private Rectangle getClientArea() {
        return clientComposite.getClientArea();
    }

    private Rectangle getBounds() {
        Rectangle bounds = getClientArea();

        if (site.getState() == IStackPresentationSite.STATE_MAXIMIZED) {
            return bounds;
        }

        boolean horizontal = Geometry.isHorizontal(side);

        int available = Geometry.getDimension(bounds, !horizontal);

        return Geometry.getExtrudedEdge(bounds, Math.min(
                FastViewPane.this.size, available), side);
    }

    /**
     * Displays the given view as a fastview. The view will be docked to the edge of the
     * given composite until it is subsequently hidden by a call to hideFastView. 
     * 
     * @param newClientComposite
     * @param pane
     * @param newSide
     */
    public void showView(Composite newClientComposite, ViewPane pane,
            int newSide, float sizeRatio) {
        side = newSide;

        if (currentPane != null) {
            hideView();
        }

        currentPane = new PresentablePart(pane, newClientComposite);
        
        fastViewAction.setPane(currentPane);
        clientComposite = newClientComposite;

        clientComposite.addListener(SWT.Resize, resizeListener);

        // Create the control first
        Control ctrl = pane.getControl();
        if (ctrl == null) {
            pane.createControl(clientComposite);
            ctrl = pane.getControl();
        }

        ctrl.addListener(SWT.Traverse, escapeListener);

        // Temporarily use the same appearance as docked views .. eventually, fastviews will
        // be independently pluggable.
        AbstractPresentationFactory factory = ((WorkbenchWindow) pane
                .getWorkbenchWindow()).getWindowConfigurer()
                .getPresentationFactory();
        StackPresentation presentation = factory.createViewPresentation(
                newClientComposite, site);

        site.setPresentation(presentation);
        site.setPresentationState(IStackPresentationSite.STATE_RESTORED);
        presentation.addPart(currentPane, null);
        presentation.selectPart(currentPane);
        presentation.setActive(StackPresentation.AS_ACTIVE_FOCUS);
        presentation.setVisible(true);

        boolean horizontalResize = Geometry.isHorizontal(side); 

        minSize = presentation.computePreferredSize(horizontalResize,
        		ISizeProvider.INFINITE,
        		Geometry.getDimension(getClientArea(), horizontalResize),
				0);
        
        // Show pane fast.
        ctrl.setEnabled(true); // Add focus support.
        Composite parent = ctrl.getParent();

        boolean horizontal = Geometry.isHorizontal(side);
        sash = new Sash(parent, Geometry
                .getSwtHorizontalOrVerticalConstant(horizontal));

        sash.addSelectionListener(selectionListener);

        Rectangle clientArea = newClientComposite.getClientArea();

        getPresentation().getControl().moveAbove(null);
        currentPane.getPane().moveAbove(null);
        sash.moveAbove(null);

        setSize((int) (Geometry.getDimension(clientArea, !horizontal) * sizeRatio));

        Display display = sash.getDisplay();

        display.addFilter(SWT.MouseDown, mouseDownListener);

        pane.setFocus();
    }

    /**
     * Updates the position of the resize sash.
     */
    private void updateFastViewSashBounds() {
        Rectangle bounds = getBounds();

        int oppositeSide = Geometry.getOppositeSide(side);
        Rectangle newBounds = Geometry.getExtrudedEdge(bounds, -SASH_SIZE,
                oppositeSide);

        Rectangle oldBounds = sash.getBounds();

        if (!newBounds.equals(oldBounds)) {
            sash.setBounds(newBounds);
        }
    }

    /**
     * Disposes of any active widgetry being used for the fast view pane. Does not dispose
     * of the view itself.
     */
    public void dispose() {
        hideView();
    }
    
    private StackPresentation getPresentation() {
        return site.getPresentation();
    }

    /**
     * Hides the sash for the fastview if it is currently visible. This method may not be
     * required anymore, and might be removed from the public interface.
     */
    public void hideFastViewSash() {
        if (sash != null) {
            sash.setVisible(false);
        }
    }

    /**
     * Hides the currently visible fastview.
     */
    public void hideView() {

        if (clientComposite != null) {
            Display display = clientComposite.getDisplay();

            display.removeFilter(SWT.MouseDown, mouseDownListener);
        }

        if (currentPane == null) {
            return;
        }

        fastViewAction.setPane(null);
        
        //unzoom before hiding
        currentPane.getPane().setZoomed(false);

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

        clientComposite.removeListener(SWT.Resize, resizeListener);

        // Get pane.
        // Hide the right side sash first
        //hideFastViewSash();
        Control ctrl = currentPane.getControl();

        ctrl.removeListener(SWT.Traverse, escapeListener);

        // Hide it completely.
        getPresentation().setVisible(false);
        site.dispose();
        //currentPane.setFastViewSash(null);
        ctrl.setEnabled(false); // Remove focus support.

        currentPane.dispose();
        currentPane = null;
    }

    /**
     * @return Returns the currently visible fastview or null if none
     */
    public ViewPane getCurrentPane() { 
        if (currentPane != null && currentPane.getPane() instanceof ViewPane) {
            return (ViewPane)currentPane.getPane();
        }
        
        return null;
    }

    public void setState(int newState) {
    	site.setState(newState);
    }
    
    public int getState() {
    	return site.getState();
    }
    
    /**
     * 
     */
    public void showSystemMenu() {
        getPresentation().showSystemMenu();
    }
    
    /**
     * 
     */
    public void showPaneMenu() {
        getPresentation().showPaneMenu();
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy