blob: e9462c39057bd55ac17d9b70b188a6f4816b9bd6 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2008, 2011 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
* Fabio Zadrozny - Bug 465666
*******************************************************************************/
package org.eclipse.jdt.internal.ui.javaeditor.breadcrumb;
import org.eclipse.swt.SWT;
import org.eclipse.swt.accessibility.AccessibleAdapter;
import org.eclipse.swt.accessibility.AccessibleEvent;
import org.eclipse.swt.events.FocusEvent;
import org.eclipse.swt.events.FocusListener;
import org.eclipse.swt.events.KeyEvent;
import org.eclipse.swt.events.KeyListener;
import org.eclipse.swt.events.MenuDetectEvent;
import org.eclipse.swt.events.MenuDetectListener;
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.events.TraverseEvent;
import org.eclipse.swt.events.TraverseListener;
import org.eclipse.swt.graphics.Image;
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.Label;
import org.eclipse.swt.widgets.Shell;
/**
* The label and icon part of the breadcrumb item.
*
* @since 3.4
*/
class BreadcrumbItemDetails {
private final Label fElementImage;
private final Label fElementText;
private final Composite fDetailComposite;
private final BreadcrumbItem fParent;
private final Composite fTextComposite;
private final Composite fImageComposite;
private boolean fTextVisible;
private boolean fSelected;
private boolean fHasFocus;
public BreadcrumbItemDetails(BreadcrumbItem parent, Composite parentContainer) {
fParent= parent;
fTextVisible= true;
fDetailComposite= new Composite(parentContainer, SWT.NONE);
fDetailComposite.setLayoutData(new GridData(SWT.BEGINNING, SWT.CENTER, false, false));
GridLayout layout= new GridLayout(2, false);
layout.marginHeight= 0;
layout.marginWidth= 0;
layout.horizontalSpacing= 0;
fDetailComposite.setLayout(layout);
addElementListener(fDetailComposite);
fImageComposite= new Composite(fDetailComposite, SWT.NONE);
fImageComposite.setLayoutData(new GridData(SWT.BEGINNING, SWT.CENTER, false, false));
layout= new GridLayout(1, false);
layout.marginHeight= 1;
layout.marginWidth= 2;
fImageComposite.setLayout(layout);
fImageComposite.addPaintListener(new PaintListener() {
@Override
public void paintControl(PaintEvent e) {
if (fHasFocus && !isTextVisible()) {
e.gc.drawFocus(e.x, e.y, e.width, e.height);
}
}
});
installFocusComposite(fImageComposite);
addElementListener(fImageComposite);
fElementImage= new Label(fImageComposite, SWT.NONE);
GridData layoutData= new GridData(SWT.BEGINNING, SWT.CENTER, false, false);
fElementImage.setLayoutData(layoutData);
addElementListener(fElementImage);
fTextComposite= new Composite(fDetailComposite, SWT.NONE);
fTextComposite.setLayoutData(new GridData(SWT.BEGINNING, SWT.CENTER, false, false));
layout= new GridLayout(1, false);
layout.marginHeight= 2;
layout.marginWidth= 2;
fTextComposite.setLayout(layout);
addElementListener(fTextComposite);
fTextComposite.addPaintListener(new PaintListener() {
@Override
public void paintControl(PaintEvent e) {
if (fHasFocus && isTextVisible()) {
e.gc.drawFocus(e.x, e.y, e.width, e.height);
}
}
});
installFocusComposite(fTextComposite);
fElementText= new Label(fTextComposite, SWT.NONE);
layoutData= new GridData(SWT.BEGINNING, SWT.CENTER, false, false);
fElementText.setLayoutData(layoutData);
addElementListener(fElementText);
fTextComposite.getAccessible().addAccessibleListener(new AccessibleAdapter() {
@Override
public void getName(AccessibleEvent e) {
e.result= fElementText.getText();
}
});
fImageComposite.getAccessible().addAccessibleListener(new AccessibleAdapter() {
@Override
public void getName(AccessibleEvent e) {
e.result= fElementText.getText();
}
});
fDetailComposite.setTabList(new Control[] { fTextComposite });
fDetailComposite.setData("org.eclipse.e4.ui.css.id", "BreadcrumbItemDetailComposite"); //$NON-NLS-1$ //$NON-NLS-2$
fTextComposite.setData("org.eclipse.e4.ui.css.id", "BreadcrumbItemDetailTextComposite"); //$NON-NLS-1$ //$NON-NLS-2$
fImageComposite.setData("org.eclipse.e4.ui.css.id", "BreadcrumbItemDetailImageComposite"); //$NON-NLS-1$ //$NON-NLS-2$
fElementImage.setData("org.eclipse.e4.ui.css.id", "BreadcrumbItemDetailImageLabel"); //$NON-NLS-1$ //$NON-NLS-2$
fElementText.setData("org.eclipse.e4.ui.css.id", "BreadcrumbItemDetailTextLabel"); //$NON-NLS-1$ //$NON-NLS-2$
}
/**
* Returns whether this element has the keyboard focus.
*
* @return true if this element has the keyboard focus.
*/
public boolean hasFocus() {
return fHasFocus;
}
/**
* Sets the tool tip to the given text.
*
* @param text the tool tip
*/
public void setToolTip(String text) {
if (isTextVisible()) {
fElementText.getParent().setToolTipText(text);
fElementText.setToolTipText(text);
fElementImage.setToolTipText(text);
} else {
fElementText.getParent().setToolTipText(null);
fElementText.setToolTipText(null);
fElementImage.setToolTipText(text);
}
}
/**
* Sets the image to the given image.
*
* @param image the image to use
*/
public void setImage(Image image) {
if (image != fElementImage.getImage()) {
fElementImage.setImage(image);
}
}
/**
* Sets the text to the given text.
*
* @param text the text to use
*/
public void setText(String text) {
if (text == null) {
text= ""; //$NON-NLS-1$
}
if (!text.equals(fElementText.getText())) {
fElementText.setText(text);
}
}
/**
* Returns the width of this element.
*
* @return current width of this element
*/
public int getWidth() {
int result= 2;
if (fElementImage.getImage() != null)
result+= fElementImage.computeSize(SWT.DEFAULT, SWT.DEFAULT).x;
if (fTextVisible && fElementText.getText().length() > 0)
result+= fElementText.computeSize(SWT.DEFAULT, SWT.DEFAULT).x;
return result;
}
public void setTextVisible(boolean enabled) {
if (fTextVisible == enabled)
return;
fTextVisible= enabled;
GridData data= (GridData) fTextComposite.getLayoutData();
data.exclude= !enabled;
fTextComposite.setVisible(enabled);
if (fTextVisible) {
fDetailComposite.setTabList(new Control[] { fTextComposite });
} else {
fDetailComposite.setTabList(new Control[] { fImageComposite });
}
if (fHasFocus) {
if (isTextVisible()) {
fTextComposite.setFocus();
} else {
fImageComposite.setFocus();
}
}
}
/**
* Tells whether this item shows a text or only an image.
*
* @return <code>true</code> if it shows a text and an image, false if it only shows the image
*/
public boolean isTextVisible() {
return fTextVisible;
}
/**
* Sets whether details should be shown.
*
* @param visible <code>true</code> if details should be shown
*/
public void setVisible(boolean visible) {
fDetailComposite.setVisible(visible);
GridData data= (GridData) fDetailComposite.getLayoutData();
data.exclude= !visible;
}
public void setSelected(boolean selected) {
if (selected == fSelected)
return;
fSelected= selected;
if (!fSelected)
fHasFocus= false;
}
public void setFocus(boolean enabled) {
if (enabled == fHasFocus)
return;
fHasFocus= enabled;
if (fHasFocus) {
if (isTextVisible()) {
fTextComposite.setFocus();
} else {
fImageComposite.setFocus();
}
}
}
/**
* Install focus and key listeners to the given composite.
*
* @param composite the composite which may get focus
*/
private void installFocusComposite(Composite composite) {
composite.addTraverseListener(new TraverseListener() {
@Override
public void keyTraversed(TraverseEvent e) {
if (e.detail == SWT.TRAVERSE_TAB_NEXT || e.detail == SWT.TRAVERSE_TAB_PREVIOUS) {
int index= fParent.getViewer().getIndexOfItem(fParent);
if (e.detail == SWT.TRAVERSE_TAB_NEXT) {
index++;
} else {
index--;
}
if (index > 0 && index < fParent.getViewer().getItemCount()) {
fParent.getViewer().selectItem(fParent.getViewer().getItem(index));
}
e.doit= true;
}
}
});
composite.addKeyListener(new KeyListener() {
@Override
public void keyPressed(KeyEvent e) {
BreadcrumbViewer viewer= fParent.getViewer();
switch (e.keyCode) {
case SWT.ARROW_LEFT:
if (fSelected) {
viewer.doTraverse(false);
e.doit= false;
} else {
viewer.selectItem(fParent);
}
break;
case SWT.ARROW_RIGHT:
if (fSelected) {
viewer.doTraverse(true);
e.doit= false;
} else {
viewer.selectItem(fParent);
}
break;
case SWT.ARROW_DOWN:
if (!fSelected) {
viewer.selectItem(fParent);
}
openDropDown();
e.doit= false;
break;
case SWT.KEYPAD_ADD:
if (!fSelected) {
viewer.selectItem(fParent);
}
openDropDown();
e.doit= false;
break;
case SWT.CR:
if (!fSelected) {
viewer.selectItem(fParent);
}
viewer.fireOpen();
break;
default:
if (e.character == ' ') {
if (!fSelected) {
viewer.selectItem(fParent);
}
openDropDown();
e.doit= false;
}
break;
}
}
private void openDropDown() {
BreadcrumbViewer viewer= fParent.getViewer();
int index= viewer.getIndexOfItem(fParent);
BreadcrumbItem parent= fParent.getViewer().getItem(index - 1);
Shell shell= parent.getDropDownShell();
if (shell == null) {
parent.openDropDownMenu();
shell= parent.getDropDownShell();
}
shell.setFocus();
}
@Override
public void keyReleased(KeyEvent e) {
}
});
composite.addFocusListener(new FocusListener() {
@Override
public void focusGained(FocusEvent e) {
if (!fHasFocus) {
fHasFocus= true;
}
}
@Override
public void focusLost(FocusEvent e) {
if (fHasFocus) {
fHasFocus= false;
}
}
});
}
/**
* Add mouse listeners to the given control.
*
* @param control the control to which may be clicked
*/
private void addElementListener(Control control) {
control.addMouseListener(new MouseListener() {
@Override
public void mouseDoubleClick(MouseEvent e) {
}
@Override
public void mouseDown(MouseEvent e) {
BreadcrumbViewer viewer= fParent.getViewer();
int parentIndex= viewer.getIndexOfItem(fParent) - 1;
Shell shell= null;
if (parentIndex >= 0) {//sanity check, must always hold
BreadcrumbItem dropDownItem= viewer.getItem(parentIndex);
shell= dropDownItem.getDropDownShell();
}
viewer.selectItem(fParent);
if (shell == null && e.button == 1 && e.stateMask == 0) {
fParent.getViewer().fireDoubleClick();
}
}
@Override
public void mouseUp(MouseEvent e) {
}
});
control.addMenuDetectListener(new MenuDetectListener() {
@Override
public void menuDetected(MenuDetectEvent e) {
BreadcrumbViewer viewer= fParent.getViewer();
viewer.selectItem(fParent);
fParent.getViewer().fireMenuDetect(e);
}
});
}
}