blob: 78a02d5a30c29246575fbf27dd4b05e089bd5456 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2004 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Common Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/cpl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*******************************************************************************/
package org.eclipse.ui.examples.presentation.sidewinder;
import org.eclipse.jface.action.Action;
import org.eclipse.jface.action.IAction;
import org.eclipse.jface.action.MenuManager;
import org.eclipse.jface.action.Separator;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.ViewForm;
import org.eclipse.swt.events.DisposeEvent;
import org.eclipse.swt.events.DisposeListener;
import org.eclipse.swt.events.MouseAdapter;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.events.MouseListener;
import org.eclipse.swt.events.PaintEvent;
import org.eclipse.swt.events.PaintListener;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.layout.RowLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.swt.widgets.ToolItem;
import org.eclipse.ui.IPropertyListener;
import org.eclipse.ui.examples.presentation.wrappedtabs.ProxyControl;
import org.eclipse.ui.presentations.IPartMenu;
import org.eclipse.ui.presentations.IPresentablePart;
import org.eclipse.ui.presentations.IStackPresentationSite;
import org.eclipse.ui.presentations.PresentationUtil;
import org.eclipse.ui.presentations.StackDropResult;
import org.eclipse.ui.presentations.StackPresentation;
public class SideWinderItemViewPresentation extends StackPresentation {
private static final String PART_DATA = "part";
private static final int TITLE_HEIGHT = 22;
private boolean activeFocus = false;
/**
* Main widget for the presentation
*/
private Composite presentationControl;
private Composite titleArea;
private Composite clientArea;
private Composite statusLineArea;
private ViewForm contentArea;
private ProxyControl toolbarProxy;
/**
* Currently selected part
*/
private IPresentablePart current;
/**
* close button
*/
private ToolItem close;
/**
* View menu button
*/
private ToolItem viewMenu;
/**
* Minimize button
*/
private ToolItem minView;
private int style = SWT.VERTICAL | SWT.LEFT;
private boolean titleAreaHiden = false;
/**
* This listener responds to selection events in all tool items.
*/
private MouseListener mouseListener = new MouseAdapter() {
// If we single-click on an empty space on the toolbar, move focus to the
// active control
public void mouseDown(MouseEvent e) {
PartItem toolItem = (PartItem) e.widget;
IPresentablePart item = getPartForTab(toolItem);
if (item != null) {
// Clicking on the active tab should give focus to the current
// part
if (item == current) {
item.setFocus();
}
getSite().selectPart(item);
selectPart(item);
Point toDisplay = toolItem.toDisplay(new Point(e.x, e.y));
if (e.button == 3) {
showSystemMenu(toDisplay);
} else {
Image image = toolItem.getImage();
if (image != null) {
if (image.getBounds().contains(e.x, e.y)) {
showPaneMenu(toDisplay);
}
}
}
}
}
};
/**
* Listener attached to all child parts. It responds to changes in part properties
*/
private IPropertyListener childPropertyChangeListener = new IPropertyListener() {
public void propertyChanged(Object source, int property) {
if (source instanceof IPresentablePart) {
IPresentablePart part = (IPresentablePart) source;
updatePartItem(getPartItem(part), part);
}
}
};
/**
* Listener attached to all tool items. It removes listeners from the associated
* part when the tool item is destroyed. This is required to prevent memory leaks.
*/
private DisposeListener tabDisposeListener = new DisposeListener() {
public void widgetDisposed(DisposeEvent e) {
if (e.widget instanceof ToolItem) {
PartItem item = (PartItem)e.widget;
IPresentablePart part = getPartForTab(item);
part.removePropertyListener(childPropertyChangeListener);
}
}
};
/**
* Drag listener for regions outside the toolbar
*/
Listener dragListener = new Listener() {
public void handleEvent(Event event) {
Point loc = new Point(event.x, event.y);
Control ctrl = (Control)event.widget;
getSite().dragStart(ctrl.toDisplay(loc), false);
}
};
private Listener menuListener = new Listener() {
public void handleEvent(Event event) {
Point globalPos = new Point(event.x, event.y);
showSystemMenu(globalPos);
return;
}
};
private boolean showText;
private boolean showImage;
private MenuManager systemMenuManager= new MenuManager();
private Listener hideTitleListener = new Listener() {
public void handleEvent(Event event) {
if (!titleAreaHiden) {
titleAreaHiden = true;
layout();
}
}
};
private Listener showTitleListener = new Listener() {
public void handleEvent(Event event) {
if (titleAreaHiden) {
titleAreaHiden = false;
layout();
}
}
};
public SideWinderItemViewPresentation(Composite parent, IStackPresentationSite stackSite, boolean showText, boolean showImage, int style) {
super(stackSite);
this.showText = showText;
this.showImage = showImage;
this.style = style;
// Create a top-level control for the presentation.
presentationControl = new Composite(parent, SWT.NONE);
titleArea = new Composite(presentationControl, SWT.NONE);
//statusLineArea = new Composite(titleArea, SWT.NONE);
//HeapStatusContributionItem item = new HeapStatusContributionItem(PlatformUI.getPreferenceStore());
//item.fill(statusLineArea);
contentArea = new ViewForm(presentationControl, SWT.NONE);
clientArea = new Composite(contentArea, SWT.NONE);
clientArea.setVisible(false);
contentArea.setContent(clientArea);
toolbarProxy = new ProxyControl(contentArea);
PresentationUtil.addDragListener(titleArea, dragListener);
titleArea.addListener(SWT.MenuDetect, menuListener);
//titleArea.addListener(SWT.MouseEnter, showTitleListener);
//titleArea.addListener(SWT.MouseExit, hideTitleListener);
RowLayout rowLayout = new RowLayout ();
rowLayout.marginLeft = 0;
rowLayout.marginRight = 0;
rowLayout.marginTop = 0;
rowLayout.marginBottom = 0;
rowLayout.type = style;
//rowLayout.justify = true;
if((style & SWT.VERTICAL) != 0) {
rowLayout.fill = true;
}
rowLayout.spacing = 0;
titleArea.setLayout (rowLayout);
// Add a dispose listener. This will call the presentationDisposed()
// method when the widget is destroyed.
presentationControl.addDisposeListener(new DisposeListener() {
public void widgetDisposed(DisposeEvent e) {
presentationDisposed();
}
});
presentationControl.addPaintListener(new PaintListener() {
public void paintControl(PaintEvent e) {
int borderWidth = getBorderWidth();
Rectangle clientArea = presentationControl.getClientArea();
e.gc.setLineWidth(borderWidth);
if(activeFocus)
e.gc.setForeground(e.display.getSystemColor(SWT.COLOR_BLUE));
else
e.gc.setForeground(e.display.getSystemColor(SWT.COLOR_DARK_GRAY));
e.gc.drawRectangle(clientArea.x, clientArea.y, clientArea.width, clientArea.height);
Rectangle contentAreaBounds = contentArea.getBounds();
int ypos = contentAreaBounds.y - 1;
//e.gc.drawLine(clientArea.x, ypos, clientArea.x + clientArea.width, ypos);
}
});
createSystemMenu();
update();
}
public IPresentablePart getCurrent() {
return current;
}
protected void presentationDisposed() {
// Remove any listeners that were attached to any
// global Eclipse resources. This is necessary in order to prevent
// memory leaks.
}
protected int getBorderWidth() {
return 2;
}
public void showSystemMenu(Point displayPos) {
Menu aMenu = systemMenuManager.createContextMenu(titleArea);
systemMenuManager.update(true);
aMenu.setLocation(displayPos.x, displayPos.y);
aMenu.setVisible(true);
}
private final void createSystemMenu() {
getSite().addSystemActions(systemMenuManager);
// This example presentation includes the part list at the end of the system menu
systemMenuManager.add(new Separator());
systemMenuManager.add(new ClosePartContributionItem(this));
systemMenuManager.add(new Separator());
Action topAction = new Action("Top", IAction.AS_RADIO_BUTTON) {
public void run() {
SideWinderItemViewPresentation.this.style = SWT.TOP;
setChecked((SideWinderItemViewPresentation.this.style & SWT.TOP) != 0);
update();
}
};
topAction.setChecked((style & SWT.TOP) != 0);
systemMenuManager.add(topAction);
Action bottomAction = new Action("Bottom", IAction.AS_RADIO_BUTTON) {
public void run() {
SideWinderItemViewPresentation.this.style = SWT.BOTTOM;
setChecked((SideWinderItemViewPresentation.this.style & SWT.BOTTOM) != 0);
update();
}
};
bottomAction.setChecked((style & SWT.BOTTOM) != 0);
systemMenuManager.add(bottomAction);
Action rightAction = new Action("Right", IAction.AS_RADIO_BUTTON) {
public void run() {
SideWinderItemViewPresentation.this.style = SWT.RIGHT;
setChecked((SideWinderItemViewPresentation.this.style & SWT.RIGHT) != 0);
update();
}
};
rightAction.setChecked((style & SWT.RIGHT) != 0);
systemMenuManager.add(rightAction);
Action leftAction = new Action("Left", IAction.AS_RADIO_BUTTON) {
public void run() {
SideWinderItemViewPresentation.this.style = SWT.LEFT;
setChecked((SideWinderItemViewPresentation.this.style & SWT.LEFT) != 0);
update();
}
};
leftAction.setChecked((style & SWT.VERTICAL) != 0);
systemMenuManager.add(leftAction);
systemMenuManager.add(new Separator());
Action textAction = new Action("Text", IAction.AS_CHECK_BOX) {
public void run() {
SideWinderItemViewPresentation.this.showText = isChecked();
setChecked(SideWinderItemViewPresentation.this.showText);
update();
}
};
textAction.setChecked(showText);
systemMenuManager.add(textAction);
Action imageAction = new Action("Image", IAction.AS_CHECK_BOX) {
public void run() {
SideWinderItemViewPresentation.this.showImage = isChecked();
setChecked(isChecked());
update();
}
};
imageAction.setChecked(showImage);
systemMenuManager.add(imageAction);
}
protected void update() {
Control[] items = titleArea.getChildren();
for (int idx = 0; idx < items.length; idx++) {
if(items[idx] instanceof PartItem) {
PartItem item = (PartItem)items[idx];
item.setShowImage(showImage);
item.setShowText(showText);
item.setFocus(activeFocus);
}
}
int type = SWT.VERTICAL;
if ((style & SWT.TOP) != 0 || (style & SWT.BOTTOM) != 0) {
type = SWT.HORIZONTAL;
}
RowLayout rowLayout = ((RowLayout)titleArea.getLayout());
rowLayout.type = type;
rowLayout.fill = type == SWT.VERTICAL;
layout();
presentationControl.redraw();
//titleArea.redraw();
//titleArea.layout();
//contentArea.layout();
}
public void close(IPresentablePart[] parts) {
getSite().close(parts);
}
public void layout() {
// Determine the inner bounds of the presentation
Rectangle presentationClientArea = presentationControl.getClientArea();
presentationClientArea.x += getBorderWidth();
presentationClientArea.width -= getBorderWidth() * 2;
presentationClientArea.y += getBorderWidth();
presentationClientArea.height -= getBorderWidth() * 2;
if ((style & SWT.TOP) != 0 || (style & SWT.BOTTOM) != 0) {
Point p = titleArea.computeSize(presentationClientArea.width, SWT.DEFAULT);
int yy = 0;
int x = 0;
int y = 0;
if((style & SWT.TOP) != 0) {
x = presentationClientArea.x;
y = presentationClientArea.y;
yy = p.y + 1;
} else {
x = presentationClientArea.x;
y = presentationClientArea.height - p.y;
yy = presentationClientArea.y;
}
if(titleAreaHiden)
p.y = 3;
titleArea.setBounds(x, y, presentationClientArea.width, p.y);
contentArea.setBounds(presentationClientArea.x, yy, presentationClientArea.width, presentationClientArea.height - p.y);
} else {
Point p = titleArea.computeSize(SWT.DEFAULT, presentationClientArea.height);
int xx = 0;
int x = 0;
int y = 0;
if((style & SWT.RIGHT) != 0) {
x = presentationClientArea.width - p.x;
y = presentationClientArea.y;
xx = presentationClientArea.x;
} else {
x = presentationClientArea.x;
y = presentationClientArea.y;
xx = p.x +1;
}
if(titleAreaHiden)
p.x = 3;
titleArea.setBounds(x, y, p.x, presentationClientArea.height);
contentArea.setBounds(xx, presentationClientArea.y, presentationClientArea.width - p.x, presentationClientArea.height);
}
//Rectangle r = titleArea.getBounds();
//Point p = titleArea.computeSize(SWT.DEFAULT, r.height);
//statusLineArea.setBounds(r);
titleArea.setBackground(titleArea.getDisplay().getSystemColor(SWT.COLOR_GRAY));
// Position the view's widgets
if (current != null) {
Control toolbar = current.getToolBar();
if(toolbar != null) {
toolbarProxy.setTargetControl(current.getToolBar());
contentArea.setTopCenter(toolbarProxy.getControl());
} else {
contentArea.setTopCenter(null);
}
contentArea.layout();
Rectangle clientRectangle = clientArea.getBounds();
Point clientAreaStart = presentationControl.getParent().toControl(
contentArea.toDisplay(clientRectangle.x, clientRectangle.y));
// current isn't parented by this widget hierarchy, the coordinates must be
// relative to the workbench window. The workbench window parents every
// part.
current.setBounds(new Rectangle(clientAreaStart.x,
clientAreaStart.y,
clientRectangle.width,
clientRectangle.height));
}
}
public void setBounds(Rectangle bounds) {
presentationControl.setBounds(bounds);
layout();
}
public void dispose() {
}
public void setActive(int newState) {
activeFocus = (newState == AS_ACTIVE_FOCUS);
Control[] items = titleArea.getChildren();
for (int idx = 0; idx < items.length; idx++) {
if(items[idx] instanceof PartItem) {
PartItem item = (PartItem)items[idx];
item.setFocus(activeFocus);
}
}
presentationControl.redraw();
}
public void setVisible(boolean isVisible) {
presentationControl.setVisible(isVisible);
// Make the currently visible part visible
if (current != null) {
current.setVisible(isVisible);
}
if (isVisible) {
// Restore the bounds of the currently visible part.
// IPartPresentations can be used by multiple StackPresentations,
// although only one such presentation is ever visible at a time.
// It is possible that some other presentation has changed the
// bounds of the part since it was last visible, so we need to
// update the part's bounds when the presentation becomes visible.
layout();
}
}
public void setState(int state) {
}
public Control getControl() {
return presentationControl;
}
public void addPart(IPresentablePart newPart, Object cookie) {
// Ignore the cookie for now, since we don't support drag-and-drop yet.
PartItem item = new PartItem(titleArea, newPart);
// Attach the newPart pointer to the ToolItem. This is used for getPartForTab
// to determine which part is associated with the tool item
item.setData(PART_DATA, newPart);
// Attach a property change listener to the part. This will update the ToolItem
// to reflect changes in the part.
newPart.addPropertyListener(childPropertyChangeListener);
// Attach a dispose listener to the item. This removes the above property
// change listener from the part when the item is destroyed. This prevents
// memory leaks.
item.addDisposeListener(tabDisposeListener);
// Listen to selection events in the new tool item
item.addMouseListener(mouseListener);
PresentationUtil.addDragListener(item, new Listener() {
public void handleEvent(Event event) {
Point loc = new Point(event.x, event.y);
PartItem item = (PartItem)event.widget;
if (item != null) {
// Move the current part
IPresentablePart draggedItem = getPartForTab(item);
draggedItem.setFocus();
getSite().dragStart(draggedItem, item.toDisplay(loc), false);
}
}
});
// Initialize the tab for this part
updatePartItem(item, newPart);
newPart.setBounds(clientArea.getBounds());
titleArea.layout();
titleArea.redraw();
update();
}
protected void updatePartItem(PartItem item, IPresentablePart part) {
String tabName = part.getTitle();
if(item == null) return;
if (!tabName.equals(item.getText())) {
item.setText(tabName);
}
if (!(part.getTitleToolTip().equals(item.getToolTipText()))) {
item.setToolTipText(part.getTitleToolTip());
}
item.setImage(part.getTitleImage());
item.setShowImage(showImage);
item.setShowText(showText);
titleArea.layout(true);
titleArea.redraw();
item.redraw();
}
protected final PartItem getPartItem(IPresentablePart part) {
if (!titleArea.isDisposed()) {
Control[] items = titleArea.getChildren();
for (int idx = 0; idx < items.length; idx++) {
Control item = items[idx];
if (!item.isDisposed() && getPartForTab(item) == part) {
return (PartItem) item;
}
}
}
return null;
}
protected final IPresentablePart getPartForTab(Control item) {
return (IPresentablePart)item.getData(PART_DATA);
}
public void removePart(IPresentablePart oldPart) {
PartItem item = getPartItem(oldPart);
if(item != null) {
item.dispose();
titleArea.layout();
titleArea.redraw();
}
}
public void selectPart(IPresentablePart toSelect) {
if (toSelect == current) {
return;
}
if(current !=null) {
current.setVisible(false);
}
// Select the new part
current = toSelect;
// Ordering is important here. We need to make the part
// visible before updating its bounds, or the call to setBounds
// may be ignored.
if (current != null) {
// Make the newly selected part visible
current.setVisible(true);
Control[] items = titleArea.getChildren();
for (int idx = 0; idx < items.length; idx++) {
if(items[idx] instanceof PartItem) {
PartItem item = (PartItem)items[idx];
item.setSelected(getPartForTab(item) == current);
}
}
}
// Update the bounds of the newly selected part
layout();
}
public StackDropResult dragOver(Control currentControl, Point location) {
return null;
}
public void showSystemMenu() {
}
public void showPaneMenu() {
}
public void showPaneMenu(Point location) {
if (current == null) {
return;
}
IPartMenu menu = current.getMenu();
if (menu == null) {
return;
}
menu.showMenu(location);
}
public Control[] getTabList(IPresentablePart part) {
if(current != null) {
return new Control[] {current.getControl()};
} else {
return new Control[0];
}
}
}