/******************************************************************************* * Copyright (c) 2008 Laurent Muller. * 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: * Laurent Muller - initial API and implementation *******************************************************************************/ package nu.bibi.breadcrumb; import org.eclipse.jface.viewers.CellLabelProvider; import org.eclipse.jface.viewers.ILabelProvider; import org.eclipse.jface.viewers.ISelectionProvider; import org.eclipse.jface.viewers.ITreeContentProvider; import org.eclipse.jface.window.Window; import org.eclipse.swt.SWT; import org.eclipse.swt.SWTException; import org.eclipse.swt.graphics.Image; 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.Item; /** * An item in a breadcrumb viewer. * <p> * The item shows a label and an image. It also has the ability to expand, that * is to open a drop down menu. * </p> * <p> * The drop down allows to select any child of the items input element. The item * shows the label and icon of its data element, if any. * </p> * * @since 3.4 */ public class BreadcrumbItem extends Item { private ILabelProvider labelProvider; private ITreeContentProvider contentProvider; private final BreadcrumbViewer parent; private final Composite container; private final BreadcrumbItemDetail itemDetail; private final BreadcrumbItemArrow itemArrow; private ILabelProvider toolTipLabelProvider; private boolean isLastItem; /* package */ Object element; /** * Create a new breadcrumb item with the given viewer and the given parent * container. * * @param viewer * the parent viewer. * @param parent * the parent container. */ public BreadcrumbItem(final BreadcrumbViewer viewer, final Composite parent) { super(parent, SWT.NONE); this.parent = viewer; container = new Composite(parent, SWT.NONE); container .setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false)); final GridLayout layout = new GridLayout(2, false); layout.marginTop = 1; layout.marginBottom = 2; layout.marginHeight = 0; layout.marginWidth = 0; layout.horizontalSpacing = 0; container.setLayout(layout); itemDetail = new BreadcrumbItemDetail(this, container); itemArrow = new BreadcrumbItemArrow(this, container); } /* * (non-Javadoc) * * @see org.eclipse.swt.widgets.Widget#dispose() */ @Override public void dispose() { container.dispose(); super.dispose(); } /** * Returns a rectangle describing the receiver's size and location relative * to its parent. * * @return the receiver's bounding rectangle. * @exception SWTException * <ul> * <li>ERROR_WIDGET_DISPOSED - if the receiver has been * disposed</li> * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the * thread that created the receiver</li> * </ul> */ public Rectangle getBounds() { checkWidget(); return container.getBounds(); } /* * (non-Javadoc) * @see org.eclipse.swt.widgets.Item#getImage() */ @Override public Image getImage() { checkWidget(); final Image image = itemDetail.getImage(); if (image == null) { return super.getImage(); } return image; } /** * Returns a rectangle describing the size and location relative to its * parent of the image. * * @return the receiver's bounding image rectangle or <code>null</code> if * no image is set. * @exception SWTException * <ul> * <li>ERROR_WIDGET_DISPOSED - if the receiver has been * disposed</li> * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the * thread that created the receiver</li> * </ul> */ public Rectangle getImageBounds() { checkWidget(); return itemDetail.getImageBounds(); } /* * (non-Javadoc) * @see org.eclipse.swt.widgets.Item#getText() */ @Override public String getText() { checkWidget(); final String text = itemDetail.getText(); if (text == null) { return super.getText(); } return text; } /** * Returns a rectangle describing the size and location relative to its * parent of the text. * * @return the receiver's bounding text rectangle or <code>null</code> if * the text is not visible. * @exception SWTException * <ul> * <li>ERROR_WIDGET_DISPOSED - if the receiver has been * disposed</li> * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the * thread that created the receiver</li> * </ul> * @see #isTextVisible() */ public Rectangle getTextBounds() { checkWidget(); return itemDetail.getTextBounds(); } /** * Returns the receiver's tool tip text, or null if it has not been set. * * @return the receiver's tool tip text. * @exception SWTException * <ul> * <li>ERROR_WIDGET_DISPOSED - if the receiver has been * disposed</li> * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the * thread that created the receiver</li> * </ul> */ public String getToolTipText() { return itemDetail.getToolTipText(); } /** * Gets the viewer parent. * * @return the viewer parent. * @exception SWTException * <ul> * <li>ERROR_WIDGET_DISPOSED - if the receiver has been * disposed</li> * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the * thread that created the receiver</li> * </ul> */ public BreadcrumbViewer getViewer() { checkWidget(); return parent; } /** * Returns <code>true</code> if the receiver has the user-interface focus, * and <code>false</code> otherwise. * * @return the receiver's focus state * @exception SWTException * <ul> * <li>ERROR_WIDGET_DISPOSED - if the receiver has been * disposed</li> * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the * thread that created the receiver</li> * </ul> */ public boolean isFocusControl() { checkWidget(); return itemDetail.isFocusControl() || itemArrow.isFocusControl(); } /** * Gets a value indicating if this item show a text or only an image? * * @return <code>true</code> if it shows a text and an image, * <code>false</code> if it only shows the image. * @exception SWTException * <ul> * <li>ERROR_WIDGET_DISPOSED - if the receiver has been * disposed</li> * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the * thread that created the receiver</li> * </ul> */ public boolean isTextVisible() { checkWidget(); return itemDetail.isTextVisible(); } /** * Sets the content provider. * * @param contentProvider * the content provider to set. * @exception SWTException * <ul> * <li>ERROR_WIDGET_DISPOSED - if the receiver has been * disposed</li> * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the * thread that created the receiver</li> * </ul> */ public void setContentProvider(final ITreeContentProvider contentProvider) { checkWidget(); this.contentProvider = contentProvider; } /* * (non-Javadoc) * * @see org.eclipse.swt.widgets.Item#setImage(org.eclipse.swt.graphics.Image) */ @Override public void setImage(final Image image) { super.setImage(image); itemDetail.setImage(image); } /** * Sets the label provider. * * @param labelProvider * the label provider to set. * @exception SWTException * <ul> * <li>ERROR_WIDGET_DISPOSED - if the receiver has been * disposed</li> * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the * thread that created the receiver</li> * </ul> */ public void setLabelProvider(final ILabelProvider labelProvider) { checkWidget(); this.labelProvider = labelProvider; } /* * (non-Javadoc) * * @see org.eclipse.swt.widgets.Item#setText(java.lang.String) */ @Override public void setText(final String string) { super.setText(string); itemDetail.setText(string); // more or less space might be required for the label if (isLastItem) { container.layout(true, true); } } /** * Sets the tooltip label provider. * * @param toolTipLabelProvider * the tooltip label provider to set. * @exception SWTException * <ul> * <li>ERROR_WIDGET_DISPOSED - if the receiver has been * disposed</li> * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the * thread that created the receiver</li> * </ul> */ public void setToolTipLabelProvider( final ILabelProvider toolTipLabelProvider) { checkWidget(); this.toolTipLabelProvider = toolTipLabelProvider; } /** * Set the tool tip of the item to the given text. * * @param toolTipText * the tool tip to set. * @exception SWTException * <ul> * <li>ERROR_WIDGET_DISPOSED - if the receiver has been * disposed</li> * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the * thread that created the receiver</li> * </ul> */ public void setToolTipText(final String toolTipText) { checkWidget(); itemDetail.setToolTipText(toolTipText); } /* * (non-Javadoc) * * @see org.eclipse.swt.widgets.Widget#toString() */ @Override public String toString() { return getText(); } /** * Gets the current item width. * * @return the current item width. */ int getCurrentWidth() { return itemDetail.getCurrentWidth() + itemArrow.getCurrentWidth(); } /** * Gets the drop down selection provider. * * @return the selection provider of the drop down or <code>null</code>. */ ISelectionProvider getDropDownSelectionProvider() { return itemArrow.getDropDownSelectionProvider(); } /** * Gets the drop down window. * * @return the drop down window if shown, <code>null</code> otherwise. */ Window getDropDownWindow() { return itemArrow.getDropDownWindow(); } /** * Gets the item detail. * * @return the item detail. */ BreadcrumbItemDetail getItemDetail() { return itemDetail; } /** * Gets the item drop-down. * * @return the item drop-down. */ BreadcrumbItemArrow getItemDropDown() { return itemArrow; } /** * Gets a value indicating if this element has the keyboard focus. * * @return <code>true</code> if this element has the keyboard focus. */ boolean hasFocus() { return itemDetail.hasFocus(); } /** * Gets a value indicating if this element is expanded. * * @return <code>true</code> if this item is expanded, <code>false</code> * otherwise. */ boolean isMenuShown() { return itemArrow.isMenuShown(); } /** * Gets a value indicating if this item show a text or only an image? Does * this item show a text label? * * @return <code>true</code> if it shows a text and an image, * <code>false</code> if it only shows the image. */ boolean isShowText() { return itemDetail.isTextVisible(); } /** * Expand this item and shows the drop down menu. */ void openDropDownMenu() { itemArrow.openDropDownMenu(); } /** * Redraw this item, retrieves new labels from its label provider. */ void refresh() { final String text = labelProvider.getText(element); final Image image = labelProvider.getImage(element); String toolTip = text; if (toolTipLabelProvider instanceof CellLabelProvider) { final CellLabelProvider provider = (CellLabelProvider) toolTipLabelProvider; toolTip = provider.getToolTipText(element); } itemDetail.setText(text); itemDetail.setImage(image); itemDetail.setToolTipText(toolTip); refreshArrow(); } /** * Refresh the arrows visibility. */ void refreshArrow() { final boolean hasChildren = contentProvider.hasChildren(element); itemArrow.setEnabled(hasChildren); } /** * Sets whether or not the this item should show the details (name and * label). * * @param visible * <code>true</code> if the item shows details. */ void setDetailsVisible(final boolean visible) { itemDetail.setVisible(visible); } /** * Causes the receiver to have the keyboard focus, such that all keyboard * events will be delivered to it. * * @param hasFocus * <code>true</code> if this element has the keyboard focus, * <code>false</code> otherwise. */ void setHasFocus(final boolean hasFocus) { itemDetail.setHasFocus(hasFocus); } /** * Sets whether this is the last item in the breadcrumb item chain or not. * * @param isLastItem * <code>true</code> if this is the last item, <code>false</code> * otherwise. */ void setIsLastItem(final boolean isLastItem) { this.isLastItem = isLastItem; final GridData data = (GridData) container.getLayoutData(); data.grabExcessHorizontalSpace = isLastItem; } /** * Sets a value indicating if this element is selected. * * @param selected * <code>true</code> if this element is selected, * <code>false</code> otherwise. */ void setSelected(final boolean selected) { itemDetail.setSelected(selected); } /** * Marks the text as visible if the argument is <code>true</code>, and marks * it invisible otherwise. * * @param visible * the new visibility state. */ void setTextVisible(final boolean textVisible) { itemDetail.setTextVisible(textVisible); } }