951 lines
35 KiB
Java
951 lines
35 KiB
Java
/*
|
|
* Copyright (c) 2006,2009 Declarative Engineering LLC.
|
|
* All rights reserved. This program and the accompanying materials
|
|
* are made available under the terms of the Declarative Engineering LLC
|
|
* verson 1 which accompanies this distribution, and is available at
|
|
* http://declarativeengineering.com/legal/DE_Developer_License_v1.txt
|
|
*/
|
|
package com.foundation.view.swt;
|
|
|
|
import org.eclipse.swt.SWT;
|
|
import org.eclipse.swt.events.SelectionEvent;
|
|
import org.eclipse.swt.events.SelectionListener;
|
|
import org.eclipse.swt.graphics.Point;
|
|
import org.eclipse.swt.graphics.Rectangle;
|
|
import org.eclipse.swt.widgets.Event;
|
|
import org.eclipse.swt.widgets.Listener;
|
|
import org.eclipse.swt.widgets.Shell;
|
|
|
|
import com.common.thread.IRunnable;
|
|
import com.common.util.LiteList;
|
|
import com.foundation.view.IMethodAssociation;
|
|
import com.foundation.view.JefImage;
|
|
import com.foundation.view.LinkData;
|
|
import com.foundation.view.SingleAssociationContainer;
|
|
import com.foundation.view.SingleResourceAssociation;
|
|
import com.foundation.view.resource.ResourceReference;
|
|
import com.foundation.view.swt.util.SwtUtilities;
|
|
|
|
public class ToolBar extends Container {
|
|
public static final int STYLE_FLAT = SWT.FLAT;
|
|
public static final int STYLE_RIGHT = SWT.RIGHT;
|
|
public static final int STYLE_WRAP = SWT.WRAP;
|
|
public static final int STYLE_HORIZONTAL = SWT.HORIZONTAL;
|
|
public static final int STYLE_VERTICAL = SWT.VERTICAL;
|
|
public static final int STYLE_SHADOW_OUT = SWT.SHADOW_OUT;
|
|
|
|
/** The collection of ToolItem instances contained by the tool bar. */
|
|
private LiteList toolItems = new LiteList(10, 20);
|
|
/** The collection of Menu instances associated with tool items. */
|
|
private LiteList menus = new LiteList(10, 20);
|
|
|
|
/**
|
|
* This tool item can be extended to provide customized tool item behavior.
|
|
*/
|
|
public static abstract class AbstractToolItem extends AbstractComponent {
|
|
public static final int STYLE_DROP_DOWN = SWT.DROP_DOWN;
|
|
public static final int STYLE_CHECK = SWT.CHECK;
|
|
public static final int STYLE_PUSH = SWT.PUSH;
|
|
public static final int STYLE_RADIO = SWT.RADIO;
|
|
public static final int STYLE_SEPARATOR = SWT.SEPARATOR;
|
|
|
|
public static final int LINK_TARGET_TOOL_TIP_TEXT = AbstractComponent.LAST_LINK_TARGET + 1;
|
|
public static final int LINK_TARGET_IS_ENABLED = AbstractComponent.LAST_LINK_TARGET + 2;
|
|
public static final int LAST_LINK_TARGET = AbstractComponent.LAST_LINK_TARGET + 2;
|
|
|
|
/** The item's tool tip text resource. */
|
|
private SingleResourceAssociation toolTipText = new SingleResourceAssociation(this, this, getViewContext(), SingleResourceAssociation.TYPE_TEXT, false, null);
|
|
/** The resource defining the enabled state for the component. */
|
|
private SingleResourceAssociation isEnabled = new SingleResourceAssociation(this, this, getViewContext(), SingleResourceAssociation.TYPE_BOOLEAN, false, Boolean.TRUE);
|
|
/** A counter tracking the number of times the component has been told to be disabled. This allows us to disable a container which in turn disables all components. */
|
|
private int disabledCounter = 0;
|
|
/** Whether this is a stateful item. */
|
|
protected final boolean isStateful;
|
|
/** Whether this is a separator. */
|
|
protected final boolean isSeparator;
|
|
/** Whether this is a drop down control. */
|
|
protected final boolean isDropDown;
|
|
|
|
/**
|
|
* AbstractToolItem constructor.
|
|
* @param parent A composite control which will be the parent of the new instance (cannot be null).
|
|
* @param name The unique component name.
|
|
* @param style The style of control to construct.
|
|
* @see #STYLE_DROP_DOWN
|
|
* @see #STYLE_CHECK
|
|
* @see #STYLE_PUSH
|
|
* @see #STYLE_RADIO
|
|
* @see #STYLE_SEPARATOR
|
|
*/
|
|
protected AbstractToolItem(Container parent, int style) {
|
|
super(parent, style);
|
|
isStateful = ((style & STYLE_RADIO) > 0) || ((style & STYLE_CHECK) > 0);
|
|
isSeparator = ((style & STYLE_SEPARATOR) > 0);
|
|
isDropDown = ((style & STYLE_DROP_DOWN) > 0);
|
|
((ToolBar) parent).addToolItem(this);
|
|
}//AbstractToolItem()//
|
|
/* (non-Javadoc)
|
|
* @see com.foundation.view.swt.IInternalAbstractComponent#getShell()
|
|
*/
|
|
public Shell getShell() {
|
|
return ((Container) getContainer()).getShell();
|
|
}//getShell()//
|
|
/* (non-Javadoc)
|
|
* @see com.foundation.view.swt.AbstractComponent#initializeControl(int)
|
|
*/
|
|
protected void initializeControl(int style, Object data) {
|
|
setSwtWidget(new org.eclipse.swt.widgets.ToolItem(((ToolBar) getContainer()).getSwtToolBar(), style));
|
|
getSwtWidget().setData(this);
|
|
}//initializeControl()//
|
|
/**
|
|
* Gets the swt tool item for this tool item.
|
|
* @return The SWT tool item providing visualization for this tool item.
|
|
*/
|
|
public org.eclipse.swt.widgets.ToolItem getSwtToolItem() {
|
|
return (org.eclipse.swt.widgets.ToolItem) getSwtWidget();
|
|
}//getSwtToolItem()//
|
|
/* (non-Javadoc)
|
|
* @see com.foundation.view.swt.AbstractComponent#internalViewInitialize()
|
|
*/
|
|
protected void internalViewInitialize() {
|
|
toolTipText.initialize();
|
|
isEnabled.initialize();
|
|
super.internalViewInitialize();
|
|
}//internalViewInitialize()//
|
|
/* (non-Javadoc)
|
|
* @see com.foundation.view.swt.AbstractComponent#internalViewRelease()
|
|
*/
|
|
protected void internalViewRelease() {
|
|
toolTipText.release();
|
|
isEnabled.release();
|
|
|
|
if(!getSwtToolItem().isDisposed()) {
|
|
getSwtToolItem().dispose();
|
|
}//if//
|
|
|
|
super.internalViewRelease();
|
|
}//internalViewRelease()//
|
|
/* (non-Javadoc)
|
|
* @see com.foundation.view.swt.AbstractComponent#internalViewRefresh()
|
|
*/
|
|
protected void internalViewRefresh() {
|
|
internalViewRefreshToolTipText();
|
|
internalViewRefreshIsEnabled();
|
|
super.internalViewRefresh();
|
|
}//internalViewRefresh()//
|
|
/**
|
|
* Refreshes the item tool tip text.
|
|
*/
|
|
protected void internalViewRefreshToolTipText() {
|
|
if(toolTipText.refresh()) {
|
|
getSwtToolItem().setToolTipText((String) toolTipText.getValue());
|
|
}//if//
|
|
}//internalViewRefreshToolTipText()//
|
|
/**
|
|
* Refreshes whether the component is enabled based on the attribute value or if null the default flag value.
|
|
*/
|
|
protected void internalViewRefreshIsEnabled() {
|
|
if(isEnabled.refresh()) {
|
|
internalSetEnabledState(isEnabled.getValue() == null ? true : ((Boolean) isEnabled.getValue()).booleanValue());
|
|
}//if//
|
|
}//internalViewRefreshIsEnabled()//
|
|
/**
|
|
* Performs the actual work of enable or disabling the component.
|
|
* @param isEnabled Whether the enabled state should be altered to be enabled, otherwise it is altered to be disabled.
|
|
*/
|
|
protected void internalSetEnabledState(boolean isEnabled) {
|
|
//Some components may not have controls, such as value holders.//
|
|
if(getSwtToolItem() != null) {
|
|
if(!isEnabled || disabledCounter > 0) {
|
|
disabledCounter += !isEnabled ? 1 : -1;
|
|
}//if//
|
|
|
|
if(isEnabled && disabledCounter == 0) {
|
|
getSwtToolItem().setEnabled(true);
|
|
}//if//
|
|
else if(!isEnabled && disabledCounter == 1) {
|
|
getSwtToolItem().setEnabled(false);
|
|
}//else if//
|
|
}//if//
|
|
}//internalSetEnabledState()//
|
|
/* (non-Javadoc)
|
|
* @see com.foundation.view.swt.AbstractComponent#internalOnValueChanged(com.foundation.view.SingleResourceAssociation)
|
|
*/
|
|
protected void internalOnValueChanged(SingleResourceAssociation resourceAssociation, int flags) {
|
|
if(resourceAssociation == toolTipText) {
|
|
internalViewRefreshToolTipText();
|
|
}//if//
|
|
else if(resourceAssociation == isEnabled) {
|
|
internalViewRefreshIsEnabled();
|
|
}//else if//
|
|
else {
|
|
super.internalOnValueChanged(resourceAssociation, flags);
|
|
}//else//
|
|
}//internalOnValueChanged()//
|
|
/**
|
|
* Forces the component to resize and requests that the window layout.
|
|
*/
|
|
public void resize() {
|
|
if(isInitialized()) {
|
|
getSwtToolItem().getParent().pack(true);
|
|
getSwtToolItem().getParent().getShell().layout(true, true);
|
|
}//if//
|
|
}//resize()//
|
|
/**
|
|
* Sets the association container used to access the tool tip.
|
|
* @param container The tool tip association metadata.
|
|
*/
|
|
public void setToolTipTextAssociation(SingleAssociationContainer container) {
|
|
verifyThread();
|
|
this.toolTipText.setAssociations(container);
|
|
}//setToolTipTextAssociation()//
|
|
/**
|
|
* Sets the association container used to access the enabled state.
|
|
* @param container The enabled state association metadata.
|
|
*/
|
|
public void setIsEnabledAssociation(SingleAssociationContainer container) {
|
|
verifyThread();
|
|
this.isEnabled.setAssociations(container);
|
|
}//setIsEnabledAssociation()//
|
|
/**
|
|
* Sets the component's default tool tip text.
|
|
* @param toolTipText The tool tip text to be displayed by this component.
|
|
*/
|
|
public void setToolTipText(String toolTipText) {
|
|
verifyThread();
|
|
this.toolTipText.setDefaultValue(toolTipText);
|
|
}//setToolTipText()//
|
|
/**
|
|
* Sets the component's default tool tip text resource.
|
|
* @return The tool tip text to be displayed by this component.
|
|
*/
|
|
public void setToolTipText(ResourceReference toolTipText) {
|
|
verifyThread();
|
|
this.toolTipText.setDefaultValue(toolTipText);
|
|
}//setToolTipText()//
|
|
/**
|
|
* Sets whether the component is enabled (by default if an attribute is bound to this value).
|
|
* @param isEnabled Whether the user can interact with the component.
|
|
*/
|
|
public void setIsEnabled(boolean isEnabled) {
|
|
verifyThread();
|
|
this.isEnabled.setDefaultValue(isEnabled ? Boolean.TRUE : Boolean.FALSE);
|
|
}//setIsEnabled()//
|
|
/**
|
|
* Sets the default enabled state resource.
|
|
* @param isEnabled Whether the user can interact with the component.
|
|
*/
|
|
public void setIsEnabled(ResourceReference isEnabled) {
|
|
verifyThread();
|
|
this.isEnabled.setDefaultValue(isEnabled);
|
|
}//setIsEnabled()//
|
|
/* (non-Javadoc)
|
|
* @see com.foundation.view.swt.AbstractComponent#internalOnLinkInvoked(int, java.lang.Object)
|
|
*/
|
|
protected void internalOnLinkInvoked(int linkTarget, Object data) {
|
|
switch(linkTarget) {
|
|
case LINK_TARGET_IS_ENABLED: {
|
|
internalSetEnabledState(data != null && data instanceof Boolean ? ((Boolean) data).booleanValue() : false);
|
|
break;
|
|
}//case//
|
|
case LINK_TARGET_TOOL_TIP_TEXT: {
|
|
getSwtToolItem().setToolTipText(data instanceof String ? (String) data : "");
|
|
break;
|
|
}//case//
|
|
default: {
|
|
super.internalOnLinkInvoked(linkTarget, data);
|
|
break;
|
|
}//default//
|
|
}//switch//
|
|
}//internalOnLinkInvoked()//
|
|
}//AbstractToolItem//
|
|
|
|
/**
|
|
* Encapsulates an item in the bar.
|
|
*/
|
|
public static class ToolItem extends AbstractToolItem implements SelectionListener {
|
|
public static final int LINK_TARGET_SELECTION = AbstractToolItem.LAST_LINK_TARGET + 1;
|
|
public static final int LINK_TARGET_TEXT = AbstractToolItem.LAST_LINK_TARGET + 2;
|
|
public static final int LINK_TARGET_IMAGE = AbstractToolItem.LAST_LINK_TARGET + 3;
|
|
public static final int LINK_TARGET_DISABLED_IMAGE = AbstractToolItem.LAST_LINK_TARGET + 4;
|
|
public static final int LINK_TARGET_ROLLOVER_IMAGE = AbstractToolItem.LAST_LINK_TARGET + 5;
|
|
public static final int LAST_LINK_TARGET = AbstractToolItem.LAST_LINK_TARGET + 5;
|
|
|
|
/** Whether the item has a custom width. */
|
|
private boolean customWidth = false;
|
|
/** Called when the button is pressed (only used for push items). */
|
|
private IMethodAssociation selectionMethod = null;
|
|
/** The item's selection state resource. */
|
|
private SingleResourceAssociation selection = new SingleResourceAssociation(this, this, getViewContext(), SingleResourceAssociation.TYPE_BOOLEAN, true, Boolean.FALSE);
|
|
/** The linkage for the selection. */
|
|
private Linkage selectionLinkage = new Linkage();
|
|
/** The item's text resource. */
|
|
private SingleResourceAssociation text = new SingleResourceAssociation(this, this, getViewContext(), SingleResourceAssociation.TYPE_TEXT, false, "");
|
|
/** The item's image resource. */
|
|
private SingleResourceAssociation image = new SingleResourceAssociation(this, this, getViewContext(), SingleResourceAssociation.TYPE_IMAGE, false, null);
|
|
/** The item's image resource. */
|
|
private SingleResourceAssociation disabledImage = new SingleResourceAssociation(this, this, getViewContext(), SingleResourceAssociation.TYPE_IMAGE, false, null);
|
|
/** The item's hot image resource. */
|
|
private SingleResourceAssociation hotImage = new SingleResourceAssociation(this, this, getViewContext(), SingleResourceAssociation.TYPE_IMAGE, false, null);
|
|
/** Whether the selection state is auto synchronized. */
|
|
private boolean autoSynchronizeSelection = true;
|
|
/** The delay to be used when auto synchronizing changes to the text. */
|
|
private long autoSynchronizeSelectionDelay = 0;
|
|
/** The task that auto synchronizes the selection after a short delay. */
|
|
private Task autoSynchronizeSelectionTask = null;
|
|
/** The custom control associated with the item. */
|
|
private Component control = null;
|
|
/** The popup menu associated with the item. */
|
|
private Menu menu = null;
|
|
/** A holder for the value of the text. */
|
|
private ResourceHolder textHolder = new ResourceHolder(this);
|
|
/** A holder for the value of the image. */
|
|
private ResourceHolder imageHolder = new ResourceHolder(this);
|
|
/** A holder for the value of the hot image. */
|
|
private ResourceHolder hotImageHolder = new ResourceHolder(this);
|
|
/** A holder for the value of the disabled image. */
|
|
private ResourceHolder disabledImageHolder = new ResourceHolder(this);
|
|
|
|
/**
|
|
* ToolItem constructor.
|
|
* @param parent A composite control which will be the parent of the new instance (cannot be null).
|
|
* @param name The unique component name.
|
|
* @param style The style of control to construct.
|
|
* @see #STYLE_DROP_DOWN
|
|
* @see #STYLE_CHECK
|
|
* @see #STYLE_PUSH
|
|
* @see #STYLE_RADIO
|
|
* @see #STYLE_SEPARATOR
|
|
*/
|
|
public ToolItem(Container parent, String name, int style) {
|
|
super(parent, style);
|
|
}//ToolItem()//
|
|
/* (non-Javadoc)
|
|
* @see com.foundation.view.IAbstractComponent#getName()
|
|
*/
|
|
public String getName() {
|
|
return "__ToolItem__";
|
|
}//getName()//
|
|
/* (non-Javadoc)
|
|
* @see com.foundation.view.swt.AbstractComponent#internalViewInitialize()
|
|
*/
|
|
protected void internalViewInitialize() {
|
|
getSwtToolItem().addSelectionListener(this);
|
|
super.internalViewInitialize();
|
|
text.initialize();
|
|
image.initialize();
|
|
hotImage.initialize();
|
|
disabledImage.initialize();
|
|
selection.initialize();
|
|
|
|
if(control != null) {
|
|
getSwtToolItem().setControl(control.getSwtControl());
|
|
}//if//
|
|
}//internalViewInitialize()//
|
|
/* (non-Javadoc)
|
|
* @see com.foundation.view.swt.AbstractComponent#internalViewRelease()
|
|
*/
|
|
protected void internalViewRelease() {
|
|
destroyImage((JefImage) imageHolder.getValue());
|
|
destroyImage((JefImage) hotImageHolder.getValue());
|
|
destroyImage((JefImage) disabledImageHolder.getValue());
|
|
|
|
synchronized(this) {
|
|
if(autoSynchronizeSelectionTask != null) {
|
|
removeTask(autoSynchronizeSelectionTask);
|
|
autoSynchronizeSelectionTask = null;
|
|
}//if//
|
|
}//synchronized//
|
|
|
|
if(!getSwtToolItem().isDisposed()) {
|
|
getSwtToolItem().removeSelectionListener(this);
|
|
getSwtToolItem().setControl(null);
|
|
}//if//
|
|
|
|
text.release();
|
|
image.release();
|
|
hotImage.release();
|
|
disabledImage.release();
|
|
selection.release();
|
|
|
|
textHolder.release();
|
|
imageHolder.release();
|
|
hotImageHolder.release();
|
|
disabledImageHolder.release();
|
|
|
|
super.internalViewRelease();
|
|
}//internalViewRelease()//
|
|
/* (non-Javadoc)
|
|
* @see com.foundation.view.swt.AbstractComponent#internalViewRefresh()
|
|
*/
|
|
protected void internalViewRefresh() {
|
|
super.internalViewRefresh();
|
|
internalViewRefreshSelection();
|
|
internalViewRefreshText();
|
|
internalViewRefreshImage();
|
|
internalViewRefreshHotImage();
|
|
internalViewRefreshDisabledImage();
|
|
|
|
//Auto calculate the width based on the packed size of the control.//
|
|
//TODO: Should we set the control's height to the bar's height?
|
|
if(!customWidth && isSeparator && control != null) {
|
|
Point size;
|
|
|
|
control.getSwtControl().pack();
|
|
size = control.getSwtControl().computeSize(SWT.DEFAULT, SWT.DEFAULT);
|
|
getSwtToolItem().setWidth(size.x);
|
|
}//if//
|
|
}//internalViewRefresh()//
|
|
/* (non-Javadoc)
|
|
* @see com.foundation.view.swt.AbstractComponent#internalViewSynchronize()
|
|
*/
|
|
protected void internalViewSynchronize() {
|
|
super.internalViewSynchronize();
|
|
|
|
if((isStateful) && (!autoSynchronizeSelection)) {
|
|
selection.setValue(getSwtToolItem().getSelection() ? Boolean.TRUE : Boolean.FALSE);
|
|
}//if//
|
|
}//internalViewSynchronize()//
|
|
/**
|
|
* Refreshes the item selection.
|
|
*/
|
|
protected void internalViewRefreshSelection() {
|
|
if((isStateful) && (selection.refresh())) {
|
|
Boolean selectionState = (Boolean) selection.getValue();
|
|
|
|
selectionState = selectionState == null ? Boolean.FALSE : selectionState;
|
|
|
|
if(getSwtToolItem().getSelection() != selectionState.booleanValue()) {
|
|
getSwtToolItem().setSelection(selectionState.booleanValue());
|
|
selectionLinkage.invoke(selectionState);
|
|
}//if//
|
|
}//if//
|
|
}//internalViewRefreshSelection()//
|
|
/**
|
|
* Refreshes the item hot image.
|
|
*/
|
|
protected void internalViewRefreshHotImage() {
|
|
if(hotImage.refresh()) {
|
|
hotImageHolder.setValue(hotImage.getValue());
|
|
}//if//
|
|
}//internalViewRefreshHotImage()//
|
|
/**
|
|
* Refreshes the item disabled image.
|
|
*/
|
|
protected void internalViewRefreshDisabledImage() {
|
|
if(disabledImage.refresh()) {
|
|
disabledImageHolder.setValue(disabledImage.getValue());
|
|
}//if//
|
|
}//internalViewRefreshDisabledImage()//
|
|
/**
|
|
* Refreshes the item image.
|
|
*/
|
|
protected void internalViewRefreshImage() {
|
|
if(image.refresh()) {
|
|
imageHolder.setValue(image.getValue());
|
|
}//if//
|
|
}//internalViewRefreshImage()//
|
|
/**
|
|
* Refreshes the item text.
|
|
*/
|
|
protected void internalViewRefreshText() {
|
|
if(text.refresh()) {
|
|
textHolder.setValue(text.getValue());
|
|
}//if//
|
|
}//internalViewRefreshText()//
|
|
/* (non-Javadoc)
|
|
* @see com.foundation.view.swt.AbstractComponent#internalResourceHolderChanged(com.foundation.view.swt.ResourceHolder, java.lang.Object, java.lang.Object)
|
|
*/
|
|
protected void internalResourceHolderChanged(ResourceHolder resource, Object oldValue, Object newValue, int flags) {
|
|
if(resource == textHolder) {
|
|
getSwtToolItem().setText((String) newValue);
|
|
resize();
|
|
}//if//
|
|
else if(resource == imageHolder) {
|
|
destroyImage(getSwtToolItem().getImage());
|
|
getSwtToolItem().setImage(createImage((JefImage) newValue));
|
|
resize();
|
|
}//else if//
|
|
else if(resource == hotImageHolder) {
|
|
destroyImage(getSwtToolItem().getHotImage());
|
|
getSwtToolItem().setHotImage(createImage((JefImage) newValue));
|
|
resize();
|
|
}//else if//
|
|
else if(resource == disabledImageHolder) {
|
|
destroyImage(getSwtToolItem().getDisabledImage());
|
|
getSwtToolItem().setDisabledImage(createImage((JefImage) newValue));
|
|
resize();
|
|
}//else if//
|
|
else {
|
|
super.internalResourceHolderChanged(resource, oldValue, newValue, flags);
|
|
}//else//
|
|
}//internalOnAssociationChanged()//
|
|
/* (non-Javadoc)
|
|
* @see org.eclipse.swt.events.SelectionListener#widgetDefaultSelected(org.eclipse.swt.events.SelectionEvent)
|
|
*/
|
|
public void widgetDefaultSelected(SelectionEvent event) {
|
|
widgetSelected(event);
|
|
}//widgetDefaultSelected()//
|
|
/* (non-Javadoc)
|
|
* @see org.eclipse.swt.events.SelectionListener#widgetSelected(org.eclipse.swt.events.SelectionEvent)
|
|
*/
|
|
public void widgetSelected(SelectionEvent event) {
|
|
if(isSeparator && control != null) {
|
|
//Do nothing.//
|
|
//TODO: Do we need to pass this even to the control? Will we even get the event?
|
|
}//if//
|
|
else if(isDropDown && event.detail == SWT.ARROW) {
|
|
Rectangle rect = getSwtToolItem().getBounds();
|
|
Point point = new Point(rect.x, rect.y + rect.height);
|
|
|
|
//Show the drop down menu.//
|
|
point = getSwtToolItem().getParent().toDisplay(point);
|
|
|
|
if(menu != null) {
|
|
menu.getSwtMenu().setLocation(point.x, point.y);
|
|
menu.getSwtMenu().setVisible(true);
|
|
}//if//
|
|
}//else if//
|
|
else if(isSeparator) {
|
|
//Ignore//
|
|
}//else if//
|
|
else {
|
|
selectionChanged(getSwtToolItem().getSelection());
|
|
}//else//
|
|
}//widgetSelected()//
|
|
/**
|
|
* Called when the selection is changed in the view control.
|
|
* This method updates all bindings and
|
|
* @param isSelected Whether the control is selected (stateful controls only).
|
|
*/
|
|
protected void selectionChanged(final boolean isSelected) {
|
|
if(!isSeparator && !isDropDown) {
|
|
//Handle the button selection.//
|
|
if((selectionMethod != null) || (autoSynchronizeSelection)) {
|
|
if((selectionMethod == null) && (autoSynchronizeSelectionDelay > 0)) {
|
|
//Start a task to send the text to the server after a short delay. This will reduce the overhead of auto synchronizing the selection.//
|
|
synchronized(this) {
|
|
if(autoSynchronizeSelectionTask != null) {
|
|
removeTask(autoSynchronizeSelectionTask);
|
|
}//if//
|
|
|
|
autoSynchronizeSelectionTask = new Task() {
|
|
public void execute() {
|
|
//Make sure that this task is still valid and is not being superceeded.//
|
|
synchronized(ToolItem.this) {
|
|
if(autoSynchronizeSelectionTask == this) {
|
|
//Cleanup after the task.//
|
|
autoSynchronizeSelectionTask = null;
|
|
getEventLoop().executeAsync(new IRunnable() {
|
|
public Object run() {
|
|
selection.setValue(isSelected ? Boolean.TRUE : Boolean.FALSE);
|
|
return null;
|
|
}//run()//
|
|
});
|
|
}//if//
|
|
}//synchronized//
|
|
}//run()//
|
|
};
|
|
addTask(autoSynchronizeSelectionTask, autoSynchronizeSelectionDelay);
|
|
}//synchronized//
|
|
}//if//
|
|
else {
|
|
if(selectionMethod != null) {
|
|
selectionMethod.invoke(new Object[] {isSelected ? Boolean.TRUE : Boolean.FALSE}, true); //TODO: Save the array for reuse.//
|
|
}//if//
|
|
else {
|
|
selection.setValue(isSelected ? Boolean.TRUE : Boolean.FALSE);
|
|
}//else//
|
|
}//else//
|
|
}//if//
|
|
|
|
selectionLinkage.invoke(isStateful ? isSelected ? Boolean.TRUE : Boolean.FALSE : null);
|
|
}//if//
|
|
}//selectionChanged()//
|
|
/* (non-Javadoc)
|
|
* @see com.foundation.view.swt.AbstractComponent#internalOnValueChanged(com.foundation.view.SingleResourceAssociation)
|
|
*/
|
|
protected void internalOnValueChanged(SingleResourceAssociation resourceAssociation, int flags) {
|
|
if(resourceAssociation == text) {
|
|
internalViewRefreshText();
|
|
}//if//
|
|
else if(resourceAssociation == image) {
|
|
internalViewRefreshImage();
|
|
}//else if//
|
|
else if(resourceAssociation == selection) {
|
|
internalViewRefreshSelection();
|
|
}//else if//
|
|
else if(resourceAssociation == hotImage) {
|
|
internalViewRefreshHotImage();
|
|
}//else if//
|
|
else if(resourceAssociation == disabledImage) {
|
|
internalViewRefreshDisabledImage();
|
|
}//else if//
|
|
else {
|
|
super.internalOnValueChanged(resourceAssociation, flags);
|
|
}//else//
|
|
}//internalOnValueChanged()//
|
|
/**
|
|
* Sets the tool item width.
|
|
* @param width The width of the tool item. This should be ignored unless this is a custom or separator item.
|
|
*/
|
|
public void setWidth(int width) {
|
|
customWidth = true;
|
|
getSwtToolItem().setWidth(width);
|
|
}//setWidth()//
|
|
/**
|
|
* Sets the component default selection state.
|
|
* @param isSelected Whether the component is in the selected state.
|
|
*/
|
|
public void setIsSelected(Boolean isSelected) {
|
|
verifyThread();
|
|
|
|
if(isStateful) {
|
|
selection.setDefaultValue(isSelected);
|
|
}//if//
|
|
}//setIsSelected()//
|
|
/**
|
|
* Sets the association container used to access the text.
|
|
* @param container The text association metadata.
|
|
*/
|
|
public void setTextAssociation(SingleAssociationContainer container) {
|
|
verifyThread();
|
|
this.text.setAssociations(container);
|
|
}//setTextAssociation()//
|
|
/**
|
|
* Sets the association container used to access the image.
|
|
* @param container The image association metadata.
|
|
*/
|
|
public void setImageAssociation(SingleAssociationContainer container) {
|
|
verifyThread();
|
|
this.image.setAssociations(container);
|
|
}//setImageAssociation()//
|
|
/**
|
|
* Sets the association container used to access the hot image.
|
|
* @param container The hot image association metadata.
|
|
*/
|
|
public void setHotImageAssociation(SingleAssociationContainer container) {
|
|
verifyThread();
|
|
this.hotImage.setAssociations(container);
|
|
}//setHotImageAssociation()//
|
|
/**
|
|
* Sets the association container used to access the disabled image.
|
|
* @param container The disabled image association metadata.
|
|
*/
|
|
public void setDisabledImageAssociation(SingleAssociationContainer container) {
|
|
verifyThread();
|
|
this.disabledImage.setAssociations(container);
|
|
}//setDisabledImageAssociation()//
|
|
/**
|
|
* Sets the association container used to access the selection.
|
|
* @param container The selection association metadata.
|
|
*/
|
|
public void setSelectionAssociation(SingleAssociationContainer container) {
|
|
verifyThread();
|
|
this.selection.setAssociations(container);
|
|
}//setSelectionAssociation()//
|
|
/**
|
|
* Adds a link for the selection.
|
|
* @param link The local linkage for the selection.
|
|
*/
|
|
public void addSelectionLink(LinkData link) {
|
|
selectionLinkage.add(link);
|
|
}//addSelectionLink()//
|
|
/**
|
|
* Sets the selection method called when the button is pressed (intended only for push buttons).
|
|
* @param selectionMethod The method called when the button is pressed.
|
|
*/
|
|
public void setSelectionMethod(IMethodAssociation selectionMethod) {
|
|
verifyThread();
|
|
|
|
if(!isStateful) {
|
|
this.selectionMethod = selectionMethod;
|
|
}//if//
|
|
}//setSelectionMethod()//
|
|
/**
|
|
* Sets the component text.
|
|
* @param text The text that will appear in the component.
|
|
*/
|
|
public void setText(String text) {
|
|
verifyThread();
|
|
this.text.setDefaultValue(text);
|
|
}//setText()//
|
|
/**
|
|
* Sets the component's default text resource.
|
|
* @param text The text to be displayed by this component.
|
|
*/
|
|
public void setText(ResourceReference text) {
|
|
verifyThread();
|
|
this.text.setDefaultValue(text);
|
|
}//setText()//
|
|
/**
|
|
* Sets the component image.
|
|
* @param image The image to be displayed by the component.
|
|
*/
|
|
public void setImage(JefImage image) {
|
|
verifyThread();
|
|
this.image.setDefaultValue(image);
|
|
}//setImage()//
|
|
/**
|
|
* Sets the component's default image resource.
|
|
* @param image The image to be displayed by this component.
|
|
*/
|
|
public void setImage(ResourceReference image) {
|
|
verifyThread();
|
|
this.image.setDefaultValue(image);
|
|
}//setImage()//
|
|
/**
|
|
* Sets the component's disabled image.
|
|
* @param image The disabled image to be displayed by the component.
|
|
*/
|
|
public void setDisabledImage(JefImage image) {
|
|
verifyThread();
|
|
this.disabledImage.setDefaultValue(image);
|
|
}//setDisabledImage()//
|
|
/**
|
|
* Sets the component's default disabled image resource.
|
|
* @param image The disabled image to be displayed by this component.
|
|
*/
|
|
public void setDisabledImage(ResourceReference image) {
|
|
verifyThread();
|
|
this.disabledImage.setDefaultValue(image);
|
|
}//setDisabledImage()//
|
|
/**
|
|
* Sets the component's hot image.
|
|
* @param image The hot image to be displayed by the component.
|
|
*/
|
|
public void setHotImage(JefImage image) {
|
|
verifyThread();
|
|
this.hotImage.setDefaultValue(image);
|
|
}//setHotImage()//
|
|
/**
|
|
* Sets the component's default hot image resource.
|
|
* @param image The hot image to be displayed by this component.
|
|
*/
|
|
public void setHotImage(ResourceReference image) {
|
|
verifyThread();
|
|
this.hotImage.setDefaultValue(image);
|
|
}//setHotImage()//
|
|
/**
|
|
* Sets whether the control auto synchronizes the selected state of the button.
|
|
* @param autoSynchronizeSelection Whether the button state is automatically synchronized.
|
|
*/
|
|
public void setAutoSynchronizeSelection(boolean autoSynchronizeSelection) {
|
|
if(isStateful) {
|
|
this.autoSynchronizeSelection = autoSynchronizeSelection;
|
|
}//if//
|
|
}//setAutoSynchronizeSelection()//
|
|
/**
|
|
* Sets the delay for the auto synchronize selection.
|
|
* @param autoSynchronizeSelectionDelay The delay in terms of milliseconds between the value of zero and ten thousand. A zero value has no delay.
|
|
*/
|
|
public void setAutoSynchronizeSelectionDelay(long autoSynchronizeSelectionDelay) {
|
|
if(autoSynchronizeSelectionDelay < 0) {
|
|
autoSynchronizeSelectionDelay = 0;
|
|
}//if//
|
|
else if(autoSynchronizeSelectionDelay > 10000) {
|
|
autoSynchronizeSelectionDelay = 10000;
|
|
}//else if//
|
|
|
|
this.autoSynchronizeSelectionDelay = autoSynchronizeSelectionDelay;
|
|
}//setAutoSynchronizeSelectionDelay()//
|
|
/**
|
|
* Sets the control used by the tool item.
|
|
* @param control The tool item's control.
|
|
*/
|
|
public void setControl(Component control) {
|
|
this.control = control;
|
|
}//setControl()//
|
|
/**
|
|
* Sets the popup menu used by the tool item.
|
|
* @param menu The tool item's popup menu.
|
|
*/
|
|
public void setMenu(Menu menu) {
|
|
this.menu = menu;
|
|
}//setMenu()//
|
|
/* (non-Javadoc)
|
|
* @see com.foundation.view.swt.AbstractComponent#internalOnLinkInvoked(int, java.lang.Object)
|
|
*/
|
|
protected void internalOnLinkInvoked(int linkTarget, Object data) {
|
|
switch(linkTarget) {
|
|
case LINK_TARGET_SELECTION: {
|
|
boolean isSelected = data instanceof Boolean ? ((Boolean) data).booleanValue() : false;
|
|
|
|
if(isStateful) {
|
|
if(isSelected != getSwtToolItem().getSelection()) {
|
|
getSwtToolItem().setSelection(isSelected);
|
|
selectionChanged(isSelected);
|
|
}//if//
|
|
}//if//
|
|
else {
|
|
selectionChanged(true);
|
|
}//else//
|
|
break;
|
|
}//case//
|
|
case LINK_TARGET_IMAGE: {
|
|
if(getSwtToolItem().getImage() != null) {
|
|
getSwtToolItem().getImage().dispose();
|
|
}//if//
|
|
|
|
getSwtToolItem().setImage(data instanceof JefImage ? SwtUtilities.getImage(getSwtToolItem().getDisplay(), (JefImage) data) : null);
|
|
resize();
|
|
break;
|
|
}//case//
|
|
case LINK_TARGET_DISABLED_IMAGE: {
|
|
if(getSwtToolItem().getDisabledImage() != null) {
|
|
getSwtToolItem().getDisabledImage().dispose();
|
|
}//if//
|
|
|
|
getSwtToolItem().setDisabledImage(data instanceof JefImage ? SwtUtilities.getImage(getSwtToolItem().getDisplay(), (JefImage) data) : null);
|
|
resize();
|
|
break;
|
|
}//case//
|
|
case LINK_TARGET_ROLLOVER_IMAGE: {
|
|
if(getSwtToolItem().getHotImage() != null) {
|
|
getSwtToolItem().getHotImage().dispose();
|
|
}//if//
|
|
|
|
getSwtToolItem().setHotImage(data instanceof JefImage ? SwtUtilities.getImage(getSwtToolItem().getDisplay(), (JefImage) data) : null);
|
|
resize();
|
|
break;
|
|
}//case//
|
|
case LINK_TARGET_TEXT: {
|
|
getSwtToolItem().setText(data instanceof String ? (String) data : "");
|
|
resize();
|
|
break;
|
|
}//case//
|
|
default: {
|
|
super.internalOnLinkInvoked(linkTarget, data);
|
|
break;
|
|
}//default//
|
|
}//switch//
|
|
}//internalOnLinkInvoked()//
|
|
}//ToolItem//
|
|
/**
|
|
* ToolBar constructor.
|
|
* @param parent A composite control which will be the parent of the new instance (cannot be null).
|
|
* @param name The unique component name.
|
|
* @param style The style of control to construct.
|
|
* @see #STYLE_FLAT
|
|
*/
|
|
public ToolBar(Container parent, String name, int style) {
|
|
super(parent, name, style);
|
|
}//ToolBar()//
|
|
/**
|
|
* Adds a tool item to the bar.
|
|
* @param toolItem The item to be added.
|
|
*/
|
|
protected void addToolItem(AbstractToolItem toolItem) {
|
|
toolItems.add(toolItem);
|
|
|
|
if(isInitialized()) {
|
|
//TODO: Initialize the tool item.
|
|
//Will the tool item's component already be initilialized?
|
|
//Would this ever occur?
|
|
}//if//
|
|
}//addToolItem()//
|
|
/* (non-Javadoc)
|
|
* @see com.foundation.view.swt.AbstractComponent#initializeControl(int)
|
|
*/
|
|
protected void initializeControl(int style, Object data) {
|
|
setSwtWidget(new org.eclipse.swt.widgets.ToolBar(((Container) getContainer()).getSwtParent(), style));
|
|
getSwtWidget().setData(this);
|
|
}//initializeControl()//
|
|
/**
|
|
* Gets the SWT tool bar that represents this tool bar.
|
|
* @return The SWT tool bar providing visualization for this tool bar.
|
|
*/
|
|
public org.eclipse.swt.widgets.ToolBar getSwtToolBar() {
|
|
return (org.eclipse.swt.widgets.ToolBar) getSwtControl();
|
|
}//getSwtToolBar()//
|
|
/* (non-Javadoc)
|
|
* @see com.foundation.view.swt.AbstractComponent#internalViewInitialize()
|
|
*/
|
|
protected void internalViewInitialize() {
|
|
//Add a listener to force the view to re-layout when the toolbar changes sizes (expands or contracts).//
|
|
getSwtToolBar().addListener(SWT.Resize, new Listener() {
|
|
public void handleEvent(Event event) {
|
|
getSwtToolBar().getParent().layout(true, true);
|
|
getSwtToolBar().getParent().redraw();
|
|
}//handleEvent()//
|
|
});
|
|
super.internalViewInitialize();
|
|
}//internalViewInitialize()//
|
|
/* (non-Javadoc)
|
|
* @see com.foundation.view.swt.AbstractComponent#internalViewInitializeAll()
|
|
*/
|
|
public void internalViewInitializeAll() {
|
|
super.internalViewInitializeAll();
|
|
|
|
//Initialize all the tool items.//
|
|
for(int index = 0; index < toolItems.getSize(); index++) {
|
|
((AbstractToolItem) toolItems.get(index)).internalViewInitialize();
|
|
}//for//
|
|
|
|
//Initialize all the menus.//
|
|
for(int index = 0; index < menus.getSize(); index++) {
|
|
((Menu) menus.get(index)).internalViewInitializeAll();
|
|
}//for//
|
|
}//internalViewInitializeAll()//
|
|
/* (non-Javadoc)
|
|
* @see com.foundation.view.swt.AbstractComponent#internalViewReleaseAll()
|
|
*/
|
|
public void internalViewReleaseAll() {
|
|
//Release all the tool items.//
|
|
for(int index = 0; index < toolItems.getSize(); index++) {
|
|
((AbstractToolItem) toolItems.get(index)).internalViewRelease();
|
|
}//for//
|
|
|
|
//Release all the menus.//
|
|
for(int index = 0; index < menus.getSize(); index++) {
|
|
((Menu) menus.get(index)).internalViewReleaseAll();
|
|
}//for//
|
|
|
|
super.internalViewReleaseAll();
|
|
}//internalViewReleaseAll()//
|
|
/* (non-Javadoc)
|
|
* @see com.foundation.view.swt.AbstractComponent#internalViewRefreshAll()
|
|
*/
|
|
public void internalViewRefreshAll() {
|
|
super.internalViewRefreshAll();
|
|
|
|
//Refresh all the tool items.//
|
|
for(int index = 0; index < toolItems.getSize(); index++) {
|
|
((AbstractToolItem) toolItems.get(index)).internalViewRefresh();
|
|
}//for//
|
|
|
|
//Refresh all the menus.//
|
|
for(int index = 0; index < menus.getSize(); index++) {
|
|
((Menu) menus.get(index)).internalViewRefreshAll();
|
|
}//for//
|
|
}//internalViewRefreshAll()//
|
|
/* (non-Javadoc)
|
|
* @see com.foundation.view.swt.AbstractComponent#internalViewSynchronizeAll()
|
|
*/
|
|
public void internalViewSynchronizeAll() {
|
|
//Synchronize all the tool items.//
|
|
for(int index = 0; index < toolItems.getSize(); index++) {
|
|
((AbstractToolItem) toolItems.get(index)).internalViewSynchronize();
|
|
}//for//
|
|
|
|
//Synchronize all the menus.//
|
|
for(int index = 0; index < menus.getSize(); index++) {
|
|
((Menu) menus.get(index)).internalViewSynchronizeAll();
|
|
}//for//
|
|
|
|
super.internalViewSynchronizeAll();
|
|
}//internalViewSynchronizeAll()//
|
|
/* (non-Javadoc)
|
|
* @see com.foundation.view.swt.Component#setMenu(com.foundation.view.swt.Menu)
|
|
*/
|
|
public void setMenu(Menu menu) {
|
|
verifyThread();
|
|
|
|
menus.add(menu);
|
|
|
|
//A tool bar can have multiple menus associated with it. Each menu is tied to a drop down tool item. Since the tool item is not a control, the menu is linked to the bar instead.//
|
|
if((isInitialized()) && (menu != null)) {
|
|
menu.internalViewInitializeAll();
|
|
}//if//
|
|
}//setMenu()//
|
|
}//ToolBar// |