public code v1

This commit is contained in:
Francisco Jesús Martínez Mimbrera
2026-05-23 00:32:57 +02:00
commit 759a8968a2
4357 changed files with 163763 additions and 0 deletions
@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/>
<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
<classpathentry kind="src" path="src"/>
<classpathentry kind="output" path="bin"/>
</classpath>
@@ -0,0 +1,14 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>flintstones.group</groupId>
<artifactId>flintstones.bundles</artifactId>
<version>1.0.0-SNAPSHOT</version>
</parent>
<artifactId>org.eclipse.nebula.widgets.opal.breadcrumb</artifactId>
<version>1.0.0-SNAPSHOT</version>
<packaging>eclipse-plugin</packaging>
<name>[bundle] Opal Breadcrumb widget plug-in</name>
</project>
@@ -0,0 +1,45 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>org.eclipse.nebula.widgets.opal.breadcrumb</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.pde.ManifestBuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.pde.SchemaBuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.m2e.core.maven2Builder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.m2e.core.maven2Nature</nature>
<nature>org.eclipse.pde.PluginNature</nature>
<nature>org.eclipse.jdt.core.javanature</nature>
</natures>
<filteredResources>
<filter>
<id>1779484362757</id>
<name></name>
<type>30</type>
<matcher>
<id>org.eclipse.core.resources.regexFilterMatcher</id>
<arguments>node_modules|\.git|__CREATED_BY_JAVA_LANGUAGE_SERVER__</arguments>
</matcher>
</filter>
</filteredResources>
</projectDescription>
@@ -0,0 +1,2 @@
eclipse.preferences.version=1
encoding/<project>=UTF-8
@@ -0,0 +1,7 @@
eclipse.preferences.version=1
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8
org.eclipse.jdt.core.compiler.compliance=1.8
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
org.eclipse.jdt.core.compiler.source=1.8
@@ -0,0 +1,4 @@
activeProfiles=
eclipse.preferences.version=1
resolveWorkspaceProjects=true
version=1
@@ -0,0 +1,9 @@
Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: Opal Breadcrumb widget plug-in
Bundle-SymbolicName: org.eclipse.nebula.widgets.opal.breadcrumb
Bundle-Version: 1.0.0.qualifier
Bundle-RequiredExecutionEnvironment: JavaSE-1.8
Require-Bundle: org.eclipse.nebula.widgets.opal.commons;visibility:=reexport
Export-Package: org.eclipse.nebula.widgets.opal.breadcrumb
Automatic-Module-Name: org.eclipse.nebula.widgets.opal.breadcrumb
@@ -0,0 +1,4 @@
source.. = src/
output.. = bin/
bin.includes = META-INF/,\
.
@@ -0,0 +1,24 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
Copyright (C) 2018, Laurent CARON.
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
-->
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.eclipse.nebula</groupId>
<artifactId>breadcrumb</artifactId>
<version>1.0.0-SNAPSHOT</version>
</parent>
<artifactId>org.eclipse.nebula.widgets.opal.breadcrumb</artifactId>
<packaging>eclipse-plugin</packaging>
</project>
@@ -0,0 +1,351 @@
/*******************************************************************************
* Copyright (c) 2012 Laurent CARON. 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 CARON (laurent.caron at gmail dot com) - initial API
* and implementation
*******************************************************************************/
package org.eclipse.nebula.widgets.opal.breadcrumb;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import org.eclipse.nebula.widgets.opal.commons.SWTGraphicUtil;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.PaintEvent;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.widgets.Canvas;
import org.eclipse.swt.widgets.Composite;
/**
* Instances of this class support the layout of selectable bar items displayed
* in a bread crumb.
* <p>
* The item children that may be added to instances of this class must be of
* type <code>BreadcrumbItem</code>.
* </p>
* <p>
* <dl>
* <dt><b>Styles:</b></dt>
* <dd>BORDER</dd>
* <dt><b>Events:</b></dt>
* <dd>(none)</dd>
* </dl>
*
*/
public class Breadcrumb extends Canvas {
private static final String IS_BUTTON_PRESSED = Breadcrumb.class.toString() + "_pressed"; //$NON-NLS-1$
private final List<BreadcrumbItem> items;
private static Color START_GRADIENT_COLOR = SWTGraphicUtil.getColorSafely(255, 255, 255);
private static Color END_GRADIENT_COLOR = SWTGraphicUtil.getColorSafely(224, 224, 224);
static Color BORDER_COLOR = SWTGraphicUtil.getColorSafely(128, 128, 128);
static Color BORDER_COLOR_1 = SWTGraphicUtil.getColorSafely(212, 212, 212);
static Color BORDER_COLOR_2 = SWTGraphicUtil.getColorSafely(229, 229, 229);
static Color BORDER_COLOR_3 = SWTGraphicUtil.getColorSafely(243, 243, 243);
boolean hasBorder = false;
/**
* Constructs a new instance of this class given its parent and a style value
* describing its behavior and appearance.
* <p>
* The style value is either one of the style constants defined in class
* <code>SWT</code> which is applicable to instances of this class, or must be
* built by <em>bitwise OR</em>'ing together (that is, using the
* <code>int</code> "|" operator) two or more of those <code>SWT</code> style
* constants. The class description lists the style constants that are
* applicable to the class. Style bits are also inherited from superclasses.
* </p>
*
* @param parent a composite control which will be the parent of the new
* instance (cannot be null)
* @param style the style of control to construct
*
* @exception IllegalArgumentException
* <ul>
* <li>ERROR_NULL_ARGUMENT - if the parent is null</li>
* </ul>
* <ul>
* <li>ERROR_THREAD_INVALID_ACCESS - if not called from the
* thread that created the parent</li>
* <li>ERROR_INVALID_SUBCLASS - if this class is not an allowed
* subclass</li>
* </ul>
*
*/
public Breadcrumb(final Composite parent, final int style) {
super(parent, Breadcrumb.checkStyle(style) | SWT.DOUBLE_BUFFERED);
this.items = new ArrayList<>();
this.hasBorder = (style & SWT.BORDER) != 0;
this.addListeners();
}
private static int checkStyle(final int style) {
if ((style & SWT.BORDER) != 0)
return style & ~SWT.BORDER;
return 0;
}
private void addListeners() {
this.addMouseDownListener();
this.addMouseUpListener();
this.addMouseHoverListener();
this.addPaintListener(e -> {
this.paintControl(e);
});
}
private void addMouseDownListener() {
this.addListener(SWT.MouseDown, event -> {
final BreadcrumbItem item = this.items.stream()//
.filter(element -> element.getBounds()
.contains(event.x, event.y)) //
.findFirst() //
.orElse(null);
if (item == null)
return;
final boolean isToggle = (item.getStyle() & SWT.TOGGLE) != 0;
final boolean isPush = (item.getStyle() & SWT.PUSH) != 0;
if (isToggle || isPush) {
item.setSelection(!item.getSelection());
this.redraw();
this.update();
}
item.setData(Breadcrumb.IS_BUTTON_PRESSED, "*"); //$NON-NLS-1$
});
}
private void addMouseUpListener() {
this.addListener(SWT.MouseUp, event -> {
final BreadcrumbItem item = this.items.stream()//
.filter(element -> element.getBounds()
.contains(event.x, event.y)) //
.findFirst() //
.orElse(null);
if (item == null)
return;
if (item.getData(Breadcrumb.IS_BUTTON_PRESSED) == null)
// The button was not pressed
return;
item.setData(Breadcrumb.IS_BUTTON_PRESSED, null);
if ((item.getStyle() & SWT.PUSH) != 0)
item.setSelection(false);
if ((item.getStyle() & (SWT.TOGGLE | SWT.PUSH)) != 0) {
item.fireSelectionEvent();
this.redraw();
this.update();
}
});
}
private void addMouseHoverListener() {
this.addListener(SWT.MouseHover, event -> {
final BreadcrumbItem item = this.items.stream()//
.filter(element -> element.getBounds()
.contains(event.x, event.y)) //
.findFirst() //
.orElse(null);
if (item == null)
return;
this.setToolTipText(item.getTooltipText() == null ? "" : item.getTooltipText()); //$NON-NLS-1$
});
}
/**
* Paint the component
*
* @param e event
*/
private void paintControl(final PaintEvent e) {
final GC gc = e.gc;
gc.setAdvanced(true);
gc.setAntialias(SWT.ON);
final int width = this.getSize().x;
final int height = this.getSize().y;
this.drawBackground(gc, width, height);
final Iterator<BreadcrumbItem> it = this.items.iterator();
int x = 0;
while (it.hasNext()) {
final BreadcrumbItem item = it.next();
item.setGc(gc)
.setToolbarHeight(height)
.setIsLastItemOfTheBreadCrumb(!it.hasNext());
item.drawButtonAtPosition(x);
x += item.getWidth();
}
}
private void drawBackground(final GC gc, final int width, final int height) {
gc.setForeground(Breadcrumb.START_GRADIENT_COLOR);
gc.setBackground(Breadcrumb.END_GRADIENT_COLOR);
gc.fillGradientRectangle(0, 0, width, height, true);
if (this.hasBorder) {
gc.setForeground(Breadcrumb.BORDER_COLOR);
gc.drawRectangle(0, 0, width - 1, height - 1);
}
}
/**
* Add an item to the toolbar
*
* @param item roundedToolItem to add
*/
void addItem(final BreadcrumbItem item) {
this.items.add(item);
}
/**
* @see org.eclipse.swt.widgets.Composite#computeSize(int, int, boolean)
*/
@Override
public Point computeSize(final int wHint, final int hHint, final boolean changed) {
int width = 0, height = 0;
for (final BreadcrumbItem item : this.items) {
width += item.getWidth();
height = Math.max(height, item.getHeight());
}
return new Point(Math.max(width, wHint), Math.max(height, hHint));
}
/**
* Returns the item at the given, zero-relative index in the receiver. Throws an
* exception if the index is out of range.
*
* @param index the index of the item to return
* @return the item at the given index
*
* @exception IllegalArgumentException
* <ul>
* <li>ERROR_INVALID_RANGE - if the index is not between 0 and
* the number of elements in the list minus 1 (inclusive)</li>
* </ul>
* <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 BreadcrumbItem getItem(final int index) {
this.checkWidget();
if (index < 0 || index > this.items.size())
SWT.error(SWT.ERROR_INVALID_ARGUMENT);
return this.items.get(index);
}
/**
* Returns the item at the given point in the receiver or null if no such item
* exists. The point is in the coordinate system of the receiver.
*
* @param point the point used to locate the item
* @return the item at the given point
*
* @exception IllegalArgumentException
* <ul>
* <li>ERROR_NULL_ARGUMENT - if the point is null</li>
* </ul>
* <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 BreadcrumbItem getItem(final Point point) {
this.checkWidget();
final BreadcrumbItem item = this.items.stream()//
.filter(element -> element.getBounds()
.contains(point)) //
.findFirst() //
.orElse(null);
return item;
}
/**
* Returns the number of items contained in the receiver.
*
* @return the number of items
*
* <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 int getItemCount() {
this.checkWidget();
return this.items.size();
}
/**
* Returns an array of <code>BreadcrumbItem</code>s which are the items in the
* receiver.
* <p>
* Note: This is not the actual structure used by the receiver to maintain its
* list of items, so modifying the array will not affect the receiver.
* </p>
*
* @return the items in the receiver
*
* <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 BreadcrumbItem[] getItems() {
this.checkWidget();
return this.items.toArray(new BreadcrumbItem[this.items.size()]);
}
/**
* Searches the receiver's list starting at the first item (index 0) until an
* item is found that is equal to the argument, and returns the index of that
* item. If no item is found, returns -1.
*
* @param item the search item
* @return the index of the item
*
* @exception IllegalArgumentException
* <ul>
* <li>ERROR_NULL_ARGUMENT - if the item is null</li>
* <li>ERROR_INVALID_ARGUMENT - if the item has been
* disposed</li>
* </ul>
* <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 int indexOf(final BreadcrumbItem item) {
this.checkWidget();
return this.items.indexOf(item);
}
/**
* Remove an item to the toolbar
*
* @param item item to remove
*/
public void removeItem(final BreadcrumbItem item) {
this.items.remove(item);
}
}
@@ -0,0 +1,932 @@
/*******************************************************************************
* Copyright (c) 2012 Laurent CARON. 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 CARON (laurent.caron at gmail dot com) - initial API
* and implementation
*******************************************************************************/
package org.eclipse.nebula.widgets.opal.breadcrumb;
import java.util.ArrayList;
import java.util.List;
import org.eclipse.nebula.widgets.opal.commons.SWTGraphicUtil;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.graphics.Color;
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.widgets.Event;
import org.eclipse.swt.widgets.Item;
/**
* Instances of this class represent a selectable user interface object that
* represents an item of a breadcrumb.
* <dl>
* <dt><b>Styles:</b></dt>
* <dd>TOGGLE,PUSH,NONE</dd>
* <dt><b>Events:</b></dt>
* <dd>Selection</dd>
* </dl>
*
*/
public class BreadcrumbItem extends Item {
private static final int MIN_WIDTH = 40;
private static final int MARGIN = 4;
private static Color SELECTED_COLOR = SWTGraphicUtil.getColorSafely(223, 220, 213);
private static Color DISABLED_COLOR = SWTGraphicUtil.getColorSafely(150, 150, 150);
private final Breadcrumb parentBreadcrumb;
private final List<SelectionListener> selectionListeners;
private Rectangle bounds;
private boolean enabled;
private boolean selection;
private int width;
private int height;
private Image disabledImage;
private Image selectionImage;
private int alignment;
private Color textColorSelected;
private Color textColor;
private String tooltipText;
private GC gc;
private int toolbarHeight;
private boolean isLastItemOfTheBreadCrumb;
/**
* Constructs a new instance of this class given its parent (which must be a
* <code>Breadcrumb</code>) and a style value describing its behavior and
* appearance. The item is added to the end of the items maintained by its
* parent.
* <p>
* The style value is either one of the style constants defined in class
* <code>SWT</code> which is applicable to instances of this class, or must be
* built by <em>bitwise OR</em>'ing together (that is, using the
* <code>int</code> "|" operator) two or more of those <code>SWT</code> style
* constants. The class description lists the style constants that are
* applicable to the class. Style bits are also inherited from superclasses.
* </p>
*
* @param parent a composite control which will be the parent of the new
* instance (cannot be null)
*
* @exception IllegalArgumentException
* <ul>
* <li>ERROR_NULL_ARGUMENT - if the parent is null</li>
* </ul>
* <ul>
* <li>ERROR_THREAD_INVALID_ACCESS - if not called from the
* thread that created the parent</li>
* <li>ERROR_INVALID_SUBCLASS - if this class is not an allowed
* subclass</li>
* </ul>
*
*/
public BreadcrumbItem(final Breadcrumb parent) {
this(parent, SWT.NONE);
}
/**
* Constructs a new instance of this class given its parent (which must be a
* <code>Breadcrumb</code>) and a style value describing its behavior and
* appearance. The item is added to the end of the items maintained by its
* parent.
* <p>
* The style value is either one of the style constants defined in class
* <code>SWT</code> which is applicable to instances of this class, or must be
* built by <em>bitwise OR</em>'ing together (that is, using the
* <code>int</code> "|" operator) two or more of those <code>SWT</code> style
* constants. The class description lists the style constants that are
* applicable to the class. Style bits are also inherited from superclasses.
* </p>
*
* @param parent a composite control which will be the parent of the new
* instance (cannot be null)
* @param style the style of control to construct
*
* @exception IllegalArgumentException
* <ul>
* <li>ERROR_NULL_ARGUMENT - if the parent is null</li>
* </ul>
* <ul>
* <li>ERROR_THREAD_INVALID_ACCESS - if not called from the
* thread that created the parent</li>
* <li>ERROR_INVALID_SUBCLASS - if this class is not an allowed
* subclass</li>
* </ul>
*
*/
public BreadcrumbItem(final Breadcrumb parent, final int style) {
super(parent, BreadcrumbItem.checkStyle(style));
parent.addItem(this);
this.parentBreadcrumb = parent;
this.textColor = parent.getDisplay()
.getSystemColor(SWT.COLOR_BLACK);
this.textColorSelected = parent.getDisplay()
.getSystemColor(SWT.COLOR_BLACK);
this.enabled = true;
if ((style & SWT.LEFT) != 0)
this.alignment = SWT.LEFT;
if ((style & SWT.CENTER) != 0)
this.alignment = SWT.CENTER;
if ((style & SWT.RIGHT) != 0)
this.alignment = SWT.RIGHT;
this.selectionListeners = new ArrayList<>();
this.width = this.height = -1;
}
private static int checkStyle(int style) {
style = BreadcrumbItem.checkBits(style, SWT.NONE, SWT.PUSH, SWT.TOGGLE);
if ((style & (SWT.PUSH | SWT.TOGGLE)) != 0)
return BreadcrumbItem.checkBits(style, SWT.CENTER, SWT.LEFT, SWT.RIGHT);
return style;
}
private static int checkBits(int style, final int int0, final int int1, final int int2) {
final int mask = int0 | int1 | int2;
if ((style & mask) == 0)
style |= int0;
if ((style & int0) != 0)
style = style & ~mask | int0;
if ((style & int1) != 0)
style = style & ~mask | int1;
if ((style & int2) != 0)
style = style & ~mask | int2;
return style;
}
/**
* Adds the listener to the collection of listeners who will be notified when
* the control is selected by the user, by sending it one of the messages
* defined in the <code>SelectionListener</code> interface.
* <p>
* <code>widgetDefaultSelected</code> is not called.
* </p>
*
* @param listener the listener which should be notified when the control is
* selected by the user,
*
* @exception IllegalArgumentException
* <ul>
* <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
* </ul>
* <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 SelectionListener
* @see #removeSelectionListener
* @see SelectionEvent
*/
public void addSelectionListener(final SelectionListener listener) {
this.checkWidget();
if (listener == null)
SWT.error(SWT.ERROR_NULL_ARGUMENT);
this.selectionListeners.add(listener);
}
/**
* @see org.eclipse.swt.widgets.Widget#dispose()
*/
@Override
public void dispose() {
this.getParent()
.removeItem(this);
this.bounds = null;
this.disabledImage = null;
this.selectionImage = null;
this.textColor = null;
this.textColorSelected = null;
super.dispose();
}
/**
* Returns a value which describes the position of the text in the receiver. The
* value will be one of <code>LEFT</code>, <code>RIGHT</code> or
* <code>CENTER</code>.
*
* @return the alignment
*
* <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 int getAlignment() {
this.checkWidget();
return this.alignment;
}
/**
* Returns a rectangle describing the receiver's size and location relative to
* its parent (or its display if its parent is null), unless the receiver is a
* shell. In this case, the location is relative to the display.
*
* @return the receiver's bounding rectangle
*
* <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() {
this.checkWidget();
return this.bounds;
}
/**
* @return the image displayed when the button is disabled
*
* <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 Image getDisabledImage() {
this.checkWidget();
return this.disabledImage;
}
/**
* Returns <code>true</code> if the receiver is enabled, and <code>false</code>
* otherwise. A disabled control is typically not selectable from the user
* interface and draws with an inactive or "grayed" look.
*
* @return the receiver's enabled state
*
* <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 #isEnabled
*/
public boolean getEnabled() {
this.checkWidget();
return this.enabled;
}
/**
* Returns the whole height of the item.
*
* @return the receiver's height
*
* <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 int getHeight() {
this.checkWidget();
if (this.height == -1)
return this.computeDefaultSize().y;
return this.height;
}
/**
* @return the default size of the item
*/
private Point computeDefaultSize() {
final Point sizeOfTextAndImages = this.computeSizeOfTextAndImages();
return new Point(2 * BreadcrumbItem.MARGIN + sizeOfTextAndImages.x, 2 * BreadcrumbItem.MARGIN + sizeOfTextAndImages.y);
}
/**
* Returns the receiver's parent, which must be a <code>Breadcrumb</code>.
*
* @return the receiver's parent
*
* <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 Breadcrumb getParent() {
this.checkWidget();
return this.parentBreadcrumb;
}
/**
* Returns <code>true</code> if the receiver is selected, and false otherwise.
*
* @return the selection state
*
* <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 getSelection() {
this.checkWidget();
return this.selection;
}
/**
* @return the image displayed when the button is selected
*
* <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 Image getSelectionImage() {
this.checkWidget();
return this.selectionImage;
}
/**
* Returns the color of the text when the button is enabled and not selected.
*
* @return the receiver's text color
*
* <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 Color getTextColor() {
this.checkWidget();
return this.textColor;
}
/**
* Returns the color of the text when the button is not selected.
*
* @return the receiver's text color
*
* <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 Color getTextColorSelected() {
this.checkWidget();
return this.textColorSelected;
}
/**
* Returns the receiver's tool tip text, or null if it has not been set.
*
* @return the receiver's tool tip text
*
* <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() {
this.checkWidget();
return this.tooltipText;
}
/**
* Returns the whole width of the item.
*
* @return the receiver's height
*
* <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 int getWidth() {
this.checkWidget();
if (this.width == -1)
return Math.max(this.computeDefaultSize().x, BreadcrumbItem.MIN_WIDTH);
return Math.max(this.width, BreadcrumbItem.MIN_WIDTH);
}
/**
* Returns <code>true</code> if the receiver is enabled, and <code>false</code>
* otherwise. A disabled control is typically not selectable from the user
* interface and draws with an inactive or "grayed" look.
*
* @return the receiver's enabled state
*
* <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 #getEnabled
*/
public boolean isEnabled() {
this.checkWidget();
return this.enabled;
}
/**
* Removes the listener from the collection of listeners who will be notified
* when the control is selected by the user.
*
* @param listener the listener which should no longer be notified
*
* @exception IllegalArgumentException
* <ul>
* <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
* </ul>
* <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 SelectionListener
* @see #addSelectionListener
*/
public void removeSelectionListener(final SelectionListener listener) {
this.checkWidget();
if (listener == null)
SWT.error(SWT.ERROR_NULL_ARGUMENT);
this.selectionListeners.remove(listener);
}
/**
* Controls how text will be displayed in the receiver. The argument should be
* one of <code>LEFT</code>, <code>RIGHT</code> or <code>CENTER</code>.
*
* @param alignment the new alignment
*
* <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 setAlignment(final int alignment) {
this.checkWidget();
this.alignment = alignment;
}
/**
* Sets the receiver's size and location to the rectangular area specified by
* the argument. The <code>x</code> and <code>y</code> fields of the rectangle
* are relative to the receiver's parent (or its display if its parent is null).
* <p>
* Note: Attempting to set the width or height of the receiver to a negative
* number will cause that value to be set to zero instead.
* </p>
*
* @param rectangle the new bounds for the receiver
*
* <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 setBounds(final Rectangle rectangle) {
this.checkWidget();
if (this.bounds == null)
SWT.error(SWT.ERROR_NULL_ARGUMENT);
this.bounds = new Rectangle(Math.max(0, rectangle.x), //
Math.max(0, rectangle.y), //
Math.max(0, rectangle.width), //
Math.max(0, rectangle.height));
}
/**
* Sets the receiver's image to the argument when this is one is disabled, which
* may be null indicating that no image should be displayed.
*
* @param image the image to display on the receiver (may be null)
*
* @exception IllegalArgumentException
* <ul>
* <li>ERROR_INVALID_ARGUMENT - if the image has been
* disposed</li>
* </ul>
* <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 setDisabledImage(final Image image) {
this.checkWidget();
this.disabledImage = image;
}
/**
* Enables the receiver if the argument is <code>true</code>, and disables it
* otherwise.
* <p>
* A disabled control is typically not selectable from the user interface and
* draws with an inactive or "grayed" look.
* </p>
*
* @param enabled the new enabled state
*
* <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 setEnabled(final boolean enabled) {
this.checkWidget();
this.enabled = enabled;
}
/**
* Sets the height of the receiver.
* <p>
* Note: Attempting to set the width or height of the receiver to a negative
* number will cause that value to be set to zero instead.
* </p>
*
* @param height the new width
*
* <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 setHeight(final int height) {
this.checkWidget();
this.height = Math.max(height, 0);
}
/**
* Sets the selection state of the receiver.
*
* @param selected the new selection state
*
* <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 setSelection(final boolean selected) {
this.checkWidget();
this.selection = selected;
}
/**
* Sets the receiver's image to the argument when this one is selected, which
* may be null indicating that no image should be displayed.
*
* @param image the image to display on the receiver (may be null)
*
* @exception IllegalArgumentException
* <ul>
* <li>ERROR_INVALID_ARGUMENT - if the image has been
* disposed</li>
* </ul>
* <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 setSelectionImage(final Image image) {
this.checkWidget();
this.selectionImage = image;
}
/**
* Sets the receiver's text color to the argument, which may be null indicating
* that no image should be displayed.
*
* @param textColor the text color to display on the receiver (may be null)
*
* @exception IllegalArgumentException
* <ul>
* <li>ERROR_INVALID_ARGUMENT - if the image has been
* disposed</li>
* </ul>
* <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 setTextColor(final Color textColor) {
this.checkWidget();
this.textColor = textColor;
}
/**
* Sets the receiver's text color to the argument when this one is selected,
* which may be null indicating that no image should be displayed.
*
* @param textColor the text color to display on the receiver (may be null)
*
* @exception IllegalArgumentException
* <ul>
* <li>ERROR_INVALID_ARGUMENT - if the image has been
* disposed</li>
* </ul>
* <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 setTextColorSelected(final Color textColor) {
this.checkWidget();
this.textColorSelected = textColor;
}
/**
* Sets the receiver's tool tip text to the argument, which may be null
* indicating that the default tool tip for the control will be shown. For a
* control that has a default tool tip, such as the Tree control on Windows,
* setting the tool tip text to an empty string replaces the default, causing no
* tool tip text to be shown.
* <p>
* The mnemonic indicator (character '&amp;') is not displayed in a tool tip. To
* display a single '&amp;' in the tool tip, the character '&amp;' can be
* escaped by doubling it in the string.
* </p>
*
* @param string the new tool tip text (or null)
*
* <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 string) {
this.checkWidget();
this.tooltipText = string == null ? "" : string; //$NON-NLS-1$
}
/**
* Sets the width of the receiver.
* <p>
* Note: Attempting to set the width or height of the receiver to a negative
* number will cause that value to be set to zero instead.
* </p>
*
* @param width the new width
*
* <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 setWidth(final int width) {
this.checkWidget();
this.width = Math.max(0, width);
}
// --------------------------------------------- Package visibility section
void fireSelectionEvent() {
if (!this.isEnabled())
return;
final Event event = new Event();
event.widget = this.parentBreadcrumb;
event.display = this.getDisplay();
event.item = this;
event.type = SWT.Selection;
for (final SelectionListener selectionListener : this.selectionListeners)
selectionListener.widgetSelected(new SelectionEvent(event));
}
void drawButtonAtPosition(final int x) {
if (this.selection || !this.enabled)
this.drawBackgroundAtPosition(x);
if (!this.isLastItemOfTheBreadCrumb)
this.drawTrianglesAtPosition(x);
int xPosition = this.computeGap();
final Image drawnedImage = this.drawImageAtPosition(x + xPosition);
if (drawnedImage != null)
xPosition += drawnedImage.getBounds().width + 2 * BreadcrumbItem.MARGIN;
this.drawTextAtPosition(x + xPosition);
this.bounds = new Rectangle(x, 0, this.getWidth(), this.toolbarHeight);
}
private void drawBackgroundAtPosition(final int x) {
this.gc.setAdvanced(true);
this.gc.setAntialias(SWT.ON);
Color color = (this.enabled) ? BreadcrumbItem.SELECTED_COLOR : BreadcrumbItem.DISABLED_COLOR;
this.gc.setForeground(color);
this.gc.setBackground(color);
final boolean hasBorder = this.parentBreadcrumb.hasBorder;
final boolean isFirst = this.parentBreadcrumb.indexOf(this) == 0;
final int borderWidth = hasBorder ? 1 : 0;
int leftSide;
if (isFirst)
leftSide = 0;
else
leftSide = 5 + (hasBorder ? 0 : 1);
final int xUpperLeft = x + borderWidth + leftSide;
final int yUpperLeft = borderWidth;
final int rectWidth = this.getWidth() - borderWidth - leftSide - (this.isLastItemOfTheBreadCrumb && hasBorder ? 1 : 0);
final int rectHeight = this.getHeight() - 2 * borderWidth;
this.gc.fillRectangle(xUpperLeft, yUpperLeft, rectWidth, rectHeight);
if (!isFirst) {
this.gc.fillPolygon(new int[] { xUpperLeft - 5, yUpperLeft, //
xUpperLeft, yUpperLeft, //
xUpperLeft, yUpperLeft + this.toolbarHeight / 2 //
});
this.gc.fillPolygon(new int[] { xUpperLeft - 5, yUpperLeft + rectHeight, //
xUpperLeft, yUpperLeft + rectHeight, //
xUpperLeft, yUpperLeft + this.toolbarHeight / 2 //
});
}
if (!this.isLastItemOfTheBreadCrumb)
this.gc.fillPolygon(new int[] { xUpperLeft + rectWidth, yUpperLeft + 1, //
xUpperLeft + rectWidth, yUpperLeft + this.getHeight(), //
xUpperLeft + rectWidth + 5, yUpperLeft + this.toolbarHeight / 2 //
});
this.gc.setClipping((Rectangle) null);
}
private void drawTrianglesAtPosition(final int x) {
this.gc.setForeground(Breadcrumb.BORDER_COLOR);
this.drawTriangleAtPosition(x + this.getWidth());
this.gc.setAlpha(127);
this.gc.setForeground(Breadcrumb.BORDER_COLOR_1);
this.drawTriangleAtPosition(x + this.getWidth() + 1);
this.gc.setForeground(Breadcrumb.BORDER_COLOR_2);
this.drawTriangleAtPosition(x + this.getWidth() + 2);
this.gc.setForeground(Breadcrumb.BORDER_COLOR_3);
this.drawTriangleAtPosition(x + this.getWidth() + 3);
this.gc.setAlpha(255);
if (this.parentBreadcrumb.hasBorder) {
this.gc.setForeground(Breadcrumb.BORDER_COLOR);
this.gc.drawLine(x + this.getWidth(), 0, x + this.getWidth() + 3, 0);
this.gc.drawLine(x + this.getWidth(), this.toolbarHeight - 1, x + this.getWidth() + 3, this.toolbarHeight - 1);
}
}
private void drawTriangleAtPosition(final int x) {
this.gc.drawLine(x, 0, x + 5, this.toolbarHeight / 2);
this.gc.drawLine(x + 5, this.toolbarHeight / 2, x, this.toolbarHeight);
}
private int computeGap() {
final int widthOfTextAndImage = this.computeSizeOfTextAndImages().x;
switch (this.alignment) {
case SWT.CENTER:
return (this.getWidth() - widthOfTextAndImage) / 2;
case SWT.RIGHT:
return this.getWidth() - widthOfTextAndImage - BreadcrumbItem.MARGIN;
default:
return BreadcrumbItem.MARGIN;
}
}
private Point computeSizeOfTextAndImages() {
int width = 0, height = 0;
final boolean textISNotEmpty = this.getText() != null && !this.getText()
.equals(""); //$NON-NLS-1$
if (textISNotEmpty) {
final GC gc = new GC(this.parentBreadcrumb);
gc.setFont(this.parentBreadcrumb.getFont());
final Point extent = gc.stringExtent(this.getText());
gc.dispose();
width += extent.x;
height = extent.y;
}
final Point imageSize = this.computeMaxWidthAndHeightForImages(this.getImage(), this.selectionImage, this.disabledImage);
if (imageSize.x != -1) {
width += imageSize.x;
height = Math.max(imageSize.y, height);
if (textISNotEmpty)
width += BreadcrumbItem.MARGIN * 2;
}
width += BreadcrumbItem.MARGIN;
return new Point(width, height);
}
private Point computeMaxWidthAndHeightForImages(final Image... images) {
final Point imageSize = new Point(-1, -1);
for (final Image image : images) {
if (image == null)
continue;
final Rectangle imageBounds = image.getBounds();
imageSize.x = Math.max(imageBounds.width, imageSize.x);
imageSize.y = Math.max(imageBounds.height, imageSize.y);
}
return imageSize;
}
private Image drawImageAtPosition(final int xPosition) {
Image image;
if (!this.isEnabled())
image = this.disabledImage;
else if (this.selection)
image = this.selectionImage;
else
image = this.getImage();
if (image == null)
return null;
final int yPosition = (this.toolbarHeight - image.getBounds().height) / 2;
this.gc.drawImage(image, (int) (xPosition + BreadcrumbItem.MARGIN * 1.5), yPosition);
return image;
}
private void drawTextAtPosition(final int xPosition) {
this.gc.setFont(this.parentBreadcrumb.getFont());
if (this.selection)
this.gc.setForeground(this.textColorSelected);
else
this.gc.setForeground(this.textColor);
final Point textSize = this.gc.stringExtent(this.getText());
final int yPosition = (this.toolbarHeight - textSize.y) / 2;
int padding;
if (this.parentBreadcrumb.indexOf(this) == 0 || this.isLastItemOfTheBreadCrumb)
padding = 0;
else
padding = 5;
this.gc.drawText(this.getText(), xPosition + padding, yPosition, true);
}
BreadcrumbItem setGc(final GC gc) {
this.gc = gc;
return this;
}
BreadcrumbItem setToolbarHeight(final int toolbarHeight) {
this.toolbarHeight = toolbarHeight;
return this;
}
BreadcrumbItem setIsLastItemOfTheBreadCrumb(final boolean isLastItemOfTheBreadCrumb) {
this.isLastItemOfTheBreadCrumb = isLastItemOfTheBreadCrumb;
return this;
}
}