Initial commit from SVN.
This commit is contained in:
13
Foundation TCV SWT Client/.classpath
Normal file
13
Foundation TCV SWT Client/.classpath
Normal file
@@ -0,0 +1,13 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<classpath>
|
||||
<classpathentry kind="src" path="src"/>
|
||||
<classpathentry kind="src" path="/Common"/>
|
||||
<classpathentry kind="src" path="/Foundation"/>
|
||||
<classpathentry kind="src" path="/SWT"/>
|
||||
<classpathentry kind="src" path="/Foundation TCV"/>
|
||||
<classpathentry kind="src" path="/Foundation TCV Client"/>
|
||||
<classpathentry kind="src" path="/Foundation TCV SWT"/>
|
||||
<classpathentry combineaccessrules="false" kind="src" path="/Foundation SWT"/>
|
||||
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
|
||||
<classpathentry kind="output" path="bin"/>
|
||||
</classpath>
|
||||
24
Foundation TCV SWT Client/.project
Normal file
24
Foundation TCV SWT Client/.project
Normal file
@@ -0,0 +1,24 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<projectDescription>
|
||||
<name>Foundation TCV SWT Client</name>
|
||||
<comment></comment>
|
||||
<projects>
|
||||
<project>Common</project>
|
||||
<project>Foundation</project>
|
||||
<project>Foundation SWT</project>
|
||||
<project>Foundation TCV</project>
|
||||
<project>Foundation TCV Client</project>
|
||||
<project>Foundation TCV SWT</project>
|
||||
<project>SWT</project>
|
||||
</projects>
|
||||
<buildSpec>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.jdt.core.javabuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>org.eclipse.jdt.core.javanature</nature>
|
||||
</natures>
|
||||
</projectDescription>
|
||||
File diff suppressed because one or more lines are too long
@@ -0,0 +1,301 @@
|
||||
/*
|
||||
* Copyright (c) 2003,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.tcv.swt.client;
|
||||
|
||||
import org.eclipse.swt.events.*;
|
||||
|
||||
import com.common.debug.*;
|
||||
import com.common.thread.IRunnable;
|
||||
import com.foundation.tcv.client.view.ResourceHolder;
|
||||
import com.foundation.tcv.model.LinkInfo;
|
||||
import com.foundation.tcv.swt.*;
|
||||
import com.foundation.tcv.view.*;
|
||||
import com.foundation.view.JefImage;
|
||||
import com.foundation.view.LinkData;
|
||||
import com.foundation.view.swt.util.SwtUtilities;
|
||||
|
||||
public class Button extends Component implements SelectionListener, IButton {
|
||||
/** The last selection state in the model, known to the component. Used to reduce method calling & round trip messages. */
|
||||
private boolean selectionState = false;
|
||||
/** Whether the selection state should be auto-synchronized. */
|
||||
private boolean autoSynchronizeSelection = false;
|
||||
/** The delay to be used when auto synchronizing changes. */
|
||||
private long autoSynchronizeSelectionDelay = 500;
|
||||
/** The task that auto synchronizes the selection state after a short delay. */
|
||||
private Task autoSynchronizeSelectionTask = null;
|
||||
/** Whether selection notifications to the server will block for a response. */
|
||||
private boolean blockOnSelections = false;
|
||||
/** Whether this is a stateful button. */
|
||||
private boolean isStateful = false;
|
||||
/** The linkage for the selection. */
|
||||
private Linkage selectionLinkage = new Linkage();
|
||||
/** 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);
|
||||
/**
|
||||
* Button constructor.
|
||||
*/
|
||||
public Button() {
|
||||
}//Button()//
|
||||
/**
|
||||
* Gets the SWT button that represents this button.
|
||||
* @return The SWT button providing visualization for this button.
|
||||
*/
|
||||
public org.eclipse.swt.widgets.Button getSwtButton() {
|
||||
return (org.eclipse.swt.widgets.Button) getSwtWidget();
|
||||
}//getSwtButton()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.AbstractComponent#internalViewInitialize()
|
||||
*/
|
||||
protected void internalViewInitialize() {
|
||||
getSwtButton().addSelectionListener(this);
|
||||
super.internalViewInitialize();
|
||||
}//internalViewInitialize()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.AbstractComponent#internalViewRelease()
|
||||
*/
|
||||
protected void internalViewRelease() {
|
||||
destroyImage((JefImage) imageHolder.getValue());
|
||||
|
||||
if((getSwtButton() != null) && (!getSwtButton().isDisposed())) {
|
||||
getSwtButton().removeSelectionListener(this);
|
||||
}//if//
|
||||
|
||||
synchronized(this) {
|
||||
if(autoSynchronizeSelectionTask != null) {
|
||||
removeTask(autoSynchronizeSelectionTask);
|
||||
autoSynchronizeSelectionTask = null;
|
||||
}//if//
|
||||
}//synchronized//
|
||||
|
||||
textHolder.release();
|
||||
imageHolder.release();
|
||||
|
||||
super.internalViewRelease();
|
||||
}//internalViewRelease()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.AbstractComponent#internalViewSynchronize()
|
||||
*/
|
||||
protected void internalViewSynchronize() {
|
||||
super.internalViewSynchronize();
|
||||
|
||||
if(isStateful) {
|
||||
if(!autoSynchronizeSelection) {
|
||||
boolean selection = getSwtButton().getSelection();
|
||||
|
||||
if(selectionState != selection) {
|
||||
selectionState = selection;
|
||||
sendMessage(MESSAGE_VIEW_SYNCHRONIZE_SELECTION, selection ? Boolean.TRUE : Boolean.FALSE);
|
||||
}//if//
|
||||
}//if//
|
||||
else {
|
||||
synchronized(this) {
|
||||
if(autoSynchronizeSelectionTask != null) {
|
||||
removeTask(autoSynchronizeSelectionTask);
|
||||
autoSynchronizeSelectionTask.execute();
|
||||
}//if//
|
||||
}//synchronized//
|
||||
}//else//
|
||||
}//if//
|
||||
}//internalViewSynchronize()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.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) && (isSelected != getSwtButton().getSelection())) {
|
||||
getSwtButton().setSelection(isSelected);
|
||||
selectionChanged(isSelected);
|
||||
}//if//
|
||||
else {
|
||||
selectionChanged(true);
|
||||
}//else//
|
||||
break;
|
||||
}//case//
|
||||
case LINK_TARGET_IMAGE: {
|
||||
if(getSwtButton().getImage() != null) {
|
||||
getSwtButton().getImage().dispose();
|
||||
}//if//
|
||||
|
||||
getSwtButton().setImage(data instanceof JefImage ? SwtUtilities.getImage(getSwtButton().getDisplay(), (JefImage) data) : null);
|
||||
resize();
|
||||
break;
|
||||
}//case//
|
||||
case LINK_TARGET_TEXT: {
|
||||
getSwtButton().setText(data instanceof String ? (String) data : "");
|
||||
resize();
|
||||
break;
|
||||
}//case//
|
||||
default: {
|
||||
super.internalOnLinkInvoked(linkTarget, data);
|
||||
break;
|
||||
}//default//
|
||||
}//switch//
|
||||
}//internalOnLinkInvoked()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.AbstractComponent#internalResourceHolderChanged(com.foundation.tcv.client.view.ResourceHolder, java.lang.Object, java.lang.Object, int)
|
||||
*/
|
||||
protected void internalResourceHolderChanged(ResourceHolder resource, Object oldValue, Object newValue, int flags) {
|
||||
if(resource == textHolder) {
|
||||
getSwtButton().setText((String) newValue);
|
||||
resize();
|
||||
}//if//
|
||||
else if(resource == imageHolder) {
|
||||
destroyImage(getSwtButton().getImage());
|
||||
getSwtButton().setImage(createImage((JefImage) newValue));
|
||||
resize();
|
||||
}//else if//
|
||||
else {
|
||||
super.internalResourceHolderChanged(resource, oldValue, newValue, flags);
|
||||
}//else//
|
||||
}//internalOnAssociationChanged()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.AbstractComponent#internalProcessMessage(com.foundation.tcv.model.ViewMessage)
|
||||
*/
|
||||
public Object internalProcessMessage(ViewMessage viewMessage) {
|
||||
Object result = null;
|
||||
|
||||
switch(viewMessage.getMessageNumber()) {
|
||||
case MESSAGE_INITIALIZE: {
|
||||
if(getSwtControl() == null) {
|
||||
int style = viewMessage.getMessageSecondaryInteger();
|
||||
|
||||
//Link to the parent container.//
|
||||
setContainer((Container) getComponent(viewMessage.getMessageInteger()));
|
||||
getContainer().addComponent(this);
|
||||
//Create the SWT widget.//
|
||||
setSwtWidget(new org.eclipse.swt.widgets.Button(getContainer().getSwtParent(), style));
|
||||
getSwtWidget().setData(this);
|
||||
isStateful = ((style & STYLE_RADIO) > 0) || ((style & STYLE_TOGGLE) > 0) || ((style & STYLE_CHECK) > 0);
|
||||
|
||||
//If the container has already been initialized then force the parent to re-layout so that this component will appear.//
|
||||
if(getContainer().isInitialized()) {
|
||||
getContainer().getSwtComposite().layout(true, true);
|
||||
}//if//
|
||||
}//if//
|
||||
break;
|
||||
}//case//
|
||||
case MESSAGE_SET_BLOCK_ON_SELECTIONS: {
|
||||
blockOnSelections = ((Boolean) viewMessage.getMessageData()).booleanValue();
|
||||
break;
|
||||
}//case//
|
||||
case MESSAGE_SET_TEXT: {
|
||||
textHolder.setValue(viewMessage.getMessageData());
|
||||
break;
|
||||
}//case//
|
||||
case MESSAGE_SET_IMAGE: {
|
||||
imageHolder.setValue(viewMessage.getMessageData());
|
||||
break;
|
||||
}//case//
|
||||
case MESSAGE_SET_IS_SELECTED: {
|
||||
Boolean isSelected = (Boolean) viewMessage.getMessageData();
|
||||
|
||||
//Only set the selection if it has changed.//
|
||||
if(isSelected.booleanValue() != getSwtButton().getSelection()) {
|
||||
getSwtButton().setSelection(isSelected.booleanValue());
|
||||
selectionState = isSelected.booleanValue();
|
||||
|
||||
//Send feedback to the server so that it will properly maintain state.//
|
||||
if(autoSynchronizeSelection) {
|
||||
sendMessage(MESSAGE_VIEW_SYNCHRONIZE_SELECTION, isSelected);
|
||||
}//if//
|
||||
|
||||
selectionLinkage.invoke(isSelected);
|
||||
}//if//
|
||||
break;
|
||||
}//case//
|
||||
case MESSAGE_SET_AUTO_SYNCHRONIZE_SELECTION: {
|
||||
autoSynchronizeSelection = ((Boolean) viewMessage.getMessageData()).booleanValue();
|
||||
break;
|
||||
}//case//
|
||||
case MESSAGE_SET_AUTO_SYNCHRONIZE_SELECTION_DELAY: {
|
||||
autoSynchronizeSelectionDelay = ((Long) viewMessage.getMessageData()).longValue();
|
||||
break;
|
||||
}//case//
|
||||
case MESSAGE_ADD_SELECTION_LINK: {
|
||||
LinkInfo info = (LinkInfo) viewMessage.getMessageData();
|
||||
|
||||
selectionLinkage.add(new LinkData(getComponent(info.getComponent()), info.getTarget(), info.getData(), info.isBoolean(), info.invertLogic(), info.nullValue()));
|
||||
break;
|
||||
}//case//
|
||||
default: {
|
||||
result = super.internalProcessMessage(viewMessage);
|
||||
}//default//
|
||||
}//switch//
|
||||
|
||||
return result;
|
||||
}//internalProcessMessage()//
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.swt.events.SelectionListener#widgetDefaultSelected(org.eclipse.swt.events.SelectionEvent)
|
||||
*/
|
||||
public void widgetDefaultSelected(SelectionEvent event) {
|
||||
//TODO: When is this called?//
|
||||
Debug.log("Default Selected called <Why?>");
|
||||
}//widgetDefaultSelected()//
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.swt.events.SelectionListener#widgetSelected(org.eclipse.swt.events.SelectionEvent)
|
||||
*/
|
||||
public void widgetSelected(SelectionEvent event) {
|
||||
selectionChanged(getSwtButton().getSelection());
|
||||
}//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) {
|
||||
try {
|
||||
if(blockOnSelections || autoSynchronizeSelection) {
|
||||
if((!blockOnSelections) && (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(Button.this) {
|
||||
if(autoSynchronizeSelectionTask == this) {
|
||||
//Cleanup after the task.//
|
||||
autoSynchronizeSelectionTask = null;
|
||||
getEventLoop().executeAsync(new IRunnable() {
|
||||
public Object run() {
|
||||
sendMessage(MESSAGE_VIEW_SYNCHRONIZE_SELECTION, isSelected ? Boolean.TRUE : Boolean.FALSE);
|
||||
return null;
|
||||
}//run()//
|
||||
});
|
||||
}//if//
|
||||
}//synchronized//
|
||||
}//run()//
|
||||
};
|
||||
addTask(autoSynchronizeSelectionTask, autoSynchronizeSelectionDelay);
|
||||
}//synchronized//
|
||||
}//if//
|
||||
else {
|
||||
if(blockOnSelections) {
|
||||
sendRoundTripMessage(MESSAGE_VIEW_SYNCHRONIZE_SELECTION, isSelected ? Boolean.TRUE : Boolean.FALSE, null);
|
||||
}//if//
|
||||
else {
|
||||
sendMessage(MESSAGE_VIEW_SYNCHRONIZE_SELECTION, isSelected ? Boolean.TRUE : Boolean.FALSE);
|
||||
}//else//
|
||||
}//else//
|
||||
}//if//
|
||||
|
||||
selectionLinkage.invoke(isStateful ? isSelected ? Boolean.TRUE : Boolean.FALSE : null);
|
||||
}//try//
|
||||
catch(Throwable e) {
|
||||
Debug.log(e);
|
||||
}//catch//
|
||||
}//selectionChanged()//
|
||||
}//Button//
|
||||
@@ -0,0 +1,109 @@
|
||||
/*
|
||||
* Copyright (c) 2007,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.tcv.swt.client;
|
||||
|
||||
import com.foundation.tcv.swt.ICardLayout;
|
||||
import com.foundation.tcv.view.ViewMessage;
|
||||
|
||||
public class CardLayout extends Layout implements ICardLayout {
|
||||
/** The zero based index of the top visible card. */
|
||||
public int topIndex = 0;
|
||||
/** The top and bottom margins. */
|
||||
public int marginHeight = 0;
|
||||
/** The left and right margins. */
|
||||
public int marginWidth = 0;
|
||||
/**
|
||||
* CardLayout constructor.
|
||||
*/
|
||||
public CardLayout() {
|
||||
}//CardLayout()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.Layout#createLayout(java.lang.Object)
|
||||
*/
|
||||
public org.eclipse.swt.widgets.Layout createLayout(Object rowObject) {
|
||||
com.foundation.view.swt.layout.CardLayout result = new com.foundation.view.swt.layout.CardLayout();
|
||||
|
||||
result.marginHeight = marginHeight;
|
||||
result.marginWidth = marginWidth;
|
||||
result.topIndex = topIndex;
|
||||
|
||||
return result;
|
||||
}//createLayout()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.Layout#initialize()
|
||||
*/
|
||||
public void initialize() {
|
||||
}//initialize()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.Layout#release()
|
||||
*/
|
||||
public void release() {
|
||||
}//release()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.Layout#synchronize()
|
||||
*/
|
||||
public void synchronize() {
|
||||
}//synchronize()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.Layout#processMessage(com.foundation.tcv.view.ViewMessage)
|
||||
*/
|
||||
public Object processMessage(ViewMessage viewMessage) {
|
||||
Object result = null;
|
||||
|
||||
switch(viewMessage.getMessageNumber()) {
|
||||
case MESSAGE_INITIALIZE: {
|
||||
setContainer((AbstractComponent) getComponent(viewMessage.getMessageInteger()));
|
||||
break;
|
||||
}//case//
|
||||
case MESSAGE_SET_MARGIN_HEIGHT: {
|
||||
this.marginHeight = viewMessage.getMessageInteger();
|
||||
break;
|
||||
}//case//
|
||||
case MESSAGE_SET_MARGIN_WIDTH: {
|
||||
this.marginWidth = viewMessage.getMessageInteger();
|
||||
break;
|
||||
}//case//
|
||||
case MESSAGE_SET_TOP_INDEX: {
|
||||
if(viewMessage.getMessageSecondaryInteger() != -1) {
|
||||
final RowObject rowObject = getCellContainer().getRowObject(viewMessage.getMessageSecondaryInteger());
|
||||
final int topIndex = viewMessage.getMessageInteger();
|
||||
|
||||
applyChanges(rowObject, new IChangeHandler() {
|
||||
public void applyChanges(org.eclipse.swt.widgets.Layout layout) {
|
||||
if(layout instanceof com.foundation.view.swt.layout.CardLayout) {
|
||||
((com.foundation.view.swt.layout.CardLayout) layout).topIndex = topIndex;
|
||||
layoutContainer(rowObject, true, true);
|
||||
}//if//
|
||||
}//applyChanges()//
|
||||
});
|
||||
}//if//
|
||||
else {
|
||||
final int topIndex = viewMessage.getMessageInteger();
|
||||
|
||||
this.topIndex = topIndex;
|
||||
|
||||
applyChanges(null, new IChangeHandler() {
|
||||
public void applyChanges(org.eclipse.swt.widgets.Layout layout) {
|
||||
if(layout instanceof com.foundation.view.swt.layout.CardLayout) {
|
||||
((com.foundation.view.swt.layout.CardLayout) layout).topIndex = topIndex;
|
||||
layoutContainer(null, true, true);
|
||||
}//if//
|
||||
}//applyChanges()//
|
||||
});
|
||||
}//else//
|
||||
break;
|
||||
}//case//
|
||||
default: {
|
||||
result = super.processMessage(viewMessage);
|
||||
break;
|
||||
}//default//
|
||||
}//switch//
|
||||
|
||||
return result;
|
||||
}//processMessage()//
|
||||
}//CardLayout//
|
||||
@@ -0,0 +1,52 @@
|
||||
package com.foundation.tcv.swt.client;
|
||||
|
||||
import com.foundation.tcv.view.ViewMessage;
|
||||
|
||||
public class CenterLayout extends Layout {
|
||||
/**
|
||||
* CenterLayout constructor.
|
||||
*/
|
||||
public CenterLayout() {
|
||||
super();
|
||||
}//CenterLayout()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.Layout#createLayout(java.lang.Object)
|
||||
*/
|
||||
public org.eclipse.swt.widgets.Layout createLayout(Object rowObject) {
|
||||
return new com.foundation.view.swt.layout.CenterLayout();
|
||||
}//createLayout()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.Layout#initialize()
|
||||
*/
|
||||
public void initialize() {
|
||||
}//initialize()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.Layout#release()
|
||||
*/
|
||||
public void release() {
|
||||
}//release()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.Layout#synchronize()
|
||||
*/
|
||||
public void synchronize() {
|
||||
}//synchronize()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.Layout#processMessage(com.foundation.tcv.view.ViewMessage)
|
||||
*/
|
||||
public Object processMessage(ViewMessage viewMessage) {
|
||||
Object result = null;
|
||||
|
||||
switch(viewMessage.getMessageNumber()) {
|
||||
case MESSAGE_INITIALIZE: {
|
||||
setContainer((AbstractComponent) getComponent(viewMessage.getMessageInteger()));
|
||||
break;
|
||||
}//case//
|
||||
default: {
|
||||
result = super.processMessage(viewMessage);
|
||||
break;
|
||||
}//default//
|
||||
}//switch//
|
||||
|
||||
return result;
|
||||
}//processMessage()//
|
||||
}//CenterLayout//
|
||||
@@ -0,0 +1,558 @@
|
||||
/*
|
||||
* Copyright (c) 2003,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.tcv.swt.client;
|
||||
|
||||
import com.common.comparison.Comparator;
|
||||
import com.common.util.IIterator;
|
||||
import com.common.util.IList;
|
||||
import com.common.util.LiteList;
|
||||
import com.common.util.optimized.IIntIterator;
|
||||
import com.common.util.optimized.IntObjectHashMap;
|
||||
import com.foundation.tcv.model.LinkInfo;
|
||||
import com.foundation.tcv.swt.*;
|
||||
import com.foundation.tcv.swt.client.cell.CellComponent;
|
||||
import com.foundation.tcv.view.*;
|
||||
import com.foundation.view.LinkData;
|
||||
|
||||
public abstract class CollectionComponent extends ScrollableComponent implements ICollectionComponent, ICellContainer {
|
||||
/** The only invalid value for an object identifier. */
|
||||
protected static final int INVALID_OBJECT_ID = -1;
|
||||
/** Used by the hidden data to identify when the previous value has not yet been assigned a value. */
|
||||
protected static final Object UNSET_VALUE = new Object();
|
||||
|
||||
/** Whether the user can type a custom selection. If this is true and the selection attribute is not a String type then the user input must match a list item's text. */
|
||||
private boolean allowUserItems = false;
|
||||
/** Whether the user is allowed to make multiple selections. */
|
||||
private boolean allowMultiSelection = false;
|
||||
/** Whether the selection should be automatically sent to the model. */
|
||||
private boolean autoSynchronizeSelection = false;
|
||||
/** The number of milliseconds of delay before auto synchronizing the selection. */
|
||||
private long autoSynchronizeSelectionDelay = 500;
|
||||
/** The task that auto synchronizes the selection after a short delay. */
|
||||
protected Task autoSynchronizeSelectionTask = null;
|
||||
/** Whether to send the double click events to the server for processing. */
|
||||
private boolean sendDoubleClick = false;
|
||||
/** The collection of HiddenData instances, one for each hidden data holder. */
|
||||
private IList hiddenDataSets = new LiteList(10, 20);
|
||||
/** Maps the row objects by their unique object identifiers. */
|
||||
private IntObjectHashMap rowObjectByObjectIdMap = new IntObjectHashMap(100, 200);
|
||||
/** The linkage for the selection related value. */
|
||||
private Linkage selectionLinkage = new Linkage();
|
||||
/** The collection of cell components. */
|
||||
private LiteList cellComponents = null;
|
||||
/** The count of calls to preChangeCollection(). Incremented for each call to preChangeCollection(), decremented for each call to postChangeCollection(). This counter determines when to call internalPostChangeCollection(). */
|
||||
private int preChangeCollectionCounter = 0;
|
||||
|
||||
/**
|
||||
* The base class for the different types of hidden data.
|
||||
* Hidden data is used by the collection to activate linkages without going through the controllers or models.
|
||||
* Each object in the collection will then be assigned a value for each hidden data and the selection determines the value assigned to the linkages.
|
||||
*/
|
||||
protected class HiddenData {
|
||||
/** The zero based index of the hidden data. This identifies the hidden data that generates events. */
|
||||
private int hiddenDataIndex;
|
||||
/** The previous selection related value for this hidden data. This allows linkages to be activated only when the value is altered. */
|
||||
private Object previousValue = UNSET_VALUE;
|
||||
/** The linkage for the selection related value. */
|
||||
private Linkage linkage = new Linkage();
|
||||
/** The multi-selection options for the hidden data. */
|
||||
private int multiSelectionOption = MULTI_SELECTION_OPTION_DEFAULT;
|
||||
/** The default value for the hidden data. */
|
||||
private Object defaultValue = null;
|
||||
|
||||
/**
|
||||
* HiddenData constructor.
|
||||
* @param hiddenDataIndex The index in the hidden data set.
|
||||
*/
|
||||
protected HiddenData(int hiddenDataIndex) {
|
||||
this.hiddenDataIndex = hiddenDataIndex;
|
||||
}//HiddenData()//
|
||||
/**
|
||||
* Adds a link associated with the collection's selection's hidden data value.
|
||||
* @param link The local linkage for the selection related data.
|
||||
*/
|
||||
public void addLink(LinkData link) {
|
||||
linkage.add(link);
|
||||
}//addLink()//
|
||||
/**
|
||||
* Invokes the linkage with the given value.
|
||||
* @param value The last value for the selection and this hidden data.
|
||||
*/
|
||||
public void invokeLinkage(RowObject[] selections) {
|
||||
Object value = null;
|
||||
|
||||
if((selections == null) || (selections.length == 0) || (multiSelectionOption == MULTI_SELECTION_OPTION_DEFAULT)) {
|
||||
value = defaultValue;
|
||||
}//if//
|
||||
else {
|
||||
value = selections[0].hiddenData[hiddenDataIndex];
|
||||
|
||||
for(int index = 1; index < selections.length; index++) {
|
||||
Object next = selections[index].hiddenData[hiddenDataIndex];
|
||||
|
||||
switch(multiSelectionOption) {
|
||||
case MULTI_SELECTION_OPTION_COMMON: {
|
||||
//If the values are not comparable then use the default value for the linkage and exit the loop.//
|
||||
if(!Comparator.equals(next, value)) {
|
||||
value = defaultValue;
|
||||
index = selections.length;
|
||||
}//if//
|
||||
break;
|
||||
}//case//
|
||||
case MULTI_SELECTION_OPTION_AND: {
|
||||
if((next instanceof Boolean) && (value instanceof Boolean)) {
|
||||
value = ((Boolean) next).booleanValue() && ((Boolean) value).booleanValue() ? Boolean.TRUE : Boolean.FALSE;
|
||||
}//if//
|
||||
//TODO: What should we do if they are not booleans? For now we will ignore this since a view building tool would prevent the possibility.
|
||||
break;
|
||||
}//case//
|
||||
case MULTI_SELECTION_OPTION_OR: {
|
||||
if((next instanceof Boolean) && (value instanceof Boolean)) {
|
||||
value = ((Boolean) next).booleanValue() || ((Boolean) value).booleanValue() ? Boolean.TRUE : Boolean.FALSE;
|
||||
}//if//
|
||||
//TODO: What should we do if they are not booleans? For now we will ignore this since a view building tool would prevent the possibility.
|
||||
break;
|
||||
}//case//
|
||||
}//switch//
|
||||
}//for//
|
||||
}//else//
|
||||
|
||||
if(!Comparator.equals(value, previousValue)) {
|
||||
previousValue = value;
|
||||
linkage.invoke(value);
|
||||
}//if//
|
||||
}//invokeLinkage()//
|
||||
/**
|
||||
* Invokes the linkage with the given value.
|
||||
* @param value The last value for the selection and this hidden data.
|
||||
*/
|
||||
public void invokeLinkage(RowObject selection) {
|
||||
Object value = selection != null ? selection.hiddenData[hiddenDataIndex] : defaultValue;
|
||||
|
||||
if(!Comparator.equals(value, previousValue)) {
|
||||
previousValue = value;
|
||||
linkage.invoke(value);
|
||||
}//if//
|
||||
}//invokeLinkage()//
|
||||
/**
|
||||
* Gets the index for the hidden data.
|
||||
* @return The zero based index identifying the hidden data.
|
||||
*/
|
||||
public int getHiddenDataIndex() {
|
||||
return hiddenDataIndex;
|
||||
}//getHiddenDataIndex()//
|
||||
}//HiddenData//
|
||||
/**
|
||||
* CollectionComponent constructor.
|
||||
*/
|
||||
public CollectionComponent() {
|
||||
super();
|
||||
}//CollectionComponent()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.ICellContainer#addCellComponent(com.foundation.tcv.swt.client.cell.CellComponent)
|
||||
*/
|
||||
public void addCellComponent(CellComponent component) {
|
||||
if(cellComponents == null) {
|
||||
cellComponents = new LiteList(10, 20);
|
||||
}//if//
|
||||
|
||||
cellComponents.add(component);
|
||||
|
||||
if(isInitialized()) {
|
||||
((AbstractComponent) component).internalViewInitializeAll();
|
||||
}//if//
|
||||
}//addCellComponent()//
|
||||
/**
|
||||
* Gets the collection of cell components for this container.
|
||||
* @return The cell components contained within this container.
|
||||
*/
|
||||
public IList getCellComponents() {
|
||||
return cellComponents == null ? LiteList.EMPTY_LIST : cellComponents;
|
||||
}//getCellComponents()//
|
||||
/**
|
||||
* Gets the SWT composite that represents this collection component.
|
||||
* @return The SWT composite providing visualization for this collection component.
|
||||
*/
|
||||
public org.eclipse.swt.widgets.Composite getSwtComposite() {
|
||||
return (org.eclipse.swt.widgets.Composite) getSwtWidget();
|
||||
}//getSwtComposite()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.ICellContainer#getSwtComposite(com.foundation.tcv.swt.client.RowObject)
|
||||
*/
|
||||
public org.eclipse.swt.widgets.Composite getSwtComposite(RowObject rowObject) {
|
||||
return getSwtComposite();
|
||||
}//getSwtComposite()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.Component#internalViewInitializeAll()
|
||||
*/
|
||||
protected void internalViewInitializeAll() {
|
||||
super.internalViewInitializeAll();
|
||||
|
||||
if(cellComponents != null) {
|
||||
for(int index = 0; index < cellComponents.getSize(); index++) {
|
||||
((AbstractComponent) cellComponents.get(index)).internalViewInitializeAll();
|
||||
}//for//
|
||||
}//if//
|
||||
}//internalViewInitializeAll()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.Component#internalViewReleaseAll()
|
||||
*/
|
||||
protected void internalViewReleaseAll() {
|
||||
super.internalViewReleaseAll();
|
||||
|
||||
if(cellComponents != null) {
|
||||
for(int index = 0; index < cellComponents.getSize(); index++) {
|
||||
((AbstractComponent) cellComponents.get(index)).internalViewReleaseAll();
|
||||
}//for//
|
||||
}//if//
|
||||
}//internalViewReleaseAll()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.Component#internalViewSynchronizeAll()
|
||||
*/
|
||||
protected void internalViewSynchronizeAll() {
|
||||
super.internalViewSynchronizeAll();
|
||||
|
||||
if(cellComponents != null) {
|
||||
for(int index = 0; index < cellComponents.getSize(); index++) {
|
||||
((AbstractComponent) cellComponents.get(index)).internalViewSynchronizeAll();
|
||||
}//for//
|
||||
}//if//
|
||||
}//internalViewSynchronizeAll()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.AbstractComponent#internalViewSynchronize()
|
||||
*/
|
||||
protected void internalViewSynchronize() {
|
||||
super.internalViewSynchronize();
|
||||
internalViewSynchronizeSelection();
|
||||
}//internalViewSynchronize()//
|
||||
/**
|
||||
* Synchronizes the selection when requested by the view controller.
|
||||
*/
|
||||
protected void internalViewSynchronizeSelection() {
|
||||
if(!getAutoSynchronizeSelection()) {
|
||||
synchronizeSelection();
|
||||
}//if//
|
||||
else {
|
||||
synchronized(this) {
|
||||
if(autoSynchronizeSelectionTask != null) {
|
||||
removeTask(autoSynchronizeSelectionTask);
|
||||
autoSynchronizeSelectionTask.execute();
|
||||
}//if//
|
||||
}//synchronized//
|
||||
}//else//
|
||||
}//internalViewSynchronizeSelection()//
|
||||
/**
|
||||
* Synchronizes the selection when the user interacts with the collection.
|
||||
*/
|
||||
protected abstract void synchronizeSelection();
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.Component#internalViewInitialize()
|
||||
*/
|
||||
protected void internalViewInitialize() {
|
||||
super.internalViewInitialize();
|
||||
}//internalViewInitialize()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.AbstractComponent#internalViewRelease()
|
||||
*/
|
||||
protected void internalViewRelease() {
|
||||
synchronized(this) {
|
||||
if(autoSynchronizeSelectionTask != null) {
|
||||
removeTask(autoSynchronizeSelectionTask);
|
||||
autoSynchronizeSelectionTask = null;
|
||||
}//if//
|
||||
}//synchronized//
|
||||
|
||||
super.internalViewRelease();
|
||||
}//internalViewRelease()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.AbstractComponent#internalProcessMessage(com.foundation.tcv.model.ViewMessage)
|
||||
*/
|
||||
public Object internalProcessMessage(ViewMessage viewMessage) {
|
||||
Object result = null;
|
||||
|
||||
switch(viewMessage.getMessageNumber()) {
|
||||
case MESSAGE_SET_AUTO_SYNCHRONIZE_SELECTION: {
|
||||
autoSynchronizeSelection = ((Boolean) viewMessage.getMessageData()).booleanValue();
|
||||
break;
|
||||
}//case//
|
||||
case MESSAGE_SET_AUTO_SYNCHRONIZE_SELECTION_DELAY: {
|
||||
autoSynchronizeSelectionDelay = ((Long) viewMessage.getMessageData()).longValue();
|
||||
break;
|
||||
}//case//
|
||||
case MESSAGE_SEND_DOUBLE_CLICK: {
|
||||
sendDoubleClick = ((Boolean) viewMessage.getMessageData()).booleanValue();
|
||||
break;
|
||||
}//case//
|
||||
case MESSAGE_ADD_HIDDEN_DATA: {
|
||||
hiddenDataSets.add(createHiddenData(hiddenDataSets.getSize()));
|
||||
break;
|
||||
}//case//
|
||||
case MESSAGE_ADD_HIDDEN_DATA_LINK: {
|
||||
HiddenData hiddenData = (HiddenData) hiddenDataSets.get(viewMessage.getMessageInteger());
|
||||
LinkInfo info = (LinkInfo) viewMessage.getMessageData();
|
||||
|
||||
hiddenData.linkage.add(new LinkData(getComponent(info.getComponent()), info.getTarget(), info.getData(), info.isBoolean(), info.invertLogic(), info.nullValue()));
|
||||
break;
|
||||
}//case//
|
||||
case MESSAGE_UPDATE_HIDDEN_DATA_DEFAULT_VALUE: {
|
||||
HiddenData hiddenData = (HiddenData) hiddenDataSets.get(viewMessage.getMessageInteger());
|
||||
Object defaultValue = viewMessage.getMessageData();
|
||||
|
||||
hiddenData.defaultValue = defaultValue;
|
||||
|
||||
if(isInitialized()) {
|
||||
updateSelectionLinks();
|
||||
}//if//
|
||||
break;
|
||||
}//case//
|
||||
case MESSAGE_UPDATE_HIDDEN_DATA: {
|
||||
Object[] data = (Object[]) viewMessage.getMessageData();
|
||||
int objectId = ((Integer) data[0]).intValue();
|
||||
int hiddenDataIndex = ((Integer) data[1]).intValue();
|
||||
Object hiddenData = data[2];
|
||||
|
||||
updateHiddenData(getRowObject(objectId), hiddenDataIndex, hiddenData);
|
||||
break;
|
||||
}//case//
|
||||
case MESSAGE_ADD_SELECTION_LINK: {
|
||||
LinkInfo info = (LinkInfo) viewMessage.getMessageData();
|
||||
|
||||
selectionLinkage.add(new LinkData(getComponent(info.getComponent()), info.getTarget(), info.getData(), info.invertLogic()));
|
||||
break;
|
||||
}//case//
|
||||
case MESSAGE_PRE_CHANGE_COLLECTION: {
|
||||
preChangeCollection();
|
||||
break;
|
||||
}//case//
|
||||
case MESSAGE_POST_CHANGE_COLLECTION: {
|
||||
postChangeCollection();
|
||||
break;
|
||||
}//case//
|
||||
default: {
|
||||
result = super.internalProcessMessage(viewMessage);
|
||||
}//default//
|
||||
}//switch//
|
||||
|
||||
return result;
|
||||
}//internalProcessMessage()//
|
||||
/**
|
||||
* Determines whether the control allows the user to type in custom items (combobox).
|
||||
* @return Whether users will be allowed to type in a custom value.
|
||||
*/
|
||||
protected boolean getAllowUserItems() {
|
||||
return allowUserItems;
|
||||
}//getAllowUserItems()//
|
||||
/**
|
||||
* Determines whether the control allows the user to type in custom items (combobox).
|
||||
* @param allowUserItems Whether users will be allowed to type in a custom value.
|
||||
*/
|
||||
protected void setAllowUserItems(boolean allowUserItems) {
|
||||
this.allowUserItems = allowUserItems;
|
||||
}//setAllowUserItems()//
|
||||
/**
|
||||
* Determines whether the control should automatically synchronize all selections.
|
||||
* @return Whether selections should automatically get sent to the server.
|
||||
*/
|
||||
protected boolean getAutoSynchronizeSelection() {
|
||||
return autoSynchronizeSelection;
|
||||
}//getAutoSynchronizeSelection()//
|
||||
/**
|
||||
* Gets the delay in milliseconds between the selection event and updating the model.
|
||||
* @return The number of milliseconds to wait before updating the model.
|
||||
*/
|
||||
protected long getAutoSynchronizeSelectionDelay() {
|
||||
return autoSynchronizeSelectionDelay;
|
||||
}//getAutoSynchronizeSelectionDelay()//
|
||||
/**
|
||||
* Sets the delay in milliseconds between the selection event and updating the model.
|
||||
* @param autoSynchronizeSelectionDelay The number of milliseconds to wait before updating the model.
|
||||
*/
|
||||
protected void setAutoSynchronizeSelectionDelay(long autoSynchronizeSelectionDelay) {
|
||||
this.autoSynchronizeSelectionDelay = autoSynchronizeSelectionDelay;
|
||||
}//setAutoSynchronizeSelectionDelay()//
|
||||
/**
|
||||
* Gets the linkage for the selection state.
|
||||
* @return The linkage used to notify listeners when there is or is not a selection.
|
||||
*/
|
||||
protected Linkage getSelectionLinkage() {
|
||||
return selectionLinkage;
|
||||
}//getSelectionLinkage()//
|
||||
/**
|
||||
* Determines whether the control allows the user to make multiple selections at one time.
|
||||
* @return Whether more than one value can be selected at a time.
|
||||
*/
|
||||
protected boolean getAllowMultiSelection() {
|
||||
return allowMultiSelection;
|
||||
}//getAllowMultiSelection()//
|
||||
/**
|
||||
* Determines whether the control allows the user to make multiple selections at one time.
|
||||
* @param allowMultiSelection Whether more than one value can be selected at a time.
|
||||
*/
|
||||
protected void setAllowMultiSelection(boolean allowMultiSelection) {
|
||||
this.allowMultiSelection = allowMultiSelection;
|
||||
}//setAllowMultiSelection()//
|
||||
/**
|
||||
* Determines whether the control should send double click events to the server.
|
||||
* @return Whether double click events need to be forwarded to the server for processing.
|
||||
*/
|
||||
protected boolean getSendDoubleClick() {
|
||||
return sendDoubleClick;
|
||||
}//getSendDoubleClick()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.ICellContainer#getSwtComposites()
|
||||
*/
|
||||
public IIterator getSwtComposites() {
|
||||
return LiteList.EMPTY_LIST.iterator();
|
||||
}//getSwtComposites()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.ICellContainer#setLayout(com.foundation.tcv.swt.client.Layout)
|
||||
*/
|
||||
public void setLayout(Layout layout) {
|
||||
//Not supported.//
|
||||
}//setLayout()//
|
||||
/**
|
||||
* Determines whether the two texts require swapping.
|
||||
* This is used by the sorting code to determine whether rows should be swapped.
|
||||
* @param text1 The first text.
|
||||
* @param text2 The second text (following the first text).
|
||||
* @param reverse Whether the logic should be reversed.
|
||||
* @return Whether text1 and text2 require swapping.
|
||||
*/
|
||||
protected boolean requiresSwap(String text1, String text2, boolean reverse) {
|
||||
int compare = Comparator.getNumericStringComparator().compare(text1, text2);
|
||||
|
||||
return reverse ? compare < 0 : compare > 0;
|
||||
}//requiresSwap()//
|
||||
/**
|
||||
* Creates a new hidden data object at the given index in the collection.
|
||||
* This can be overloaded to use subclasses which can hold the data associated with the hidden data and the rows of data in the component.
|
||||
* @param hiddenDataIndex The index at for the hidden data which will serve to identify it on the server and client.
|
||||
*/
|
||||
protected HiddenData createHiddenData(int hiddenDataIndex) {
|
||||
return new HiddenData(hiddenDataIndex);
|
||||
}//createHiddenData()//
|
||||
/**
|
||||
* Gets the hidden data set for the given index.
|
||||
* @param hiddenDataIndex The zero based index for the desired hidden data metadata.
|
||||
* @return The metadata describing the hidden data and providing access to the current value for any collection item.
|
||||
*/
|
||||
protected HiddenData getHiddenData(int hiddenDataIndex) {
|
||||
return (HiddenData) hiddenDataSets.get(hiddenDataIndex);
|
||||
}//getHiddenData()//
|
||||
/**
|
||||
* Creates a new row object.
|
||||
* @param objectId The identifier for the object that is represented by the row.
|
||||
* @return An empty row object.
|
||||
*/
|
||||
protected RowObject createRowObject(int objectId) {
|
||||
return new RowObject(objectId, getHiddenDataCount());
|
||||
}//createRowObject()//
|
||||
/**
|
||||
* Gets the row object containing the data for the object with the given identifier.
|
||||
* @param objectId Identifies the object that the row object represents.
|
||||
* @return The row object that is the avatar for the object identified by the object id.
|
||||
*/
|
||||
public RowObject getRowObject(int objectId) {
|
||||
return (RowObject) rowObjectByObjectIdMap.get(objectId);
|
||||
}//getRowObject()//
|
||||
/**
|
||||
* Adds a new row object to the collection.
|
||||
* @param rowObject The row object to be added.
|
||||
*/
|
||||
protected void addRowObject(RowObject rowObject) {
|
||||
rowObjectByObjectIdMap.put(rowObject.getObjectId(), rowObject);
|
||||
}//addRowObject()//
|
||||
/**
|
||||
* Removes a row object from the collection.
|
||||
* @param rowObject The row object to be removed.
|
||||
*/
|
||||
protected void removeRowObject(int rowObjectId) {
|
||||
((RowObject) rowObjectByObjectIdMap.remove(rowObjectId)).dispose();
|
||||
}//removeRowObject()//
|
||||
/**
|
||||
* Removes all row objects from the collection.
|
||||
*/
|
||||
protected void removeRowObjects() {
|
||||
IIterator iterator = rowObjectByObjectIdMap.valueIterator();
|
||||
|
||||
while(iterator.hasNext()) {
|
||||
((RowObject) iterator.next()).dispose();
|
||||
}//while//
|
||||
|
||||
rowObjectByObjectIdMap.removeAll();
|
||||
}//removeRowObjects()//
|
||||
/**
|
||||
* Gets an iterator over all the row objects.
|
||||
* @return The RowObject iterator.
|
||||
*/
|
||||
public IIterator getRowObjects() {
|
||||
return rowObjectByObjectIdMap.valueIterator();
|
||||
}//getRowObjects()//
|
||||
/**
|
||||
* Gets an iterator over all the row object identifiers.
|
||||
* @return The row object identifier iterator.
|
||||
*/
|
||||
protected IIntIterator getRowObjectIds() {
|
||||
return rowObjectByObjectIdMap.keyIterator();
|
||||
}//getRowObjectIds()//
|
||||
/**
|
||||
* Gets the number of hidden data sets used by the collection component.
|
||||
* @return The count of hidden data 'columns'.
|
||||
*/
|
||||
protected int getHiddenDataCount() {
|
||||
return hiddenDataSets.getSize();
|
||||
}//getHiddenDataCount()//
|
||||
/**
|
||||
* Gets the number of selections in the component.
|
||||
* @return The count of selections.
|
||||
*/
|
||||
protected abstract int controlGetSelectionCount();
|
||||
/**
|
||||
* Updates selection linkages associated with the hidden data 'columns' based on the current selection settings.
|
||||
*/
|
||||
protected void updateSelectionLinks() {
|
||||
selectionLinkage.invoke(controlGetSelectionCount() > 0 ? Boolean.TRUE : Boolean.FALSE);
|
||||
}//updateSelectionLinks()//
|
||||
/**
|
||||
* Sets the hidden data for an object displayed in the collection and the hidden data column.
|
||||
* @param object The row object representing the object whose hidden data is being set.
|
||||
* @param hiddenDataIndex The zero based index of the hidden data column.
|
||||
* @param value The new value for the hidden data for the object.
|
||||
*/
|
||||
protected abstract void updateHiddenData(RowObject object, int hiddenDataIndex, Object value);
|
||||
/**
|
||||
* Called before the collection of displayed values is modified.
|
||||
* This method, in combination with postChangeCollection(), allows the control to be more efficient about its adding of items.
|
||||
*/
|
||||
protected final void preChangeCollection() {
|
||||
if(preChangeCollectionCounter++ == 0) {
|
||||
internalPreChangeCollection();
|
||||
}//if//
|
||||
}//preChangeCollection()//
|
||||
/**
|
||||
* Called after the collection of displayed values is modified.
|
||||
*/
|
||||
protected final void postChangeCollection() {
|
||||
if(--preChangeCollectionCounter == 0) {
|
||||
internalPostChangeCollection();
|
||||
}//if//
|
||||
}//postChangeCollection()//
|
||||
/**
|
||||
* Called before the collection of displayed values is modified.
|
||||
* This method, in combination with postChangeCollection(), allows the control to be more efficient about its adding of items.
|
||||
*/
|
||||
protected void internalPreChangeCollection() {
|
||||
//Subclasses should override as required.//
|
||||
}//preChangeCollection()//
|
||||
/**
|
||||
* Called after the collection of displayed values is modified.
|
||||
*/
|
||||
protected void internalPostChangeCollection() {
|
||||
//Subclasses should override as required.//
|
||||
}//postChangeCollection()//
|
||||
}//CollectionComponent//
|
||||
@@ -0,0 +1,374 @@
|
||||
/*
|
||||
* Copyright (c) 2003,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.tcv.swt.client;
|
||||
|
||||
import org.eclipse.swt.SWT;
|
||||
import org.eclipse.swt.events.*;
|
||||
|
||||
import com.common.thread.IRunnable;
|
||||
import com.foundation.tcv.swt.*;
|
||||
import com.foundation.tcv.swt.client.cell.CellComponent;
|
||||
import com.foundation.tcv.view.*;
|
||||
|
||||
public class ComboBox extends IndexedCollectionComponent implements SelectionListener, IComboBox, ModifyListener {
|
||||
/** Used to stop selection events from being handled while the items are being changed. */
|
||||
private boolean suspendSelectionEvents = false;
|
||||
/**
|
||||
* ComboBox constructor.
|
||||
*/
|
||||
public ComboBox() {
|
||||
super();
|
||||
}//ComboBox()//
|
||||
/**
|
||||
* Gets the SWT combo that represents this combo box.
|
||||
* @return The SWT combo providing visualization for this combo box.
|
||||
*/
|
||||
public org.eclipse.swt.widgets.Combo getSwtCombo() {
|
||||
return (org.eclipse.swt.widgets.Combo) getSwtWidget();
|
||||
}//getSwtCombo()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.AbstractComponent#internalViewInitialize()
|
||||
*/
|
||||
protected void internalViewInitialize() {
|
||||
getSwtCombo().addSelectionListener(this);
|
||||
getSwtCombo().addModifyListener(this);
|
||||
super.internalViewInitialize();
|
||||
}//internalViewInitialize()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.AbstractComponent#internalViewRelease()
|
||||
*/
|
||||
protected void internalViewRelease() {
|
||||
if((getSwtCombo() != null) && (!getSwtCombo().isDisposed())) {
|
||||
getSwtCombo().removeSelectionListener(this);
|
||||
getSwtCombo().removeModifyListener(this);
|
||||
}//if//
|
||||
|
||||
super.internalViewRelease();
|
||||
}//internalViewRelease()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.AbstractComponent#internalProcessMessage(com.foundation.tcv.model.ViewMessage)
|
||||
*/
|
||||
public Object internalProcessMessage(ViewMessage viewMessage) {
|
||||
Object retVal = null;
|
||||
|
||||
switch(viewMessage.getMessageNumber()) {
|
||||
case MESSAGE_INITIALIZE: {
|
||||
if(getSwtControl() == null) {
|
||||
int[] data = (int[]) viewMessage.getMessageData();
|
||||
int style = data[1];
|
||||
|
||||
//Link to the parent container.//
|
||||
setContainer((Container) getComponent(data[0]));
|
||||
getContainer().addComponent(this);
|
||||
//Create the SWT widget.//
|
||||
setSwtWidget(new org.eclipse.swt.widgets.Combo(getContainer().getSwtParent(), style));
|
||||
getSwtWidget().setData(this);
|
||||
//Set the allows user items flag.//
|
||||
setAllowUserItems(!((style & SWT.READ_ONLY) > 0));
|
||||
|
||||
//If the container has already been initialized then force the parent to re-layout so that this component will appear.//
|
||||
if(getContainer().isInitialized()) {
|
||||
getContainer().getSwtComposite().layout(true, true);
|
||||
}//if//
|
||||
}//if//
|
||||
break;
|
||||
}//case//
|
||||
case MESSAGE_SET_TEXT_LIMIT: {
|
||||
getSwtCombo().setTextLimit(((Integer) viewMessage.getMessageData()).intValue());
|
||||
break;
|
||||
}//case//
|
||||
default: {
|
||||
retVal = super.internalProcessMessage(viewMessage);
|
||||
}//default//
|
||||
}//switch//
|
||||
|
||||
return retVal;
|
||||
}//internalProcessMessage()//
|
||||
/* (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) {
|
||||
updateSelectionLinks();
|
||||
|
||||
if(getAutoSynchronizeSelection()) {
|
||||
if(getAutoSynchronizeSelectionDelay() > 0) {
|
||||
//TODO: Multiple selections are never allowed for a combo...
|
||||
int[] selectedObjectIds = getAllowMultiSelection() ? getSelectedObjectIds() : null;
|
||||
int selectedObjectId = !getAllowMultiSelection() && !hasCustomSelection() ? getSelectedObjectId() : -1;
|
||||
String customSelection = !getAllowMultiSelection() && hasCustomSelection() ? controlGetText() : null;
|
||||
|
||||
if((selectedObjectIds != null) || ((customSelection != null) && (!customSelection.equals(getCustomSelectionOnServer()))) || (selectedObjectId != getSelectedObjectIdOnServer())) {
|
||||
final Object selection = customSelection != null ? (Object) customSelection : selectedObjectIds != null ? (Object) selectedObjectIds : selectedObjectId != -1 ? new Integer(selectedObjectId) : null;
|
||||
|
||||
//Update the known server state.//
|
||||
if(selectedObjectIds == null) {
|
||||
setSelectedObjectIdOnServer(selectedObjectId);
|
||||
setCustomSelectionOnServer(customSelection);
|
||||
}//if//
|
||||
|
||||
//Start a task to send the selection 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(ComboBox.this) {
|
||||
if(autoSynchronizeSelectionTask == this) {
|
||||
//Cleanup after the task.//
|
||||
autoSynchronizeSelectionTask = null;
|
||||
getEventLoop().executeAsync(new IRunnable() {
|
||||
public Object run() {
|
||||
sendMessage(MESSAGE_VIEW_SYNCHRONIZE_SELECTION, selection);
|
||||
return null;
|
||||
}//run()//
|
||||
});
|
||||
}//if//
|
||||
}//synchronized//
|
||||
}//run()//
|
||||
};
|
||||
addTask(autoSynchronizeSelectionTask, getAutoSynchronizeSelectionDelay());
|
||||
}//synchronized//
|
||||
}//if//
|
||||
}//if//
|
||||
else {
|
||||
synchronizeSelection();
|
||||
}//else//
|
||||
}//if//
|
||||
}//widgetSelected()//
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.swt.events.ModifyListener#modifyText(org.eclipse.swt.events.ModifyEvent)
|
||||
*/
|
||||
public void modifyText(ModifyEvent event) {
|
||||
if(!suspendSelectionEvents) {
|
||||
//TODO: Should we remove this if block? Shouldn't widgetSelected(null) be called regardless?
|
||||
if(controlGetSelection() == -1) {
|
||||
widgetSelected(null);
|
||||
}//if//
|
||||
}//if//
|
||||
}//modifyText()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.view.swt.CollectionComponent#controlRemoveAll()
|
||||
*/
|
||||
protected void controlRemoveAll() {
|
||||
suspendSelectionEvents = true;
|
||||
|
||||
try {
|
||||
getSwtCombo().removeAll();
|
||||
}//try//
|
||||
finally {
|
||||
suspendSelectionEvents = false;
|
||||
}//finally//
|
||||
}//controlRemoveAll()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.view.swt.CollectionComponent#controlSetItems(String[])
|
||||
*/
|
||||
protected void controlSetItems(Object[] items) {
|
||||
String[] itemTexts = new String[items.length];
|
||||
|
||||
System.arraycopy(items, 0, itemTexts, 0, itemTexts.length);
|
||||
suspendSelectionEvents = true;
|
||||
|
||||
try {
|
||||
getSwtCombo().setItems(itemTexts);
|
||||
}//try//
|
||||
finally {
|
||||
suspendSelectionEvents = false;
|
||||
}//finally//
|
||||
}//controlSetItems()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.view.swt.CollectionComponent#controlSetItem(int, Object)
|
||||
*/
|
||||
protected void controlSetItem(int index, Object itemData) {
|
||||
suspendSelectionEvents = true;
|
||||
|
||||
try {
|
||||
getSwtCombo().setItem(index, (String) itemData);
|
||||
}//try//
|
||||
finally {
|
||||
suspendSelectionEvents = false;
|
||||
}//finally//
|
||||
}//controlSetItem()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.view.swt.CollectionComponent#controlAddItem(Object, int)
|
||||
*/
|
||||
protected void controlAddItem(Object itemData, int index) {
|
||||
suspendSelectionEvents = true;
|
||||
|
||||
try {
|
||||
getSwtCombo().add((String) itemData, index);
|
||||
}//try//
|
||||
finally {
|
||||
suspendSelectionEvents = false;
|
||||
}//finally//
|
||||
}//controlAddItem()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.view.swt.CollectionComponent#controlAddItem(Object)
|
||||
*/
|
||||
protected void controlAddItem(Object itemData) {
|
||||
suspendSelectionEvents = true;
|
||||
|
||||
try {
|
||||
getSwtCombo().add((String) itemData);
|
||||
}//try//
|
||||
finally {
|
||||
suspendSelectionEvents = false;
|
||||
}//finally//
|
||||
}//controlAddItem()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.view.swt.CollectionComponent#controlRemoveItem(int)
|
||||
*/
|
||||
protected void controlRemoveItem(int index) {
|
||||
suspendSelectionEvents = true;
|
||||
|
||||
try {
|
||||
getSwtCombo().remove(index);
|
||||
}//try//
|
||||
finally {
|
||||
suspendSelectionEvents = false;
|
||||
}//finally//
|
||||
}//controlRemoveItem()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.view.swt.CollectionComponent#controlGetSelections()
|
||||
*/
|
||||
protected int[] controlGetSelections() {
|
||||
//return getSwtCombo().getSelectionIndices();
|
||||
throw new RuntimeException("Method not supported - controlGetSelections");
|
||||
}//controlGetSelections()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.view.swt.CollectionComponent#controlGetSelection()
|
||||
*/
|
||||
protected int controlGetSelection() {
|
||||
return getSwtCombo().getSelectionIndex();
|
||||
}//controlGetSelection()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.view.swt.CollectionComponent#controlSetSelections()
|
||||
*/
|
||||
protected void controlSetSelections(int[] indices) {
|
||||
//getSwtCombo().setSelection(indices);
|
||||
throw new RuntimeException("Method not supported - controlSetSelections");
|
||||
}//controlSetSelections()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.view.swt.CollectionComponent#controlSetSelection()
|
||||
*/
|
||||
protected void controlSetSelection(int index) {
|
||||
suspendSelectionEvents = true;
|
||||
|
||||
try {
|
||||
if(index == -1) {
|
||||
getSwtCombo().deselectAll();
|
||||
}//if//
|
||||
else {
|
||||
getSwtCombo().select(index);
|
||||
}//else//
|
||||
}//try//
|
||||
finally {
|
||||
suspendSelectionEvents = false;
|
||||
}//finally//
|
||||
}//controlSetSelection()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.IndexedCollectionComponent#controlSetSelection(java.lang.String)
|
||||
*/
|
||||
protected void controlSetSelection(String text) {
|
||||
suspendSelectionEvents = true;
|
||||
|
||||
try {
|
||||
if(text == null) {
|
||||
getSwtCombo().deselectAll();
|
||||
}//if//
|
||||
else {
|
||||
getSwtCombo().deselectAll();
|
||||
getSwtCombo().setText(text);
|
||||
}//else//
|
||||
}//try//
|
||||
finally {
|
||||
suspendSelectionEvents = false;
|
||||
}//finally//
|
||||
}//controlSetSelection()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.view.swt.CollectionComponent#controlAddSelection()
|
||||
*/
|
||||
protected void controlAddSelection(int index) {
|
||||
//getSwtCombo().select(index);
|
||||
throw new RuntimeException("Method not supported - controlAddSelection");
|
||||
}//controlAddSelection()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.view.swt.CollectionComponent#controlRemoveSelection()
|
||||
*/
|
||||
protected void controlRemoveSelection(int index) {
|
||||
suspendSelectionEvents = true;
|
||||
|
||||
try {
|
||||
getSwtCombo().deselect(index);
|
||||
}//try//
|
||||
finally {
|
||||
suspendSelectionEvents = false;
|
||||
}//finally//
|
||||
}//controlRemoveSelection()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.view.swt.CollectionComponent#controlRemoveAllSelections()
|
||||
*/
|
||||
protected void controlRemoveAllSelections() {
|
||||
suspendSelectionEvents = true;
|
||||
getSwtCombo().deselectAll();
|
||||
suspendSelectionEvents = false;
|
||||
}//controlRemoveAllSelections()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.view.swt.CollectionComponent#controlIsSelected()
|
||||
*/
|
||||
protected boolean controlIsSelected(int index) {
|
||||
return getSwtCombo().getSelectionIndex() == index;
|
||||
}//controlIsSelected()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.view.swt.CollectionComponent#controlGetText()
|
||||
*/
|
||||
protected String controlGetText() {
|
||||
return getSwtCombo().getText();
|
||||
}//controlGetText()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.view.swt.CollectionComponent#controlSetText(String)
|
||||
*/
|
||||
protected void controlSetText(String text) {
|
||||
suspendSelectionEvents = true;
|
||||
|
||||
if(text == null) {
|
||||
getSwtCombo().deselectAll();
|
||||
}//if//
|
||||
else {
|
||||
getSwtCombo().setText(text);
|
||||
}//else//
|
||||
|
||||
suspendSelectionEvents = false;
|
||||
}//controlSetText()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.CollectionComponent#controlGetSelectionCount()
|
||||
*/
|
||||
protected int controlGetSelectionCount() {
|
||||
return getSwtCombo().getText().length() > 0 ? 1 : 0;
|
||||
}//controlGetSelectionCount()//
|
||||
/**
|
||||
* Forces the selection event handler to be called.
|
||||
*/
|
||||
protected void forceSelectionEvent() { //Should call widgetSelected implemented by the subclass. This name may need to change.//
|
||||
widgetSelected(null);
|
||||
}//forceSelectionEvent()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.ICellContainer#addComponent(com.foundation.tcv.swt.client.cell.CellComponent)
|
||||
*/
|
||||
public void addComponent(CellComponent component) {
|
||||
//Never used.//
|
||||
}//addComponent()//
|
||||
}//ComboBox//
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,307 @@
|
||||
/*
|
||||
* Copyright (c) 2003,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.tcv.swt.client;
|
||||
|
||||
import org.eclipse.swt.SWT;
|
||||
import org.eclipse.swt.widgets.Control;
|
||||
import org.eclipse.swt.widgets.Composite;
|
||||
|
||||
import com.common.util.*;
|
||||
import com.foundation.tcv.swt.*;
|
||||
import com.foundation.tcv.view.*;
|
||||
|
||||
public abstract class Container extends ScrollableComponent implements IContainer, IAbstractSwtContainer {
|
||||
/** A collection of components contained by this container. */
|
||||
private IList components = new LiteList(10, 30);
|
||||
/** The layout used by the container. */
|
||||
private Layout layout = null;
|
||||
/**
|
||||
* Container constructor.
|
||||
*/
|
||||
public Container() {
|
||||
}//Container()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.IAbstractSwtContainer#getSwtComposite()
|
||||
*/
|
||||
public Composite getSwtComposite() {
|
||||
return (Composite) getSwtControl();
|
||||
}//getComposite()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.IAbstractSwtContainer#getSwtParent()
|
||||
*/
|
||||
public Composite getSwtParent() {
|
||||
return (Composite) getSwtControl();
|
||||
}//getSwtParent()//
|
||||
/**
|
||||
* Adds a component as a child of this container.
|
||||
* @param component The component to be contained by this container.
|
||||
*/
|
||||
public void addComponent(Component component) {
|
||||
components.add(component);
|
||||
}//addComponent()//
|
||||
/**
|
||||
* Removes a component that was child of this container.
|
||||
* @param component The component to no longer be contained by this container.
|
||||
*/
|
||||
public void removeComponent(Component component) {
|
||||
components.remove(component);
|
||||
}//removeComponent()//
|
||||
/**
|
||||
* Gets the collection of components contained by this container.
|
||||
* @return The collection of all contained components.
|
||||
*/
|
||||
public IList getComponents() {
|
||||
return components;
|
||||
}//getComponents()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.Component#getFocusControl()
|
||||
*/
|
||||
protected Control getFocusControl() {
|
||||
Control result = getSwtControl().isFocusControl() ? getSwtControl() : null;
|
||||
|
||||
if(result != null) {
|
||||
for(int index = 0; (result == null) && (index < getComponents().getSize()); index++) {
|
||||
Component component = (Component) getComponents().get(index);
|
||||
|
||||
result = component.getFocusControl();
|
||||
}//for//
|
||||
}//if//
|
||||
|
||||
return result;
|
||||
}//getFocusControl()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.AbstractComponent#internalViewInitializeAll()
|
||||
*/
|
||||
protected void internalViewInitializeAll() {
|
||||
IList components = getComponents();
|
||||
IIterator iterator = components.iterator();
|
||||
|
||||
//Initialize all contained components that are not value holders.//
|
||||
while(iterator.hasNext()) {
|
||||
Component component = (Component) iterator.next();
|
||||
|
||||
component.internalViewInitializeAll();
|
||||
}//for//
|
||||
|
||||
super.internalViewInitializeAll();
|
||||
}//internalViewInitializeAll()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.AbstractComponent#internalViewReleaseAll()
|
||||
*/
|
||||
protected void internalViewReleaseAll() {
|
||||
IIterator iterator = new LiteList(getComponents()).iterator();
|
||||
|
||||
//Release sub-components.//
|
||||
while(iterator.hasNext()) {
|
||||
Component component = (Component) iterator.next();
|
||||
|
||||
component.internalViewReleaseAll();
|
||||
}//for//
|
||||
|
||||
super.internalViewReleaseAll();
|
||||
}//internalViewReleaseAll()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.AbstractComponent#internalViewSynchronizeAll()
|
||||
*/
|
||||
protected void internalViewSynchronizeAll() {
|
||||
IIterator iterator = components.iterator();
|
||||
|
||||
//Synchronize sub-components.//
|
||||
while(iterator.hasNext()) {
|
||||
Component component = (Component) iterator.next();
|
||||
|
||||
component.internalViewSynchronizeAll();
|
||||
}//for//
|
||||
|
||||
super.internalViewSynchronizeAll();
|
||||
}//internalViewSynchronizeAll()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.AbstractComponent#internalViewInitialize()
|
||||
*/
|
||||
protected void internalViewInitialize() {
|
||||
super.internalViewInitialize();
|
||||
|
||||
if(layout != null) {
|
||||
layout.initialize();
|
||||
getSwtParent().setLayout(layout.createLayout(null));
|
||||
}//if//
|
||||
}//internalViewInitialize()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.AbstractComponent#internalViewRelease()
|
||||
*/
|
||||
protected void internalViewRelease() {
|
||||
if(layout != null) {
|
||||
layout.release();
|
||||
}//if//
|
||||
|
||||
super.internalViewRelease();
|
||||
}//internalViewRelease()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.AbstractComponent#internalViewSynchronize()
|
||||
*/
|
||||
protected void internalViewSynchronize() {
|
||||
super.internalViewSynchronize();
|
||||
|
||||
if(layout != null) {
|
||||
layout.synchronize();
|
||||
}//if//
|
||||
}//internalViewSynchronize()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.AbstractComponent#internalProcessMessage(com.foundation.tcv.model.ViewMessage)
|
||||
*/
|
||||
public Object internalProcessMessage(ViewMessage viewMessage) {
|
||||
Object result = null;
|
||||
|
||||
switch(viewMessage.getMessageNumber()) {
|
||||
case MESSAGE_LAYOUT: {
|
||||
layout();
|
||||
break;
|
||||
}//case//
|
||||
case MESSAGE_SET_TAB_ORDER: {
|
||||
int[] componentNumbers = (int[]) viewMessage.getMessageData();
|
||||
Control[] array = new Control[componentNumbers.length];
|
||||
|
||||
for(int index = 0; index < componentNumbers.length; index++) {
|
||||
array[index] = getComponent(componentNumbers[index]) instanceof Container ? ((Container) getComponent(componentNumbers[index])).getSwtParent() : ((Component) getComponent(componentNumbers[index])).getSwtControl();
|
||||
}//for//
|
||||
|
||||
getSwtParent().setTabList(array);
|
||||
break;
|
||||
}//case//
|
||||
case MESSAGE_CENTER: {
|
||||
long[] centerOnView = (long[]) viewMessage.getMessageData();
|
||||
|
||||
if(centerOnView != null) {
|
||||
center(centerOnView);
|
||||
}//if//
|
||||
else {
|
||||
center();
|
||||
}//else//
|
||||
break;
|
||||
}//case//
|
||||
case MESSAGE_INHERIT_BACKGROUND: {
|
||||
int inheritType = viewMessage.getMessageInteger();
|
||||
int mode = inheritType == INHERIT_FORCE ? SWT.INHERIT_FORCE : inheritType == INHERIT_DEFAULT ? SWT.INHERIT_DEFAULT : SWT.INHERIT_NONE;
|
||||
|
||||
getSwtComposite().setBackgroundMode(mode);
|
||||
|
||||
if(getSwtParent() != getSwtComposite()) {
|
||||
getSwtParent().setBackgroundMode(mode);
|
||||
}//if//
|
||||
break;
|
||||
}//case//
|
||||
case MESSAGE_PACK: {
|
||||
if(!isSuspendingLayouts()) {
|
||||
if(viewMessage.getMessageData() instanceof Boolean) {
|
||||
getSwtParent().pack(((Boolean) viewMessage.getMessageData()).booleanValue());
|
||||
}//if//
|
||||
else {
|
||||
getSwtParent().pack();
|
||||
}//else//
|
||||
|
||||
internalPack();
|
||||
}//if//
|
||||
break;
|
||||
}//case//
|
||||
default: {
|
||||
result = super.internalProcessMessage(viewMessage);
|
||||
}//case//
|
||||
}//switch//
|
||||
|
||||
return result;
|
||||
}//internalProcessMessage()//
|
||||
/**
|
||||
* Centers the view on the primary monitor.
|
||||
*/
|
||||
protected void center() {
|
||||
//Does nothing. This should be overloaded for subclasses which are capable of standalone behavior (window, frame, etc).//
|
||||
}//center()//
|
||||
/**
|
||||
* Centers the view on the primary monitor.
|
||||
* @param centerOnView The view to center on. If this is null then it will center on the primary monitor.
|
||||
*/
|
||||
protected void center(long[] centerOnView) {
|
||||
//Does nothing. This should be overloaded for subclasses which are capable of standalone behavior (window, frame, etc).//
|
||||
}//center()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.Component#internalSetEnabledState(boolean, boolean)
|
||||
*/
|
||||
protected void internalSetEnabledState(boolean isEnabled, boolean isLocal) {
|
||||
IIterator iterator = getComponents().iterator();
|
||||
|
||||
if(isLocal) {
|
||||
isLocallyEnabled = isEnabled;
|
||||
}//if//
|
||||
else {
|
||||
isParentEnabled = isEnabled;
|
||||
}//else//
|
||||
|
||||
if(getSwtControl().getEnabled() != isLocallyEnabled && isParentEnabled) {
|
||||
//Update the control's state.//
|
||||
getSwtControl().setEnabled(isLocallyEnabled && isParentEnabled);
|
||||
|
||||
//Enable or disable all the contained components.//
|
||||
while(iterator.hasNext()) {
|
||||
AbstractComponent next = (AbstractComponent) iterator.next();
|
||||
|
||||
if(next instanceof Component) {
|
||||
((Component) next).internalSetEnabledState(isEnabled, false);
|
||||
}//if//
|
||||
}//while//
|
||||
}//if//
|
||||
}//internalSetEnabledState()//
|
||||
/**
|
||||
* Tells the container to layout the components contained within it.
|
||||
*/
|
||||
public final void layout() {
|
||||
if(!isSuspendingLayouts()) {
|
||||
getSwtParent().layout(true, true);
|
||||
internalLayout();
|
||||
}//if//
|
||||
}//layout()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.view.swt.AbstractComponent#internalPack()
|
||||
*/
|
||||
protected void internalPack() {
|
||||
//Call internalPack on all sub-components.//
|
||||
for(int index = 0; index < getComponents().getSize(); index++) {
|
||||
((AbstractComponent) getComponents().get(index)).internalPack();
|
||||
}//for//
|
||||
}//internalPack()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.view.swt.AbstractComponent#internalLayout()
|
||||
*/
|
||||
protected void internalLayout() {
|
||||
//Call internalLayout on all sub-components.//
|
||||
for(int index = 0; index < getComponents().getSize(); index++) {
|
||||
((AbstractComponent) getComponents().get(index)).internalLayout();
|
||||
}//for//
|
||||
}//internalLayout()//
|
||||
/**
|
||||
* Called after a child resizes.
|
||||
* This allows the opportunity for the container to appropriately handle the resize of children.
|
||||
*/
|
||||
public void postResize() {
|
||||
if(getContainer() != null) {
|
||||
getContainer().postResize();
|
||||
}//if//
|
||||
}//postResize()//
|
||||
/**
|
||||
* Gets the layout for this container.
|
||||
* @return The container's layout.
|
||||
*/
|
||||
public Layout getLayout() {
|
||||
return layout;
|
||||
}//getLayout()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.IAbstractSwtContainer#setLayout(com.foundation.tcv.swt.client.Layout)
|
||||
*/
|
||||
public void setLayout(Layout layout) {
|
||||
this.layout = layout;
|
||||
}//setLayout()//
|
||||
}//Container//
|
||||
@@ -0,0 +1,366 @@
|
||||
/*
|
||||
* Copyright (c) 2006,2007 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.tcv.swt.client;
|
||||
|
||||
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.widgets.Event;
|
||||
import org.eclipse.swt.widgets.Listener;
|
||||
import org.eclipse.swt.widgets.Shell;
|
||||
|
||||
import com.common.util.LiteList;
|
||||
import com.foundation.tcv.swt.ICoolBar;
|
||||
import com.foundation.tcv.view.ViewMessage;
|
||||
|
||||
public class CoolBar extends Container implements ICoolBar {
|
||||
/** The collection of CoolItem instances contained by the cool bar. */
|
||||
private LiteList coolItems = new LiteList(10, 20);
|
||||
|
||||
/**
|
||||
* Encapsulates an item in the bar.
|
||||
*/
|
||||
public static class CoolItem extends AbstractComponent implements ICoolItem, SelectionListener {
|
||||
private Container container = null;
|
||||
/** The control displayed by the cool item. */
|
||||
private Component control = null;
|
||||
/** The style used by the item. */
|
||||
private int style;
|
||||
/** Whether a custom size is used for the item. */
|
||||
private boolean customSize = false;
|
||||
/** The custom width for the item. */
|
||||
private int customWidth = 0;
|
||||
/** The custom height for the item. */
|
||||
private int customHeight = 0;
|
||||
/** Whether a custom preferred size is used for the item. */
|
||||
private boolean customPreferredSize = false;
|
||||
/** The custom preferred width for the item. */
|
||||
private int customPreferredWidth = 0;
|
||||
/** The custom preferred height for the item. */
|
||||
private int customPreferredHeight = 0;
|
||||
/** Whether a custom minimum size is used for the item. */
|
||||
private boolean customMinimumSize = false;
|
||||
/** The custom minimum width for the item. */
|
||||
private int customMinimumWidth = 0;
|
||||
/** The custom minimum height for the item. */
|
||||
private int customMinimumHeight = 0;
|
||||
/** Whether the item is currently visible. */
|
||||
private boolean visible = true;
|
||||
|
||||
/**
|
||||
* CoolItem constructor.
|
||||
*/
|
||||
public CoolItem() {
|
||||
}//CoolItem()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.view.IAbstractComponent#getContainer()
|
||||
*/
|
||||
public Container getContainer() {
|
||||
return container;
|
||||
}//getContainer()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.view.swt.IInternalAbstractComponent#getShell()
|
||||
*/
|
||||
public Shell getShell() {
|
||||
return container != null ? container.getShell() : null;
|
||||
}//getShell()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.AbstractComponent#internalProcessMessage(com.foundation.tcv.view.ViewMessage)
|
||||
*/
|
||||
public Object internalProcessMessage(ViewMessage viewMessage) {
|
||||
Object result = null;
|
||||
|
||||
switch(viewMessage.getMessageNumber()) {
|
||||
case MESSAGE_INITIALIZE: {
|
||||
if(getSwtCoolItem() == null) {
|
||||
int[] data = (int[]) viewMessage.getMessageData();
|
||||
|
||||
style = data[1];
|
||||
//Link to the parent container.//
|
||||
this.container = (Container) getComponent(data[0]);
|
||||
((CoolBar) getContainer()).addCoolItem(this);
|
||||
initializeControl(style);
|
||||
}//if//
|
||||
break;
|
||||
}//case//
|
||||
case MESSAGE_SET_SIZE: {
|
||||
int[] data = (int[]) viewMessage.getMessageData();
|
||||
|
||||
customSize = true;
|
||||
customWidth = data[0];
|
||||
customHeight = data[1];
|
||||
|
||||
if(getSwtCoolItem() != null) {
|
||||
getSwtCoolItem().setSize(customWidth, customHeight);
|
||||
}//if//
|
||||
break;
|
||||
}//case//
|
||||
case MESSAGE_SET_PREFERRED_SIZE: {
|
||||
int[] data = (int[]) viewMessage.getMessageData();
|
||||
|
||||
customPreferredSize = true;
|
||||
customPreferredWidth = data[0];
|
||||
customPreferredHeight = data[1];
|
||||
|
||||
if(getSwtCoolItem() != null) {
|
||||
getSwtCoolItem().setPreferredSize(customPreferredWidth, customPreferredHeight);
|
||||
}//if//
|
||||
break;
|
||||
}//case//
|
||||
case MESSAGE_SET_MINIMUM_SIZE: {
|
||||
int[] data = (int[]) viewMessage.getMessageData();
|
||||
|
||||
customMinimumSize = true;
|
||||
customMinimumWidth = data[0];
|
||||
customMinimumHeight = data[1];
|
||||
|
||||
if(getSwtCoolItem() != null) {
|
||||
getSwtCoolItem().setMinimumSize(customMinimumWidth, customMinimumHeight);
|
||||
}//if//
|
||||
break;
|
||||
}//case//
|
||||
case MESSAGE_SET_CONTROL: {
|
||||
int[] data = (int[]) viewMessage.getMessageData();
|
||||
|
||||
control = (Component) getComponent(data[0]);
|
||||
//TODO: If we are already initialized we should swap controls. Currently this could not happen, but we may allow it in the future.
|
||||
break;
|
||||
}//case//
|
||||
case MESSAGE_AUTO_SIZE: {
|
||||
if(!customPreferredSize && !customSize) {
|
||||
Point size;
|
||||
|
||||
//control.getSwtControl().pack();
|
||||
size = control.getSwtControl().computeSize(SWT.DEFAULT, SWT.DEFAULT);
|
||||
|
||||
if(!customMinimumSize) {
|
||||
getSwtCoolItem().setMinimumSize(size);
|
||||
}//if//
|
||||
|
||||
size = getSwtCoolItem().computeSize(size.x, size.y);
|
||||
size.x = Math.max(size.x, getSwtCoolItem().getMinimumSize().x);
|
||||
size.y = Math.max(size.y, getSwtCoolItem().getMinimumSize().y);
|
||||
|
||||
getSwtCoolItem().setPreferredSize(size);
|
||||
getSwtCoolItem().setSize(size);
|
||||
}//if//
|
||||
break;
|
||||
}//case//
|
||||
case MESSAGE_SET_IS_VISIBLE: {
|
||||
boolean visible = ((Boolean) viewMessage.getMessageData()).booleanValue();
|
||||
|
||||
controlSetIsVisible(visible);
|
||||
break;
|
||||
}//case//
|
||||
default: {
|
||||
result = super.internalProcessMessage(viewMessage);
|
||||
}//default//
|
||||
}//switch//
|
||||
|
||||
return result;
|
||||
}//internalProcessMessage()//
|
||||
/**
|
||||
* Initializes the control.
|
||||
* @param style The style for the control.
|
||||
*/
|
||||
protected void initializeControl(int style) {
|
||||
//Create the SWT widget.//
|
||||
setSwtWidget(new org.eclipse.swt.widgets.CoolItem(((CoolBar) getContainer()).getSwtCoolBar(), style));
|
||||
getSwtWidget().setData(this);
|
||||
}//initializeControl()//
|
||||
/**
|
||||
* Sets whether the control is visible.
|
||||
* @param visible Whether the control is visible to the user.
|
||||
*/
|
||||
protected void controlSetIsVisible(boolean visible) {
|
||||
if(this.visible != visible) {
|
||||
this.visible = visible;
|
||||
|
||||
//Destroy or create the cool item.//
|
||||
if(!visible) {
|
||||
if(getSwtCoolItem() != null && !getSwtCoolItem().isDisposed()) {
|
||||
getSwtCoolItem().dispose();
|
||||
}//if//
|
||||
|
||||
setSwtWidget(null);
|
||||
}//if//
|
||||
else {
|
||||
initializeControl(style);
|
||||
}//else//
|
||||
}//if//
|
||||
}//controlSetIsVisible()//
|
||||
/**
|
||||
* Gets the swt cool item for this cool item.
|
||||
* @return The SWT cool item providing visualization for this cool item.
|
||||
*/
|
||||
public org.eclipse.swt.widgets.CoolItem getSwtCoolItem() {
|
||||
return (org.eclipse.swt.widgets.CoolItem) getSwtWidget();
|
||||
}//getSwtCoolItem()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.view.swt.AbstractComponent#internalViewInitialize()
|
||||
*/
|
||||
protected void internalViewInitialize() {
|
||||
getSwtCoolItem().addSelectionListener(this);
|
||||
super.internalViewInitialize();
|
||||
getSwtCoolItem().setControl(control.getSwtControl());
|
||||
}//internalViewInitialize()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.view.swt.AbstractComponent#internalViewRelease()
|
||||
*/
|
||||
protected void internalViewRelease() {
|
||||
if(!getSwtCoolItem().isDisposed()) {
|
||||
getSwtCoolItem().setControl(null);
|
||||
}//if//
|
||||
|
||||
super.internalViewRelease();
|
||||
}//internalViewRelease()//
|
||||
/**
|
||||
* Sets the control used by the cool item.
|
||||
* @param control The cool item's control.
|
||||
*/
|
||||
public void setControl(Component control) {
|
||||
this.control = control;
|
||||
}//setControl()//
|
||||
/* (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) {
|
||||
/* TODO: Enable the drop down cheveron to display a menu of items not visible in the cool item.
|
||||
if((menu != null) && (event.detail == SWT.ARROW)) {
|
||||
Rectangle rect = getSwtCoolItem().getBounds();
|
||||
Point point = new Point(rect.x, rect.y + rect.height);
|
||||
|
||||
//Show the drop down menu.//
|
||||
point = getSwtCoolItem().getParent().toDisplay(point);
|
||||
|
||||
if(menu != null) {
|
||||
menu.getSwtMenu().setLocation(point.x, point.y);
|
||||
menu.getSwtMenu().setVisible(true);
|
||||
}//if//
|
||||
}//if//
|
||||
*/
|
||||
}//widgetSelected()//
|
||||
}//CoolItem//
|
||||
/**
|
||||
* CoolBar constructor.
|
||||
*/
|
||||
public CoolBar() {
|
||||
super();
|
||||
}//CoolBar()//
|
||||
/**
|
||||
* Adds a cool item to the bar.
|
||||
* @param coolItem The item to be added.
|
||||
*/
|
||||
protected void addCoolItem(CoolItem coolItem) {
|
||||
coolItems.add(coolItem); //TODO: Is this necessary?
|
||||
|
||||
if(isInitialized()) {
|
||||
//TODO: Initialize the cool item.
|
||||
//Will the cool item's component already be initilialized?
|
||||
//Would this ever occur?
|
||||
}//if//
|
||||
}//addCoolItem()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.AbstractComponent#internalProcessMessage(com.foundation.tcv.view.ViewMessage)
|
||||
*/
|
||||
public Object internalProcessMessage(ViewMessage viewMessage) {
|
||||
Object result = null;
|
||||
|
||||
switch(viewMessage.getMessageNumber()) {
|
||||
case MESSAGE_INITIALIZE: {
|
||||
if(getSwtCoolBar() == null) {
|
||||
int[] data = (int[]) viewMessage.getMessageData();
|
||||
int style = data[1];
|
||||
|
||||
//Link to the parent container.//
|
||||
setContainer((Container) getComponent(data[0]));
|
||||
getContainer().addComponent(this);
|
||||
//Create the SWT widget.//
|
||||
setSwtWidget(new org.eclipse.swt.widgets.CoolBar(getContainer().getSwtParent(), style));
|
||||
getSwtWidget().setData(this);
|
||||
|
||||
//If the container has already been initialized then force the parent to re-layout so that this component will appear.//
|
||||
if(getContainer().isInitialized()) {
|
||||
getContainer().getSwtComposite().layout(true, true);
|
||||
}//if//
|
||||
}//if//
|
||||
break;
|
||||
}//case//
|
||||
default: {
|
||||
result = super.internalProcessMessage(viewMessage);
|
||||
}//default//
|
||||
}//switch//
|
||||
|
||||
return result;
|
||||
}//internalProcessMessage()//
|
||||
/**
|
||||
* Gets the SWT cool bar that represents this cool bar.
|
||||
* @return The SWT cool bar providing visualization for this cool bar.
|
||||
*/
|
||||
public org.eclipse.swt.widgets.CoolBar getSwtCoolBar() {
|
||||
return (org.eclipse.swt.widgets.CoolBar) getSwtControl();
|
||||
}//getSwtCoolBar()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.AbstractComponent#internalViewInitialize()
|
||||
*/
|
||||
protected void internalViewInitialize() {
|
||||
//Add a listener to force the view to re-layout when the coolbar changes sizes (expands or contracts).//
|
||||
getSwtCoolBar().addListener(SWT.Resize, new Listener() {
|
||||
public void handleEvent(Event event) {
|
||||
getShell().layout(true, true);
|
||||
}//handleEvent()//
|
||||
});
|
||||
super.internalViewInitialize();
|
||||
}//internalViewInitialize()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.AbstractComponent#internalViewRelease()
|
||||
*/
|
||||
protected void internalViewRelease() {
|
||||
super.internalViewRelease();
|
||||
}//internalViewRelease()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.AbstractComponent#internalViewInitializeAll()
|
||||
*/
|
||||
protected void internalViewInitializeAll() {
|
||||
super.internalViewInitializeAll();
|
||||
|
||||
//Initialize all the cool items.//
|
||||
for(int index = 0; index < coolItems.getSize(); index++) {
|
||||
((CoolItem) coolItems.get(index)).internalViewInitialize();
|
||||
}//for//
|
||||
}//internalViewInitializeAll()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.AbstractComponent#internalViewReleaseAll()
|
||||
*/
|
||||
protected void internalViewReleaseAll() {
|
||||
//Release all the cool items.//
|
||||
for(int index = 0; index < coolItems.getSize(); index++) {
|
||||
((CoolItem) coolItems.get(index)).internalViewRelease();
|
||||
}//for//
|
||||
|
||||
super.internalViewReleaseAll();
|
||||
}//internalViewReleaseAll()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.AbstractComponent#internalViewSynchronizeAll()
|
||||
*/
|
||||
protected void internalViewSynchronizeAll() {
|
||||
//Synchronize all the tool items.//
|
||||
for(int index = 0; index < coolItems.getSize(); index++) {
|
||||
((CoolItem) coolItems.get(index)).internalViewSynchronize();
|
||||
}//for//
|
||||
|
||||
super.internalViewSynchronizeAll();
|
||||
}//internalViewSynchronizeAll()//
|
||||
}//CoolBar//
|
||||
@@ -0,0 +1,286 @@
|
||||
/*
|
||||
* Copyright (c) 2007,2008 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.tcv.swt.client;
|
||||
|
||||
import java.util.Calendar;
|
||||
import java.util.Date;
|
||||
import java.util.GregorianCalendar;
|
||||
|
||||
import org.eclipse.swt.events.SelectionEvent;
|
||||
import org.eclipse.swt.events.SelectionListener;
|
||||
|
||||
import com.common.debug.Debug;
|
||||
import com.common.thread.IRunnable;
|
||||
import com.foundation.tcv.swt.IDateTime;
|
||||
import com.foundation.tcv.view.ViewMessage;
|
||||
|
||||
public class DateTime extends Component implements IDateTime, SelectionListener {
|
||||
/** Whether the selection state should be auto-synchronized. */
|
||||
private boolean autoSynchronizeSelection = true;
|
||||
/** The delay to be used when auto synchronizing changes. */
|
||||
private long autoSynchronizeSelectionDelay = 500;
|
||||
/** The task that auto synchronizes the selection state after a short delay. */
|
||||
private Task autoSynchronizeSelectionTask = null;
|
||||
/** Whether to send the double click events to the server for processing. */
|
||||
private boolean sendDoubleClick = false;
|
||||
/** Whether the year should be transfered to/from the view/model. */
|
||||
private boolean includeYear = false;
|
||||
/** Whether the month should be transfered to/from the view/model. */
|
||||
private boolean includeMonth = false;
|
||||
/** Whether the day should be transfered to/from the view/model. */
|
||||
private boolean includeDay = false;
|
||||
/** Whether the hour should be transfered to/from the view/model. */
|
||||
private boolean includeHour = false;
|
||||
/** Whether the minutes should be transfered to/from the view/model. */
|
||||
private boolean includeMinute = false;
|
||||
/** Whether the seconds should be transfered to/from the view/model. */
|
||||
private boolean includeSecond = false;
|
||||
/** The calendar used to transfer the date/time data to/from the model. */
|
||||
private Calendar calendar = GregorianCalendar.getInstance();
|
||||
/**
|
||||
* DateTime constructor.
|
||||
*/
|
||||
public DateTime() {
|
||||
}//DateTime()//
|
||||
/**
|
||||
* Gets the SWT button that represents this button.
|
||||
* @return The SWT button providing visualization for this button.
|
||||
*/
|
||||
public org.eclipse.swt.widgets.DateTime getSwtDateTime() {
|
||||
return (org.eclipse.swt.widgets.DateTime) getSwtControl();
|
||||
}//getSwtDateTime()//
|
||||
/**
|
||||
* Determines whether the control should send double click events to the server.
|
||||
* @return Whether double click events need to be forwarded to the server for processing.
|
||||
*/
|
||||
protected boolean getSendDoubleClick() {
|
||||
return sendDoubleClick;
|
||||
}//getSendDoubleClick()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.AbstractComponent#internalViewInitialize()
|
||||
*/
|
||||
protected void internalViewInitialize() {
|
||||
getSwtDateTime().addSelectionListener(this);
|
||||
super.internalViewInitialize();
|
||||
}//internalViewInitialize()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.AbstractComponent#internalViewRelease()
|
||||
*/
|
||||
protected void internalViewRelease() {
|
||||
if((getSwtDateTime() != null) && (!getSwtDateTime().isDisposed())) {
|
||||
getSwtDateTime().removeSelectionListener(this);
|
||||
}//if//
|
||||
|
||||
synchronized(this) {
|
||||
if(autoSynchronizeSelectionTask != null) {
|
||||
removeTask(autoSynchronizeSelectionTask);
|
||||
autoSynchronizeSelectionTask = null;
|
||||
}//if//
|
||||
}//synchronized//
|
||||
|
||||
super.internalViewRelease();
|
||||
}//internalViewRelease()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.AbstractComponent#internalViewSynchronize()
|
||||
*/
|
||||
protected void internalViewSynchronize() {
|
||||
super.internalViewSynchronize();
|
||||
|
||||
if(!autoSynchronizeSelection) {
|
||||
Calendar calendar = GregorianCalendar.getInstance();
|
||||
|
||||
calendar.set(getSwtDateTime().getYear(), getSwtDateTime().getMonth(), getSwtDateTime().getDay(), getSwtDateTime().getHours(), getSwtDateTime().getMinutes(), getSwtDateTime().getSeconds());
|
||||
sendMessage(MESSAGE_VIEW_SYNCHRONIZE_SELECTION, calendar.getTime());
|
||||
}//if//
|
||||
}//internalViewSynchronize()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.AbstractComponent#internalProcessMessage(com.foundation.tcv.model.ViewMessage)
|
||||
*/
|
||||
public Object internalProcessMessage(ViewMessage viewMessage) {
|
||||
Object result = null;
|
||||
|
||||
switch(viewMessage.getMessageNumber()) {
|
||||
case MESSAGE_INITIALIZE: {
|
||||
if(getSwtControl() == null) {
|
||||
int style = viewMessage.getMessageSecondaryInteger();
|
||||
|
||||
//Link to the parent container.//
|
||||
setContainer((Container) getComponent(viewMessage.getMessageInteger()));
|
||||
getContainer().addComponent(this);
|
||||
//Create the SWT widget.//
|
||||
setSwtWidget(new org.eclipse.swt.widgets.DateTime(getContainer().getSwtParent(), style));
|
||||
getSwtWidget().setData(this);
|
||||
|
||||
//If the container has already been initialized then force the parent to re-layout so that this component will appear.//
|
||||
if(getContainer().isInitialized()) {
|
||||
getContainer().getSwtComposite().layout(true, true);
|
||||
}//if//
|
||||
|
||||
includeYear = (((style & STYLE_DATE) > 0) || ((style & STYLE_CALENDAR) > 0));
|
||||
includeMonth = (((style & STYLE_DATE) > 0) || ((style & STYLE_CALENDAR) > 0));
|
||||
includeDay = ((((style & STYLE_DATE) > 0) && ((style & STYLE_SHORT) == 0)) || ((style & STYLE_CALENDAR) > 0));
|
||||
includeHour = ((style & STYLE_TIME) > 0);
|
||||
includeMinute = ((style & STYLE_TIME) > 0);
|
||||
includeSecond = (((style & STYLE_TIME) > 0) && ((style & STYLE_SHORT) == 0));
|
||||
}//if//
|
||||
break;
|
||||
}//case//
|
||||
case MESSAGE_VIEW_REFRESH_SELECTION: {
|
||||
Date date = (Date) viewMessage.getMessageData();
|
||||
|
||||
date = date == null ? new Date() : date;
|
||||
calendar.setTime(date);
|
||||
|
||||
if(includeYear) {
|
||||
getSwtDateTime().setYear(calendar.get(Calendar.YEAR));
|
||||
}//if//
|
||||
|
||||
if(includeMonth) {
|
||||
getSwtDateTime().setMonth(calendar.get(Calendar.MONTH));
|
||||
}//if//
|
||||
|
||||
if(includeDay) {
|
||||
getSwtDateTime().setDay(calendar.get(Calendar.DAY_OF_MONTH));
|
||||
}//if//
|
||||
|
||||
if(includeHour) {
|
||||
getSwtDateTime().setHours(calendar.get(Calendar.HOUR_OF_DAY));
|
||||
}//if//
|
||||
|
||||
if(includeMinute) {
|
||||
getSwtDateTime().setMinutes(calendar.get(Calendar.MINUTE));
|
||||
}//if//
|
||||
|
||||
if(includeSecond) {
|
||||
getSwtDateTime().setSeconds(calendar.get(Calendar.SECOND));
|
||||
}//if//
|
||||
break;
|
||||
}//case//
|
||||
case MESSAGE_SET_AUTO_SYNCHRONIZE_SELECTION: {
|
||||
autoSynchronizeSelection = ((Boolean) viewMessage.getMessageData()).booleanValue();
|
||||
break;
|
||||
}//case//
|
||||
case MESSAGE_SET_AUTO_SYNCHRONIZE_SELECTION_DELAY: {
|
||||
autoSynchronizeSelectionDelay = ((Long) viewMessage.getMessageData()).longValue();
|
||||
break;
|
||||
}//case//
|
||||
case MESSAGE_SEND_DOUBLE_CLICK: {
|
||||
sendDoubleClick = ((Boolean) viewMessage.getMessageData()).booleanValue();
|
||||
break;
|
||||
}//case//
|
||||
default: {
|
||||
result = super.internalProcessMessage(viewMessage);
|
||||
}//default//
|
||||
}//switch//
|
||||
|
||||
return result;
|
||||
}//internalProcessMessage()//
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.swt.events.SelectionListener#widgetDefaultSelected(org.eclipse.swt.events.SelectionEvent)
|
||||
*/
|
||||
public void widgetDefaultSelected(SelectionEvent event) {
|
||||
//Called when the user double clicks a calendar date.//
|
||||
if(getSendDoubleClick()) {
|
||||
long oldAutoSynchronizeSelectionDelay = autoSynchronizeSelectionDelay;
|
||||
|
||||
try {
|
||||
//Hold the messages so they get sent together.//
|
||||
addMessageHold();
|
||||
//Set the synchronize delay to zero so the synchronize occurs immediatly.//
|
||||
autoSynchronizeSelectionDelay = 0L;
|
||||
|
||||
//Force any selection task to complete prior to sending the double click, or force any selection change to be synchronized.//
|
||||
synchronized(this) {
|
||||
if(autoSynchronizeSelectionTask != null) {
|
||||
autoSynchronizeSelectionTask.run();
|
||||
}//if//
|
||||
else if(!autoSynchronizeSelection) {
|
||||
selectionChanged(calendar.getTime());
|
||||
}//else if//
|
||||
}//synchronized//
|
||||
|
||||
//Send the double click message.//
|
||||
sendRoundTripMessage(MESSAGE_DOUBLE_CLICK, null, null);
|
||||
}//try//
|
||||
finally {
|
||||
//Reset the delay and send the messages.//
|
||||
autoSynchronizeSelectionDelay = oldAutoSynchronizeSelectionDelay;
|
||||
removeMessageHold();
|
||||
}//finally//
|
||||
}//if//
|
||||
}//widgetDefaultSelected()//
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.swt.events.SelectionListener#widgetSelected(org.eclipse.swt.events.SelectionEvent)
|
||||
*/
|
||||
public void widgetSelected(SelectionEvent event) {
|
||||
if(includeYear) {
|
||||
calendar.set(Calendar.YEAR, getSwtDateTime().getYear());
|
||||
}//if//
|
||||
|
||||
if(includeMonth) {
|
||||
calendar.set(Calendar.MONTH, getSwtDateTime().getMonth());
|
||||
}//if//
|
||||
|
||||
if(includeDay) {
|
||||
calendar.set(Calendar.DAY_OF_MONTH, getSwtDateTime().getDay());
|
||||
}//if//
|
||||
|
||||
if(includeHour) {
|
||||
calendar.set(Calendar.HOUR_OF_DAY, getSwtDateTime().getHours());
|
||||
}//if//
|
||||
|
||||
if(includeMinute) {
|
||||
calendar.set(Calendar.MINUTE, getSwtDateTime().getMinutes());
|
||||
}//if//
|
||||
|
||||
if(includeSecond) {
|
||||
calendar.set(Calendar.SECOND, getSwtDateTime().getSeconds());
|
||||
}//if//
|
||||
|
||||
selectionChanged(calendar.getTime());
|
||||
}//widgetSelected()//
|
||||
/**
|
||||
* Called when the selection is changed in the view control.
|
||||
* This method updates all bindings and
|
||||
* @param date The selected value.
|
||||
*/
|
||||
protected void selectionChanged(final Date date) {
|
||||
if(autoSynchronizeSelection) {
|
||||
if(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(DateTime.this) {
|
||||
if(autoSynchronizeSelectionTask == this) {
|
||||
//Cleanup after the task.//
|
||||
autoSynchronizeSelectionTask = null;
|
||||
getEventLoop().executeAsync(new IRunnable() {
|
||||
public Object run() {
|
||||
sendMessage(MESSAGE_VIEW_SYNCHRONIZE_SELECTION, date);
|
||||
return null;
|
||||
}//run()//
|
||||
});
|
||||
}//if//
|
||||
}//synchronized//
|
||||
}//run()//
|
||||
};
|
||||
addTask(autoSynchronizeSelectionTask, autoSynchronizeSelectionDelay);
|
||||
}//synchronized//
|
||||
}//if//
|
||||
else {
|
||||
sendMessage(MESSAGE_VIEW_SYNCHRONIZE_SELECTION, date);
|
||||
}//else//
|
||||
}//if//
|
||||
}//selectionChanged()//
|
||||
}//DateTime//
|
||||
@@ -0,0 +1,208 @@
|
||||
/*
|
||||
* Copyright (c) 2007,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.tcv.swt.client;
|
||||
|
||||
import org.eclipse.swt.SWT;
|
||||
import org.eclipse.swt.events.DisposeEvent;
|
||||
import org.eclipse.swt.events.DisposeListener;
|
||||
import org.eclipse.swt.events.MouseEvent;
|
||||
import org.eclipse.swt.events.MouseMoveListener;
|
||||
import org.eclipse.swt.events.MouseTrackListener;
|
||||
import org.eclipse.swt.graphics.*;
|
||||
import org.eclipse.swt.widgets.*;
|
||||
|
||||
import com.common.util.IHashSet;
|
||||
import com.foundation.tcv.client.view.ResourceHolder;
|
||||
import com.foundation.view.ControlDecoration;
|
||||
import com.foundation.view.AbstractMultiResourceHolder;
|
||||
import com.foundation.view.AbstractResourceHolder;
|
||||
import com.foundation.view.IResourceHolderComponent;
|
||||
import com.foundation.view.JefImage;
|
||||
import com.foundation.view.resource.AbstractResourceService;
|
||||
import com.foundation.view.swt.IOverlay;
|
||||
|
||||
public class Decoration extends Canvas implements IOverlay, IResourceHolderComponent, MouseMoveListener, MouseTrackListener, DisposeListener {
|
||||
private IDecorationContainer decorationContainer;
|
||||
private Point size = new Point(10, 10);
|
||||
private ControlDecoration decoration = null;
|
||||
private ResourceHolder imageHolder = new ResourceHolder(this);
|
||||
private ResourceHolder toolTipTextHolder = new ResourceHolder(this);
|
||||
private Image image = null;
|
||||
private ToolTip toolTip;
|
||||
/**
|
||||
* Decoration constructor.
|
||||
* @param decorationContainer The decoration container used to access the peer and parent, as well as certain system resources.
|
||||
* @param decoration The control decoration data.
|
||||
*/
|
||||
public Decoration(IDecorationContainer decorationContainer, ControlDecoration decoration) {
|
||||
super(decorationContainer.getDecorationParent(), SWT.NO_FOCUS);
|
||||
|
||||
if(decoration == null) {
|
||||
throw new IllegalArgumentException("Must provide a decoration.");
|
||||
}//if//
|
||||
|
||||
this.decorationContainer = decorationContainer;
|
||||
this.decoration = decoration;
|
||||
getPeerControl().addDisposeListener(this);
|
||||
imageHolder.setValue(decoration.getImage());
|
||||
toolTipTextHolder.setValue(decoration.getToolTip());
|
||||
//setBackgroundMode(SWT.INHERIT_FORCE);
|
||||
addListener(SWT.Paint, new Listener() {
|
||||
public void handleEvent(Event event) {
|
||||
if(Decoration.this.image != null) {
|
||||
event.gc.drawImage(Decoration.this.image, 0, 0);
|
||||
}//if//
|
||||
}//handleEvent()//
|
||||
});
|
||||
addMouseTrackListener(this);
|
||||
addMouseMoveListener(this);
|
||||
}//Decoration()//
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.swt.events.DisposeListener#widgetDisposed(org.eclipse.swt.events.DisposeEvent)
|
||||
*/
|
||||
public void widgetDisposed(DisposeEvent event) {
|
||||
if(!isDisposed()) {
|
||||
dispose();
|
||||
}//if//
|
||||
}//widgetDisposed()//
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.swt.widgets.Widget#dispose()
|
||||
*/
|
||||
public void dispose() {
|
||||
getPeerControl().removeDisposeListener(this);
|
||||
|
||||
if(image != null) {
|
||||
decorationContainer.destroyImage(image);
|
||||
}//if//
|
||||
|
||||
imageHolder.release();
|
||||
toolTipTextHolder.release();
|
||||
super.dispose();
|
||||
decorationContainer = null;
|
||||
}//dispose()//
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.swt.widgets.Composite#computeSize(int, int, boolean)
|
||||
*/
|
||||
public Point computeSize(int wHint, int hHint, boolean changed) {
|
||||
return size;
|
||||
}//computeSize()//
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.swt.widgets.Control#getSize()
|
||||
*/
|
||||
public Point getSize() {
|
||||
return size;
|
||||
}//getSize()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.view.swt.IOverlay#getPeerControl()
|
||||
*/
|
||||
public Control getPeerControl() {
|
||||
return decorationContainer.getDecorationPeer();
|
||||
}//getPeerControl()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.view.swt.IOverlay#getHorizontalOffset()
|
||||
*/
|
||||
public int getHorizontalOffset() {
|
||||
return -2;
|
||||
}//getWidthOffset()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.view.swt.IOverlay#getVerticalOffset()
|
||||
*/
|
||||
public int getVerticalOffset() {
|
||||
return -2;
|
||||
}//getHeightOffset()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.view.swt.IOverlay#getCorner()
|
||||
*/
|
||||
public int getPosition() {
|
||||
return decoration.getPosition();
|
||||
}//getCorner()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.view.IResourceHolderComponent#getResourceService()
|
||||
*/
|
||||
public AbstractResourceService getResourceService() {
|
||||
return decorationContainer.getResourceService();
|
||||
}//getResourceService()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.view.IResourceHolderComponent#resourceHolderChanged(com.foundation.view.AbstractMultiResourceHolder, com.common.util.IHashSet, java.lang.Object, java.lang.Object)
|
||||
*/
|
||||
public void resourceHolderChanged(AbstractMultiResourceHolder resourceHolder, IHashSet rows, Object oldValue, Object newValue) {
|
||||
}//resourceHolderChanged()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.view.IResourceHolderComponent#resourceHolderChanged(com.foundation.view.AbstractMultiResourceHolder, java.lang.Object, java.lang.Object, java.lang.Object)
|
||||
*/
|
||||
public void resourceHolderChanged(AbstractMultiResourceHolder resourceHolder, Object row, Object oldValue, Object newValue) {
|
||||
}//resourceHolderChanged()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.view.IResourceHolderComponent#resourceHolderChanged(com.foundation.view.AbstractResourceHolder, java.lang.Object, java.lang.Object)
|
||||
*/
|
||||
public void resourceHolderChanged(AbstractResourceHolder resourceHolder, Object oldValue, Object newValue, int flags) {
|
||||
if(resourceHolder == imageHolder) {
|
||||
if(image != null) {
|
||||
decorationContainer.destroyImage(image);
|
||||
}//if//
|
||||
|
||||
image = decorationContainer.createImage((JefImage) imageHolder.getValue());
|
||||
|
||||
//TODO: If the size changes, do we need to call layout?
|
||||
if(image != null) {
|
||||
Rectangle bounds = image.getBounds();
|
||||
|
||||
size.x = bounds.width;
|
||||
size.y = bounds.height;
|
||||
}//if//
|
||||
|
||||
redraw();
|
||||
}//if//
|
||||
else if(resourceHolder == toolTipTextHolder) {
|
||||
if(oldValue == null) {
|
||||
toolTip = new ToolTip(getShell(), SWT.BALLOON); //SWT.BALLOON | SWT.ICON_INFORMATION
|
||||
|
||||
//The text is bold and on top.//
|
||||
//toolTip.setText((String) newValue);
|
||||
//The message is normal text and shows below the text.//
|
||||
toolTip.setMessage((String) newValue);
|
||||
//If false, the user must click the tooltip to make it disappear.//
|
||||
toolTip.setAutoHide(true);
|
||||
}//if//
|
||||
else if(newValue == null) {
|
||||
toolTip.dispose();
|
||||
toolTip = null;
|
||||
}//else if//
|
||||
else {
|
||||
toolTip.setText((String) newValue);
|
||||
}//else//
|
||||
}//else if//
|
||||
}//resourceHolderChanged()//
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.swt.events.MouseMoveListener#mouseMove(org.eclipse.swt.events.MouseEvent)
|
||||
*/
|
||||
public void mouseMove(MouseEvent event) {
|
||||
if((toolTip != null) && (toolTip.getVisible())) {
|
||||
toolTip.setVisible(false);
|
||||
}//if//
|
||||
}//mouseMove()//
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.swt.events.MouseTrackListener#mouseEnter(org.eclipse.swt.events.MouseEvent)
|
||||
*/
|
||||
public void mouseEnter(MouseEvent event) {
|
||||
}//mouseEnter()//
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.swt.events.MouseTrackListener#mouseExit(org.eclipse.swt.events.MouseEvent)
|
||||
*/
|
||||
public void mouseExit(MouseEvent event) {
|
||||
}//mouseExit()//
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.swt.events.MouseTrackListener#mouseHover(org.eclipse.swt.events.MouseEvent)
|
||||
*/
|
||||
public void mouseHover(MouseEvent event) {
|
||||
if((toolTip != null) && (!toolTip.getVisible())) {
|
||||
toolTip.setLocation(toDisplay(event.x, event.y));
|
||||
toolTip.setVisible(true);
|
||||
}//if//
|
||||
}//mouseHover()//
|
||||
}//Decoration//
|
||||
@@ -0,0 +1,80 @@
|
||||
/*
|
||||
* Copyright (c) 2003,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.tcv.swt.client;
|
||||
|
||||
import org.eclipse.swt.widgets.Shell;
|
||||
|
||||
import com.foundation.tcv.swt.*;
|
||||
import com.foundation.tcv.view.ViewMessage;
|
||||
|
||||
public abstract class Dialog extends AbstractComponent implements IDialog {
|
||||
private org.eclipse.swt.widgets.Dialog swtDialog = null;
|
||||
/**
|
||||
* Dialog constructor.
|
||||
*/
|
||||
public Dialog() {
|
||||
super();
|
||||
}//Dialog()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.AbstractComponent#getContainer()
|
||||
*/
|
||||
public Container getContainer() {
|
||||
//TODO: Verify that this is not used.//
|
||||
return null;
|
||||
}//getContainer()//
|
||||
/**
|
||||
* Gets the SWT dialog that represents this dialog.
|
||||
* @return The SWT dialog providing visualization for this dialog.
|
||||
*/
|
||||
public org.eclipse.swt.widgets.Dialog getSwtDialog() {
|
||||
return swtDialog;
|
||||
}//getSwtDialog()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.AbstractComponent#getShell()
|
||||
*/
|
||||
public Shell getShell() {
|
||||
return getSwtDialog() != null ? getSwtDialog().getParent() : null;
|
||||
}//getShell()//
|
||||
/**
|
||||
* Sets the SWT dialog that represents this dialog.
|
||||
* @param dialog The SWT dialog providing visualization for this dialog.
|
||||
*/
|
||||
protected void setSwtDialog(org.eclipse.swt.widgets.Dialog dialog) {
|
||||
this.swtDialog = dialog;
|
||||
}//setSwtDialog()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.AbstractComponent#internalViewInitialize()
|
||||
*/
|
||||
protected void internalViewInitialize() {
|
||||
super.internalViewInitialize();
|
||||
}//internalViewInitialize()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.AbstractComponent#internalViewRelease()
|
||||
*/
|
||||
protected void internalViewRelease() {
|
||||
super.internalViewRelease();
|
||||
}//internalViewRelease()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.AbstractComponent#internalProcessMessage(com.foundation.tcv.model.ViewMessage)
|
||||
*/
|
||||
public Object internalProcessMessage(ViewMessage viewMessage) {
|
||||
Object retVal = null;
|
||||
|
||||
switch(viewMessage.getMessageNumber()) {
|
||||
case MESSAGE_SET_TEXT: {
|
||||
getSwtDialog().setText((String) viewMessage.getMessageData());
|
||||
break;
|
||||
}//case//
|
||||
default: {
|
||||
retVal = super.internalProcessMessage(viewMessage);
|
||||
}//default//
|
||||
}//switch//
|
||||
|
||||
return retVal;
|
||||
}//internalProcessMessage()//
|
||||
}//Dialog//
|
||||
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
* Copyright (c) 2008,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.tcv.swt.client;
|
||||
|
||||
import org.eclipse.swt.widgets.Shell;
|
||||
|
||||
public class DynamicMenu extends AbstractComponent {
|
||||
/**
|
||||
* DynamicMenu constructor.
|
||||
*/
|
||||
public DynamicMenu() {
|
||||
}//DynamicMenu()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.AbstractComponent#getContainer()
|
||||
*/
|
||||
public Container getContainer() {
|
||||
return null;
|
||||
}//getContainer()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.AbstractComponent#getShell()
|
||||
*/
|
||||
public Shell getShell() {
|
||||
return null;
|
||||
}//getShell()//
|
||||
}//DynamicMenu//
|
||||
@@ -0,0 +1,625 @@
|
||||
/*
|
||||
* Copyright (c) 2007,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.tcv.swt.client;
|
||||
|
||||
import org.eclipse.swt.SWT;
|
||||
import org.eclipse.swt.events.SelectionEvent;
|
||||
import org.eclipse.swt.events.SelectionListener;
|
||||
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.Listener;
|
||||
import org.eclipse.swt.widgets.TableColumn;
|
||||
import org.eclipse.swt.widgets.TableItem;
|
||||
|
||||
import com.common.debug.Debug;
|
||||
import com.common.util.IHashSet;
|
||||
import com.common.util.IIterator;
|
||||
import com.common.util.IList;
|
||||
import com.common.util.LiteList;
|
||||
import com.foundation.tcv.client.view.MultiResourceHolder;
|
||||
import com.foundation.tcv.swt.IEnhancedList;
|
||||
import com.foundation.tcv.view.ViewMessage;
|
||||
import com.foundation.view.JefImage;
|
||||
import com.foundation.view.swt.util.SwtUtilities;
|
||||
|
||||
public class EnhancedList extends TableComponent implements IEnhancedList, SelectionListener {
|
||||
/** A holder for the value of the container image. */
|
||||
private MultiResourceHolder imageHolder = new MultiResourceHolder(this);
|
||||
/** The only column used by the table. */
|
||||
private TableColumn column;
|
||||
/** A flag indicating whether the control's selection events should be ignored temporarily. */
|
||||
protected boolean suspendSelectionEvents = false;
|
||||
|
||||
/**
|
||||
* The data stored by the table item under the data reference.
|
||||
*/
|
||||
protected class ListRowObject extends TableRowObject {
|
||||
public int width = -1;
|
||||
public int height = -1;
|
||||
/** The set of ImageDecoration's that are applied to the row. */
|
||||
public IHashSet decorations = null;
|
||||
|
||||
/**
|
||||
* ListRowObject constructor.
|
||||
* @param objectId
|
||||
* @param hiddenDataCount
|
||||
*/
|
||||
public ListRowObject(int objectId, int hiddenDataCount) {
|
||||
super(objectId, hiddenDataCount);
|
||||
}//ListRowObject()//
|
||||
}//ListRowObject//
|
||||
/**
|
||||
* EnhancedList constructor.
|
||||
*/
|
||||
public EnhancedList() {
|
||||
}//EnhancedList()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.TableComponent#controlAddColumn()
|
||||
*/
|
||||
protected void controlAddColumn() {
|
||||
}//controlAddColumn()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.TableComponent#controlAddColumn(int)
|
||||
*/
|
||||
protected void controlAddColumn(int columnIndex) {
|
||||
}//controlAddColumn()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.TableComponent#controlRemoveColumn(int)
|
||||
*/
|
||||
protected void controlRemoveColumn(int columnIndex) {
|
||||
}//controlRemoveColumn()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.TableComponent#controlAddRow(int, com.foundation.tcv.swt.ITableComponent.TableRowData, int, com.foundation.tcv.swt.client.TableComponent.TableRowObject, int[])
|
||||
*/
|
||||
protected Object controlAddRow(int objectId, TableRowData rowData, int index, TableRowObject rowObject, int[] columnIndexMap) {
|
||||
TableItem tableItem = null;
|
||||
|
||||
tableItem = index == -1 ? new TableItem(getSwtTable(), 0) : new TableItem(getSwtTable(), 0, index);
|
||||
initializeRow(tableItem, rowObject, rowData, columnIndexMap);
|
||||
|
||||
return tableItem;
|
||||
}//controlAddRow()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.TableComponent#initializeRow(org.eclipse.swt.widgets.TableItem, com.foundation.tcv.swt.client.TableComponent.TableRowObject, com.foundation.tcv.swt.ITableComponent.TableRowData, int[])
|
||||
*/
|
||||
protected void initializeRow(TableItem tableItem, TableRowObject rowObject, TableRowData rowData, int[] columnIndexMap) {
|
||||
tableItem.setText(rowData.getText() == null ? "" : (String) rowData.getText());
|
||||
|
||||
if(rowData.getImage() != null) {
|
||||
imageHolder.setValue(rowObject, rowData.getImage(), true);
|
||||
tableItem.setImage(createImage((JefImage) imageHolder.getValue(rowObject)));
|
||||
}//if//
|
||||
|
||||
super.initializeRow(tableItem, rowObject, rowData, columnIndexMap);
|
||||
}//()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.TableComponent#controlRemoveRow(java.lang.Object)
|
||||
*/
|
||||
protected void controlRemoveRow(Object itemData) {
|
||||
TableItem tableItem = (TableItem) itemData;
|
||||
|
||||
//Dispose of any color, font, or image resources used.//
|
||||
destroyImage(tableItem.getImage());
|
||||
destroyColor(tableItem.getBackground());
|
||||
destroyColor(tableItem.getForeground());
|
||||
destroyFont(tableItem.getFont());
|
||||
|
||||
for(int columnIndex = 0; columnIndex < getSwtTable().getColumnCount(); columnIndex++) {
|
||||
destroyImage(tableItem.getImage(columnIndex));
|
||||
destroyColor(tableItem.getBackground(columnIndex));
|
||||
destroyColor(tableItem.getForeground(columnIndex));
|
||||
destroyFont(tableItem.getFont(columnIndex));
|
||||
}//for//
|
||||
|
||||
tableItem.dispose();
|
||||
}//controlRemoveRow()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.TableComponent#controlAddSelection(java.lang.Object)
|
||||
*/
|
||||
protected void controlAddSelection(Object itemData) {
|
||||
if(!getSwtTable().isDisposed()) {
|
||||
TableItem tableItem = (TableItem) itemData;
|
||||
int count = getSwtTable().getSelectionCount();
|
||||
|
||||
getSwtTable().select(getSwtTable().indexOf(tableItem));
|
||||
|
||||
if(count == 0) {
|
||||
getSwtTable().showItem(tableItem);
|
||||
}//if//
|
||||
}//if//
|
||||
}//controlAddSelection()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.TableComponent#controlRemoveSelection(java.lang.Object)
|
||||
*/
|
||||
protected void controlRemoveSelection(Object itemData) {
|
||||
if(!getSwtTable().isDisposed()) {
|
||||
TableItem tableItem = (TableItem) itemData;
|
||||
|
||||
getSwtTable().deselect(getSwtTable().indexOf(tableItem));
|
||||
}//if//
|
||||
}//controlRemoveSelection()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.TableComponent#controlSetSelection(java.lang.Object)
|
||||
*/
|
||||
protected void controlSetSelection(Object itemData) {
|
||||
if(!getSwtTable().isDisposed()) {
|
||||
TableItem tableItem = (TableItem) itemData;
|
||||
|
||||
getSwtTable().setSelection(getSwtTable().indexOf(tableItem));
|
||||
getSwtTable().showItem(tableItem);
|
||||
}//if//
|
||||
}//controlSetSelection()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.TableComponent#controlSetSelections(com.common.util.IList)
|
||||
*/
|
||||
protected void controlSetSelections(IList itemData) {
|
||||
if(!getSwtTable().isDisposed()) {
|
||||
TableItem[] tableItems = new TableItem[itemData.getSize()];
|
||||
|
||||
//Collect the table items for the selected rows.//
|
||||
for(int index = 0; index < tableItems.length; index++) {
|
||||
tableItems[index] = (TableItem) itemData.get(index);
|
||||
}//for//
|
||||
|
||||
getSwtTable().setSelection(tableItems);
|
||||
|
||||
if(tableItems.length > 0) {
|
||||
getSwtTable().showItem(tableItems[0]);
|
||||
}//if//
|
||||
}//if//
|
||||
}//controlSetSelections()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.TableComponent#controlIsSelected(java.lang.Object)
|
||||
*/
|
||||
protected boolean controlIsSelected(Object itemData) {
|
||||
TableItem tableItem = (TableItem) itemData;
|
||||
|
||||
return getSwtTable().isSelected(getSwtTable().indexOf(tableItem));
|
||||
}//controlIsSelected()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.TableComponent#controlGetObjectIds()
|
||||
*/
|
||||
protected int[] controlGetObjectIds() {
|
||||
TableItem[] tableItems = getSwtTable().getItems();
|
||||
int[] result = new int[tableItems.length];
|
||||
|
||||
//Collect the objectId for each row.//
|
||||
for(int index = tableItems.length - 1; index >= 0; index--) {
|
||||
result[index] = ((ListRowObject) tableItems[index].getData()).objectId;
|
||||
}//for//
|
||||
|
||||
return result;
|
||||
}//controlGetObjectIds()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.TableComponent#controlOrderRows(int[])
|
||||
*/
|
||||
protected void controlOrderRows(int[] mapping) {
|
||||
int columnCount = getSwtTable().getColumnCount();
|
||||
TableItem[] tableItems = getSwtTable().getItems();
|
||||
int tableItemCount = tableItems.length;
|
||||
IList newTableItems = new LiteList(tableItemCount + 100);
|
||||
int selectionIndex = getAllowMultiSelection() ? 0 : getSwtTable().getSelectionIndex();
|
||||
int[] selectionIndices = getAllowMultiSelection() ? getSwtTable().getSelectionIndices() : null;
|
||||
|
||||
SwtUtilities.setRedraw(getSwtComposite(), false);
|
||||
suspendSelectionEvents = true;
|
||||
|
||||
try {
|
||||
for(int index = 0; index < tableItemCount; index++) {
|
||||
TableItem tableItem = (TableItem) tableItems[mapping[index]];
|
||||
TableItem newTableItem = new TableItem(getSwtTable(), tableItem.getStyle(), index);
|
||||
ListRowObject rowObject = (ListRowObject) tableItem.getData();
|
||||
|
||||
newTableItem.setChecked(tableItem.getChecked());
|
||||
newTableItem.setGrayed(tableItem.getGrayed());
|
||||
newTableItem.setText(tableItem.getText());
|
||||
newTableItem.setImage(tableItem.getImage());
|
||||
newTableItem.setBackground(tableItem.getBackground());
|
||||
newTableItem.setForeground(tableItem.getForeground());
|
||||
newTableItem.setFont(tableItem.getFont());
|
||||
newTableItem.setData(tableItem.getData());
|
||||
|
||||
for(int column = 0; column < columnCount; column++) {
|
||||
newTableItem.setText(column, tableItem.getText(column));
|
||||
newTableItem.setImage(column, tableItem.getImage(column));
|
||||
newTableItem.setBackground(column, tableItem.getBackground(column));
|
||||
newTableItem.setForeground(column, tableItem.getForeground(column));
|
||||
newTableItem.setFont(column, tableItem.getFont(column));
|
||||
}//for//
|
||||
|
||||
newTableItems.add(newTableItem);
|
||||
|
||||
//((ListRowObject) tableItem.getData()).replaceControlItem(tableItem, newTableItem);
|
||||
if(rowObject.controlItems != null) {
|
||||
rowObject.controlItems.replace(tableItem, newTableItem);
|
||||
}//if//
|
||||
else {
|
||||
rowObject.controlItem = newTableItem;
|
||||
}//else//
|
||||
|
||||
tableItem.dispose();
|
||||
}//for//
|
||||
|
||||
//Refresh the selection.//
|
||||
if(getAllowMultiSelection()) {
|
||||
if(selectionIndices != null && selectionIndices.length > 0) {
|
||||
for(int index = 0; index < selectionIndices.length; index++) {
|
||||
selectionIndices[index] = mapping[selectionIndices[index]];
|
||||
}//for//
|
||||
|
||||
getSwtTable().setSelection(selectionIndices);
|
||||
}//if//
|
||||
}//if//
|
||||
else {
|
||||
if(selectionIndex >= 0) {
|
||||
selectionIndex = mapping[selectionIndex];
|
||||
getSwtTable().setSelection(selectionIndex);
|
||||
}//if//
|
||||
}//else//
|
||||
}//try//
|
||||
finally {
|
||||
SwtUtilities.setRedraw(getSwtComposite(), true);
|
||||
suspendSelectionEvents = false;
|
||||
}//finally//
|
||||
}//controlOrderRows()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.TableComponent#controlSetCellText(com.foundation.tcv.swt.client.TableComponent.TableRowObject, int, java.lang.Object)
|
||||
*/
|
||||
protected void controlSetCellText(TableRowObject tableRowObject, int columnIndex, Object data) {
|
||||
if(!getSwtTable().isDisposed()) {
|
||||
if(columnIndex != -1) {
|
||||
if(tableRowObject.controlItems != null) {
|
||||
IIterator itemIterator = tableRowObject.controlItems.iterator();
|
||||
|
||||
while(itemIterator.hasNext()) {
|
||||
TableItem tableItem = (TableItem) itemIterator.next();
|
||||
|
||||
tableItem.setText(0, data == null ? "" : (String) data);
|
||||
}//while//
|
||||
}//if//
|
||||
else if(tableRowObject.controlItem != null) {
|
||||
TableItem tableItem = (TableItem) tableRowObject.controlItem;
|
||||
|
||||
tableItem.setText(0, data == null ? "" : (String) data);
|
||||
}//else if//
|
||||
else {
|
||||
Debug.log(new RuntimeException("Item data not found for the cell that is to be updated."));
|
||||
}//else//
|
||||
}//if//
|
||||
}//if//
|
||||
}//controlSetCellText()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.TableComponent#controlSetCellImage(com.foundation.tcv.swt.client.TableComponent.TableRowObject, int, java.lang.Object)
|
||||
*/
|
||||
protected void controlSetCellImage(TableRowObject tableRowObject, int columnIndex, Object data) {
|
||||
ListRowObject rowObject = (ListRowObject) tableRowObject;
|
||||
|
||||
if(!getSwtTable().isDisposed()) {
|
||||
imageHolder.setValue(rowObject, data);
|
||||
}//if//
|
||||
}//controlSetCellImage()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.TableComponent#controlSetCellBackgroundColor(com.foundation.tcv.swt.client.TableComponent.TableRowObject, int, java.lang.Object)
|
||||
*/
|
||||
protected void controlSetCellBackgroundColor(TableRowObject tableRowObject, int columnIndex, Object data) {
|
||||
}//controlSetCellBackgroundColor()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.TableComponent#controlSetCellForegroundColor(com.foundation.tcv.swt.client.TableComponent.TableRowObject, int, java.lang.Object)
|
||||
*/
|
||||
protected void controlSetCellForegroundColor(TableRowObject tableRowObject, int columnIndex, Object data) {
|
||||
}//controlSetCellForegroundColor()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.TableComponent#controlSetCellFont(com.foundation.tcv.swt.client.TableComponent.TableRowObject, int, java.lang.Object)
|
||||
*/
|
||||
protected void controlSetCellFont(TableRowObject tableRowObject, int columnIndex, Object data) {
|
||||
}//controlSetCellFont()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.TableComponent#controlSetColumnHeaderText(int, java.lang.Object)
|
||||
*/
|
||||
protected void controlSetColumnHeaderText(int columnIndex, Object text) {
|
||||
}//controlSetColumnHeaderText()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.TableComponent#controlSetColumnHeaderImage(int, java.lang.Object)
|
||||
*/
|
||||
protected void controlSetColumnHeaderImage(int columnIndex, Object image) {
|
||||
}//controlSetColumnHeaderImage()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.TableComponent#controlGetSelection()
|
||||
*/
|
||||
protected int controlGetSelection() {
|
||||
int selectionIndex = getSwtTable().getSelectionIndex();
|
||||
|
||||
return selectionIndex == -1 ? -1 : ((ListRowObject) getSwtTable().getItem(selectionIndex).getData()).objectId;
|
||||
}//controlGetSelection()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.TableComponent#controlGetSelections()
|
||||
*/
|
||||
protected int[] controlGetSelections() {
|
||||
int[] results = null;
|
||||
|
||||
if(getSwtTable().getSelectionCount() > 0) {
|
||||
TableItem[] tableItems = getSwtTable().getSelection();
|
||||
|
||||
results = new int[tableItems.length];
|
||||
|
||||
for(int index = 0; index < tableItems.length; index++) {
|
||||
results[index] = ((ListRowObject) tableItems[index].getData()).objectId;
|
||||
}//for//
|
||||
}//if//
|
||||
|
||||
return results;
|
||||
}//controlGetSelections()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.TableComponent#controlRemoveAll()
|
||||
*/
|
||||
protected void controlRemoveAll() {
|
||||
TableItem[] items = getSwtTable().getItems();
|
||||
|
||||
for(int index = 0; index < items.length; index++) {
|
||||
destroyImage(items[index].getImage());
|
||||
}//for//
|
||||
|
||||
getSwtTable().removeAll();
|
||||
}//controlRemoveAll()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.TableComponent#controlRemoveAllSelections()
|
||||
*/
|
||||
protected void controlRemoveAllSelections() {
|
||||
if(!getSwtTable().isDisposed()) {
|
||||
getSwtTable().deselectAll();
|
||||
}//if//
|
||||
}//controlRemoveAllSelections()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.IndexedCollectionComponent#controlRemoveSelection(int)
|
||||
*/
|
||||
protected void controlRemoveSelection(int index) {
|
||||
getSwtTable().deselect(index);
|
||||
}//controlRemoveSelection()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.TableComponent#createClientToServerColumnMapping()
|
||||
*/
|
||||
protected int[] createClientToServerColumnMapping() {
|
||||
return null;
|
||||
}//createClientToServerColumnMapping()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.TableComponent#createServerToClientColumnMapping()
|
||||
*/
|
||||
protected int[] createServerToClientColumnMapping() {
|
||||
return null;
|
||||
}//createServerToClientColumnMapping()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.TableComponent#createRowObject(int)
|
||||
*/
|
||||
protected RowObject createRowObject(int objectId) {
|
||||
return new ListRowObject(objectId, getHiddenDataCount());
|
||||
}//createRowObject()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.TableComponent#getColumn(int)
|
||||
*/
|
||||
protected ColumnData getColumnByServerIndex(int serverColumnIndex) {
|
||||
return null;
|
||||
}//getColumn()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.TableComponent#getColumnCount()
|
||||
*/
|
||||
protected int getColumnCount() {
|
||||
return 0;
|
||||
}//getColumnCount()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.IndexedCollectionComponent#forceSelectionEvent()
|
||||
*/
|
||||
protected void forceSelectionEvent() { //Should call widgetSelected implemented by the subclass. This name may need to change.//
|
||||
widgetSelected(null);
|
||||
}//forceSelectionEvent()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.CollectionComponent#controlGetSelectionCount()
|
||||
*/
|
||||
protected int controlGetSelectionCount() {
|
||||
return getSwtTable().getSelectionCount();
|
||||
}//controlGetSelectionCount()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.IndexedCollectionComponent#internalViewInitialize()
|
||||
*/
|
||||
protected void internalViewInitialize() {
|
||||
getSwtTable().addListener(SWT.Resize, new Listener() {
|
||||
public void handleEvent(Event event) {
|
||||
Rectangle area = getSwtTable().getClientArea();
|
||||
int requiredWidth = 0;
|
||||
|
||||
for(int index = 0; index < getSwtTable().getItemCount(); index++) {
|
||||
ListRowObject itemData = (ListRowObject) getSwtTable().getItem(index).getData();
|
||||
|
||||
if(itemData != null) {
|
||||
requiredWidth = Math.max(requiredWidth, itemData.width);
|
||||
}//if//
|
||||
}//for//
|
||||
|
||||
if(requiredWidth < area.width) {
|
||||
column.setWidth(area.width);
|
||||
}//if//
|
||||
else {
|
||||
column.setWidth(requiredWidth);
|
||||
}//else//
|
||||
}//handleEvent()//
|
||||
});
|
||||
|
||||
super.internalViewInitialize();
|
||||
}//internalViewInitialize()//
|
||||
/**
|
||||
* Initializes the measure item listener.
|
||||
*/
|
||||
protected void initializeMeasureItemListener() {
|
||||
getSwtTable().addListener(SWT.MeasureItem, new Listener() {
|
||||
public void handleEvent(Event event) {
|
||||
if((rowHeightValue > 0) && (getSwtTable().getItemHeight() != rowHeightValue)) {
|
||||
event.height = rowHeightValue;
|
||||
SwtUtilities.setRedraw(getSwtTable(), false);
|
||||
}//if//
|
||||
else {
|
||||
TableItem item = (TableItem) event.item;
|
||||
ListRowObject itemData = (ListRowObject) item.getData();
|
||||
|
||||
//TODO: This should never be null, but for some reason it is happening occationally.
|
||||
if(itemData != null) {
|
||||
if(itemData.width == -1 || itemData.height == -1) {
|
||||
String text = item.getText(event.index);
|
||||
Image image = item.getImage(event.index);
|
||||
|
||||
event.width = 0;
|
||||
event.height = 0;
|
||||
|
||||
if(text != null && text.length() > 0) {
|
||||
Point size = event.gc.textExtent(text);
|
||||
|
||||
event.width += size.x;
|
||||
event.height = size.y;
|
||||
}//if//
|
||||
|
||||
if(image != null) {
|
||||
Rectangle size = image.getBounds();
|
||||
|
||||
event.width += size.x;
|
||||
event.height = Math.max(size.y, event.height);
|
||||
}//if//
|
||||
|
||||
itemData.width = event.width;
|
||||
itemData.height = event.height;
|
||||
}//if//
|
||||
else {
|
||||
event.width = itemData.width;
|
||||
event.height = itemData.height;
|
||||
}//else//
|
||||
}//if//
|
||||
|
||||
//Debug.log("Measured: " + event.width);
|
||||
}//else//
|
||||
}//handleEvent()//
|
||||
});
|
||||
}//initializeMeasureItemListener()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.IndexedCollectionComponent#internalViewRelease()
|
||||
*/
|
||||
protected void internalViewRelease() {
|
||||
if((getSwtTable() != null) && (!getSwtTable().isDisposed())) {
|
||||
getSwtTable().removeSelectionListener(this);
|
||||
controlRemoveAll();
|
||||
}//if//
|
||||
else {
|
||||
Debug.log(new RuntimeException("ERROR: Failed to call controlRemoveAll() which is required to clean up any font/color/image resources."));
|
||||
}//else//
|
||||
|
||||
imageHolder.release();
|
||||
|
||||
if(column != null && !column.isDisposed()) {
|
||||
column.dispose();
|
||||
}//if//
|
||||
|
||||
super.internalViewRelease();
|
||||
}//internalViewRelease()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.AbstractComponent#internalResourceHolderChanged(com.foundation.tcv.client.view.MultiResourceHolder, java.lang.Object, java.lang.Object, java.lang.Object)
|
||||
*/
|
||||
protected void internalResourceHolderChanged(MultiResourceHolder resource, Object row, Object oldValue, Object newValue) {
|
||||
if(resource == imageHolder) {
|
||||
ListRowObject rowObject = (ListRowObject) row;
|
||||
|
||||
destroyImage((JefImage) oldValue);
|
||||
|
||||
if(rowObject.controlItems != null) {
|
||||
for(int index = 0; index < rowObject.controlItems.getSize(); index++) {
|
||||
destroyImage((JefImage) oldValue);
|
||||
((TableItem) rowObject.controlItems.get(index)).setImage(0, createImage((JefImage) newValue));
|
||||
}//for//
|
||||
}//if//
|
||||
else {
|
||||
destroyImage((JefImage) oldValue);
|
||||
((TableItem) rowObject.controlItem).setImage(0, createImage((JefImage) newValue));
|
||||
}//else//
|
||||
}//if//
|
||||
else {
|
||||
super.internalResourceHolderChanged(resource, row, oldValue, newValue);
|
||||
}//else//
|
||||
}//internalResourceHolderChanged()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.AbstractComponent#internalResourceHolderChanged(com.foundation.tcv.client.view.MultiResourceHolder, com.common.util.IHashSet, java.lang.Object, java.lang.Object)
|
||||
*/
|
||||
protected void internalResourceHolderChanged(MultiResourceHolder resource, IHashSet rows, Object oldValue, Object newValue) {
|
||||
if(resource == imageHolder) {
|
||||
IIterator iterator = rows.iterator();
|
||||
|
||||
while(iterator.hasNext()) {
|
||||
destroyImage((JefImage) oldValue);
|
||||
((TableItem) iterator.next()).setImage(0, createImage((JefImage) newValue));
|
||||
}//while//
|
||||
}//if//
|
||||
else {
|
||||
super.internalResourceHolderChanged(resource, rows, oldValue, newValue);
|
||||
}//else//
|
||||
}//internalResourceHolderChanged()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.AbstractComponent#internalProcessMessage(com.foundation.tcv.model.ViewMessage)
|
||||
*/
|
||||
public Object internalProcessMessage(ViewMessage viewMessage) {
|
||||
Object result = null;
|
||||
|
||||
switch(viewMessage.getMessageNumber()) {
|
||||
case MESSAGE_INITIALIZE: {
|
||||
if(getSwtControl() == null) {
|
||||
int[] data = (int[]) viewMessage.getMessageData();
|
||||
int style = data[1];
|
||||
|
||||
//Link to the parent container.//
|
||||
setContainer((Container) getComponent(data[0]));
|
||||
getContainer().addComponent(this);
|
||||
//Create the SWT widget.//
|
||||
setSwtWidget(new org.eclipse.swt.widgets.Table(((Container) getContainer()).getSwtParent(), style | SWT.FULL_SELECTION));
|
||||
getSwtWidget().setData(this);
|
||||
getSwtTable().setHeaderVisible(false);
|
||||
getSwtTable().setLinesVisible(false);
|
||||
column = new TableColumn(getSwtTable(), 0);
|
||||
column.setWidth(10);
|
||||
//Set the allows multiple selections flag.//
|
||||
setAllowMultiSelection((style & SWT.MULTI) > 0);
|
||||
|
||||
//If the container has already been initialized then force the parent to re-layout so that this component will appear.//
|
||||
if(getContainer().isInitialized()) {
|
||||
getContainer().getSwtComposite().layout(true, true);
|
||||
}//if//
|
||||
}//if//
|
||||
break;
|
||||
}//case//
|
||||
case MESSAGE_SET_TOP_INDEX: {
|
||||
int topIndex = viewMessage.getMessageInteger();
|
||||
|
||||
getSwtTable().setTopIndex(topIndex);
|
||||
break;
|
||||
}//case//
|
||||
case MESSAGE_SHOW_SELECTION: {
|
||||
getSwtTable().showSelection();
|
||||
break;
|
||||
}//case//
|
||||
default: {
|
||||
result = super.internalProcessMessage(viewMessage);
|
||||
}//default//
|
||||
}//switch//
|
||||
|
||||
return result;
|
||||
}//internalProcessMessage()//
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.swt.events.SelectionListener#widgetSelected(org.eclipse.swt.events.SelectionEvent)
|
||||
*/
|
||||
public void widgetSelected(SelectionEvent event) {
|
||||
if(!suspendSelectionEvents && ((event == null) || (event.widget == getSwtTable()))) {
|
||||
updateSelectionLinks();
|
||||
//TODO: Is there some way to determine exactly what selection or deselection occured given the event object?
|
||||
synchronizeSelection();
|
||||
}//if//
|
||||
}//widgetSelected()//
|
||||
}//EnhancedList//
|
||||
@@ -0,0 +1,280 @@
|
||||
/*
|
||||
* 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.tcv.swt.client;
|
||||
|
||||
import org.eclipse.swt.SWT;
|
||||
import org.eclipse.swt.events.ControlEvent;
|
||||
import org.eclipse.swt.events.ControlListener;
|
||||
import org.eclipse.swt.graphics.Image;
|
||||
import org.eclipse.swt.widgets.Control;
|
||||
import org.eclipse.swt.widgets.ExpandItem;
|
||||
|
||||
import com.common.util.IList;
|
||||
import com.common.util.LiteHashMap;
|
||||
import com.common.util.LiteList;
|
||||
import com.foundation.tcv.swt.IExpandBar;
|
||||
import com.foundation.tcv.view.ViewMessage;
|
||||
|
||||
public class ExpandBar extends Container implements IExpandBar, Component.IComponentListener, ControlListener {
|
||||
/** A mapping of ExpandItem instances indexed by the Component displayed by the item. */
|
||||
private LiteHashMap expandItemsByComponentMap = new LiteHashMap(15);
|
||||
/** A collection of Component instances which require initialization. */
|
||||
private IList pendingItems = new LiteList(10, 50);
|
||||
/**
|
||||
* ExpandBar constructor.
|
||||
*/
|
||||
public ExpandBar() {
|
||||
super();
|
||||
}//ExpandBar()//
|
||||
/**
|
||||
* Gets the SWT expand bar that represents this expand bar.
|
||||
* @return The SWT expand bar providing visualization for this expand bar.
|
||||
*/
|
||||
public org.eclipse.swt.widgets.ExpandBar getSwtExpandBar() {
|
||||
return (org.eclipse.swt.widgets.ExpandBar) getSwtWidget();
|
||||
}//getSwtExpandBar()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.AbstractComponent#internalViewInitialize()
|
||||
*/
|
||||
protected void internalViewInitialize() {
|
||||
//Complete the initialization of the component items since the components should have set themselves up by now.//
|
||||
for(int index = 0; index < pendingItems.getSize(); index++) {
|
||||
internalAddItem((Component) pendingItems.get(index), -1);
|
||||
}//for//
|
||||
|
||||
super.internalViewInitialize();
|
||||
}//internalViewInitialize()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.AbstractComponent#internalViewRelease()
|
||||
*/
|
||||
protected void internalViewRelease() {
|
||||
super.internalViewRelease();
|
||||
}//internalViewRelease()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.AbstractComponent#internalViewSynchronize()
|
||||
*/
|
||||
protected void internalViewSynchronize() {
|
||||
super.internalViewSynchronize();
|
||||
}//internalViewSynchronize()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.AbstractComponent#internalProcessMessage(com.foundation.tcv.model.ViewMessage)
|
||||
*/
|
||||
public Object internalProcessMessage(ViewMessage viewMessage) {
|
||||
Object result = null;
|
||||
|
||||
switch(viewMessage.getMessageNumber()) {
|
||||
case MESSAGE_INITIALIZE: {
|
||||
if(getSwtControl() == null) {
|
||||
int[] data = (int[]) viewMessage.getMessageData();
|
||||
int style = data[1];
|
||||
|
||||
//Link to the parent container.//
|
||||
setContainer((Container) getComponent(data[0]));
|
||||
getContainer().addComponent(this);
|
||||
//Create the SWT widget.//
|
||||
setSwtWidget(new org.eclipse.swt.widgets.ExpandBar(getContainer().getSwtParent(), style));
|
||||
getSwtWidget().setData(this);
|
||||
|
||||
//If the container has already been initialized then force the parent to re-layout so that this component will appear.//
|
||||
if(getContainer().isInitialized()) {
|
||||
getContainer().getSwtComposite().layout(true, true);
|
||||
}//if//
|
||||
}//if//
|
||||
break;
|
||||
}//case//
|
||||
case MESSAGE_ADD_ITEM: {
|
||||
int componentNumber = viewMessage.getMessageInteger();
|
||||
Component component = (Component) getComponent(componentNumber);
|
||||
int index = viewMessage.getMessageSecondaryInteger();
|
||||
|
||||
if(isInitialized()) {
|
||||
internalAddItem(component, index);
|
||||
}//if//
|
||||
else {
|
||||
if(index != -1) {
|
||||
pendingItems.add(index, component);
|
||||
}//if//
|
||||
else {
|
||||
pendingItems.add(component);
|
||||
}//else//
|
||||
}//else//
|
||||
break;
|
||||
}//case//
|
||||
case MESSAGE_REMOVE_ITEM: {
|
||||
int componentNumber = ((Integer) viewMessage.getMessageData()).intValue();
|
||||
Component component = (Component) getComponent(componentNumber);
|
||||
|
||||
if(component != null) {
|
||||
ExpandItem expandItem = (ExpandItem) expandItemsByComponentMap.remove(component);
|
||||
|
||||
if(expandItem != null && !expandItem.isDisposed()) {
|
||||
//Note: Don't dispose of the image because it comes from the component's container-image property whose lifecycle is managed by the component.//
|
||||
expandItem.dispose();
|
||||
}//if//
|
||||
|
||||
component.unregisterListener(this);
|
||||
}//if//
|
||||
break;
|
||||
}//case//
|
||||
case MESSAGE_REPOSITION_ITEM: {
|
||||
int componentNumber = ((int[]) viewMessage.getMessageData())[0];
|
||||
int newIndex = ((int[]) viewMessage.getMessageData())[1];
|
||||
Component component = (Component) getComponent(componentNumber);
|
||||
|
||||
if(component != null) {
|
||||
ExpandItem oldExpandItem = (ExpandItem) expandItemsByComponentMap.remove(component);
|
||||
|
||||
if(oldExpandItem != null && !oldExpandItem.isDisposed()) {
|
||||
ExpandItem newExpandItem = new ExpandItem(getSwtExpandBar(), 0, newIndex);
|
||||
|
||||
newExpandItem.setText(oldExpandItem.getText());
|
||||
newExpandItem.setImage(oldExpandItem.getImage());
|
||||
//SWT does not yet support tool tip text for expand items.//
|
||||
//newExpandItem.setToolTipText(oldExpandItem.getToolTipText());
|
||||
newExpandItem.setData(oldExpandItem.getData());
|
||||
newExpandItem.setControl(oldExpandItem.getControl());
|
||||
oldExpandItem.dispose();
|
||||
expandItemsByComponentMap.put(component, newExpandItem);
|
||||
}//if//
|
||||
}//if//
|
||||
break;
|
||||
}//case//
|
||||
case MESSAGE_SORT_ITEMS: {
|
||||
int startIndex = ((Integer) ((Object[]) viewMessage.getMessageData())[0]).intValue();
|
||||
int[] mapping = (int[]) ((Object[]) viewMessage.getMessageData())[1];
|
||||
ExpandItem[] oldExpandItems = new ExpandItem[mapping.length];
|
||||
int nextIndex = startIndex;
|
||||
|
||||
//Reorder the item items by adding new item items before the old ones.//
|
||||
for(int index = 0; index < mapping.length; index++) {
|
||||
int oldIndex = nextIndex + index + mapping[index];
|
||||
ExpandItem oldExpandItem = getSwtExpandBar().getItem(oldIndex);
|
||||
ExpandItem expandItem = new org.eclipse.swt.widgets.ExpandItem(getSwtExpandBar(), 0, index);
|
||||
Component component = (Component) oldExpandItem.getData();
|
||||
|
||||
expandItem.setText(oldExpandItem.getText());
|
||||
expandItem.setImage(oldExpandItem.getImage());
|
||||
//SWT does not yet support tool tip text for expand items.//
|
||||
//expandItem.setToolTipText(oldExpandItem.getToolTipText());
|
||||
expandItem.setControl(oldExpandItem.getControl());
|
||||
expandItem.setData(oldExpandItem.getData());
|
||||
oldExpandItems[index] = oldExpandItem;
|
||||
expandItemsByComponentMap.put(component, expandItem);
|
||||
nextIndex++;
|
||||
}//for//
|
||||
|
||||
//Remove the old item items.//
|
||||
for(int index = 0; index < oldExpandItems.length; index++) {
|
||||
oldExpandItems[index].dispose();
|
||||
}//for//
|
||||
break;
|
||||
}//case//
|
||||
case MESSAGE_SET_SPACING: {
|
||||
Integer spacing = (Integer) viewMessage.getMessageData();
|
||||
|
||||
if(spacing != null) {
|
||||
getSwtExpandBar().setSpacing(spacing.intValue());
|
||||
}//if//
|
||||
|
||||
resize();
|
||||
break;
|
||||
}//case//
|
||||
default: {
|
||||
result = super.internalProcessMessage(viewMessage);
|
||||
}//default//
|
||||
}//switch//
|
||||
|
||||
return result;
|
||||
}//internalProcessMessage()//
|
||||
/**
|
||||
* Adds an item to the expand bar.
|
||||
* @param component The component which will be placed as an expandable item.
|
||||
* @param index The index of the expand bar item within the expand bar item set. A value of -1 indicates a new expand bar should be created at the end.
|
||||
*/
|
||||
protected void internalAddItem(Component component, int index) {
|
||||
String title = component.getContainerTitle();
|
||||
Image image = component.getContainerImage();
|
||||
//SWT does not yet support tool tip text for expand items.//
|
||||
//String toolTipText = component.getToolTipText();
|
||||
ExpandItem expandItem = null;
|
||||
|
||||
if(index != -1) {
|
||||
expandItem = new ExpandItem(getSwtExpandBar(), 0, index);
|
||||
}//if//
|
||||
else {
|
||||
expandItem = new ExpandItem(getSwtExpandBar(), 0);
|
||||
}//else//
|
||||
|
||||
expandItem.setText(title == null ? "" : title);
|
||||
expandItem.setImage(image);
|
||||
//SWT does not yet support tool tip text for expand items.//
|
||||
//expandItem.setToolTipText(toolTipText);
|
||||
expandItem.setData(component);
|
||||
expandItem.setControl(component.getSwtControl());
|
||||
expandItemsByComponentMap.put(component, expandItem);
|
||||
component.registerListener(this);
|
||||
component.getSwtControl().addControlListener(this);
|
||||
}//internalAddItem()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.Component.IComponentListener#toolTipTextChanged(com.foundation.tcv.swt.client.Component, java.lang.String)
|
||||
*/
|
||||
public void toolTipTextChanged(Component component, String newToolTipText) {
|
||||
ExpandItem expandItem = (ExpandItem) expandItemsByComponentMap.get(component);
|
||||
|
||||
if(expandItem != null && !expandItem.isDisposed()) {
|
||||
//SWT does not yet support tool tip text for expand items.//
|
||||
//expandItem.setToolTipText(newToolTipText);
|
||||
}//if//
|
||||
}//toolTipTextChanged()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.Component.IComponentListener#imageChanged(com.foundation.tcv.swt.client.Component, org.eclipse.swt.graphics.Image)
|
||||
*/
|
||||
public void imageChanged(Component container, Image image) {
|
||||
ExpandItem expandItem = (ExpandItem) expandItemsByComponentMap.get(container);
|
||||
|
||||
if(expandItem != null && !expandItem.isDisposed()) {
|
||||
expandItem.setImage(image);
|
||||
}//if//
|
||||
}//imageChanged()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.Component.IComponentListener#titleChanged(com.foundation.tcv.swt.client.Component, java.lang.String)
|
||||
*/
|
||||
public void titleChanged(Component container, String newTitle) {
|
||||
ExpandItem expandItem = (ExpandItem) expandItemsByComponentMap.get(container);
|
||||
|
||||
if(expandItem != null && !expandItem.isDisposed()) {
|
||||
expandItem.setText(newTitle);
|
||||
}//if//
|
||||
}//titleChanged()//
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.swt.events.ControlListener#controlMoved(org.eclipse.swt.events.ControlEvent)
|
||||
*/
|
||||
public void controlMoved(ControlEvent e) {
|
||||
}//controlMoved()//
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.swt.events.ControlListener#controlResized(org.eclipse.swt.events.ControlEvent)
|
||||
*/
|
||||
public void controlResized(ControlEvent e) {
|
||||
//TODO: Is this the right place for this?
|
||||
((ExpandItem) expandItemsByComponentMap.get(e.widget.getData())).setHeight(((Control) e.widget).computeSize(SWT.DEFAULT, SWT.DEFAULT).y);
|
||||
}//controlResized()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.Container#internalLayout()
|
||||
*/
|
||||
protected void internalLayout() {
|
||||
ExpandItem[] items = getSwtExpandBar().getItems();
|
||||
|
||||
//TODO: Is this the right place for this?
|
||||
//Set the height of all the expand items.//
|
||||
for(int index = 0; index < items.length; index++) {
|
||||
items[index].setHeight(items[index].getControl().computeSize(SWT.DEFAULT, SWT.DEFAULT).y);
|
||||
}//for//
|
||||
|
||||
super.internalLayout();
|
||||
}//internalLayout()//
|
||||
}//ExpandBar//
|
||||
@@ -0,0 +1,88 @@
|
||||
/*
|
||||
* Copyright (c) 2007 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.tcv.swt.client;
|
||||
|
||||
import org.eclipse.swt.SWT;
|
||||
|
||||
import com.foundation.tcv.swt.IFillLayout;
|
||||
import com.foundation.tcv.view.ViewMessage;
|
||||
|
||||
public class FillLayout extends Layout implements IFillLayout {
|
||||
private int type = SWT.HORIZONTAL;
|
||||
private int marginWidth = 0;
|
||||
private int marginHeight = 0;
|
||||
private int spacing = 0;
|
||||
/**
|
||||
* FillLayout constructor.
|
||||
*/
|
||||
public FillLayout() {
|
||||
}//FillLayout()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.Layout#createLayout(java.lang.Object)
|
||||
*/
|
||||
public org.eclipse.swt.widgets.Layout createLayout(Object rowObject) {
|
||||
com.foundation.view.swt.layout.FillLayout result = new com.foundation.view.swt.layout.FillLayout();
|
||||
|
||||
result.type = type;
|
||||
result.marginHeight = marginHeight;
|
||||
result.marginWidth = marginWidth;
|
||||
result.spacing = spacing;
|
||||
|
||||
return result;
|
||||
}//createLayout()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.Layout#initialize()
|
||||
*/
|
||||
public void initialize() {
|
||||
}//initialize()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.Layout#release()
|
||||
*/
|
||||
public void release() {
|
||||
}//release()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.Layout#synchronize()
|
||||
*/
|
||||
public void synchronize() {
|
||||
}//synchronize()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.Layout#processMessage(com.foundation.tcv.view.ViewMessage)
|
||||
*/
|
||||
public Object processMessage(ViewMessage viewMessage) {
|
||||
Object result = null;
|
||||
|
||||
switch(viewMessage.getMessageNumber()) {
|
||||
case MESSAGE_INITIALIZE: {
|
||||
setContainer((AbstractComponent) getComponent(viewMessage.getMessageInteger()));
|
||||
break;
|
||||
}//case//
|
||||
case MESSAGE_SET_TYPE: {
|
||||
this.type = viewMessage.getMessageInteger();
|
||||
break;
|
||||
}//case//
|
||||
case MESSAGE_SET_MARGIN_HEIGHT: {
|
||||
this.marginHeight = viewMessage.getMessageInteger();
|
||||
break;
|
||||
}//case//
|
||||
case MESSAGE_SET_MARGIN_WIDTH: {
|
||||
this.marginWidth = viewMessage.getMessageInteger();
|
||||
break;
|
||||
}//case//
|
||||
case MESSAGE_SET_SPACING: {
|
||||
this.spacing = viewMessage.getMessageInteger();
|
||||
break;
|
||||
}//case//
|
||||
default: {
|
||||
result = super.processMessage(viewMessage);
|
||||
break;
|
||||
}//default//
|
||||
}//switch//
|
||||
|
||||
return result;
|
||||
}//processMessage()//
|
||||
}//FillLayout//
|
||||
@@ -0,0 +1,447 @@
|
||||
/*
|
||||
* 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.tcv.swt.client;
|
||||
|
||||
import org.eclipse.swt.SWT;
|
||||
import org.eclipse.swt.events.*;
|
||||
import org.eclipse.swt.graphics.Font;
|
||||
import org.eclipse.swt.graphics.FontData;
|
||||
import org.eclipse.swt.widgets.Composite;
|
||||
import org.eclipse.swt.widgets.Control;
|
||||
import org.eclipse.swt.widgets.Display;
|
||||
import org.eclipse.swt.widgets.Shell;
|
||||
|
||||
import com.common.comparison.Comparator;
|
||||
import com.common.util.LiteList;
|
||||
import com.foundation.tcv.model.LinkInfo;
|
||||
import com.foundation.tcv.swt.*;
|
||||
import com.foundation.tcv.view.*;
|
||||
import com.foundation.view.LinkData;
|
||||
|
||||
public class FontNameComboBox extends Component implements IFontNameComboBox {
|
||||
/** Whether the selection state should be auto-synchronized. */
|
||||
private boolean autoSynchronizeSelection = true;
|
||||
/** The linkage for the selection. */
|
||||
private Linkage selectionLinkage = new Linkage();
|
||||
/** The last known selection used to prevent sending unnecessary messages. This value will be null if there isn't a selection. */
|
||||
private String lastSelection = null;
|
||||
|
||||
private class FontNameCombo extends com.foundation.view.swt.custom.CustomCombo {
|
||||
private org.eclipse.swt.widgets.Table table;
|
||||
private org.eclipse.swt.widgets.Text editor;
|
||||
private LiteList allFontMetadata = null;
|
||||
private boolean isDisplayingSubset = false;
|
||||
private boolean caseSensitive = false;
|
||||
/** A flag to prevent the synchronization of the selection from causing a refresh of the list contents and re-display of the drop down. */
|
||||
private boolean ignoreEditorChanges = false;
|
||||
//private org.eclipse.swt.graphics.Image scalableFontImage = null;
|
||||
//private org.eclipse.swt.graphics.Image unscalableFontImage = null;
|
||||
|
||||
/**
|
||||
* Encapsulates metadata about the font that is relavant to the combo.
|
||||
*/
|
||||
private class FontMetadata {
|
||||
public String name;
|
||||
public boolean isScalable;
|
||||
public Font font;
|
||||
|
||||
public FontMetadata(Display display, FontData fontData, boolean isScalable) {
|
||||
this.font = new Font(display, fontData);
|
||||
this.name = fontData.getName();
|
||||
this.isScalable = isScalable;
|
||||
}//FontMetadata()//
|
||||
public void dispose() {
|
||||
if(font != null) {
|
||||
font.dispose();
|
||||
}//if//
|
||||
}//dispose()//
|
||||
}//FontMetadata//
|
||||
|
||||
/**
|
||||
* FontNameCombo constructor.
|
||||
* @param parent A non-null widget which will be the parent of the new instance.
|
||||
* @param style The style of widget to construct.
|
||||
* @see SWT#RESIZE
|
||||
* @see SWT#BORDER
|
||||
*/
|
||||
public FontNameCombo(Composite parent, int style) {
|
||||
super(parent, style);
|
||||
}//FontNameCombo()//
|
||||
/**
|
||||
* Gets the current selection text for the combo.
|
||||
* <p>This will be the text in the text box.</p>
|
||||
* @return The selection or an empty string if there is no selection.
|
||||
*/
|
||||
public String getSelection() {
|
||||
return editor.getText() == null ? "" : editor.getText();
|
||||
}//getSelection()//
|
||||
/**
|
||||
* Sets the current selection text for the combo.
|
||||
* @param selection The selection or an empty string if there is no selection.
|
||||
*/
|
||||
public void setSelection(String selection) {
|
||||
if(refreshDrop(selection == null ? "" : selection)) {
|
||||
ignoreEditorChanges = true;
|
||||
editor.setText(selection == null ? "" : selection);
|
||||
ignoreEditorChanges = false;
|
||||
}//if//
|
||||
else {
|
||||
//TODO: What should we do here - the font is not on this system!
|
||||
//We could set the text to the selection and highlight it red to indicate the font is missing. We probably should also show the full font list in the drop box.
|
||||
}//else//
|
||||
|
||||
//If the selection is not in the list then update the editor.//
|
||||
if(isDisplayingSubset) {
|
||||
if(table.getSelectionCount() == 1) {
|
||||
int selectionIndex = table.getSelectionIndex();
|
||||
String tableSelection = selectionIndex != -1 ? ((FontMetadata) table.getItem(selectionIndex).getData()).name : null;
|
||||
|
||||
editor.setText(tableSelection);
|
||||
}//if//
|
||||
else {
|
||||
editor.setText("");
|
||||
}//else//
|
||||
}//if//
|
||||
}//getSelection()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.view.swt.custom.CustomCombo#createDropControl(org.eclipse.swt.widgets.Shell)
|
||||
*/
|
||||
protected Control createDropControl(Shell parent) {
|
||||
table = new org.eclipse.swt.widgets.Table(parent, SWT.SINGLE | SWT.FULL_SELECTION | SWT.V_SCROLL);
|
||||
table.addSelectionListener(new SelectionListener() {
|
||||
public void widgetDefaultSelected(SelectionEvent event) {
|
||||
}//widgetDefaultSelected()//
|
||||
public void widgetSelected(SelectionEvent event) {
|
||||
hideDrop(true);
|
||||
}//widgetSelected()//
|
||||
});
|
||||
|
||||
return table;
|
||||
}//createDropControl()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.view.swt.custom.CustomCombo#createSelectionControl()
|
||||
*/
|
||||
protected Control createSelectionControl() {
|
||||
editor = new org.eclipse.swt.widgets.Text(this, SWT.SINGLE | SWT.LEFT);
|
||||
editor.addFocusListener(new FocusListener() {
|
||||
public void focusLost(FocusEvent e) {
|
||||
String text = editor.getText();
|
||||
String selection = null;
|
||||
|
||||
if((text == null) || (text.trim().length() == 0)) {
|
||||
if(isDisplayingSubset) {
|
||||
updateTable(allFontMetadata);
|
||||
isDisplayingSubset = false;
|
||||
}//if//
|
||||
}//if//
|
||||
else {
|
||||
if(isDisplayingSubset) {
|
||||
selection = ((FontMetadata) table.getItem(table.getSelectionIndex()).getData()).name;
|
||||
editor.setText(selection);
|
||||
updateTable(allFontMetadata);
|
||||
isDisplayingSubset = false;
|
||||
}//if//
|
||||
}//else//
|
||||
|
||||
selectionChanged(selection);
|
||||
}//focusLost()//
|
||||
public void focusGained(FocusEvent e) {
|
||||
}//focusGained()//
|
||||
});
|
||||
editor.addModifyListener(new ModifyListener() {
|
||||
public void modifyText(ModifyEvent e) {
|
||||
if(!ignoreEditorChanges) {
|
||||
refreshDrop();
|
||||
|
||||
if(!isShowingDrop()) {
|
||||
showDrop();
|
||||
}//if//
|
||||
|
||||
//TODO: Do we need to force the focus back to the editor?
|
||||
//TODO: Do we need to keep the drop from hiding?
|
||||
}//if//
|
||||
}//modifyText()//
|
||||
});
|
||||
|
||||
return editor;
|
||||
}//createSelectionControl()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.view.swt.custom.CustomCombo#initialize()
|
||||
*/
|
||||
protected void initialize() {
|
||||
}//initialize()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.view.swt.custom.CustomCombo#postInitialize()
|
||||
*/
|
||||
protected void postInitialize() {
|
||||
FontData[] fonts = table.getDisplay().getFontList(null, true);
|
||||
|
||||
allFontMetadata = new LiteList(fonts.length);
|
||||
|
||||
//Collect all the font metadata for scalable fonts.//
|
||||
for(int index = 0; index < fonts.length; index++) {
|
||||
allFontMetadata.add(new FontMetadata(table.getDisplay(), fonts[index], true));
|
||||
}//for//
|
||||
|
||||
//Order the fonts by name.//
|
||||
allFontMetadata.setOrderComparator(new Comparator() {
|
||||
public int compare(Object value1, Object value2) {
|
||||
return ((FontMetadata) value1).name.compareTo(((FontMetadata) value2).name);
|
||||
}//compare()//
|
||||
});
|
||||
|
||||
updateTable(allFontMetadata);
|
||||
}//postInitialize()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.view.swt.custom.CustomCombo#refreshDrop()
|
||||
*/
|
||||
protected void refreshDrop() {
|
||||
refreshDrop(editor.getText() == null ? "" : editor.getText().trim());
|
||||
}//refreshDrop()//
|
||||
/**
|
||||
* Refreshes the drop down table so it has the selection displayed.
|
||||
* @param selection The table item to be selected. This should be an empty string if there isn't a selection.
|
||||
* @return Whether the selection could be found. If not found then the drop control will be populated with the matching subset of the font names and the most likely match will be selected.
|
||||
*/
|
||||
protected boolean refreshDrop(String selection) {
|
||||
boolean result = false;
|
||||
|
||||
if(selection == null || selection.length() == 0) {
|
||||
table.setSelection(-1);
|
||||
result = true;
|
||||
}//if//
|
||||
else if(allFontMetadata != null) {
|
||||
for(int index = 0; (!result) && (index < allFontMetadata.getSize()); index++) {
|
||||
if(areEqual(((FontMetadata) allFontMetadata.get(index)).name, selection)) {
|
||||
if(isDisplayingSubset) {
|
||||
updateTable(allFontMetadata);
|
||||
isDisplayingSubset = false;
|
||||
}//if//
|
||||
|
||||
table.setSelection(index);
|
||||
result = true;
|
||||
}//if//
|
||||
}//for//
|
||||
|
||||
//If we couldn't find an exact match then find the closest thing and filter the list to all possible matches (placing starts with's first).//
|
||||
if(!result) {
|
||||
LiteList startsWithMatches = new LiteList(allFontMetadata.getSize());
|
||||
LiteList containsMatches = new LiteList(allFontMetadata.getSize());
|
||||
|
||||
//Collect any matches.//
|
||||
for(int index = 0; index < allFontMetadata.getSize(); index++) {
|
||||
String next = ((FontMetadata) allFontMetadata.get(index)).name;
|
||||
|
||||
if(startsWith(next, selection)) {
|
||||
startsWithMatches.add(allFontMetadata.get(index));
|
||||
}//if//
|
||||
else if(contains(next, selection)) {
|
||||
containsMatches.add(allFontMetadata.get(index));
|
||||
}//else if//
|
||||
}//for//
|
||||
|
||||
//TODO: Sort matches by relavance.
|
||||
|
||||
//Collect all matches into one list.//
|
||||
startsWithMatches.addAll(containsMatches);
|
||||
isDisplayingSubset = true;
|
||||
|
||||
if(startsWithMatches.getSize() > 0) {
|
||||
table.setSelection(0);
|
||||
}//if//
|
||||
}//if//
|
||||
}//else if//
|
||||
|
||||
return result;
|
||||
}//refreshDrop()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.view.swt.custom.CustomCombo#synchronizeDrop()
|
||||
*/
|
||||
protected void synchronizeDrop() {
|
||||
int selectionIndex = table.getSelectionIndex();
|
||||
String selection = selectionIndex != -1 ? ((FontMetadata) table.getItem(selectionIndex).getData()).name : null;
|
||||
String editorContents = selection == null ? "" : selection;
|
||||
|
||||
if(!Comparator.equals(editor.getText(), editorContents)) {
|
||||
ignoreEditorChanges = true;
|
||||
editor.setText(editorContents);
|
||||
ignoreEditorChanges = false;
|
||||
}//if//
|
||||
|
||||
if(!Comparator.equals(lastSelection, selection)) {
|
||||
lastSelection = selection;
|
||||
selectionChanged(selection);
|
||||
}//if//
|
||||
}//synchronizeDrop()//
|
||||
/**
|
||||
* Updates the table items to display the given font metadata objects.
|
||||
* @param fontMetadata The fonts to be displayed in the table.
|
||||
*/
|
||||
private void updateTable(LiteList fontMetadata) {
|
||||
table.removeAll();
|
||||
|
||||
for(int index = 0; index < fontMetadata.getSize(); index++) {
|
||||
org.eclipse.swt.widgets.TableItem item = new org.eclipse.swt.widgets.TableItem(table, 0);
|
||||
FontMetadata font = (FontMetadata) fontMetadata.get(index);
|
||||
|
||||
item.setFont(font.font);
|
||||
item.setText(font.name);
|
||||
//item.setImage(font.isScalable ? )
|
||||
item.setData(font);
|
||||
}//for//
|
||||
}//updateTable()//
|
||||
/**
|
||||
* Determines whether the two strings are equivalent.
|
||||
* @param s1 The first string.
|
||||
* @param s2 The second string.
|
||||
* @return Whether they are considered equal.
|
||||
*/
|
||||
private boolean areEqual(String s1, String s2) {
|
||||
return caseSensitive ? s1.equals(s2) : s1.equalsIgnoreCase(s2);
|
||||
}//areEqual()//
|
||||
/**
|
||||
* Determines whether the full string starts with the second string.
|
||||
* @param fullString The full string to compare with.
|
||||
* @param part The string part to compare against the first characters in the full string.
|
||||
* @return Whether they are considered equal.
|
||||
*/
|
||||
private boolean startsWith(String fullString, String part) {
|
||||
return caseSensitive ? fullString.toLowerCase().startsWith(part.toLowerCase()) : fullString.startsWith(part);
|
||||
}//startsWith()//
|
||||
/**
|
||||
* Determines whether the full string contains the second string as a subset.
|
||||
* @param fullString The full string to compare with.
|
||||
* @param part The string part to compare against any subset of characters in the full string.
|
||||
* @return Whether they are considered equal.
|
||||
*/
|
||||
private boolean contains(String fullString, String part) {
|
||||
return caseSensitive ? fullString.toLowerCase().contains(part.toLowerCase()) : fullString.contains(part);
|
||||
}//contains()//
|
||||
}//FontNameCombo//
|
||||
/**
|
||||
* FontNameComboBox constructor.
|
||||
*/
|
||||
public FontNameComboBox() {
|
||||
}//FontNameComboBox()//
|
||||
/**
|
||||
* Gets the SWT control that represents this combo.
|
||||
* @return The SWT control providing visualization for this combo.
|
||||
*/
|
||||
public FontNameCombo getSwtCombo() {
|
||||
return (FontNameCombo) getSwtControl();
|
||||
}//getSwtCombo()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.AbstractComponent#internalViewInitialize()
|
||||
*/
|
||||
protected void internalViewInitialize() {
|
||||
super.internalViewInitialize();
|
||||
}//internalViewInitialize()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.AbstractComponent#internalViewRelease()
|
||||
*/
|
||||
protected void internalViewRelease() {
|
||||
super.internalViewRelease();
|
||||
}//internalViewRelease()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.AbstractComponent#internalViewSynchronize()
|
||||
*/
|
||||
protected void internalViewSynchronize() {
|
||||
super.internalViewSynchronize();
|
||||
|
||||
if(!autoSynchronizeSelection) {
|
||||
String text = getSwtCombo().getSelection();
|
||||
|
||||
//Convert empty strings to no selection.//
|
||||
sendMessage(MESSAGE_VIEW_SYNCHRONIZE_SELECTION, text == null || text.trim().length() == 0 ? null : text.trim());
|
||||
}//if//
|
||||
}//internalViewSynchronize()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.AbstractComponent#internalOnLinkInvoked(int, java.lang.Object)
|
||||
*/
|
||||
protected void internalOnLinkInvoked(int linkTarget, Object data) {
|
||||
switch(linkTarget) {
|
||||
case LINK_TARGET_SELECTION: {
|
||||
String selection = data instanceof String ? (String) data : null;
|
||||
|
||||
if(!Comparator.equals(selection, getSwtCombo().getSelection())) {
|
||||
getSwtCombo().setSelection(selection);
|
||||
selectionChanged(selection);
|
||||
}//if//
|
||||
break;
|
||||
}//case//
|
||||
default: {
|
||||
super.internalOnLinkInvoked(linkTarget, data);
|
||||
break;
|
||||
}//default//
|
||||
}//switch//
|
||||
}//internalOnLinkInvoked()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.AbstractComponent#internalProcessMessage(com.foundation.tcv.model.ViewMessage)
|
||||
*/
|
||||
public Object internalProcessMessage(ViewMessage viewMessage) {
|
||||
Object retVal = null;
|
||||
|
||||
switch(viewMessage.getMessageNumber()) {
|
||||
case MESSAGE_INITIALIZE: {
|
||||
if(getSwtControl() == null) {
|
||||
int[] data = (int[]) viewMessage.getMessageData();
|
||||
int style = data[1];
|
||||
|
||||
//Link to the parent container.//
|
||||
setContainer((Container) getComponent(data[0]));
|
||||
getContainer().addComponent(this);
|
||||
//Create the SWT widget.//
|
||||
setSwtWidget(new FontNameCombo(((Container) getContainer()).getSwtParent(), style));
|
||||
getSwtWidget().setData(this);
|
||||
|
||||
//If the container has already been initialized then force the parent to re-layout so that this component will appear.//
|
||||
if(getContainer().isInitialized()) {
|
||||
getContainer().getSwtComposite().layout(true, true);
|
||||
}//if//
|
||||
}//if//
|
||||
break;
|
||||
}//case//
|
||||
case MESSAGE_SET_SELECTION: {
|
||||
String selection = (String) viewMessage.getMessageData();
|
||||
|
||||
//Only set the selection if it has changed.//
|
||||
if(!Comparator.equals(selection, getSwtCombo().getSelection())) {
|
||||
getSwtCombo().setSelection(selection);
|
||||
selectionLinkage.invoke(selection);
|
||||
}//if//
|
||||
break;
|
||||
}//case//
|
||||
case MESSAGE_SET_AUTO_SYNCHRONIZE_SELECTION: {
|
||||
autoSynchronizeSelection = ((Boolean) viewMessage.getMessageData()).booleanValue();
|
||||
break;
|
||||
}//case//
|
||||
case MESSAGE_ADD_SELECTION_LINK: {
|
||||
LinkInfo info = (LinkInfo) viewMessage.getMessageData();
|
||||
|
||||
selectionLinkage.add(new LinkData(getComponent(info.getComponent()), info.getTarget(), info.getData(), info.isBoolean(), info.invertLogic(), info.nullValue()));
|
||||
break;
|
||||
}//case//
|
||||
default: {
|
||||
retVal = super.internalProcessMessage(viewMessage);
|
||||
}//default//
|
||||
}//switch//
|
||||
|
||||
return retVal;
|
||||
}//internalProcessMessage()//
|
||||
/**
|
||||
* Called when the selection is changed in the view control.
|
||||
* @param selection The control's selection.
|
||||
*/
|
||||
protected void selectionChanged(String selection) {
|
||||
if(autoSynchronizeSelection) {
|
||||
sendMessage(MESSAGE_VIEW_SYNCHRONIZE_SELECTION, selection);
|
||||
}//if//
|
||||
|
||||
selectionLinkage.invoke(selection);
|
||||
}//selectionChanged()//
|
||||
}//FontNameComboBox//
|
||||
@@ -0,0 +1,351 @@
|
||||
/*
|
||||
* 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.tcv.swt.client;
|
||||
|
||||
import org.eclipse.swt.SWT;
|
||||
import org.eclipse.swt.events.*;
|
||||
import org.eclipse.swt.widgets.Composite;
|
||||
import org.eclipse.swt.widgets.Control;
|
||||
import org.eclipse.swt.widgets.Shell;
|
||||
|
||||
import com.common.comparison.Comparator;
|
||||
import com.foundation.tcv.model.LinkInfo;
|
||||
import com.foundation.tcv.swt.*;
|
||||
import com.foundation.tcv.view.*;
|
||||
import com.foundation.view.LinkData;
|
||||
|
||||
public class FontSizeComboBox extends Component implements IFontNameComboBox {
|
||||
/** Whether the selection state should be auto-synchronized. */
|
||||
private boolean autoSynchronizeSelection = true;
|
||||
/** The linkage for the selection. */
|
||||
private Linkage selectionLinkage = new Linkage();
|
||||
|
||||
/**
|
||||
* This combo allows the user to type an integer on a specified range, or pull down the drop box containing all numbers or a subset of available numbers.
|
||||
*/
|
||||
private class FontSizeCombo extends com.foundation.view.swt.custom.CustomCombo {
|
||||
private org.eclipse.swt.widgets.List list;
|
||||
private org.eclipse.swt.widgets.Text editor;
|
||||
/** The displayed values in the combo drop down. */
|
||||
private int[] listed = null;
|
||||
/** The beginning of the range of valid values. */
|
||||
private int start = 1;
|
||||
/** The end of the range of valid values. */
|
||||
private int end = 1638;
|
||||
/** The value to use when the user has not specified a value (ie: equivalent to null). */
|
||||
private int empty = 12;
|
||||
|
||||
/**
|
||||
* FontSizeCombo constructor.
|
||||
* @param parent A non-null widget which will be the parent of the new instance.
|
||||
* @param style The style of widget to construct.
|
||||
* @see SWT#RESIZE
|
||||
* @see SWT#BORDER
|
||||
*/
|
||||
public FontSizeCombo(Composite parent, int style) {
|
||||
super(parent, style);
|
||||
}//FontSizeCombo()//
|
||||
/**
|
||||
* Sets the range data for the combo.
|
||||
* <p>Note: This method tries to fix any data that is not correct.</p>
|
||||
* @param start The start of the valid range of integers.
|
||||
* @param end The end of the valid range.
|
||||
* @param empty The value to use if the user removes all text from the combo.
|
||||
* @param listed The list of listed numbers. This may not be null.
|
||||
*/
|
||||
private void setRange(int start, int end, int empty, int[] listed) {
|
||||
String[] items = null;
|
||||
|
||||
//Ensure the ranges are correct.//
|
||||
if(start > end) {
|
||||
int temp = start;
|
||||
|
||||
start = end;
|
||||
end = temp;
|
||||
}//if//
|
||||
|
||||
if(empty < start) {
|
||||
empty = start;
|
||||
}//if//
|
||||
|
||||
if(empty > end) {
|
||||
empty = end;
|
||||
}//if//
|
||||
|
||||
this.start = start;
|
||||
this.end = end;
|
||||
this.empty = empty;
|
||||
this.listed = listed;
|
||||
|
||||
//Update the list control.//
|
||||
list.removeAll();
|
||||
items = new String[listed.length];
|
||||
|
||||
for(int index = 0; index < listed.length; index++) {
|
||||
items[index] = "" + listed[index];
|
||||
}//for//
|
||||
|
||||
list.setItems(items);
|
||||
}//setRange()//
|
||||
/**
|
||||
* Gets the integer selected in the view.
|
||||
* @return The selected integer.
|
||||
*/
|
||||
public Integer getSelection() {
|
||||
validateText();
|
||||
|
||||
return Integer.getInteger(editor.getText().trim());
|
||||
}//getSelection()//
|
||||
/**
|
||||
* Sets the integer selected in the view.
|
||||
* @param The selected integer.
|
||||
*/
|
||||
public void setSelection(Integer integer) {
|
||||
editor.setText(integer == null ? "" : integer.toString());
|
||||
|
||||
for(int index = 0; (integer != null) && (index < listed.length); index++) {
|
||||
if(listed[index] == integer.intValue()) {
|
||||
list.setSelection(index);
|
||||
integer = null;
|
||||
}//if//
|
||||
}//for//
|
||||
}//setSelection()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.view.swt.custom.CustomCombo#createDropControl(org.eclipse.swt.widgets.Shell)
|
||||
*/
|
||||
protected Control createDropControl(Shell parent) {
|
||||
list = new org.eclipse.swt.widgets.List(parent, SWT.SINGLE);
|
||||
list.addSelectionListener(new SelectionListener() {
|
||||
public void widgetDefaultSelected(SelectionEvent event) {
|
||||
}//widgetDefaultSelected()//
|
||||
public void widgetSelected(SelectionEvent event) {
|
||||
hideDrop(true);
|
||||
}//widgetSelected()//
|
||||
});
|
||||
|
||||
return list;
|
||||
}//createDropControl()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.view.swt.custom.CustomCombo#createSelectionControl()
|
||||
*/
|
||||
protected Control createSelectionControl() {
|
||||
//TODO: We should probably synchronize the value to the IntegerComboBox after a user types the value and after some time limit. We currently only synchronize upon focus lost.
|
||||
editor = new org.eclipse.swt.widgets.Text(this, SWT.SINGLE | SWT.LEFT);
|
||||
editor.addFocusListener(new FocusListener() {
|
||||
public void focusLost(FocusEvent e) {
|
||||
selectionChanged(getSelection());
|
||||
}//focusLost()//
|
||||
public void focusGained(FocusEvent e) {
|
||||
}//focusGained()//
|
||||
});
|
||||
editor.addVerifyListener(new VerifyListener() {
|
||||
public void verifyText(VerifyEvent event) {
|
||||
if((event.text != null) && (event.text.length() != 0)) {
|
||||
boolean isValid = true;
|
||||
|
||||
for(int index = 0; (isValid) && (index < event.text.length()); index++) {
|
||||
char next = event.text.charAt(index);
|
||||
|
||||
if(!Character.isDigit(next)) {
|
||||
//Allow the negative sign if the range allows negatives.//
|
||||
if(!((start < 0) && (next == '-') && (event.start == 0) && (index == 0))) {
|
||||
isValid = false;
|
||||
}//if//
|
||||
}//if//
|
||||
}//for//
|
||||
|
||||
if(!isValid) {
|
||||
event.doit = false;
|
||||
}//if//
|
||||
}//if//
|
||||
}//verifyText()//
|
||||
});
|
||||
|
||||
return editor;
|
||||
}//createSelectionControl()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.view.swt.custom.CustomCombo#initialize()
|
||||
*/
|
||||
protected void initialize() {
|
||||
}//initialize()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.view.swt.custom.CustomCombo#postInitialize()
|
||||
*/
|
||||
protected void postInitialize() {
|
||||
setRange(1, 1638, 12, new int[] {8, 9, 10, 11, 12, 14, 16, 18, 20, 22, 24, 26, 28, 36, 48, 72});
|
||||
}//postInitialize()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.view.swt.custom.CustomCombo#refreshDrop()
|
||||
*/
|
||||
protected void refreshDrop() {
|
||||
String selection = editor.getText().trim();
|
||||
int number = selection.length() == 0 ? 0 : Integer.parseInt(selection);
|
||||
|
||||
for(int index = 0; (selection != null) && (index < listed.length); index++) {
|
||||
if(listed[index] == number) {
|
||||
list.setSelection(index);
|
||||
selection = null;
|
||||
}//if//
|
||||
}//for//
|
||||
}//refreshDrop()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.view.swt.custom.CustomCombo#synchronizeDrop()
|
||||
*/
|
||||
protected void synchronizeDrop() {
|
||||
int selectionIndex = list.getSelectionIndex();
|
||||
String selection = selectionIndex != -1 ? list.getItem(selectionIndex) : null;
|
||||
|
||||
if(selection != null) {
|
||||
editor.setText(selection == null ? "" : selection);
|
||||
selectionChanged(new Integer(selection));
|
||||
}//if//
|
||||
}//synchronizeDrop()//
|
||||
/**
|
||||
* Validates the text in the editor after the user finishes typing or before the value is synchronized to the data model.
|
||||
* This method will replace the value if it does not meet the requirements.
|
||||
*/
|
||||
protected void validateText() {
|
||||
//Replace no text with the empty value, and ensure that the value is on the right range.//
|
||||
if(editor.getText().trim().length() == 0) {
|
||||
editor.setText("" + empty);
|
||||
}//if//
|
||||
else {
|
||||
long number = Long.parseLong(editor.getText().trim());
|
||||
|
||||
if(number < start) {
|
||||
editor.setText("" + start);
|
||||
refreshDrop();
|
||||
}//if//
|
||||
else if(number > end) {
|
||||
editor.setText("" + end);
|
||||
refreshDrop();
|
||||
}//else if//
|
||||
}//else//
|
||||
}//validateText()//
|
||||
}//FontSizeCombo//
|
||||
/**
|
||||
* FontSizeComboBox constructor.
|
||||
*/
|
||||
public FontSizeComboBox() {
|
||||
}//FontSizeComboBox()//
|
||||
/**
|
||||
* Gets the SWT control that represents this combo.
|
||||
* @return The SWT control providing visualization for this combo.
|
||||
*/
|
||||
public FontSizeCombo getSwtCombo() {
|
||||
return (FontSizeCombo) getSwtControl();
|
||||
}//getSwtCombo()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.AbstractComponent#internalViewInitialize()
|
||||
*/
|
||||
protected void internalViewInitialize() {
|
||||
super.internalViewInitialize();
|
||||
}//internalViewInitialize()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.AbstractComponent#internalViewRelease()
|
||||
*/
|
||||
protected void internalViewRelease() {
|
||||
super.internalViewRelease();
|
||||
}//internalViewRelease()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.AbstractComponent#internalViewSynchronize()
|
||||
*/
|
||||
protected void internalViewSynchronize() {
|
||||
super.internalViewSynchronize();
|
||||
|
||||
if(!autoSynchronizeSelection) {
|
||||
Integer selection = getSwtCombo().getSelection();
|
||||
|
||||
sendMessage(MESSAGE_VIEW_SYNCHRONIZE_SELECTION, selection);
|
||||
}//if//
|
||||
}//internalViewSynchronize()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.AbstractComponent#internalOnLinkInvoked(int, java.lang.Object)
|
||||
*/
|
||||
protected void internalOnLinkInvoked(int linkTarget, Object data) {
|
||||
switch(linkTarget) {
|
||||
case LINK_TARGET_SELECTION: {
|
||||
Integer selection = data instanceof Integer ? (Integer) data : null;
|
||||
|
||||
if(!Comparator.equals(selection, getSwtCombo().getSelection())) {
|
||||
getSwtCombo().setSelection(selection);
|
||||
selectionChanged(selection);
|
||||
}//if//
|
||||
break;
|
||||
}//case//
|
||||
default: {
|
||||
super.internalOnLinkInvoked(linkTarget, data);
|
||||
break;
|
||||
}//default//
|
||||
}//switch//
|
||||
}//internalOnLinkInvoked()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.AbstractComponent#internalProcessMessage(com.foundation.tcv.model.ViewMessage)
|
||||
*/
|
||||
public Object internalProcessMessage(ViewMessage viewMessage) {
|
||||
Object retVal = null;
|
||||
|
||||
switch(viewMessage.getMessageNumber()) {
|
||||
case MESSAGE_INITIALIZE: {
|
||||
if(getSwtControl() == null) {
|
||||
int[] data = (int[]) viewMessage.getMessageData();
|
||||
int style = data[1];
|
||||
|
||||
//Link to the parent container.//
|
||||
setContainer((Container) getComponent(data[0]));
|
||||
getContainer().addComponent(this);
|
||||
//Create the SWT widget.//
|
||||
setSwtWidget(new FontSizeCombo(((Container) getContainer()).getSwtParent(), style));
|
||||
getSwtWidget().setData(this);
|
||||
|
||||
//If the container has already been initialized then force the parent to re-layout so that this component will appear.//
|
||||
if(getContainer().isInitialized()) {
|
||||
getContainer().getSwtComposite().layout(true, true);
|
||||
}//if//
|
||||
}//if//
|
||||
break;
|
||||
}//case//
|
||||
case MESSAGE_SET_SELECTION: {
|
||||
Integer selection = (Integer) viewMessage.getMessageData();
|
||||
|
||||
//Only set the selection if it has changed.//
|
||||
if(!Comparator.equals(selection, getSwtCombo().getSelection())) {
|
||||
getSwtCombo().setSelection(selection);
|
||||
selectionLinkage.invoke(selection);
|
||||
}//if//
|
||||
break;
|
||||
}//case//
|
||||
case MESSAGE_SET_AUTO_SYNCHRONIZE_SELECTION: {
|
||||
autoSynchronizeSelection = ((Boolean) viewMessage.getMessageData()).booleanValue();
|
||||
break;
|
||||
}//case//
|
||||
case MESSAGE_ADD_SELECTION_LINK: {
|
||||
LinkInfo info = (LinkInfo) viewMessage.getMessageData();
|
||||
|
||||
selectionLinkage.add(new LinkData(getComponent(info.getComponent()), info.getTarget(), info.getData(), info.isBoolean(), info.invertLogic(), info.nullValue()));
|
||||
break;
|
||||
}//case//
|
||||
default: {
|
||||
retVal = super.internalProcessMessage(viewMessage);
|
||||
}//default//
|
||||
}//switch//
|
||||
|
||||
return retVal;
|
||||
}//internalProcessMessage()//
|
||||
/**
|
||||
* Called when the selection is changed in the view control.
|
||||
* @param selection The control's selection.
|
||||
*/
|
||||
protected void selectionChanged(Integer selection) {
|
||||
if(autoSynchronizeSelection) {
|
||||
sendMessage(MESSAGE_VIEW_SYNCHRONIZE_SELECTION, selection);
|
||||
}//if//
|
||||
|
||||
selectionLinkage.invoke(selection);
|
||||
}//selectionChanged()//
|
||||
}//FontSizeComboBox//
|
||||
@@ -0,0 +1,88 @@
|
||||
/*
|
||||
* Copyright (c) 2007 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.tcv.swt.client;
|
||||
|
||||
import com.foundation.tcv.swt.IFillLayout;
|
||||
import com.foundation.tcv.view.ViewMessage;
|
||||
|
||||
public class FormLayout extends Layout implements IFillLayout {
|
||||
public int marginWidth = 0;
|
||||
public int marginHeight = 0;
|
||||
public int marginLeft = 0;
|
||||
public int marginTop = 0;
|
||||
public int marginRight = 0;
|
||||
public int marginBottom = 0;
|
||||
public int spacing = 0;
|
||||
/**
|
||||
* FormLayout constructor.
|
||||
*/
|
||||
public FormLayout() {
|
||||
}//FormLayout()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.Layout#createLayout(java.lang.Object)
|
||||
*/
|
||||
public org.eclipse.swt.widgets.Layout createLayout(Object rowObject) {
|
||||
com.foundation.view.swt.layout.FormLayout result = new com.foundation.view.swt.layout.FormLayout();
|
||||
|
||||
result.marginHeight = marginHeight;
|
||||
result.marginWidth = marginWidth;
|
||||
result.spacing = spacing;
|
||||
result.marginLeft = marginLeft;
|
||||
result.marginTop = marginTop;
|
||||
result.marginRight = marginRight;
|
||||
result.marginBottom = marginBottom;
|
||||
|
||||
return result;
|
||||
}//createLayout()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.Layout#initialize()
|
||||
*/
|
||||
public void initialize() {
|
||||
}//initialize()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.Layout#release()
|
||||
*/
|
||||
public void release() {
|
||||
}//release()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.Layout#synchronize()
|
||||
*/
|
||||
public void synchronize() {
|
||||
}//synchronize()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.Layout#processMessage(com.foundation.tcv.view.ViewMessage)
|
||||
*/
|
||||
public Object processMessage(ViewMessage viewMessage) {
|
||||
Object result = null;
|
||||
|
||||
switch(viewMessage.getMessageNumber()) {
|
||||
case MESSAGE_INITIALIZE: {
|
||||
setContainer((AbstractComponent) getComponent(viewMessage.getMessageInteger()));
|
||||
break;
|
||||
}//case//
|
||||
case MESSAGE_SET_MARGIN_HEIGHT: {
|
||||
this.marginHeight = viewMessage.getMessageInteger();
|
||||
break;
|
||||
}//case//
|
||||
case MESSAGE_SET_MARGIN_WIDTH: {
|
||||
this.marginWidth = viewMessage.getMessageInteger();
|
||||
break;
|
||||
}//case//
|
||||
case MESSAGE_SET_SPACING: {
|
||||
this.spacing = viewMessage.getMessageInteger();
|
||||
break;
|
||||
}//case//
|
||||
default: {
|
||||
result = super.processMessage(viewMessage);
|
||||
break;
|
||||
}//default//
|
||||
}//switch//
|
||||
|
||||
return result;
|
||||
}//processMessage()//
|
||||
}//FormLayout//
|
||||
@@ -0,0 +1,421 @@
|
||||
/*
|
||||
* Copyright (c) 2003,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.tcv.swt.client;
|
||||
|
||||
import org.eclipse.swt.events.*;
|
||||
import org.eclipse.swt.graphics.*;
|
||||
import org.eclipse.swt.widgets.Event;
|
||||
|
||||
import com.foundation.tcv.client.view.ResourceHolder;
|
||||
import com.foundation.tcv.swt.*;
|
||||
import com.foundation.tcv.view.ViewMessage;
|
||||
import com.foundation.view.JefImage;
|
||||
|
||||
public class Frame extends Container implements IDecoration, IFrame, Component.IComponentListener {
|
||||
/** A holder for the value of the container images. */
|
||||
private ResourceHolder containerImagesHolder = new ResourceHolder(this);
|
||||
/** The swt images used by the container of this component to represent the component. */
|
||||
private Image[] swtContainerImages = null;
|
||||
private Menu menuBar = null;
|
||||
/** Whether to send closed events to the server. */
|
||||
private boolean sendClosedEvent = false;
|
||||
/** Whether to send activated or deactivated events to the server. */
|
||||
private boolean sendActivatedEvents = false;
|
||||
/**
|
||||
* Frame constructor.
|
||||
*/
|
||||
public Frame() {
|
||||
super();
|
||||
}//Frame()//
|
||||
/**
|
||||
* Gets the SWT decorations that represents this frame.
|
||||
* @return The decorations providing visualization for this frame.
|
||||
*/
|
||||
public org.eclipse.swt.widgets.Decorations getSwtDecorations() {
|
||||
return (org.eclipse.swt.widgets.Decorations) getSwtControl();
|
||||
}//getSwtDecorations()//
|
||||
/**
|
||||
* Gets the frame's default button.
|
||||
* @return The default button in this container.
|
||||
*/
|
||||
public Button getDefaultButton() {
|
||||
return (Button) getSwtDecorations().getDefaultButton().getData();
|
||||
}//getDefaultButton()//
|
||||
/**
|
||||
* Sets the frame's default button.
|
||||
* @param defaultButton The default button in this container.
|
||||
*/
|
||||
public void setDefaultButton(Button defaultButton) {
|
||||
getSwtDecorations().setDefaultButton(defaultButton != null ? defaultButton.getSwtButton() : null);
|
||||
}//setDefaultButton()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.view.swt.IDecoration#getMenuBar()
|
||||
*/
|
||||
public Menu getMenuBar() {
|
||||
return menuBar;
|
||||
}//getMenuBar()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.view.swt.IDecoration#setMenuBar(com.foundation.view.swt.Menu)
|
||||
*/
|
||||
public void setMenuBar(Menu menuBar) {
|
||||
this.menuBar = menuBar;
|
||||
}//setMenuBar()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.Container#center()
|
||||
*/
|
||||
public void center() {
|
||||
Rectangle window = getSwtDecorations().getBounds();
|
||||
Rectangle screen = getSwtDecorations().getMonitor().getBounds();
|
||||
int x = (int) ((screen.width / 2) - (window.width / 2));
|
||||
int y = (int) ((screen.height / 2) - (window.height / 2));
|
||||
|
||||
if(x < screen.x) {
|
||||
x = screen.x;
|
||||
}//if//
|
||||
|
||||
if(y < screen.y) {
|
||||
y = screen.y;
|
||||
}//if//
|
||||
|
||||
getSwtDecorations().setLocation(x, y);
|
||||
}//center()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.Container#center(long[])
|
||||
*/
|
||||
public void center(long[] centerOnView) {
|
||||
Frame frame = (Frame) getComponent(centerOnView);
|
||||
Rectangle windowRect = getSwtDecorations().getBounds();
|
||||
Rectangle screen = getSwtDecorations().getDisplay().getBounds();
|
||||
Rectangle componentRect = frame.getSwtDecorations().getBounds();
|
||||
|
||||
int x = (int) ((componentRect.width / 2) - (windowRect.width / 2) + componentRect.x);
|
||||
int y = (int) ((componentRect.height / 2) - (windowRect.height / 2) + componentRect.y);
|
||||
|
||||
if((x + windowRect.width) - screen.x > screen.width) {
|
||||
x = (int) (screen.width - windowRect.width + screen.x);
|
||||
}//if//
|
||||
|
||||
if((y + windowRect.height) - screen.y > screen.height) {
|
||||
y = (int) (screen.height - windowRect.height + screen.y);
|
||||
}//if//
|
||||
|
||||
if(x < screen.x) {
|
||||
x = screen.x;
|
||||
}//if//
|
||||
|
||||
if(y < screen.y) {
|
||||
y = screen.y;
|
||||
}//if//
|
||||
|
||||
getSwtDecorations().setLocation(x, y);
|
||||
}//center()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.AbstractComponent#internalViewInitializeAll()
|
||||
*/
|
||||
protected void internalViewInitializeAll() {
|
||||
super.internalViewInitializeAll();
|
||||
|
||||
if(getMenuBar() != null) {
|
||||
getMenuBar().internalViewInitializeAll();
|
||||
}//if//
|
||||
}//internalViewInitializeAll()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.AbstractComponent#internalViewReleaseAll()
|
||||
*/
|
||||
protected void internalViewReleaseAll() {
|
||||
super.internalViewReleaseAll();
|
||||
|
||||
if(getMenuBar() != null) {
|
||||
getMenuBar().internalViewReleaseAll();
|
||||
}//if//
|
||||
}//internalViewReleaseAll()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.AbstractComponent#internalViewSynchronizeAll()
|
||||
*/
|
||||
protected void internalViewSynchronizeAll() {
|
||||
super.internalViewSynchronizeAll();
|
||||
|
||||
if(getMenuBar() != null) {
|
||||
getMenuBar().internalViewSynchronizeAll();
|
||||
}//if//
|
||||
}//internalViewSynchronizeAll()//
|
||||
/**
|
||||
* Registers the listener(s) necessary to capture shell events.
|
||||
*/
|
||||
protected void registerShellListeners() {
|
||||
/*
|
||||
getSwtDecorations().addControlListener(new ControlListener() {
|
||||
private boolean wasLastMaximized = false;
|
||||
|
||||
public void controlResized(ControlEvent e) {
|
||||
boolean isMaximized = getSwtDecorations().getMaximized();
|
||||
|
||||
if(isMaximized != wasLastMaximized) {
|
||||
wasLastMaximized = isMaximized;
|
||||
shellMaximized(isMaximized);
|
||||
}//if//
|
||||
}//controlResized()//
|
||||
public void controlMoved(ControlEvent e) {
|
||||
}//controlMoved()//
|
||||
});
|
||||
getSwtDecorations().addListener(SWT.Iconify, new org.eclipse.swt.widgets.Listener() {
|
||||
public void handleEvent(Event event) {
|
||||
shellIconified(event);
|
||||
}//handleEvent()//
|
||||
});
|
||||
getSwtDecorations().addListener(SWT.Deiconify, new org.eclipse.swt.widgets.Listener() {
|
||||
public void handleEvent(Event event) {
|
||||
shellDeiconified(event);
|
||||
}//handleEvent()//
|
||||
});
|
||||
*/
|
||||
|
||||
/* GCJ Doesn't like this... since it isn't used I am commenting it.
|
||||
getSwtDecorations().addListener(SWT.Close, new org.eclipse.swt.widgets.Listener() {
|
||||
public void handleEvent(Event event) {
|
||||
shellClosed(event);
|
||||
event.doit = false;
|
||||
}//handleEvent()//
|
||||
});
|
||||
getSwtDecorations().addListener(SWT.Activate, new org.eclipse.swt.widgets.Listener() {
|
||||
public void handleEvent(Event event) {
|
||||
shellActivated(event);
|
||||
}//handleEvent()//
|
||||
});
|
||||
getSwtDecorations().addListener(SWT.Deactivate, new org.eclipse.swt.widgets.Listener() {
|
||||
public void handleEvent(Event event) {
|
||||
shellDeactivated(event);
|
||||
}//handleEvent()//
|
||||
});
|
||||
*/
|
||||
}//registerShellListeners()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.AbstractComponent#internalViewInitialize()
|
||||
*/
|
||||
protected void internalViewInitialize() {
|
||||
//Add this component as a shell listener so we get shell events.//
|
||||
registerShellListeners();
|
||||
//Register for image and title changes. Note: it is not necessary to initialize the title & image since they will be updated on the container's refresh and an event will fire if they are anything other than null.//
|
||||
registerListener(this);
|
||||
|
||||
if(getContainerTitle() != null) {
|
||||
getSwtDecorations().setText(getContainerTitle());
|
||||
}//if//
|
||||
|
||||
super.internalViewInitialize();
|
||||
}//internalViewInitialize()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.AbstractComponent#internalViewRelease()
|
||||
*/
|
||||
protected void internalViewRelease() {
|
||||
containerImagesHolder.release();
|
||||
|
||||
if(swtContainerImages != null) {
|
||||
destroyImages(swtContainerImages);
|
||||
swtContainerImages = null;
|
||||
}//if//
|
||||
|
||||
super.internalViewRelease();
|
||||
unregisterListener(this);
|
||||
}//internalViewRelease()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.AbstractComponent#internalViewSynchronize()
|
||||
*/
|
||||
protected void internalViewSynchronize() {
|
||||
super.internalViewSynchronize();
|
||||
}//internalViewSynchronize()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.Component#internalResourceHolderChanged(com.foundation.tcv.client.view.ResourceHolder, java.lang.Object, java.lang.Object)
|
||||
*/
|
||||
protected void internalResourceHolderChanged(ResourceHolder resource, Object oldValue, Object newValue, int flags) {
|
||||
if(resource == containerImagesHolder) {
|
||||
destroyImages(swtContainerImages);
|
||||
swtContainerImages = createImages(containerImagesHolder.getValue() instanceof JefImage ? new JefImage[] {(JefImage) containerImagesHolder.getValue()} : (JefImage[]) containerImagesHolder.getValue());
|
||||
getSwtDecorations().setImages(swtContainerImages == null ? new Image[0] : swtContainerImages);
|
||||
}//if//
|
||||
else {
|
||||
super.internalResourceHolderChanged(resource, oldValue, newValue, flags);
|
||||
}//else//
|
||||
}//internalOnAssociationChanged()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.AbstractComponent#internalProcessMessage(com.foundation.tcv.model.ViewMessage)
|
||||
*/
|
||||
public Object internalProcessMessage(ViewMessage viewMessage) {
|
||||
Object retVal = null;
|
||||
|
||||
switch(viewMessage.getMessageNumber()) {
|
||||
case MESSAGE_INITIALIZE: {
|
||||
if(getSwtControl() == null) {
|
||||
int[] data = (int[]) viewMessage.getMessageData();
|
||||
|
||||
setContainer((Container) getComponent(data[0]));
|
||||
setSwtWidget(new org.eclipse.swt.widgets.Decorations(getContainer().getSwtComposite(), data[1]));
|
||||
getSwtWidget().setData(this);
|
||||
|
||||
//If the container has already been initialized then force the parent to re-layout so that this component will appear.//
|
||||
if(getContainer().isInitialized()) {
|
||||
getContainer().getSwtComposite().layout(true, true);
|
||||
}//if//
|
||||
|
||||
registerListener(this);
|
||||
}//if//
|
||||
break;
|
||||
}//case//
|
||||
case MESSAGE_REQUEST_CLOSED_NOTIFICATION: {
|
||||
sendClosedEvent = ((Boolean) viewMessage.getMessageData()).booleanValue();
|
||||
break;
|
||||
}//case//
|
||||
case MESSAGE_MAXIMIZE: {
|
||||
boolean isMaximized = ((Boolean) viewMessage.getMessageData()).booleanValue();
|
||||
|
||||
if(getSwtDecorations().getMaximized() != isMaximized) {
|
||||
getSwtDecorations().setMaximized(isMaximized);
|
||||
}//if//
|
||||
break;
|
||||
}//case//
|
||||
case MESSAGE_MINIMIZE: {
|
||||
boolean isMinimized = ((Boolean) viewMessage.getMessageData()).booleanValue();
|
||||
|
||||
if(getSwtDecorations().getMinimized() != isMinimized) {
|
||||
getSwtDecorations().setMinimized(isMinimized);
|
||||
}//if//
|
||||
break;
|
||||
}//case//
|
||||
case MESSAGE_SHOW: {
|
||||
if(getSwtDecorations().getMinimized()) {
|
||||
getSwtDecorations().setMinimized(false);
|
||||
}//if//
|
||||
|
||||
resize();
|
||||
getSwtDecorations().setVisible(true);
|
||||
getSwtDecorations().setFocus();
|
||||
break;
|
||||
}//case//
|
||||
case MESSAGE_SEND_ACTIVATED_EVENTS: {
|
||||
sendActivatedEvents = ((Boolean) viewMessage.getMessageData()).booleanValue();
|
||||
break;
|
||||
}//case//
|
||||
case MESSAGE_SET_DEFAULT_BUTTON: {
|
||||
setDefaultButton(viewMessage.getMessageData() != null ? (Button) getComponent(((Integer) viewMessage.getMessageData()).intValue()) : null);
|
||||
break;
|
||||
}//case//
|
||||
case MESSAGE_SET_CONTAINER_IMAGES: {
|
||||
containerImagesHolder.setValue(viewMessage.getMessageData());
|
||||
break;
|
||||
}//case//
|
||||
default: {
|
||||
retVal = super.internalProcessMessage(viewMessage);
|
||||
}//case//
|
||||
}//switch//
|
||||
|
||||
return retVal;
|
||||
}//internalProcessMessage()//
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.swt.events.ShellListener#shellClosed(org.eclipse.swt.events.ShellEvent)
|
||||
*/
|
||||
public void shellClosed(ShellEvent e) {
|
||||
if(sendClosedEvent) {
|
||||
sendRoundTripMessage(MESSAGE_IS_CLOSED, null, null);
|
||||
}//if//
|
||||
|
||||
e.doit = false;
|
||||
}//shellClosed()//
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.swt.events.ShellListener#shellClosed(org.eclipse.swt.events.ShellEvent)
|
||||
*/
|
||||
public void shellClosed(Event e) {
|
||||
//TODO: Why have two shell closed methods? Which gets called?//
|
||||
if(sendClosedEvent) {
|
||||
sendRoundTripMessage(MESSAGE_IS_CLOSED, null, null);
|
||||
}//if//
|
||||
|
||||
e.doit = false;
|
||||
}//shellClosed()//
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.swt.events.ShellListener#shellActivated(org.eclipse.swt.events.ShellEvent)
|
||||
*/
|
||||
public void shellActivated(ShellEvent e) {
|
||||
if(sendActivatedEvents) {
|
||||
sendMessage(MESSAGE_IS_ACTIVATED, Boolean.TRUE);
|
||||
}//if//
|
||||
}//shellActivated()//
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.swt.events.ShellListener#shellActivated(org.eclipse.swt.events.ShellEvent)
|
||||
*/
|
||||
public void shellActivated(Event e) {
|
||||
if(sendActivatedEvents) {
|
||||
sendMessage(MESSAGE_IS_ACTIVATED, Boolean.TRUE);
|
||||
}//if//
|
||||
}//shellActivated()//
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.swt.events.ShellListener#shellDeactivated(org.eclipse.swt.events.ShellEvent)
|
||||
*/
|
||||
public void shellDeactivated(ShellEvent e) {
|
||||
if(sendActivatedEvents) {
|
||||
sendMessage(MESSAGE_IS_ACTIVATED, Boolean.FALSE);
|
||||
}//if//
|
||||
}//shellDeactivated()//
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.swt.events.ShellListener#shellDeactivated(org.eclipse.swt.events.ShellEvent)
|
||||
*/
|
||||
public void shellDeactivated(Event e) {
|
||||
if(sendActivatedEvents) {
|
||||
sendMessage(MESSAGE_IS_ACTIVATED, Boolean.FALSE);
|
||||
}//if//
|
||||
}//shellDeactivated()//
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.swt.events.ShellListener#shellDeiconified(org.eclipse.swt.events.ShellEvent)
|
||||
*/
|
||||
public void shellDeiconified(ShellEvent e) {
|
||||
//if(!suspendResizeEvents) {
|
||||
// sendMessage(MESSAGE_SET_MINIMIZED, Boolean.FALSE);
|
||||
//}//if//
|
||||
}//shellDeiconified()//
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.swt.events.ShellListener#shellDeiconified(org.eclipse.swt.events.ShellEvent)
|
||||
*/
|
||||
public void shellDeiconified(Event e) {
|
||||
//if(!suspendResizeEvents) {
|
||||
// sendMessage(MESSAGE_SET_MINIMIZED, Boolean.FALSE);
|
||||
//}//if//
|
||||
}//shellDeiconified()//
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.swt.events.ShellListener#shellIconified(org.eclipse.swt.events.ShellEvent)
|
||||
*/
|
||||
public void shellIconified(ShellEvent e) {
|
||||
//if(!suspendResizeEvents) {
|
||||
// sendMessage(MESSAGE_SET_MINIMIZED, Boolean.TRUE);
|
||||
//}//if//
|
||||
}//shellIconified()//
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.swt.events.ShellListener#shellIconified(org.eclipse.swt.events.ShellEvent)
|
||||
*/
|
||||
public void shellIconified(Event e) {
|
||||
//if(!suspendResizeEvents) {
|
||||
// sendMessage(MESSAGE_SET_MINIMIZED, Boolean.TRUE);
|
||||
//}//if//
|
||||
}//shellIconified()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.Component.IComponentListener#imageChanged(com.foundation.tcv.swt.client.Component, org.eclipse.swt.graphics.Image)
|
||||
*/
|
||||
public void imageChanged(Component component, Image newImage) {
|
||||
getSwtDecorations().setImage(newImage);
|
||||
}//imageChanged()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.Component.IComponentListener#titleChanged(com.foundation.tcv.swt.client.Component, java.lang.String)
|
||||
*/
|
||||
public void titleChanged(Component component, String newTitle) {
|
||||
getSwtDecorations().setText(newTitle);
|
||||
}//titleChanged()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.Component.IComponentListener#toolTipTextChanged(com.foundation.tcv.swt.client.Component, java.lang.String)
|
||||
*/
|
||||
public void toolTipTextChanged(Component component, String newToolTipText) {
|
||||
getSwtDecorations().setToolTipText(newToolTipText);
|
||||
}//toolTipTextChanged()//
|
||||
}//Frame//
|
||||
@@ -0,0 +1,106 @@
|
||||
/*
|
||||
* Copyright (c) 2007 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.tcv.swt.client;
|
||||
|
||||
import com.foundation.tcv.swt.IGridLayout;
|
||||
import com.foundation.tcv.view.ViewMessage;
|
||||
|
||||
public class GridLayout extends Layout implements IGridLayout {
|
||||
public int numColumns = 1;
|
||||
public boolean makeColumnsEqualWidth = false;
|
||||
public int marginWidth = 0;
|
||||
public int marginHeight = 0;
|
||||
public int marginLeft = 0;
|
||||
public int marginTop = 0;
|
||||
public int marginRight = 0;
|
||||
public int marginBottom = 0;
|
||||
public int horizontalSpacing = 5;
|
||||
public int verticalSpacing = 5;
|
||||
/**
|
||||
* GridLayout constructor.
|
||||
*/
|
||||
public GridLayout() {
|
||||
}//GridLayout()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.Layout#createLayout(java.lang.Object)
|
||||
*/
|
||||
public org.eclipse.swt.widgets.Layout createLayout(Object rowObject) {
|
||||
com.foundation.view.swt.layout.GridLayout result = new com.foundation.view.swt.layout.GridLayout();
|
||||
|
||||
result.marginHeight = marginHeight;
|
||||
result.marginWidth = marginWidth;
|
||||
result.marginLeft = marginLeft;
|
||||
result.marginTop = marginTop;
|
||||
result.marginRight = marginRight;
|
||||
result.marginBottom = marginBottom;
|
||||
result.numColumns = numColumns;
|
||||
result.makeColumnsEqualWidth = makeColumnsEqualWidth;
|
||||
result.horizontalSpacing = horizontalSpacing;
|
||||
result.verticalSpacing = verticalSpacing;
|
||||
|
||||
return result;
|
||||
}//createLayout()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.Layout#initialize()
|
||||
*/
|
||||
public void initialize() {
|
||||
}//initialize()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.Layout#release()
|
||||
*/
|
||||
public void release() {
|
||||
}//release()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.Layout#synchronize()
|
||||
*/
|
||||
public void synchronize() {
|
||||
}//synchronize()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.Layout#processMessage(com.foundation.tcv.view.ViewMessage)
|
||||
*/
|
||||
public Object processMessage(ViewMessage viewMessage) {
|
||||
Object result = null;
|
||||
|
||||
switch(viewMessage.getMessageNumber()) {
|
||||
case MESSAGE_INITIALIZE: {
|
||||
setContainer((AbstractComponent) getComponent(viewMessage.getMessageInteger()));
|
||||
break;
|
||||
}//case//
|
||||
case MESSAGE_SET_NUM_COLUMNS: {
|
||||
this.numColumns = viewMessage.getMessageInteger();
|
||||
break;
|
||||
}//case//
|
||||
case MESSAGE_SET_MARGIN_HEIGHT: {
|
||||
this.marginHeight = viewMessage.getMessageInteger();
|
||||
break;
|
||||
}//case//
|
||||
case MESSAGE_SET_MARGIN_WIDTH: {
|
||||
this.marginWidth = viewMessage.getMessageInteger();
|
||||
break;
|
||||
}//case//
|
||||
case MESSAGE_SET_MAKE_COLUMNS_EQUAL_WIDTH: {
|
||||
this.makeColumnsEqualWidth = viewMessage.getMessageInteger() != 0;
|
||||
break;
|
||||
}//case//
|
||||
case MESSAGE_SET_HORIZONTAL_SPACING: {
|
||||
this.horizontalSpacing = viewMessage.getMessageInteger();
|
||||
break;
|
||||
}//case//
|
||||
case MESSAGE_SET_VERTICAL_SPACING: {
|
||||
this.verticalSpacing = viewMessage.getMessageInteger();
|
||||
break;
|
||||
}//case//
|
||||
default: {
|
||||
result = super.processMessage(viewMessage);
|
||||
break;
|
||||
}//default//
|
||||
}//switch//
|
||||
|
||||
return result;
|
||||
}//processMessage()//
|
||||
}//GridLayout//
|
||||
@@ -0,0 +1,107 @@
|
||||
/*
|
||||
* Copyright (c) 2007,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.tcv.swt.client;
|
||||
|
||||
import org.eclipse.swt.graphics.Image;
|
||||
|
||||
import com.foundation.tcv.swt.*;
|
||||
import com.foundation.tcv.view.*;
|
||||
|
||||
public class Group extends Container implements IGroup, Component.IComponentListener {
|
||||
/**
|
||||
* Group constructor.
|
||||
*/
|
||||
public Group() {
|
||||
super();
|
||||
}//Group()//
|
||||
/**
|
||||
* Gets the SWT Group that represents this group.
|
||||
* @return The SWT Group providing visualization for this group.
|
||||
*/
|
||||
public org.eclipse.swt.widgets.Group getSwtGroup() {
|
||||
return (org.eclipse.swt.widgets.Group) getSwtWidget();
|
||||
}//getSwtGroup()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.AbstractComponent#internalViewInitialize()
|
||||
*/
|
||||
protected void internalViewInitialize() {
|
||||
//Register for image and title changes. Note: it is not necessary to initialize the title & image since they will be updated on the container's refresh and an event will fire if they are anything other than null.//
|
||||
registerListener(this);
|
||||
|
||||
if(getContainerTitle() != null) {
|
||||
getSwtGroup().setText(getContainerTitle());
|
||||
}//if//
|
||||
|
||||
super.internalViewInitialize();
|
||||
}//internalViewInitialize()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.AbstractComponent#internalViewRelease()
|
||||
*/
|
||||
protected void internalViewRelease() {
|
||||
super.internalViewRelease();
|
||||
unregisterListener(this);
|
||||
}//internalViewRelease()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.AbstractComponent#internalViewSynchronize()
|
||||
*/
|
||||
protected void internalViewSynchronize() {
|
||||
super.internalViewSynchronize();
|
||||
}//internalViewSynchronize()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.AbstractComponent#internalProcessMessage(com.foundation.tcv.model.ViewMessage)
|
||||
*/
|
||||
public Object internalProcessMessage(ViewMessage viewMessage) {
|
||||
Object result = null;
|
||||
|
||||
switch(viewMessage.getMessageNumber()) {
|
||||
case MESSAGE_INITIALIZE: {
|
||||
if(getSwtControl() == null) {
|
||||
int[] data = (int[]) viewMessage.getMessageData();
|
||||
int style = data[1];
|
||||
|
||||
//Link to the parent container.//
|
||||
setContainer((Container) getComponent(data[0]));
|
||||
getContainer().addComponent(this);
|
||||
//Create the SWT widget.//
|
||||
setSwtWidget(new org.eclipse.swt.widgets.Group(getContainer().getSwtParent(), style));
|
||||
getSwtWidget().setData(this);
|
||||
|
||||
//If the container has already been initialized then force the parent to re-layout so that this component will appear.//
|
||||
if(getContainer().isInitialized()) {
|
||||
getContainer().getSwtComposite().layout(true, true);
|
||||
}//if//
|
||||
}//if//
|
||||
break;
|
||||
}//case//
|
||||
default: {
|
||||
result = super.internalProcessMessage(viewMessage);
|
||||
}//default//
|
||||
}//switch//
|
||||
|
||||
return result;
|
||||
}//internalProcessMessage()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.Component.IComponentListener#imageChanged(com.foundation.tcv.swt.client.Component, org.eclipse.swt.graphics.Image)
|
||||
*/
|
||||
public void imageChanged(Component component, Image newImage) {
|
||||
//Images not currently supported by Group.//
|
||||
//getSwtGroup().setImage(newImage);
|
||||
}//imageChanged()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.Component.IComponentListener#titleChanged(com.foundation.tcv.swt.client.Component, java.lang.String)
|
||||
*/
|
||||
public void titleChanged(Component component, String newTitle) {
|
||||
getSwtGroup().setText(newTitle);
|
||||
}//titleChanged()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.Component.IComponentListener#toolTipTextChanged(com.foundation.tcv.swt.client.Component, java.lang.String)
|
||||
*/
|
||||
public void toolTipTextChanged(Component component, String newToolTipText) {
|
||||
getSwtGroup().setToolTipText(newToolTipText);
|
||||
}//toolTipTextChanged()//
|
||||
}//Group//
|
||||
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
* Copyright (c) 2008,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.tcv.swt.client;
|
||||
|
||||
public interface IAbstractMenu {
|
||||
/**
|
||||
* Creates this menu's resources.
|
||||
* This allows the menu to be lazily created when the user wants to interact with it, and then cleaned up when done.
|
||||
*/
|
||||
public void loadMenu();
|
||||
/**
|
||||
* Destroys this menu's resources.
|
||||
* This allows the menu to be lazily created when the user wants to interact with it, and then cleaned up when done.
|
||||
*/
|
||||
public void unloadMenu();
|
||||
/**
|
||||
* Creates the menu's children's resources (all children in the tree).
|
||||
* This allows the menu to be lazily created when the user wants to interact with it, and then cleaned up when done.
|
||||
*/
|
||||
public void loadMenuChildren();
|
||||
/**
|
||||
* Destroys the menu's children's resources (all children in the tree).
|
||||
* This allows the menu to be lazily created when the user wants to interact with it, and then cleaned up when done.
|
||||
*/
|
||||
public void unloadMenuChildren();
|
||||
}//IAbstractMenu//
|
||||
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
* Copyright (c) 2006,2007 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.tcv.swt.client;
|
||||
|
||||
import org.eclipse.swt.widgets.Composite;
|
||||
|
||||
public interface IAbstractSwtContainer {
|
||||
/**
|
||||
* Gets the SWT composite control for the container.
|
||||
* Note that this composite might not be the one to place children in.
|
||||
* @return The composite control that SWT uses to designate a container.
|
||||
*/
|
||||
public Composite getSwtComposite();
|
||||
/**
|
||||
* Gets the SWT composite control used to contain the child controls.
|
||||
* Note that this may be the same object as returned by the getSwtComposite() method.
|
||||
* @return The composite control that SWT uses to designate a container and which will be used to contain any children.
|
||||
*/
|
||||
public Composite getSwtParent();
|
||||
/**
|
||||
* Sets the layout for this container.
|
||||
* @param layout The container's layout.
|
||||
*/
|
||||
public void setLayout(Layout layout);
|
||||
}//IAbstractContainer//
|
||||
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
* Copyright (c) 2006,2007 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.tcv.swt.client;
|
||||
|
||||
import org.eclipse.swt.widgets.Composite;
|
||||
|
||||
import com.common.util.IIterator;
|
||||
import com.foundation.tcv.swt.client.cell.CellComponent;
|
||||
import com.foundation.view.resource.AbstractResourceService;
|
||||
|
||||
public interface ICellContainer {
|
||||
/**
|
||||
* Gets the row object metadata for the given object identifier.
|
||||
* @param objectId The identifying number for the desired collection item's metadata.
|
||||
* @return The row object for the given identifer.
|
||||
*/
|
||||
public RowObject getRowObject(int objectId);
|
||||
/**
|
||||
* Gets an iterator over all row objects.
|
||||
* @return The iterator containing all the row objects.
|
||||
*/
|
||||
public IIterator getRowObjects();
|
||||
/**
|
||||
* Gets the container that defines the space occupied by the cells.
|
||||
* @return The container for the cells.
|
||||
*/
|
||||
public Container getContainer();
|
||||
/**
|
||||
* Gets the composite that the cell should use as the parent SWT component.
|
||||
* @param rowObject The row object whose composite is required. The composite may be the container for the cells, or a sub-container within the cell.
|
||||
* @return The SWT composite that contains all children.
|
||||
*/
|
||||
public Composite getSwtComposite(RowObject rowObject);
|
||||
/**
|
||||
* Gets the composites that the cells use as the parent SWT component.
|
||||
* @return The iterator over all active SWT composites that contain all children.
|
||||
*/
|
||||
public IIterator getSwtComposites();
|
||||
/**
|
||||
* Adds the cell component to the container.
|
||||
* @param component The component to be added.
|
||||
*/
|
||||
public void addCellComponent(CellComponent component);
|
||||
/**
|
||||
* Gets the resource service.
|
||||
* @return The component's resource service.
|
||||
*/
|
||||
public AbstractResourceService getResourceService();
|
||||
/**
|
||||
* Sets the layout for this container.
|
||||
* @param layout The container's layout.
|
||||
*/
|
||||
public void setLayout(Layout layout);
|
||||
}//ICellContainer//
|
||||
@@ -0,0 +1,19 @@
|
||||
/*
|
||||
* Copyright (c) 2003,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.tcv.swt.client;
|
||||
|
||||
/**
|
||||
* Implementors must be able to display them selves with a menu bar.
|
||||
*/
|
||||
public interface IDecoration {
|
||||
/**
|
||||
* Sets the decoration's menu bar.
|
||||
* @param menu The menu to be displayed in the menu bar.
|
||||
*/
|
||||
public void setMenuBar(Menu menu);
|
||||
}//IDecoration//
|
||||
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
* Copyright (c) 2007 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.tcv.swt.client;
|
||||
|
||||
import org.eclipse.swt.graphics.Image;
|
||||
import org.eclipse.swt.widgets.Composite;
|
||||
import org.eclipse.swt.widgets.Control;
|
||||
|
||||
import com.foundation.view.JefImage;
|
||||
import com.foundation.view.resource.AbstractResourceService;
|
||||
|
||||
public interface IDecorationContainer {
|
||||
/**
|
||||
* Gets the view system's resource service.
|
||||
* @return The resource service for the view system.
|
||||
*/
|
||||
public AbstractResourceService getResourceService();
|
||||
/**
|
||||
* Gets the parent control for the decorations.
|
||||
* @return The decoration's parent control.
|
||||
*/
|
||||
public Composite getDecorationParent();
|
||||
/**
|
||||
* Gets the decoration's peer control (the one it is decorating).
|
||||
* @return The peer control for the decorations.
|
||||
*/
|
||||
public Control getDecorationPeer();
|
||||
/**
|
||||
* Creates an image given the jef image.
|
||||
* @param image The image to be created.
|
||||
* @return The image resource.
|
||||
*/
|
||||
public Image createImage(JefImage image);
|
||||
/**
|
||||
* Destroys an image resource, or decrements the useage count.
|
||||
* @param image The image to destroy.
|
||||
*/
|
||||
public void destroyImage(Image image);
|
||||
}//IDecorationContainer//
|
||||
@@ -0,0 +1,18 @@
|
||||
/*
|
||||
* Copyright (c) 2007 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.tcv.swt.client;
|
||||
|
||||
import org.eclipse.swt.widgets.Composite;
|
||||
|
||||
public interface IDualLayerContainer {
|
||||
/**
|
||||
* Gets the parent composite for the child controls.
|
||||
* @return The child control's parent composite which may differ from the container's outer composite.
|
||||
*/
|
||||
public Composite getSwtParent();
|
||||
}//IDualLayerContainer//
|
||||
@@ -0,0 +1,742 @@
|
||||
/*
|
||||
* Copyright (c) 2003,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.tcv.swt.client;
|
||||
|
||||
import com.common.util.LiteList;
|
||||
import com.foundation.tcv.swt.*;
|
||||
import com.foundation.tcv.view.*;
|
||||
|
||||
public abstract class IndexedCollectionComponent extends CollectionComponent implements IIndexedCollectionComponent {
|
||||
/** The currently selected index (on the server) if allowing only a single selection. A negative one indicates no selection. */
|
||||
private int selectedObjectIdOnServer = -1;
|
||||
/** The custom selection last sent to the server or received by the server. This will be null if there is no custom selection or there is no selection at all. */
|
||||
private String customSelectionOnServer = null;
|
||||
/** Maps the row objects given the index in the control. An object can be represented more than once in the control if the same row object exists in multiple indices. */
|
||||
private LiteList rowObjectByIndexMap = new LiteList(100, 200);
|
||||
|
||||
protected static class IndexedRowObject extends RowObject {
|
||||
public Object value = null;
|
||||
|
||||
public IndexedRowObject(int objectId, int hiddenDataCount) {
|
||||
super(objectId, hiddenDataCount);
|
||||
}//IndexedRowObject()//
|
||||
}//IndexedRowObject//
|
||||
/**
|
||||
* IndexedCollectionComponent constructor.
|
||||
*/
|
||||
public IndexedCollectionComponent() {
|
||||
super();
|
||||
}//IndexedCollectionComponent()//
|
||||
/**
|
||||
* Gets the row object for the given display collection index.
|
||||
* @param index The zero based index of the row object in the display collection.
|
||||
* @return The row object for the display index.
|
||||
*/
|
||||
protected RowObject getRowObjectAtIndex(int index) {
|
||||
return (RowObject) rowObjectByIndexMap.get(index);
|
||||
}//getRowObjectAtIndex()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.view.IViewComponent#viewInitialize()
|
||||
*/
|
||||
protected void internalViewInitialize() {
|
||||
super.internalViewInitialize();
|
||||
}//internalViewInitialize()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.view.IViewComponent#viewRelease()
|
||||
*/
|
||||
protected void internalViewRelease() {
|
||||
super.internalViewRelease();
|
||||
}//internalViewRelease()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.view.IViewComponent#viewSynchronize()
|
||||
*/
|
||||
protected void internalViewSynchronize() {
|
||||
super.internalViewSynchronize();
|
||||
internalViewSynchronizeSelection();
|
||||
}//internalViewSynchronize()//
|
||||
/**
|
||||
* Synchronizes the selection or forces the auto synchronize task to run if one is pending.
|
||||
*/
|
||||
protected void internalViewSynchronizeSelection() {
|
||||
if(!getAutoSynchronizeSelection()) {
|
||||
synchronizeSelection();
|
||||
}//if//
|
||||
else {
|
||||
synchronized(this) {
|
||||
if(autoSynchronizeSelectionTask != null) {
|
||||
removeTask(autoSynchronizeSelectionTask);
|
||||
autoSynchronizeSelectionTask.execute();
|
||||
}//if//
|
||||
}//synchronized//
|
||||
}//else//
|
||||
}//internalViewSynchronizeSelection()//
|
||||
/**
|
||||
* Synchronizes the selection to the model from the view.
|
||||
* <p>This method has no logic to examine the auto synchronization state. It simply synchronizes the selection immediatly.</p>
|
||||
*/
|
||||
protected void synchronizeSelection() {
|
||||
if(getAllowMultiSelection()) {
|
||||
int[] selectionIndices = controlGetSelections();
|
||||
|
||||
//Convert each selection index into an object id.//
|
||||
for(int index = 0; index < selectionIndices.length; index++) {
|
||||
selectionIndices[index] = getRowObjectAtIndex(selectionIndices[index]).objectId;
|
||||
}//for//
|
||||
|
||||
if(selectionIndices.length == 0) {
|
||||
selectionIndices = null;
|
||||
}//if//
|
||||
|
||||
sendMessage(MESSAGE_VIEW_SYNCHRONIZE_SELECTION, (Object) selectionIndices);
|
||||
}//if//
|
||||
else if(hasCustomSelection()) {
|
||||
String text = controlGetText();
|
||||
|
||||
if(!text.equals(customSelectionOnServer)) {
|
||||
selectedObjectIdOnServer = -1;
|
||||
customSelectionOnServer = text;
|
||||
sendMessage(MESSAGE_VIEW_SYNCHRONIZE_SELECTION, text);
|
||||
}//if//
|
||||
}//else if//
|
||||
else {
|
||||
int selectionIndex = controlGetSelection();
|
||||
|
||||
//Convert from the index to the object identifier.//
|
||||
selectionIndex = selectionIndex != -1 ? getRowObjectAtIndex(selectionIndex).objectId : -1;
|
||||
|
||||
if(selectionIndex != selectedObjectIdOnServer) {
|
||||
selectedObjectIdOnServer = selectionIndex;
|
||||
customSelectionOnServer = null;
|
||||
sendMessage(MESSAGE_VIEW_SYNCHRONIZE_SELECTION, selectionIndex != -1 ? new Integer(selectionIndex) : null);
|
||||
}//if//
|
||||
}//else//
|
||||
}//synchronizeSelection()//
|
||||
/**
|
||||
* Gets the set of selected object identifiers.
|
||||
* @return The set of selected object identifiers, or null if nothing is selected.
|
||||
*/
|
||||
protected int[] getSelectedObjectIds() {
|
||||
int[] selectionIndices = controlGetSelections();
|
||||
|
||||
//Convert each selection index into an object id.//
|
||||
for(int index = 0; index < selectionIndices.length; index++) {
|
||||
selectionIndices[index] = getRowObjectAtIndex(selectionIndices[index]).objectId;
|
||||
}//for//
|
||||
|
||||
if(selectionIndices.length == 0) {
|
||||
selectionIndices = null;
|
||||
}//if//
|
||||
|
||||
return selectionIndices;
|
||||
//sendMessage(MESSAGE_VIEW_SYNCHRONIZE_SELECTION, (Object) selectionIndices);
|
||||
}//getSelectedObjectIds()//
|
||||
/**
|
||||
* Determines whether there is a custom selection.
|
||||
* @return Whether the user has typed a value in the control that is not in the set to select from.
|
||||
*/
|
||||
protected boolean hasCustomSelection() {
|
||||
return getAllowUserItems() && (controlGetSelection() == -1) && (controlGetText() != null) && (controlGetText().length() > 0);
|
||||
}//hasCustomSelection()//
|
||||
/**
|
||||
* Gets the set of selected object identifiers.
|
||||
* @return The set of selected object identifiers, or null if nothing is selected.
|
||||
*/
|
||||
protected int getSelectedObjectId() {
|
||||
int selectionIndex = controlGetSelection();
|
||||
/*
|
||||
if((getAllowUserItems()) && (selectionIndex == -1)) {
|
||||
//TODO: Track whether the text has changed?
|
||||
//sendMessage(MESSAGE_VIEW_SYNCHRONIZE_SELECTION, controlGetText());
|
||||
currentlySelectedObjectId = -2;
|
||||
}//if//
|
||||
else {
|
||||
|
||||
//sendMessage(MESSAGE_VIEW_SYNCHRONIZE_SELECTION, selectionIndex != -1 ? new Integer(selectionIndex) : null);
|
||||
}//else//
|
||||
*/
|
||||
return selectionIndex != -1 ? getRowObjectAtIndex(selectionIndex).objectId : -1;
|
||||
}//getSelectedObjectId()//
|
||||
/**
|
||||
* Gets the currently selected object identifier on the server.
|
||||
* @return The object identifier for the selection known by the server, or -1 for no selection.
|
||||
*/
|
||||
protected int getSelectedObjectIdOnServer() {
|
||||
return selectedObjectIdOnServer;
|
||||
}//getSelectedObjectIdOnServer()//
|
||||
/**
|
||||
* Sets the currently selected object identifier on the server.
|
||||
* @param objectId The object identifier for the selection known by the server, or -1 for no selection.
|
||||
*/
|
||||
protected void setSelectedObjectIdOnServer(int objectId) {
|
||||
this.selectedObjectIdOnServer = objectId;
|
||||
}//setSelectedObjectIdOnServer()//
|
||||
/**
|
||||
* Gets the current custom selection text on the server.
|
||||
* @return The selection text, or null if there isn't a custom selection.
|
||||
*/
|
||||
protected String getCustomSelectionOnServer() {
|
||||
return customSelectionOnServer;
|
||||
}//getCustomSelectionOnServer()//
|
||||
/**
|
||||
* Sets the current custom selection text on the server.
|
||||
* @param customSelection The selection text, or null if there isn't a custom selection.
|
||||
*/
|
||||
protected void setCustomSelectionOnServer(String customSelection) {
|
||||
this.customSelectionOnServer = customSelection;
|
||||
}//setCustomSelectionOnServer()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.CollectionComponent#updateSelectionLinks()
|
||||
*/
|
||||
protected void updateSelectionLinks() {
|
||||
super.updateSelectionLinks();
|
||||
|
||||
if(getHiddenDataCount() > 0) {
|
||||
if(getAllowMultiSelection()) {
|
||||
int[] selectedIndices = controlGetSelections();
|
||||
RowObject[] selectedObjects = selectedIndices != null && selectedIndices.length > 0 ? new RowObject[selectedIndices.length] : null;
|
||||
|
||||
if(selectedObjects != null) {
|
||||
//Collect the selected values.//
|
||||
for(int selectionIndex = 0; selectionIndex < selectedIndices.length; selectionIndex++) {
|
||||
selectedObjects[selectionIndex] = getRowObjectAtIndex(selectedIndices[selectionIndex]);
|
||||
}//for//
|
||||
}//if//
|
||||
|
||||
//Update the hidden data linkages.//
|
||||
for(int hiddenDataIndex = 0; hiddenDataIndex < getHiddenDataCount(); hiddenDataIndex++) {
|
||||
getHiddenData(hiddenDataIndex).invokeLinkage(selectedObjects);
|
||||
}//for//
|
||||
}//if//
|
||||
else {
|
||||
int selectedIndex = controlGetSelection();
|
||||
RowObject selectedObject = selectedIndex != -1 ? getRowObjectAtIndex(selectedIndex) : null;
|
||||
|
||||
//Update the hidden data linkages.//
|
||||
for(int hiddenDataIndex = 0; hiddenDataIndex < getHiddenDataCount(); hiddenDataIndex++) {
|
||||
getHiddenData(hiddenDataIndex).invokeLinkage(selectedObject);
|
||||
}//for//
|
||||
}//else//
|
||||
}//if//
|
||||
}//updateSelectionLinks()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.CollectionComponent#createRowObject(int)
|
||||
*/
|
||||
protected RowObject createRowObject(int objectId) {
|
||||
return new IndexedRowObject(objectId, getHiddenDataCount());
|
||||
}//createRowObject()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.AbstractComponent#internalProcessMessage(com.foundation.tcv.model.ViewMessage)
|
||||
*/
|
||||
public Object internalProcessMessage(ViewMessage viewMessage) {
|
||||
Object retVal = null;
|
||||
|
||||
switch(viewMessage.getMessageNumber()) {
|
||||
// case MESSAGE_SET_ITEMS: { //A string array and an int array. The int array is the object ID's.//
|
||||
// Object[] data = (Object[]) viewMessage.getMessageData();
|
||||
//
|
||||
// if(data == null) {
|
||||
// controlRemoveAll();
|
||||
// removeRowObjects();
|
||||
// rowObjectByIndexMap.removeAll();
|
||||
// forceSelectionEvent();
|
||||
// }//if//
|
||||
// else {
|
||||
// Object[] items = (Object[]) data[0];
|
||||
// int[] objectIds = (int[]) data[1];
|
||||
// Object[] hiddenData = (Object[]) data[2];
|
||||
//
|
||||
// if(((items == null) && (objectIds != null)) || ((items != null) && (objectIds == null)) || ((items != null) && (items.length != objectIds.length))) {
|
||||
// Debug.log("Error: Invalid parameters.");
|
||||
// }//if//
|
||||
//
|
||||
// //Remove all the mappings.//
|
||||
// removeRowObjects();
|
||||
// rowObjectByIndexMap.removeAll();
|
||||
//
|
||||
// if(objectIds != null) {
|
||||
// //Initialize the mappings between indexes and object IDs.//
|
||||
// for(int index = 0; index < objectIds.length; index++) {
|
||||
// IndexedRowObject rowObject = (IndexedRowObject) getRowObject(objectIds[index]);
|
||||
//
|
||||
// //Create a row object or increment its reference count.//
|
||||
// if(rowObject == null) {
|
||||
// rowObject = (IndexedRowObject) createRowObject(objectIds[index]);
|
||||
// rowObject.value = items[index];
|
||||
//
|
||||
// if(rowObject.hiddenData != null && hiddenData != null && hiddenData[index] instanceof Object[]) {
|
||||
// //Copy the hidden data to the row object.//
|
||||
// System.arraycopy(hiddenData[index], 0, rowObject.hiddenData, 0, rowObject.hiddenData.length);
|
||||
// }//if//
|
||||
// }//if//
|
||||
// else {
|
||||
// rowObject.referenceCount++;
|
||||
// items[index] = rowObject.value;
|
||||
// }//else//
|
||||
//
|
||||
// addRowObject(rowObject);
|
||||
// rowObjectByIndexMap.add(rowObject);
|
||||
// }//for//
|
||||
// }//if//
|
||||
//
|
||||
// //Set the items in the control.//
|
||||
// controlSetItems(items);
|
||||
// }//else//
|
||||
// break;
|
||||
// }//case//
|
||||
case MESSAGE_ADD_ITEM: { //Sends item data and object ID and an optional index.//
|
||||
Object itemData = viewMessage.getMessageData();
|
||||
Object[] hiddenData = (Object[]) viewMessage.getMessageSecondaryData();
|
||||
int objectId = viewMessage.getMessageInteger();
|
||||
IndexedRowObject rowObject = (IndexedRowObject) getRowObject(objectId);
|
||||
|
||||
//Create a row object or increment its reference count.//
|
||||
if(rowObject == null) {
|
||||
rowObject = (IndexedRowObject) createRowObject(objectId);
|
||||
rowObject.value = itemData;
|
||||
|
||||
if(hiddenData != null && rowObject.hiddenData != null) {
|
||||
//Copy the hidden data to the row object.//
|
||||
System.arraycopy(hiddenData, 0, rowObject.hiddenData, 0, rowObject.hiddenData.length);
|
||||
}//if//.
|
||||
}//if//
|
||||
else {
|
||||
rowObject.referenceCount++;
|
||||
itemData = rowObject.value;
|
||||
}//else//
|
||||
|
||||
//If an index was provided then place the item at the requested index.//
|
||||
if(viewMessage.getMessageSecondaryInteger() != -1) {
|
||||
int index = viewMessage.getMessageSecondaryInteger();
|
||||
|
||||
//A little error checking just in case.//
|
||||
if(index > rowObjectByIndexMap.getSize()) {
|
||||
index = rowObjectByIndexMap.getSize();
|
||||
}//if//
|
||||
|
||||
//Add the new value to the control.//
|
||||
controlAddItem(itemData, index);
|
||||
//Update the mappings.//
|
||||
rowObjectByIndexMap.add(index, rowObject);
|
||||
}//if//
|
||||
else {
|
||||
//Add the new value to the control.//
|
||||
controlAddItem(itemData);
|
||||
//Update the mappings.//
|
||||
rowObjectByIndexMap.add(rowObject);
|
||||
}//else//
|
||||
|
||||
//Update the mappings.//
|
||||
addRowObject(rowObject);
|
||||
break;
|
||||
}//case//
|
||||
case MESSAGE_REMOVE_ITEM: { //Note: Since removals are most often of selected items we will first try removing selected objects with the same object id.//
|
||||
int objectId = viewMessage.getMessageInteger();
|
||||
|
||||
//Handle multi-selection capable controls differently since single selection controls may not implement the controlGetSelections method.//
|
||||
if(getAllowMultiSelection()) {
|
||||
int[] selectedIndices = controlGetSelections();
|
||||
boolean isRemoved = false;
|
||||
|
||||
//First pass, remove from only selected items. (Most removals are selected.)//
|
||||
for(int index = selectedIndices.length - 1; ((!isRemoved) && (index >= 0)); index--) {
|
||||
if(getRowObjectAtIndex(selectedIndices[index]).objectId == objectId) {
|
||||
IndexedRowObject rowObject;
|
||||
|
||||
//TODO: Is this really necessary?//
|
||||
controlRemoveSelection(selectedIndices[index]);
|
||||
//Remove the item from the collection.//
|
||||
controlRemoveItem(selectedIndices[index]);
|
||||
//Remove the item from the mappings.//
|
||||
rowObject = (IndexedRowObject) rowObjectByIndexMap.remove(selectedIndices[index]);
|
||||
|
||||
//Remove the row object from the object id map if it is no longer referenced.//
|
||||
if(--rowObject.referenceCount == 0) {
|
||||
removeRowObject(rowObject.objectId);
|
||||
}//if//
|
||||
|
||||
isRemoved = true;
|
||||
}//if//
|
||||
}//for//
|
||||
|
||||
//Second pass, remove from all items.//
|
||||
for(int index = rowObjectByIndexMap.getSize() - 1; ((!isRemoved) && (index >= 0)); index--) {
|
||||
if(getRowObjectAtIndex(index).objectId == objectId) {
|
||||
IndexedRowObject rowObject;
|
||||
|
||||
//Remove the item from the collection.//
|
||||
controlRemoveItem(index);
|
||||
//Remove the item from the mappings.//
|
||||
rowObject = (IndexedRowObject) rowObjectByIndexMap.remove(index);
|
||||
|
||||
//Remove the row object from the object id map if it is no longer referenced.//
|
||||
if(--rowObject.referenceCount == 0) {
|
||||
removeRowObject(rowObject.objectId);
|
||||
}//if//
|
||||
|
||||
isRemoved = true;
|
||||
}//if//
|
||||
}//for//
|
||||
|
||||
if(!isRemoved) {
|
||||
//TODO: Unable to remove the value! Should we notify the server?//
|
||||
}//if//
|
||||
}//if//
|
||||
else {
|
||||
int selectedIndex = controlGetSelection();
|
||||
|
||||
if((selectedIndex != -1) && (getRowObjectAtIndex(selectedIndex).objectId == objectId)) {
|
||||
IndexedRowObject rowObject;
|
||||
|
||||
//TODO: Is this really necessary?//
|
||||
controlRemoveSelection(selectedIndex);
|
||||
//Remove the item from the collection.//
|
||||
controlRemoveItem(selectedIndex);
|
||||
//Remove the item from the mappings.//
|
||||
rowObject = (IndexedRowObject) rowObjectByIndexMap.remove(selectedIndex);
|
||||
|
||||
//Remove the row object from the object id map if it is no longer referenced.//
|
||||
if(--rowObject.referenceCount == 0) {
|
||||
removeRowObject(rowObject.objectId);
|
||||
}//if//
|
||||
}//if//
|
||||
else {
|
||||
//Second pass, remove from all items.//
|
||||
for(int index = rowObjectByIndexMap.getSize() - 1; index >= 0; index--) {
|
||||
if(getRowObjectAtIndex(index).objectId == objectId) {
|
||||
IndexedRowObject rowObject;
|
||||
|
||||
//Remove the item from the collection.//
|
||||
controlRemoveItem(index);
|
||||
//Remove the item from the mappings.//
|
||||
rowObject = (IndexedRowObject) rowObjectByIndexMap.remove(index);
|
||||
|
||||
//Remove the row object from the object id map if it is no longer referenced.//
|
||||
if(--rowObject.referenceCount == 0) {
|
||||
removeRowObject(rowObject.objectId);
|
||||
}//if//
|
||||
|
||||
break;
|
||||
}//if//
|
||||
}//for//
|
||||
}//else//
|
||||
}//else//
|
||||
break;
|
||||
}//case//
|
||||
case MESSAGE_REMOVE_ALL: {
|
||||
controlRemoveAll();
|
||||
removeRowObjects();
|
||||
rowObjectByIndexMap.removeAll();
|
||||
//This should not be necessary since the server should send a selection event immediatly following the remove all.//
|
||||
//forceSelectionEvent();
|
||||
break;
|
||||
}//case//
|
||||
case MESSAGE_SET_ITEM: {
|
||||
Object[] data = (Object[]) viewMessage.getMessageData();
|
||||
int objectId = ((Integer) data[0]).intValue();
|
||||
Object itemData = data[1];
|
||||
IndexedRowObject rowObject = (IndexedRowObject) getRowObject(objectId);
|
||||
|
||||
//Set the row object's value.//
|
||||
rowObject.value = itemData;
|
||||
|
||||
//Find all instances of the object and apply the new display data.//
|
||||
for(int index = 0; index < rowObjectByIndexMap.getSize(); index++) {
|
||||
if(getRowObjectAtIndex(index) == rowObject) {
|
||||
//TODO: Do we need to do anything to preserve the selection?
|
||||
controlSetItem(index, itemData);
|
||||
}//if//
|
||||
}//for//
|
||||
break;
|
||||
}//case//
|
||||
case MESSAGE_SET_SELECTION: {
|
||||
Object messageData = viewMessage.getMessageData();
|
||||
|
||||
if(messageData instanceof int[]) {
|
||||
int[] selectionObjectIds = (int[]) messageData;
|
||||
|
||||
//For non-multi-selection collections, set the currently selected id.//
|
||||
if(!getAllowMultiSelection()) {
|
||||
if((selectionObjectIds != null) && (selectionObjectIds.length > 1)) {
|
||||
selectedObjectIdOnServer = -1;
|
||||
//Error: Invalid message value!//
|
||||
throw new RuntimeException("Error: Invalid message parameter! MESSAGE_SET_SELECTION");
|
||||
}//if//
|
||||
else {
|
||||
selectedObjectIdOnServer = ((selectionObjectIds == null) || (selectionObjectIds.length == 0)) ? -1 : selectionObjectIds[0];
|
||||
}//else//
|
||||
|
||||
if(selectedObjectIdOnServer != -1) {
|
||||
boolean found = false;
|
||||
int controlSelection = controlGetSelection();
|
||||
|
||||
if((controlSelection == -1) || (getRowObjectAtIndex(controlSelection).objectId != selectedObjectIdOnServer)) {
|
||||
//Locate an entry matching the selection.//
|
||||
for(int index = rowObjectByIndexMap.getSize() - 1; (!found) && (index >= 0); index--) {
|
||||
if(getRowObjectAtIndex(index).objectId == selectedObjectIdOnServer) {
|
||||
controlSetSelection(index);
|
||||
found = true;
|
||||
}//if//
|
||||
}//for//
|
||||
|
||||
if(!found) {
|
||||
//Error: Could not find an object matching the server's description!//
|
||||
//TODO: Should we tell the server to deselect the value?
|
||||
}//if//
|
||||
}//if//
|
||||
}//if//
|
||||
else {
|
||||
controlSetSelection(-1);
|
||||
}//else//
|
||||
}//if//
|
||||
else { //Allow multiple selections.//
|
||||
if((selectionObjectIds == null) || (selectionObjectIds.length == 0)) {
|
||||
//Clear all selections.//
|
||||
controlSetSelection(-1);
|
||||
}//if//
|
||||
else {
|
||||
//TODO: Creating an array of flags the size of the entire collection seems inefficient. Perhaps we can make this more efficient.//
|
||||
boolean[] selectionFlags = new boolean[rowObjectByIndexMap.getSize()];
|
||||
|
||||
//Initialize the bit field.//
|
||||
for(int index = 0; index < selectionFlags.length; index++) {
|
||||
selectionFlags[index] = false;
|
||||
}//for//
|
||||
|
||||
//Apply all selections.//
|
||||
for(int selectionIndex = 0; selectionIndex < selectionObjectIds.length; selectionIndex++) {
|
||||
boolean hasSelected = false;
|
||||
|
||||
//Since an object can occur multiple times in the control we will the one already selected.//
|
||||
for(int index = 0; (!hasSelected) && (index < selectionFlags.length); index++) {
|
||||
if((!selectionFlags[index]) && (getRowObjectAtIndex(index).objectId == selectionObjectIds[selectionIndex]) && (controlIsSelected(index))) {
|
||||
hasSelected = true;
|
||||
selectionObjectIds[selectionIndex] = index;
|
||||
}//if//
|
||||
}//for//
|
||||
|
||||
//TODO: Looping twice sucks... we could combine the loops with a little extra code.//
|
||||
//If an object was not already selected then pick the first one in the control.//
|
||||
for(int index = 0; (!hasSelected) && (index < selectionFlags.length); index++) {
|
||||
if((!selectionFlags[index]) && (getRowObjectAtIndex(index).objectId == selectionObjectIds[selectionIndex]) && (!controlIsSelected(index))) {
|
||||
hasSelected = true;
|
||||
selectionObjectIds[selectionIndex] = index;
|
||||
}//if//
|
||||
}//for//
|
||||
|
||||
//We were not able to apply the selection since there were not enough instances of the object in the control.//
|
||||
if(!hasSelected) {
|
||||
int[] temp = new int[selectionObjectIds.length];
|
||||
|
||||
//Fix the array of selections since it now has one too many positions.//
|
||||
System.arraycopy(selectionObjectIds, 0, temp, 0, selectionIndex - 1);
|
||||
System.arraycopy(selectionObjectIds, selectionIndex - 1, temp, selectionIndex - 1, selectionObjectIds.length - selectionIndex);
|
||||
selectionObjectIds = temp;
|
||||
|
||||
//TODO: Should we notify the server that the selection is not possible? We could simply remove the selection.//
|
||||
}//if//
|
||||
}//for//
|
||||
|
||||
controlSetSelections(selectionObjectIds);
|
||||
}//else//
|
||||
}//else//
|
||||
|
||||
//Update the linkages that connect to the selection.//
|
||||
updateSelectionLinks();
|
||||
}//if//
|
||||
else {
|
||||
String selectionText = (String) messageData;
|
||||
|
||||
controlSetSelection(selectionText);
|
||||
selectedObjectIdOnServer = -1;
|
||||
customSelectionOnServer = selectionText;
|
||||
}//else//
|
||||
break;
|
||||
}//case//
|
||||
case MESSAGE_ADD_SELECTION: {
|
||||
int[] selectionObjectIds = (int[]) viewMessage.getMessageData();
|
||||
|
||||
//For each additional selection, find the first non-selected item with the given object id and select it.//
|
||||
for(int selectionIndex = 0; selectionIndex < selectionObjectIds.length; selectionIndex++) {
|
||||
boolean hasSelected = false;
|
||||
|
||||
for(int index = 0; (!hasSelected) && (index < rowObjectByIndexMap.getSize()); index++) {
|
||||
if((getRowObjectAtIndex(index).objectId == selectionObjectIds[selectionIndex]) && (!controlIsSelected(index))) {
|
||||
hasSelected = true;
|
||||
controlAddSelection(index);
|
||||
}//if//
|
||||
}//for//
|
||||
|
||||
if(!hasSelected) {
|
||||
//TODO: Should we notify the server that the selection is not possible? We could simply remove the selection.//
|
||||
}//if//
|
||||
}//for//
|
||||
break;
|
||||
}//case//
|
||||
case MESSAGE_REMOVE_SELECTION: {
|
||||
int[] selectionObjectIds = (int[]) viewMessage.getMessageData();
|
||||
|
||||
//For each additional selection, find the first non-selected item with the given object id and select it.//
|
||||
for(int selectionIndex = 0; selectionIndex < selectionObjectIds.length; selectionIndex++) {
|
||||
boolean hasDeselected = false;
|
||||
|
||||
for(int index = rowObjectByIndexMap.getSize(); (!hasDeselected) && (index >= 0); index--) {
|
||||
if((getRowObjectAtIndex(index).objectId == selectionObjectIds[selectionIndex]) && (controlIsSelected(index))) {
|
||||
hasDeselected = true;
|
||||
controlRemoveSelection(index);
|
||||
}//if//
|
||||
}//for//
|
||||
|
||||
if(!hasDeselected) {
|
||||
//I don't think any action is necessary, though this should not occur.//
|
||||
}//if//
|
||||
}//for//
|
||||
break;
|
||||
}//case//
|
||||
case MESSAGE_REMOVE_SELECTIONS: {
|
||||
selectedObjectIdOnServer = -1;
|
||||
controlRemoveAllSelections();
|
||||
break;
|
||||
}//case//
|
||||
default: {
|
||||
retVal = super.internalProcessMessage(viewMessage);
|
||||
}//default//
|
||||
}//switch//
|
||||
|
||||
return retVal;
|
||||
}//internalProcessMessage()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.CollectionComponent#updateHiddenData(com.foundation.tcv.swt.client.CollectionComponent.RowObject, int, java.lang.Object)
|
||||
*/
|
||||
protected void updateHiddenData(RowObject object, int hiddenDataIndex, Object value) {
|
||||
object.hiddenData[hiddenDataIndex] = value;
|
||||
|
||||
if(getAllowMultiSelection()) {
|
||||
boolean updateSelectionLinks = false;
|
||||
int[] selectedIndices = controlGetSelections();
|
||||
RowObject[] selectedObjects = new RowObject[selectedIndices.length];
|
||||
|
||||
if((selectedIndices != null) && (selectedIndices.length > 0)) {
|
||||
//Determine whether any of the selections match with the hidden data's object to see whether we need to update any hidden data linkages.//
|
||||
for(int selectionIndex = 0; (!updateSelectionLinks) && (selectionIndex < selectedIndices.length); selectionIndex++) {
|
||||
RowObject selection = getRowObjectAtIndex(selectedIndices[selectionIndex]);
|
||||
|
||||
updateSelectionLinks = selection == object;
|
||||
selectedObjects[selectionIndex] = selection;
|
||||
}//for//
|
||||
}//if//
|
||||
|
||||
if(updateSelectionLinks) {
|
||||
getHiddenData(hiddenDataIndex).invokeLinkage(selectedObjects);
|
||||
}//if//
|
||||
}//if//
|
||||
else {
|
||||
int selectedIndex = controlGetSelection();
|
||||
|
||||
if(selectedIndex != -1) {
|
||||
RowObject selectedObject = getRowObjectAtIndex(selectedIndex);
|
||||
|
||||
if(selectedObject == object) {
|
||||
getHiddenData(hiddenDataIndex).invokeLinkage(selectedObject);
|
||||
}//if//
|
||||
}//if//
|
||||
}//else//
|
||||
}//updateHiddenData()//
|
||||
/**
|
||||
* Removes all displayed items from the control.
|
||||
*/
|
||||
protected abstract void controlRemoveAll(); //removeAll//
|
||||
/**
|
||||
* Sets the control's displayed collection values ordered by index.
|
||||
* @param items The indexed values displayed by the control.
|
||||
*/
|
||||
protected abstract void controlSetItems(Object[] items); //setItems//
|
||||
/**
|
||||
* Sets an item in the control's collection display.
|
||||
* @param index The index at which the item should be set.
|
||||
* @param itemData The value displayed by the control.
|
||||
*/
|
||||
protected abstract void controlSetItem(int index, Object itemData); //setItem//
|
||||
/**
|
||||
* Adds an item to the control's collection at a given index.
|
||||
* @param itemData The value displayed by the control.
|
||||
* @param index The index at which the item should be added.
|
||||
*/
|
||||
protected abstract void controlAddItem(Object itemData, int index); //add//
|
||||
/**
|
||||
* Adds an item to the control's collection at the end.
|
||||
* @param itemData The value displayed by the control.
|
||||
*/
|
||||
protected abstract void controlAddItem(Object itemData); //add//
|
||||
/**
|
||||
* Removes an item from the control's collection display.
|
||||
* @param index The index of the item to be removed.
|
||||
*/
|
||||
protected abstract void controlRemoveItem(int index); //remove//
|
||||
/**
|
||||
* Gets the indices selected within the control.
|
||||
* @return The collection of indices selected.
|
||||
*/
|
||||
protected abstract int[] controlGetSelections(); //getSelectionIndices//
|
||||
/**
|
||||
* Gets the index selected within the control.
|
||||
* @return The index currently selected.
|
||||
*/
|
||||
protected abstract int controlGetSelection(); //getSelectionIndex//
|
||||
/**
|
||||
* Sets the selected values in the control.
|
||||
* @param indices The indices of the selected values.
|
||||
*/
|
||||
protected abstract void controlSetSelections(int[] indices); //setSelection//
|
||||
/**
|
||||
* Sets the selected value in the control.
|
||||
* <p>Note: Not all controls support custom selected text. Currently only combo box does. </p>
|
||||
* @param text The text of the selected value.
|
||||
*/
|
||||
protected abstract void controlSetSelection(String text); //setSelection//
|
||||
/**
|
||||
* Sets the selected value in the control.
|
||||
* @param index The index of the selected value.
|
||||
*/
|
||||
protected abstract void controlSetSelection(int index); //setSelection//
|
||||
/**
|
||||
* Adds a selected value in the control.
|
||||
* @param index The index of the selected value.
|
||||
*/
|
||||
protected abstract void controlAddSelection(int index); //select//
|
||||
/**
|
||||
* Deselects a value in the control.
|
||||
* @param index The index of the selected value.
|
||||
*/
|
||||
protected abstract void controlRemoveSelection(int index); //deselect//
|
||||
/**
|
||||
* Deselects all values in the control.
|
||||
*/
|
||||
protected abstract void controlRemoveAllSelections(); //deselectAll//
|
||||
/**
|
||||
* Checks to see if a value is selected.
|
||||
* @param index The index of the checked value.
|
||||
* @return Whether the value is currently selected.
|
||||
*/
|
||||
protected abstract boolean controlIsSelected(int index); //isSelected//
|
||||
/**
|
||||
* Gets the current text for the control.
|
||||
* <p>Some controls such as comboboxes have a text which may not be one of the listed items.</p>
|
||||
* @return The control's current text.
|
||||
*/
|
||||
protected abstract String controlGetText(); //getText//
|
||||
/**
|
||||
* Sets the current text for the control.
|
||||
* <p>Some controls such as comboboxes have a text which may not be one of the listed items.</p>
|
||||
* @param text The control's new text.
|
||||
*/
|
||||
protected abstract void controlSetText(String text); //setText//
|
||||
/**
|
||||
* Forces the selection event handler to be called.
|
||||
*/
|
||||
protected abstract void forceSelectionEvent(); //Should call widgetSelected implemented by the subclass. This name may need to change.//
|
||||
}//IndexedCollectionComponent//
|
||||
@@ -0,0 +1,112 @@
|
||||
/*
|
||||
* Copyright (c) 2003,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.tcv.swt.client;
|
||||
|
||||
import com.foundation.tcv.client.view.ResourceHolder;
|
||||
import com.foundation.tcv.swt.*;
|
||||
import com.foundation.tcv.view.*;
|
||||
import com.foundation.view.JefImage;
|
||||
|
||||
public class Label extends Component implements ILabel {
|
||||
/** 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);
|
||||
/**
|
||||
* Label constructor.
|
||||
*/
|
||||
public Label() {
|
||||
}//Label()//
|
||||
/**
|
||||
* Gets the SWT label that represents this button.
|
||||
* @return The SWT label providing visualization for this button.
|
||||
*/
|
||||
public org.eclipse.swt.widgets.Label getSwtLabel() {
|
||||
return (org.eclipse.swt.widgets.Label) getSwtWidget();
|
||||
}//getSwtLabel()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.AbstractComponent#internalViewInitialize()
|
||||
*/
|
||||
protected void internalViewInitialize() {
|
||||
super.internalViewInitialize();
|
||||
}//internalViewInitialize()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.AbstractComponent#internalViewRelease()
|
||||
*/
|
||||
protected void internalViewRelease() {
|
||||
destroyImage((JefImage) imageHolder.getValue());
|
||||
textHolder.release();
|
||||
imageHolder.release();
|
||||
super.internalViewRelease();
|
||||
}//internalViewRelease()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.AbstractComponent#internalViewSynchronize()
|
||||
*/
|
||||
protected void internalViewSynchronize() {
|
||||
super.internalViewSynchronize();
|
||||
}//internalViewSynchronize()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.AbstractComponent#internalResourceHolderChanged(com.foundation.tcv.client.view.ResourceHolder, java.lang.Object, java.lang.Object, int)
|
||||
*/
|
||||
protected void internalResourceHolderChanged(ResourceHolder resource, Object oldValue, Object newValue, int flags) {
|
||||
if(resource == textHolder) {
|
||||
getSwtLabel().setText(newValue != null ? (String) newValue : "");
|
||||
resize();
|
||||
}//if//
|
||||
else if(resource == imageHolder) {
|
||||
destroyImage(getSwtLabel().getImage());
|
||||
|
||||
getSwtLabel().setImage(createImage((JefImage) newValue));
|
||||
resize();
|
||||
}//else if//
|
||||
else {
|
||||
super.internalResourceHolderChanged(resource, oldValue, newValue, flags);
|
||||
}//else//
|
||||
}//internalOnAssociationChanged()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.AbstractComponent#internalProcessMessage(com.foundation.tcv.model.ViewMessage)
|
||||
*/
|
||||
public Object internalProcessMessage(ViewMessage viewMessage) {
|
||||
Object retVal = null;
|
||||
|
||||
switch(viewMessage.getMessageNumber()) {
|
||||
case MESSAGE_INITIALIZE: {
|
||||
if(getSwtControl() == null) {
|
||||
int[] data = (int[]) viewMessage.getMessageData();
|
||||
int style = data[1];
|
||||
|
||||
//Link to the parent container.//
|
||||
setContainer((Container) getComponent(data[0]));
|
||||
getContainer().addComponent(this);
|
||||
//Create the SWT widget.//
|
||||
setSwtWidget(new org.eclipse.swt.widgets.Label(getContainer().getSwtParent(), style));
|
||||
getSwtWidget().setData(this);
|
||||
|
||||
//If the container has already been initialized then force the parent to re-layout so that this component will appear.//
|
||||
if(getContainer().isInitialized()) {
|
||||
getContainer().getSwtComposite().layout(true, true);
|
||||
}//if//
|
||||
}//if//
|
||||
break;
|
||||
}//case//
|
||||
case MESSAGE_SET_TEXT: {
|
||||
textHolder.setValue(viewMessage.getMessageData());
|
||||
break;
|
||||
}//case//
|
||||
case MESSAGE_SET_IMAGE: {
|
||||
imageHolder.setValue(viewMessage.getMessageData());
|
||||
break;
|
||||
}//case//
|
||||
default: {
|
||||
retVal = super.internalProcessMessage(viewMessage);
|
||||
}//default//
|
||||
}//switch//
|
||||
|
||||
return retVal;
|
||||
}//internalProcessMessage()//
|
||||
}//Label//
|
||||
@@ -0,0 +1,210 @@
|
||||
/*
|
||||
* Copyright (c) 2007,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.tcv.swt.client;
|
||||
|
||||
import org.eclipse.swt.widgets.Composite;
|
||||
|
||||
import com.common.debug.Debug;
|
||||
import com.common.util.IHashSet;
|
||||
import com.common.util.IIterator;
|
||||
import com.foundation.tcv.client.controller.SessionViewController;
|
||||
import com.foundation.tcv.client.view.IAbstractClientViewComponent;
|
||||
import com.foundation.tcv.swt.ILayout;
|
||||
import com.foundation.tcv.view.ViewMessage;
|
||||
import com.foundation.view.AbstractMultiResourceHolder;
|
||||
import com.foundation.view.AbstractResourceHolder;
|
||||
import com.foundation.view.resource.AbstractResourceService;
|
||||
|
||||
public abstract class Layout implements ILayout, IAbstractClientViewComponent {
|
||||
/** The container that uses this layout. Only one of the container or cellContainer will be provided. */
|
||||
private IAbstractSwtContainer container = null;
|
||||
/** The cell container that uses this layout. */
|
||||
private ICellContainer cellContainer = null;
|
||||
/** The controller for this view session. */
|
||||
private SessionViewController sessionViewController = null;
|
||||
/** The component number assigned to this instance. */
|
||||
private int number = -1;
|
||||
|
||||
/**
|
||||
* A handler that is called to apply a set of changes to one or more layout.
|
||||
*/
|
||||
public interface IChangeHandler {
|
||||
/**
|
||||
* Applies the changes to the layout.
|
||||
* @param layout The layout to apply the changes to.
|
||||
*/
|
||||
public void applyChanges(org.eclipse.swt.widgets.Layout layout);
|
||||
}//IChangeHandler//
|
||||
/**
|
||||
* Layout constructor.
|
||||
*/
|
||||
public Layout() {
|
||||
}//Layout()//
|
||||
/**
|
||||
* Initializes the layout.
|
||||
*/
|
||||
public abstract void initialize();
|
||||
/**
|
||||
* Synchronizes the layout by transfering data from the view to the model.
|
||||
*/
|
||||
public abstract void synchronize();
|
||||
/**
|
||||
* Releases the layout.
|
||||
*/
|
||||
public abstract void release();
|
||||
/**
|
||||
* Creates a layout that is used by an SWT control.
|
||||
* @param rowObject The optional row object that the layout is associated with. This should be provided if the cellComponent is specified, otherwise it should be null.
|
||||
* @return The SWT layout.
|
||||
*/
|
||||
public abstract org.eclipse.swt.widgets.Layout createLayout(Object rowObject);
|
||||
/**
|
||||
* Calls layout on the container.
|
||||
* @param rowObject The optional row object with which the container is associated.
|
||||
* @param changed If the container's cache should be flushed.
|
||||
* @param all If all the children also require laying out.
|
||||
*/
|
||||
protected void layoutContainer(RowObject rowObject, boolean changed, boolean all) {
|
||||
if(getCellContainer() != null) {
|
||||
if(rowObject != null) {
|
||||
getCellContainer().getSwtComposite(rowObject).layout(changed, all);
|
||||
}//if//
|
||||
else {
|
||||
IIterator iterator = getCellContainer().getSwtComposites();
|
||||
|
||||
while(iterator.hasNext()) {
|
||||
((Composite) iterator.next()).layout(changed, all);
|
||||
}//while//
|
||||
}//else//
|
||||
}//if//
|
||||
else {
|
||||
getContainer().getSwtComposite().layout(changed, all);
|
||||
}//else//
|
||||
}//layoutContainer()//
|
||||
/**
|
||||
* Applies changes to the layout in the container.
|
||||
* @param rowObject The optional row object with which the container is associated.
|
||||
* @param handler The handler called to make the actual changes.
|
||||
*/
|
||||
protected void applyChanges(RowObject rowObject, IChangeHandler handler) {
|
||||
if(getCellContainer() != null) {
|
||||
if(rowObject != null) {
|
||||
handler.applyChanges(getCellContainer().getSwtComposite(rowObject).getLayout());
|
||||
}//if//
|
||||
else {
|
||||
IIterator iterator = getCellContainer().getSwtComposites();
|
||||
|
||||
while(iterator.hasNext()) {
|
||||
handler.applyChanges(((Composite) iterator.next()).getLayout());
|
||||
}//while//
|
||||
}//else//
|
||||
}//if//
|
||||
else {
|
||||
if(getContainer().getSwtComposite() != null && !getContainer().getSwtComposite().isDisposed()) {
|
||||
handler.applyChanges(getContainer().getSwtComposite().getLayout());
|
||||
}//if//
|
||||
}//else//
|
||||
}//applyChanges()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.client.view.IAbstractClientViewComponent#getSessionViewController()
|
||||
*/
|
||||
public SessionViewController getSessionViewController() {
|
||||
return sessionViewController;
|
||||
}//getSessionViewController()//
|
||||
/**
|
||||
* Gets the component in the same view given the component's view unique number.
|
||||
* @return The view component assigned the component number.
|
||||
*/
|
||||
protected AbstractComponent getComponent(int componentNumber) {
|
||||
return (AbstractComponent) getSessionViewController().getComponent(componentNumber);
|
||||
}//getComponent()//
|
||||
/**
|
||||
* Gets the unique number assigned to this view part.
|
||||
* @return The number identifying this view part on both the client and server.
|
||||
*/
|
||||
public int getNumber() {
|
||||
return number;
|
||||
}//getNumber()//
|
||||
/**
|
||||
* Gets the container using this layout.
|
||||
* @return The container that this layout supports.
|
||||
*/
|
||||
protected IAbstractSwtContainer getContainer() {
|
||||
return container;
|
||||
}//getContainer()//
|
||||
/**
|
||||
* Gets the cell container using this layout.
|
||||
* @return The cell container that this layout supports.
|
||||
*/
|
||||
protected ICellContainer getCellContainer() {
|
||||
return cellContainer;
|
||||
}//getCellContainer()//
|
||||
/**
|
||||
* Sets the container using this layout.
|
||||
* @param container The container that this layout supports.
|
||||
*/
|
||||
protected void setContainer(AbstractComponent container) {
|
||||
if(container instanceof IAbstractSwtContainer) {
|
||||
this.container = (IAbstractSwtContainer) container;
|
||||
this.container.setLayout(this);
|
||||
}//if//
|
||||
else {
|
||||
this.cellContainer = (ICellContainer) container;
|
||||
this.cellContainer.setLayout(this);
|
||||
}//else//
|
||||
}//setContainer()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.client.view.IAbstractClientViewComponent#initialize(int, com.foundation.tcv.client.controller.SessionViewController)
|
||||
*/
|
||||
public void initialize(int number, SessionViewController sessionViewController) {
|
||||
this.number = number;
|
||||
this.sessionViewController = sessionViewController;
|
||||
}//initialize()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.view.IAbstractRemoteViewComponent#processMessage(com.foundation.tcv.view.ViewMessage)
|
||||
*/
|
||||
public Object processMessage(ViewMessage viewMessage) {
|
||||
Object result = null;
|
||||
|
||||
switch(viewMessage.getMessageNumber()) {
|
||||
default: {
|
||||
Debug.log("Error: processMessage(ViewMessage) is not implemented.");
|
||||
break;
|
||||
}//default//
|
||||
}//switch//
|
||||
|
||||
return result;
|
||||
}//processMessage()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.view.IAbstractRemoteViewComponent#processRequest(int, java.lang.Object, java.lang.Object, java.lang.Object, java.lang.Object)
|
||||
*/
|
||||
public final Object processRequest(int eventNumber, Object value1, Object value2, Object value3, Object value4) {
|
||||
return null;
|
||||
}//processRequest()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.view.IResourceHolderComponent#getResourceService()
|
||||
*/
|
||||
public final AbstractResourceService getResourceService() {
|
||||
return null;
|
||||
}//getResourceService()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.view.IResourceHolderComponent#resourceHolderChanged(com.foundation.view.AbstractMultiResourceHolder, com.common.util.IHashSet, java.lang.Object, java.lang.Object)
|
||||
*/
|
||||
public final void resourceHolderChanged(AbstractMultiResourceHolder resourceHolder, IHashSet rows, Object oldValue, Object newValue) {
|
||||
}//resourceHolderChanged()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.view.IResourceHolderComponent#resourceHolderChanged(com.foundation.view.AbstractMultiResourceHolder, java.lang.Object, java.lang.Object, java.lang.Object)
|
||||
*/
|
||||
public final void resourceHolderChanged(AbstractMultiResourceHolder resourceHolder, Object row, Object oldValue, Object newValue) {
|
||||
}//resourceHolderChanged()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.view.IResourceHolderComponent#resourceHolderChanged(com.foundation.view.AbstractResourceHolder, java.lang.Object, java.lang.Object)
|
||||
*/
|
||||
public final void resourceHolderChanged(AbstractResourceHolder resourceHolder, Object oldValue, Object newValue, int flags) {
|
||||
}//resourceHolderChanged()//
|
||||
}//Layout//
|
||||
@@ -0,0 +1,98 @@
|
||||
/*
|
||||
* Copyright (c) 2005,2007 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.tcv.swt.client;
|
||||
|
||||
import org.eclipse.swt.events.SelectionEvent;
|
||||
import org.eclipse.swt.events.SelectionListener;
|
||||
|
||||
import com.common.debug.Debug;
|
||||
import com.foundation.tcv.swt.ILink;
|
||||
import com.foundation.tcv.view.ViewMessage;
|
||||
|
||||
public class Link extends Component implements ILink, SelectionListener {
|
||||
/**
|
||||
* Link constructor.
|
||||
*/
|
||||
public Link() {
|
||||
super();
|
||||
}//Link()//
|
||||
/**
|
||||
* Gets the SWT link that represents this link.
|
||||
* @return The SWT link providing visualization for this link.
|
||||
*/
|
||||
public org.eclipse.swt.widgets.Link getSwtLink() {
|
||||
return (org.eclipse.swt.widgets.Link) getSwtControl();
|
||||
}//getSwtLink()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.AbstractComponent#internalViewInitialize()
|
||||
*/
|
||||
protected void internalViewInitialize() {
|
||||
getSwtLink().addSelectionListener(this);
|
||||
super.internalViewInitialize();
|
||||
}//internalViewInitialize()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.AbstractComponent#internalViewRelease()
|
||||
*/
|
||||
protected void internalViewRelease() {
|
||||
if(getSwtLink() != null && !getSwtLink().isDisposed()) {
|
||||
getSwtLink().removeSelectionListener(this);
|
||||
}//if//
|
||||
|
||||
super.internalViewRelease();
|
||||
}//internalViewRelease()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.AbstractComponent#internalProcessMessage(com.foundation.tcv.model.ViewMessage)
|
||||
*/
|
||||
public Object internalProcessMessage(ViewMessage viewMessage) {
|
||||
Object retVal = null;
|
||||
|
||||
switch(viewMessage.getMessageNumber()) {
|
||||
case MESSAGE_INITIALIZE: {
|
||||
if(getSwtControl() == null) {
|
||||
int[] data = (int[]) viewMessage.getMessageData();
|
||||
int style = data[1];
|
||||
|
||||
//Link to the parent container.//
|
||||
setContainer((Container) getComponent(data[0]));
|
||||
getContainer().addComponent(this);
|
||||
//Create the SWT widget.//
|
||||
setSwtWidget(new org.eclipse.swt.widgets.Link(getContainer().getSwtParent(), style));
|
||||
getSwtWidget().setData(this);
|
||||
|
||||
//If the container has already been initialized then force the parent to re-layout so that this component will appear.//
|
||||
if(getContainer().isInitialized()) {
|
||||
getContainer().getSwtComposite().layout(true, true);
|
||||
}//if//
|
||||
}//if//
|
||||
break;
|
||||
}//case//
|
||||
case MESSAGE_SET_TEXT: {
|
||||
getSwtLink().setText((String) viewMessage.getMessageData());
|
||||
break;
|
||||
}//case//
|
||||
default: {
|
||||
retVal = super.internalProcessMessage(viewMessage);
|
||||
}//default//
|
||||
}//switch//
|
||||
|
||||
return retVal;
|
||||
}//internalProcessMessage()//
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.swt.events.SelectionListener#widgetDefaultSelected(org.eclipse.swt.events.SelectionEvent)
|
||||
*/
|
||||
public void widgetDefaultSelected(SelectionEvent e) {
|
||||
//TODO: When is this called?//
|
||||
Debug.log("Default Selected Called <Why?>");
|
||||
}//widgetDefaultSelected()//
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.swt.events.SelectionListener#widgetSelected(org.eclipse.swt.events.SelectionEvent)
|
||||
*/
|
||||
public void widgetSelected(SelectionEvent e) {
|
||||
sendRoundTripMessage(MESSAGE_VIEW_SYNCHRONIZE_SELECTION, null, null);
|
||||
}//widgetSelected()//
|
||||
}//Link//
|
||||
@@ -0,0 +1,334 @@
|
||||
/*
|
||||
* Copyright (c) 2003,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.tcv.swt.client;
|
||||
|
||||
import org.eclipse.swt.SWT;
|
||||
import org.eclipse.swt.events.*;
|
||||
|
||||
import com.common.thread.IRunnable;
|
||||
import com.foundation.tcv.swt.*;
|
||||
import com.foundation.tcv.swt.client.cell.CellComponent;
|
||||
import com.foundation.tcv.view.*;
|
||||
|
||||
public class ListBox extends IndexedCollectionComponent implements SelectionListener, IListBox {
|
||||
/**
|
||||
* ListBox constructor.
|
||||
*/
|
||||
public ListBox() {
|
||||
super();
|
||||
}//ListBox()//
|
||||
/**
|
||||
* Gets the SWT list that represents this list box.
|
||||
* @return The SWT list providing visualization for this list box.
|
||||
*/
|
||||
public org.eclipse.swt.widgets.List getSwtList() {
|
||||
return (org.eclipse.swt.widgets.List) getSwtWidget();
|
||||
}//getSwtList()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.view.IViewComponent#viewInitialize()
|
||||
*/
|
||||
protected void internalViewInitialize() {
|
||||
getSwtList().addSelectionListener(this);
|
||||
super.internalViewInitialize();
|
||||
}//internalViewInitialize()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.view.IViewComponent#viewRelease()
|
||||
*/
|
||||
protected void internalViewRelease() {
|
||||
if(getSwtList() != null && !getSwtList().isDisposed()) {
|
||||
getSwtList().removeSelectionListener(this);
|
||||
}//if//
|
||||
|
||||
super.internalViewRelease();
|
||||
}//internalViewRelease()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.AbstractComponent#internalViewSynchronize()
|
||||
*/
|
||||
protected void internalViewSynchronize() {
|
||||
super.internalViewSynchronize();
|
||||
//Synchronize the top visible item index.//
|
||||
sendMessage(MESSAGE_SYNCHRONIZE_TOP_INDEX, new Integer(getSwtList().getTopIndex()));
|
||||
}//internalViewSynchronize()//
|
||||
/* (non-Javadoc)
|
||||
* @see #getTopIndex()
|
||||
*/
|
||||
protected Integer internalGetTopIndex() {
|
||||
return new Integer(getSwtList().getTopIndex());
|
||||
}//internalGetTextLimit()//
|
||||
/* (non-Javadoc)
|
||||
* @see #setTopIndex(Integer)
|
||||
*/
|
||||
protected void internalSetTopIndex(Integer topIndex) {
|
||||
getSwtList().setTopIndex(topIndex.intValue());
|
||||
}//internalSetTopIndex()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.AbstractComponent#internalProcessMessage(com.foundation.tcv.model.ViewMessage)
|
||||
*/
|
||||
public Object internalProcessMessage(ViewMessage viewMessage) {
|
||||
Object retVal = null;
|
||||
|
||||
switch(viewMessage.getMessageNumber()) {
|
||||
case MESSAGE_INITIALIZE: {
|
||||
if(getSwtControl() == null) {
|
||||
int[] data = (int[]) viewMessage.getMessageData();
|
||||
int style = data[1];
|
||||
|
||||
//Link to the parent container.//
|
||||
setContainer((Container) getComponent(data[0]));
|
||||
getContainer().addComponent(this);
|
||||
//Create the SWT widget.//
|
||||
setSwtWidget(new org.eclipse.swt.widgets.List(getContainer().getSwtParent(), style));
|
||||
getSwtWidget().setData(this);
|
||||
//Set the allows multiple selections flag.//
|
||||
setAllowMultiSelection((style & SWT.MULTI) > 0);
|
||||
|
||||
//If the container has already been initialized then force the parent to re-layout so that this component will appear.//
|
||||
if(getContainer().isInitialized()) {
|
||||
getContainer().getSwtComposite().layout(true, true);
|
||||
}//if//
|
||||
}//if//
|
||||
break;
|
||||
}//case//
|
||||
case MESSAGE_SET_TOP_INDEX: {
|
||||
Integer topIndex = (Integer) viewMessage.getMessageData();
|
||||
|
||||
getSwtList().setTopIndex(topIndex.intValue());
|
||||
break;
|
||||
}//case//
|
||||
case MESSAGE_SHOW_SELECTION: {
|
||||
getSwtList().showSelection();
|
||||
break;
|
||||
}//case//
|
||||
default: {
|
||||
retVal = super.internalProcessMessage(viewMessage);
|
||||
}//default//
|
||||
}//switch//
|
||||
|
||||
return retVal;
|
||||
}//internalProcessMessage()//
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.swt.events.SelectionListener#widgetDefaultSelected(org.eclipse.swt.events.SelectionEvent)
|
||||
*/
|
||||
public void widgetDefaultSelected(SelectionEvent e) {
|
||||
if(getSendDoubleClick()) {
|
||||
long oldAutoSynchronizeSelectionDelay = getAutoSynchronizeSelectionDelay();
|
||||
|
||||
updateSelectionLinks();
|
||||
|
||||
try {
|
||||
//Hold the messages so they get sent together.//
|
||||
addMessageHold();
|
||||
//Set the synchronize delay to zero so the synchronize occurs immediatly.//
|
||||
setAutoSynchronizeSelectionDelay(0L);
|
||||
|
||||
//Force any selection task to complete prior to sending the double click, or force any selection change to be synchronized.//
|
||||
synchronized(this) {
|
||||
if(autoSynchronizeSelectionTask != null) {
|
||||
autoSynchronizeSelectionTask.run();
|
||||
}//if//
|
||||
else {
|
||||
synchronizeSelection();
|
||||
}//else//
|
||||
}//synchronized//
|
||||
|
||||
//Send the double click message.//
|
||||
sendRoundTripMessage(MESSAGE_DOUBLE_CLICK, null, null);
|
||||
}//try//
|
||||
finally {
|
||||
//Reset the delay and send the messages.//
|
||||
setAutoSynchronizeSelectionDelay(oldAutoSynchronizeSelectionDelay);
|
||||
removeMessageHold();
|
||||
}//finally//
|
||||
}//if//
|
||||
else {
|
||||
widgetSelected(e);
|
||||
}//else//
|
||||
}//widgetDefaultSelected()//
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.swt.events.SelectionListener#widgetSelected(org.eclipse.swt.events.SelectionEvent)
|
||||
*/
|
||||
public void widgetSelected(SelectionEvent e) {
|
||||
updateSelectionLinks();
|
||||
|
||||
if(getAutoSynchronizeSelection()) {
|
||||
if(getAutoSynchronizeSelectionDelay() > 0) {
|
||||
int[] selectedObjectIds = getAllowMultiSelection() ? getSelectedObjectIds() : null;
|
||||
int selectedObjectId = !getAllowMultiSelection() ? getSelectedObjectId() : -1;
|
||||
|
||||
if((selectedObjectIds != null) || (selectedObjectId != getSelectedObjectIdOnServer())) {
|
||||
final Object selection = selectedObjectIds != null ? (Object) selectedObjectIds : selectedObjectId != -1 ? new Integer(selectedObjectId) : null;
|
||||
|
||||
//Update the known server state.//
|
||||
if(selectedObjectIds == null) {
|
||||
setSelectedObjectIdOnServer(selectedObjectId);
|
||||
}//if//
|
||||
|
||||
//Start a task to send the selection 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(ListBox.this) {
|
||||
if(autoSynchronizeSelectionTask == this) {
|
||||
//Cleanup after the task.//
|
||||
autoSynchronizeSelectionTask = null;
|
||||
getEventLoop().executeAsync(new IRunnable() {
|
||||
public Object run() {
|
||||
sendMessage(MESSAGE_VIEW_SYNCHRONIZE_SELECTION, selection);
|
||||
return null;
|
||||
}//run()//
|
||||
});
|
||||
}//if//
|
||||
}//synchronized//
|
||||
}//run()//
|
||||
};
|
||||
addTask(autoSynchronizeSelectionTask, getAutoSynchronizeSelectionDelay());
|
||||
}//synchronized//
|
||||
}//if//
|
||||
}//if//
|
||||
else {
|
||||
synchronizeSelection();
|
||||
}//else//
|
||||
}//if//
|
||||
}//widgetSelected()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.IndexedCollectionComponent#controlRemoveAll()
|
||||
*/
|
||||
protected void controlRemoveAll() {
|
||||
getSwtList().removeAll();
|
||||
}//controlRemoveAll()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.IndexedCollectionComponent#controlSetItems(String[])
|
||||
*/
|
||||
protected void controlSetItems(Object[] items) {
|
||||
if((items == null) || (items.length == 0)) {
|
||||
getSwtList().removeAll();
|
||||
}//if//
|
||||
else {
|
||||
String[] itemTexts = new String[items.length];
|
||||
|
||||
System.arraycopy(items, 0, itemTexts, 0, itemTexts.length);
|
||||
getSwtList().setItems(itemTexts);
|
||||
}//else//
|
||||
}//controlSetItems()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.IndexedCollectionComponent#controlSetItem(int, Object)
|
||||
*/
|
||||
protected void controlSetItem(int index, Object itemData) {
|
||||
getSwtList().setItem(index, (String) itemData);
|
||||
}//controlSetItem()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.IndexedCollectionComponent#controlAddItem(Object, int)
|
||||
*/
|
||||
protected void controlAddItem(Object itemData, int index) {
|
||||
getSwtList().add((String) itemData, index);
|
||||
}//controlAddItem()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.IndexedCollectionComponent#controlAddItem(Object)
|
||||
*/
|
||||
protected void controlAddItem(Object itemData) {
|
||||
getSwtList().add((String) itemData);
|
||||
}//controlAddItem()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.IndexedCollectionComponent#controlRemoveItem(int)
|
||||
*/
|
||||
protected void controlRemoveItem(int index) {
|
||||
getSwtList().remove(index);
|
||||
}//controlRemoveItem()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.IndexedCollectionComponent#controlGetSelections()
|
||||
*/
|
||||
protected int[] controlGetSelections() {
|
||||
return getSwtList().getSelectionIndices();
|
||||
}//controlGetSelections()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.IndexedCollectionComponent#controlGetSelection()
|
||||
*/
|
||||
protected int controlGetSelection() {
|
||||
return getSwtList().getSelectionIndex();
|
||||
}//controlGetSelection()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.IndexedCollectionComponent#controlSetSelections(int[])
|
||||
*/
|
||||
protected void controlSetSelections(int[] indices) {
|
||||
getSwtList().setSelection(indices);
|
||||
getSwtList().showSelection();
|
||||
}//controlSetSelections()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.IndexedCollectionComponent#controlSetSelection(int)
|
||||
*/
|
||||
protected void controlSetSelection(int index) {
|
||||
getSwtList().setSelection(index);
|
||||
getSwtList().showSelection();
|
||||
}//controlSetSelection()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.IndexedCollectionComponent#controlSetSelection(java.lang.String)
|
||||
*/
|
||||
protected void controlSetSelection(String text) {
|
||||
//Not supported.//
|
||||
}//controlSetSelection()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.IndexedCollectionComponent#controlAddSelection(int)
|
||||
*/
|
||||
protected void controlAddSelection(int index) {
|
||||
getSwtList().select(index);
|
||||
getSwtList().showSelection();
|
||||
}//controlAddSelection()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.IndexedCollectionComponent#controlRemoveSelection(int)
|
||||
*/
|
||||
protected void controlRemoveSelection(int index) {
|
||||
getSwtList().deselect(index);
|
||||
}//controlRemoveSelection()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.IndexedCollectionComponent#controlRemoveAllSelections()
|
||||
*/
|
||||
protected void controlRemoveAllSelections() {
|
||||
getSwtList().deselectAll();
|
||||
}//controlRemoveAllSelections()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.IndexedCollectionComponent#controlIsSelected(int)
|
||||
*/
|
||||
protected boolean controlIsSelected(int index) {
|
||||
return getSwtList().isSelected(index);
|
||||
}//controlIsSelected()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.IndexedCollectionComponent#controlGetText()
|
||||
*/
|
||||
protected String controlGetText() {
|
||||
throw new RuntimeException("Method not supported - controlGetText");
|
||||
}//controlGetText()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.IndexedCollectionComponent#controlSetText(String)
|
||||
*/
|
||||
protected void controlSetText(String text) {
|
||||
throw new RuntimeException("Method not supported - controlSetText");
|
||||
}//controlSetText()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.CollectionComponent#controlGetSelectionCount()
|
||||
*/
|
||||
protected int controlGetSelectionCount() {
|
||||
return getSwtList().getSelectionCount();
|
||||
}//controlGetSelectionCount()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.IndexedCollectionComponent#forceSelectionEvent()
|
||||
*/
|
||||
protected void forceSelectionEvent() { //Should call widgetSelected implemented by the subclass. This name may need to change.//
|
||||
widgetSelected(null);
|
||||
}//forceSelectionEvent()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.ICellContainer#addComponent(com.foundation.tcv.swt.client.cell.CellComponent)
|
||||
*/
|
||||
public void addComponent(CellComponent component) {
|
||||
//Never used.//
|
||||
}//addComponent()//
|
||||
}//ListBox//
|
||||
@@ -0,0 +1,586 @@
|
||||
/*
|
||||
* Copyright (c) 2003,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.tcv.swt.client;
|
||||
|
||||
import org.eclipse.swt.SWT;
|
||||
import org.eclipse.swt.events.*;
|
||||
import org.eclipse.swt.widgets.Shell;
|
||||
|
||||
import com.common.util.*;
|
||||
import com.common.debug.*;
|
||||
import com.foundation.tcv.client.view.ResourceHolder;
|
||||
import com.foundation.tcv.model.LinkInfo;
|
||||
import com.foundation.tcv.swt.*;
|
||||
import com.foundation.tcv.view.*;
|
||||
import com.foundation.view.JefImage;
|
||||
import com.foundation.view.LinkData;
|
||||
|
||||
public class Menu extends AbstractComponent implements SelectionListener, IMenu, IAbstractMenu {
|
||||
/** The menu style. */
|
||||
private int style = 0;
|
||||
/** The menu's parent component. */
|
||||
private AbstractComponent parent = null;
|
||||
/** An internal flag to assist in determining whether this menu is allowed to have sub-menus. */
|
||||
private boolean canHaveSubMenus = false;
|
||||
/** A collection of sub menus. */
|
||||
private IList subMenus = null;
|
||||
/** Non-null if the menu is a bar, pop up, or cascade type menu. */
|
||||
private org.eclipse.swt.widgets.Menu swtMenu = null;
|
||||
/** Non-null if the menu is a cascade, push, radio, check, or separator type menu. */
|
||||
private org.eclipse.swt.widgets.MenuItem swtMenuItem = null;
|
||||
/** Whether the menu item supports a selection state. If this is false then selections are sent immediatly to the server. */
|
||||
private boolean isStateful = false;
|
||||
/** Whether the method called when the menu is pressed should be performed on the UI thread. */
|
||||
private boolean synchronousSelection = false;
|
||||
/** The linkage for the selection. */
|
||||
private Linkage selectionLinkage = new Linkage();
|
||||
/** 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 visibility flag. */
|
||||
private ResourceHolder isVisibleHolder = new ResourceHolder(this);
|
||||
/** A holder for the value of the enabled state flag. */
|
||||
private ResourceHolder isEnabledHolder = new ResourceHolder(this);
|
||||
/** The current value for the visibility of the menu. This stores the visiblity even if the menu control is not currently created. */
|
||||
private boolean isVisibleValue = true;
|
||||
/** The current value for the enabled state of the menu. This stores the enabled state even if the menu control is not currently created. */
|
||||
private boolean isEnabledValue = true;
|
||||
/** The current value for the selection state of the menu. This stores the selection state even if the menu control is not currently created. */
|
||||
private boolean isSelectedValue = false;
|
||||
/** The current value for the menu's text. This stores the text even if the menu control is not currently created. */
|
||||
private String textValue = null;
|
||||
/** The current value for the menu's image. This stores the image even if the menu control is not currently created. */
|
||||
private JefImage imageValue = null;
|
||||
/** The accelerator for the menu item. */
|
||||
private int acceleratorValue = 0;
|
||||
/**
|
||||
* Menu constructor.
|
||||
*/
|
||||
public Menu() {
|
||||
}//Menu()//
|
||||
/**
|
||||
* Gets the collection of all sub menus.
|
||||
* @return A collection of menus, or null if this menu cannot hold other menus.
|
||||
*/
|
||||
private IList getSubMenus() {
|
||||
if((canHaveSubMenus) && (subMenus == null)) {
|
||||
subMenus = new LiteList(10, 30);
|
||||
}//if//
|
||||
|
||||
return subMenus;
|
||||
}//getSubMenus()//
|
||||
/**
|
||||
* Adds a sub menu to this menu.
|
||||
* @param subMenu The sub menu to be added. Must also implement IAbstractMenu.
|
||||
*/
|
||||
public void addSubMenu(AbstractComponent subMenu) {
|
||||
if(!isInitialized()) {
|
||||
if(subMenu instanceof IAbstractMenu) {
|
||||
getSubMenus().add(subMenu);
|
||||
}//if//
|
||||
else {
|
||||
throw new RuntimeException();
|
||||
}//else//
|
||||
}//if//
|
||||
}//addSubMenu()//
|
||||
/**
|
||||
* Gets the SWT menu item that represents this menu.
|
||||
* @return The SWT menu item providing visualization for this menu.
|
||||
*/
|
||||
public org.eclipse.swt.widgets.MenuItem getSwtMenuItem() {
|
||||
return (org.eclipse.swt.widgets.MenuItem) swtMenuItem;
|
||||
}//getSwtMenuItem()//
|
||||
/**
|
||||
* Gets the SWT menu that represents this menu.
|
||||
* @return The SWT menu providing visualization for this menu.
|
||||
*/
|
||||
public org.eclipse.swt.widgets.Menu getSwtMenu() {
|
||||
return (org.eclipse.swt.widgets.Menu) swtMenu;
|
||||
}//getSwtMenu()//
|
||||
/**
|
||||
* Gets the parent component for this component.
|
||||
* @return The view component containing this component. This will not be null, and may be a Component or another Menu instance.
|
||||
*/
|
||||
public AbstractComponent getParent() {
|
||||
return parent;
|
||||
}//getParent()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.AbstractComponent#getShell()
|
||||
*/
|
||||
public Shell getShell() {
|
||||
return getParent() != null ? getParent().getShell() : null;
|
||||
}//getShell()//
|
||||
/**
|
||||
* Gets the container nearest the menu.
|
||||
* @return The nearest container to this menu.
|
||||
*/
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.AbstractComponent#getContainer()
|
||||
*/
|
||||
public Container getContainer() {
|
||||
AbstractComponent component = getParent();
|
||||
|
||||
while(!(component instanceof Component)) {
|
||||
component = ((Menu) component).getParent();
|
||||
}//while//
|
||||
|
||||
return component instanceof Container ? (Container) component : ((Component) component).getContainer();
|
||||
}//getContainer()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.AbstractComponent#internalProcessMessage(com.foundation.tcv.model.ViewMessage)
|
||||
*/
|
||||
public Object internalProcessMessage(ViewMessage viewMessage) {
|
||||
Object result = null;
|
||||
|
||||
switch(viewMessage.getMessageNumber()) {
|
||||
case MESSAGE_INITIALIZE: {
|
||||
if((getSwtMenu() == null) && (getSwtMenuItem() == null)) {
|
||||
style = viewMessage.getMessageSecondaryInteger();
|
||||
parent = getComponent(viewMessage.getMessageInteger());
|
||||
|
||||
if((style & STYLE_CASCADE) > 0) {
|
||||
canHaveSubMenus = true;
|
||||
((Menu) getParent()).addSubMenu(this);
|
||||
|
||||
if(getParent() instanceof Menu && (((Menu) getParent()).style & STYLE_BAR) > 0) {
|
||||
loadMenu();
|
||||
swtMenu.addMenuListener(new MenuListener() {
|
||||
boolean isLoaded = false;
|
||||
|
||||
public void menuShown(MenuEvent e) {
|
||||
if(isLoaded) {
|
||||
unloadMenuChildren();
|
||||
}//if//
|
||||
|
||||
loadMenuChildren();
|
||||
}//menuShown()//
|
||||
public void menuHidden(MenuEvent e) {
|
||||
isLoaded = true;
|
||||
}//menuHidden()//
|
||||
});
|
||||
}//if//
|
||||
}//if//
|
||||
else if((style & STYLE_BAR) > 0) {
|
||||
org.eclipse.swt.widgets.Control parentControl = getParent() instanceof Component ? ((Component) getParent()).getSwtControl() : ((AbstractComponent) getParent()).getShell();
|
||||
|
||||
//Setup the popup menu or menu bar depending on the style.//
|
||||
if(parentControl instanceof org.eclipse.swt.widgets.Decorations) {
|
||||
swtMenu = new org.eclipse.swt.widgets.Menu((org.eclipse.swt.widgets.Decorations) parentControl, SWT.BAR); //(style ^ STYLE_BAR) |
|
||||
((org.eclipse.swt.widgets.Decorations) parentControl).setMenuBar(swtMenu);
|
||||
canHaveSubMenus = true;
|
||||
swtMenu.setData(this);
|
||||
setSwtWidget(swtMenu);
|
||||
|
||||
if(getParent() instanceof IDecoration) {
|
||||
((IDecoration) getParent()).setMenuBar(this);
|
||||
}//if//
|
||||
else {
|
||||
Debug.log("Error: The component must be an IDecoration to have a menu bar: " + getParent().getClass().getName());
|
||||
}//else//
|
||||
}//if//
|
||||
else {
|
||||
Debug.log("Error: Cannot have a menu bar in a control that does not inherit from SWT's Decorations class.");
|
||||
}//else//
|
||||
}//else if//
|
||||
else if((style & STYLE_POPUP) > 0) {
|
||||
org.eclipse.swt.widgets.Control control = getParent() instanceof Component ? ((Component) getParent()).getSwtControl() : ((AbstractComponent) getParent()).getShell();
|
||||
|
||||
swtMenu = new org.eclipse.swt.widgets.Menu(control);
|
||||
canHaveSubMenus = true;
|
||||
swtMenu.setData(this);
|
||||
swtMenu.addMenuListener(new MenuListener() {
|
||||
boolean isLoaded = false;
|
||||
|
||||
public void menuShown(MenuEvent e) {
|
||||
if(isLoaded) {
|
||||
unloadMenuChildren();
|
||||
}//if//
|
||||
|
||||
loadMenuChildren();
|
||||
}//menuShown()//
|
||||
public void menuHidden(MenuEvent e) {
|
||||
isLoaded = true;
|
||||
}//menuHidden()//
|
||||
});
|
||||
setSwtWidget(swtMenu);
|
||||
((AbstractComponent) getParent()).setMenu(this);
|
||||
}//else if//
|
||||
else {
|
||||
((Menu) getParent()).addSubMenu(this);
|
||||
isStateful = ((style & Menu.STYLE_CHECK) > 0) || ((style & Menu.STYLE_RADIO) > 0);
|
||||
}//else//
|
||||
}//if//
|
||||
break;
|
||||
}//case//
|
||||
case MESSAGE_SET_TEXT: {
|
||||
textHolder.setValue(viewMessage.getMessageData());
|
||||
break;
|
||||
}//case//
|
||||
case MESSAGE_SET_IMAGE: {
|
||||
imageHolder.setValue(viewMessage.getMessageData());
|
||||
break;
|
||||
}//case//
|
||||
case MESSAGE_SET_ACCELERATOR: {
|
||||
acceleratorValue = ((Integer) viewMessage.getMessageData()).intValue();
|
||||
|
||||
if(getSwtMenuItem() != null) {
|
||||
getSwtMenuItem().setAccelerator(acceleratorValue);
|
||||
}//if//
|
||||
break;
|
||||
}//case//
|
||||
case MESSAGE_SET_IS_SELECTED: {
|
||||
Boolean isSelected = (Boolean) viewMessage.getMessageData();
|
||||
|
||||
isSelectedValue = isSelected != null ? isSelected.booleanValue() : false;
|
||||
|
||||
//Only set the selection if it has changed.//
|
||||
if((getSwtMenuItem() != null) && (!getSwtMenuItem().isDisposed()) && (getSwtMenuItem().getSelection() != isSelectedValue)) {
|
||||
getSwtMenuItem().setSelection(isSelectedValue);
|
||||
//Send feedback to the server updating its state. This is necessary to avoid data corruption given the client and server run on different threads.//
|
||||
sendMessage(MESSAGE_VIEW_SYNCHRONIZE_SELECTION, isSelectedValue ? Boolean.TRUE : Boolean.FALSE);
|
||||
selectionLinkage.invoke(isSelected);
|
||||
}//if//
|
||||
break;
|
||||
}//case//
|
||||
case MESSAGE_SET_LOCATION: {
|
||||
int[] point = (int[]) viewMessage.getMessageData();
|
||||
|
||||
//Note: This is safe since this should only ever be performed on a floating menu.//
|
||||
if(getSwtMenu() != null && !getSwtMenu().isDisposed()) {
|
||||
getSwtMenu().setLocation(point[0], point[1]);
|
||||
}//if//
|
||||
break;
|
||||
}//case//
|
||||
case MESSAGE_SET_IS_VISIBLE: {
|
||||
isVisibleHolder.setValue(viewMessage.getMessageData());
|
||||
break;
|
||||
}//case//
|
||||
case MESSAGE_SET_IS_ENABLED: {
|
||||
isEnabledHolder.setValue(viewMessage.getMessageData());
|
||||
break;
|
||||
}//case//
|
||||
case MESSAGE_SET_SYNCHRONOUS_SELECTION: {
|
||||
synchronousSelection = ((Boolean) viewMessage.getMessageData()).booleanValue();
|
||||
break;
|
||||
}//case//
|
||||
case MESSAGE_ADD_SELECTION_LINK: {
|
||||
LinkInfo info = (LinkInfo) viewMessage.getMessageData();
|
||||
|
||||
selectionLinkage.add(new LinkData(getComponent(info.getComponent()), info.getTarget(), info.getData(), info.isBoolean(), info.invertLogic(), info.nullValue()));
|
||||
break;
|
||||
}//case//
|
||||
default: {
|
||||
result = super.internalProcessMessage(viewMessage);
|
||||
}//default//
|
||||
}//switch//
|
||||
|
||||
return result;
|
||||
}//internalProcessMessage()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.AbstractComponent#internalViewInitializeAll()
|
||||
*/
|
||||
protected void internalViewInitializeAll() {
|
||||
super.internalViewInitializeAll();
|
||||
|
||||
//Initialize sub-menus.//
|
||||
if((getSubMenus() != null) && (getSubMenus().getSize() > 0)) {
|
||||
IIterator iterator = getSubMenus().iterator();
|
||||
|
||||
while(iterator.hasNext()) {
|
||||
Menu next = (Menu) iterator.next();
|
||||
|
||||
next.internalViewInitializeAll();
|
||||
}//while//
|
||||
}//if//
|
||||
}//internalViewInitializeAll()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.AbstractComponent#internalViewReleaseAll()
|
||||
*/
|
||||
protected void internalViewReleaseAll() {
|
||||
//Release sub-menus.//
|
||||
if((getSubMenus() != null) && (getSubMenus().getSize() > 0)) {
|
||||
IIterator iterator = getSubMenus().iterator();
|
||||
|
||||
while(iterator.hasNext()) {
|
||||
Menu next = (Menu) iterator.next();
|
||||
|
||||
next.internalViewReleaseAll();
|
||||
}//while//
|
||||
}//if//
|
||||
|
||||
super.internalViewReleaseAll();
|
||||
}//internalViewReleaseAll()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.AbstractComponent#internalViewSynchronizeAll()
|
||||
*/
|
||||
protected void internalViewSynchronizeAll() {
|
||||
super.internalViewSynchronizeAll();
|
||||
|
||||
//Synchronize sub-menus.//
|
||||
if((getSubMenus() != null) && (getSubMenus().getSize() > 0)) {
|
||||
IIterator iterator = getSubMenus().iterator();
|
||||
|
||||
while(iterator.hasNext()) {
|
||||
Menu next = (Menu) iterator.next();
|
||||
|
||||
next.internalViewSynchronizeAll();
|
||||
}//while//
|
||||
}//if//
|
||||
}//internalViewSynchronizeAll()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.AbstractComponent#internalViewInitialize()
|
||||
*/
|
||||
protected void internalViewInitialize() {
|
||||
super.internalViewInitialize();
|
||||
}//internalViewInitialize()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.AbstractComponent#internalViewRelease()
|
||||
*/
|
||||
protected void internalViewRelease() {
|
||||
textHolder.release();
|
||||
imageHolder.release();
|
||||
isVisibleHolder.release();
|
||||
isEnabledHolder.release();
|
||||
|
||||
if(imageValue != null && getSwtMenuItem() != null) {
|
||||
destroyImage(imageValue);
|
||||
imageValue = null;
|
||||
}//if//
|
||||
|
||||
if(getSwtMenu() != null && !getSwtMenu().isDisposed()) {
|
||||
getSwtMenu().dispose();
|
||||
}//if//
|
||||
|
||||
if(getSwtMenuItem() != null && !getSwtMenuItem().isDisposed()) {
|
||||
getSwtMenuItem().removeSelectionListener(this);
|
||||
getSwtMenuItem().dispose();
|
||||
}//if//
|
||||
|
||||
super.internalViewRelease();
|
||||
}//internalViewRelease()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.AbstractComponent#internalViewSynchronize()
|
||||
*/
|
||||
protected void internalViewSynchronize() {
|
||||
super.internalViewSynchronize();
|
||||
}//internalViewSynchronize()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.AbstractComponent#internalOnLinkInvoked(int, java.lang.Object)
|
||||
*/
|
||||
protected void internalOnLinkInvoked(int linkTarget, Object data) {
|
||||
switch(linkTarget) {
|
||||
case LINK_TARGET_IS_VISIBLE: {
|
||||
isVisibleValue = data != null && data instanceof Boolean ? ((Boolean) data).booleanValue() : false;
|
||||
|
||||
if(getSwtMenu() != null && !getSwtMenu().isDisposed()) {
|
||||
getSwtMenu().setVisible(isVisibleValue);
|
||||
}//if//
|
||||
break;
|
||||
}//case//
|
||||
case LINK_TARGET_IS_ENABLED: {
|
||||
isEnabledValue = data != null && data instanceof Boolean ? ((Boolean) data).booleanValue() : false;
|
||||
|
||||
if(getSwtMenu() != null && !getSwtMenu().isDisposed()) {
|
||||
getSwtMenu().setEnabled(isEnabledValue);
|
||||
}//if//
|
||||
|
||||
if(getSwtMenuItem() != null && !getSwtMenuItem().isDisposed()) {
|
||||
getSwtMenuItem().setEnabled(isEnabledValue);
|
||||
}//if//
|
||||
break;
|
||||
}//case//
|
||||
case LINK_TARGET_SELECTION: {
|
||||
isSelectedValue = data instanceof Boolean ? ((Boolean) data).booleanValue() : false;
|
||||
|
||||
if(getSwtMenuItem() != null && !getSwtMenuItem().isDisposed()) {
|
||||
if((isStateful) && (isSelectedValue != getSwtMenuItem().getSelection())) {
|
||||
getSwtMenuItem().setSelection(isSelectedValue);
|
||||
selectionChanged(isSelectedValue);
|
||||
}//if//
|
||||
else {
|
||||
selectionChanged(true);
|
||||
}//else//
|
||||
}//if//
|
||||
break;
|
||||
}//case//
|
||||
case LINK_TARGET_IMAGE: {
|
||||
if(data instanceof JefImage) {
|
||||
imageValue = (JefImage) data;
|
||||
|
||||
if(getSwtMenuItem() != null && !getSwtMenuItem().isDisposed()) {
|
||||
destroyImage(getSwtMenuItem().getImage());
|
||||
getSwtMenuItem().setImage(createImage(imageValue));
|
||||
}//if//
|
||||
}//if//
|
||||
break;
|
||||
}//case//
|
||||
case LINK_TARGET_TEXT: {
|
||||
textValue = data instanceof String ? (String) data : "";
|
||||
|
||||
if(getSwtMenuItem() != null && !getSwtMenuItem().isDisposed()) {
|
||||
getSwtMenuItem().setText(textValue);
|
||||
}//if//
|
||||
break;
|
||||
}//case//
|
||||
default: {
|
||||
super.internalOnLinkInvoked(linkTarget, data);
|
||||
break;
|
||||
}//default//
|
||||
}//switch//
|
||||
}//internalOnLinkInvoked()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.AbstractComponent#internalResourceHolderChanged(com.foundation.tcv.client.view.ResourceHolder, java.lang.Object, java.lang.Object, int)
|
||||
*/
|
||||
protected void internalResourceHolderChanged(ResourceHolder resource, Object oldValue, Object newValue, int flags) {
|
||||
if(resource == textHolder) {
|
||||
textValue = newValue != null ? (String) newValue : "";
|
||||
|
||||
if(getSwtMenuItem() != null && !getSwtMenuItem().isDisposed()) {
|
||||
getSwtMenuItem().setText(textValue);
|
||||
}//if//
|
||||
}//if//
|
||||
else if(resource == imageHolder) {
|
||||
imageValue = (JefImage) newValue;
|
||||
|
||||
if(getSwtMenuItem() != null && !getSwtMenuItem().isDisposed()) {
|
||||
destroyImage(getSwtMenuItem().getImage());
|
||||
getSwtMenuItem().setImage(createImage(imageValue));
|
||||
}//if//
|
||||
}//else if//
|
||||
else if(resource == isVisibleHolder) {
|
||||
isVisibleValue = ((Boolean) newValue).booleanValue();
|
||||
|
||||
if(getSwtMenuItem() != null && !getSwtMenuItem().isDisposed()) {
|
||||
//getSwtMenuItem().setVisible(isVisibleValue);
|
||||
}//if//
|
||||
|
||||
if(getSwtMenu() != null && !getSwtMenu().isDisposed()) {
|
||||
getSwtMenu().setVisible(isVisibleValue);
|
||||
}//if//
|
||||
}//else if//
|
||||
else if(resource == isEnabledHolder) {
|
||||
isEnabledValue = ((Boolean) newValue).booleanValue();
|
||||
|
||||
if(getSwtMenuItem() != null && !getSwtMenuItem().isDisposed()) {
|
||||
getSwtMenuItem().setEnabled(isEnabledValue);
|
||||
}//if//
|
||||
|
||||
if(getSwtMenu() != null && !getSwtMenu().isDisposed()) {
|
||||
getSwtMenu().setEnabled(isEnabledValue);
|
||||
}//if//
|
||||
}//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) {
|
||||
selectionChanged(getSwtMenuItem().getSelection());
|
||||
}//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(boolean isSelected) {
|
||||
if(synchronousSelection) {
|
||||
sendRoundTripMessage(MESSAGE_VIEW_SYNCHRONIZE_SELECTION, isSelected ? Boolean.TRUE : Boolean.FALSE, null);
|
||||
}//if//
|
||||
else {
|
||||
sendMessage(MESSAGE_VIEW_SYNCHRONIZE_SELECTION, isSelected ? Boolean.TRUE : Boolean.FALSE);
|
||||
}//else//
|
||||
|
||||
selectionLinkage.invoke(isStateful ? isSelected ? Boolean.TRUE : Boolean.FALSE : null);
|
||||
}//selectionChanged()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.view.swt.IAbstractMenu#loadMenu()
|
||||
*/
|
||||
public void loadMenu() {
|
||||
if((style & STYLE_CASCADE) > 0) {
|
||||
//Setup both a menu and menu item since they work as one in SWT.//
|
||||
swtMenuItem = new org.eclipse.swt.widgets.MenuItem((org.eclipse.swt.widgets.Menu) ((Menu) getParent()).getSwtMenu(), SWT.CASCADE); //style
|
||||
swtMenu = new org.eclipse.swt.widgets.Menu(swtMenuItem);
|
||||
swtMenuItem.setMenu(swtMenu);
|
||||
swtMenu.setData(this);
|
||||
swtMenuItem.setData(this);
|
||||
setSwtWidget(swtMenuItem);
|
||||
}//if//
|
||||
else if(isVisibleValue) {
|
||||
swtMenuItem = new org.eclipse.swt.widgets.MenuItem(((Menu) getParent()).getSwtMenu(), style);
|
||||
swtMenuItem.setData(this);
|
||||
setSwtWidget(swtMenuItem);
|
||||
swtMenuItem.addSelectionListener(this);
|
||||
}//else if//
|
||||
|
||||
if(getSwtMenu() != null) {
|
||||
getSwtMenu().setVisible(isVisibleValue);
|
||||
getSwtMenu().setEnabled(isEnabledValue);
|
||||
}//if//
|
||||
|
||||
if(getSwtMenuItem() != null) {
|
||||
getSwtMenuItem().setText(textValue == null ? "" : textValue);
|
||||
getSwtMenuItem().setImage(createImage(imageValue));
|
||||
getSwtMenuItem().setSelection(isSelectedValue);
|
||||
getSwtMenuItem().setEnabled(isEnabledValue);
|
||||
getSwtMenuItem().setAccelerator(acceleratorValue);
|
||||
}//if//
|
||||
}//loadMenu()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.view.swt.IAbstractMenu#unloadMenu()
|
||||
*/
|
||||
public void unloadMenu() {
|
||||
if(getSwtMenuItem() != null && imageValue != null) {
|
||||
destroyImage(imageValue);
|
||||
}//if//
|
||||
|
||||
if(getSwtMenu() != null && !getSwtMenu().isDisposed()) {
|
||||
getSwtMenu().dispose();
|
||||
swtMenu = null;
|
||||
}//if//
|
||||
|
||||
if(getSwtMenuItem() != null && !getSwtMenuItem().isDisposed()) {
|
||||
getSwtMenuItem().dispose();
|
||||
swtMenuItem = null;
|
||||
}//if//
|
||||
}//loadMenu()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.view.swt.IAbstractMenu#loadMenuChildren()
|
||||
*/
|
||||
public void loadMenuChildren() {
|
||||
if(getSubMenus() != null) {
|
||||
for(int index = 0; index < getSubMenus().getSize(); index++) {
|
||||
IAbstractMenu menu = (IAbstractMenu) getSubMenus().get(index);
|
||||
|
||||
menu.loadMenu();
|
||||
menu.loadMenuChildren();
|
||||
}//for//
|
||||
}//if//
|
||||
}//loadMenuChildren()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.view.swt.IAbstractMenu#unloadMenuChildren()
|
||||
*/
|
||||
public void unloadMenuChildren() {
|
||||
if(getSubMenus() != null) {
|
||||
for(int index = 0; index < getSubMenus().getSize(); index++) {
|
||||
IAbstractMenu menu = (IAbstractMenu) getSubMenus().get(index);
|
||||
|
||||
menu.unloadMenuChildren();
|
||||
menu.unloadMenu();
|
||||
}//for//
|
||||
}//if//
|
||||
}//unloadMenuChildren()//
|
||||
}//Menu()//
|
||||
@@ -0,0 +1,93 @@
|
||||
/*
|
||||
* Copyright (c) 2004,2008 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.tcv.swt.client;
|
||||
|
||||
import com.foundation.tcv.swt.*;
|
||||
import com.foundation.tcv.view.ViewMessage;
|
||||
|
||||
public class MessageDialog extends Dialog implements IMessageDialog {
|
||||
/**
|
||||
* MessageDialog constructor.
|
||||
*/
|
||||
public MessageDialog() {
|
||||
super();
|
||||
}//MessageDialog()//
|
||||
/**
|
||||
* Gets the SWT message box that represents this message dialog.
|
||||
* @return The SWT message box providing visualization for this message dialog.
|
||||
*/
|
||||
public org.eclipse.swt.widgets.MessageBox getSwtMessageBox() {
|
||||
return (org.eclipse.swt.widgets.MessageBox) getSwtDialog();
|
||||
}//getSwtMessageBox()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.AbstractComponent#internalViewInitialize()
|
||||
*/
|
||||
protected void internalViewInitialize() {
|
||||
super.internalViewInitialize();
|
||||
}//internalViewInitialize()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.AbstractComponent#internalViewRelease()
|
||||
*/
|
||||
protected void internalViewRelease() {
|
||||
super.internalViewRelease();
|
||||
}//internalViewRelease()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.AbstractComponent#internalProcessMessage(com.foundation.tcv.model.ViewMessage)
|
||||
*/
|
||||
public Object internalProcessMessage(ViewMessage viewMessage) {
|
||||
Object retVal = null;
|
||||
|
||||
switch(viewMessage.getMessageNumber()) {
|
||||
case MESSAGE_INITIALIZE: {
|
||||
if(getSwtMessageBox() == null) {
|
||||
int[] data = (int[]) viewMessage.getMessageData();
|
||||
Container parent = null;
|
||||
org.eclipse.swt.widgets.Shell shell = null;
|
||||
|
||||
//Link to the parent container.//
|
||||
parent = (Container) getComponent(data[0]);
|
||||
|
||||
if(parent.getSwtComposite() instanceof org.eclipse.swt.widgets.Shell) {
|
||||
//TODO: May be able to simplify this into the one statement below.//
|
||||
shell = (org.eclipse.swt.widgets.Shell) parent.getSwtComposite();
|
||||
}//if//
|
||||
else {
|
||||
shell = parent.getSwtComposite().getShell();
|
||||
}//else//
|
||||
|
||||
//Force the focus to the parent (I believe that is how the dialog knows its parent).//
|
||||
//parent.getSwtComposite().setFocus();
|
||||
|
||||
//Create the SWT widget.//
|
||||
if(data.length > 1) {
|
||||
setSwtDialog(new org.eclipse.swt.widgets.MessageBox(shell, data[1]));
|
||||
}//if//
|
||||
else {
|
||||
setSwtDialog(new org.eclipse.swt.widgets.MessageBox(shell));
|
||||
}//else//
|
||||
}//if//
|
||||
break;
|
||||
}//case//
|
||||
case MESSAGE_SET_MESSAGE: {
|
||||
getSwtMessageBox().setMessage((String) viewMessage.getMessageData());
|
||||
break;
|
||||
}//case//
|
||||
case MESSAGE_OPEN: {
|
||||
int response = getSwtMessageBox().open();
|
||||
|
||||
sendMessage(MESSAGE_SET_PRESSED_BUTTON, new Integer(response));
|
||||
break;
|
||||
}//case//
|
||||
default: {
|
||||
retVal = super.internalProcessMessage(viewMessage);
|
||||
}//default//
|
||||
}//switch//
|
||||
|
||||
return retVal;
|
||||
}//internalProcessMessage()//
|
||||
}//MessageDialog//
|
||||
@@ -0,0 +1,168 @@
|
||||
/*
|
||||
* Copyright (c) 2003,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.tcv.swt.client;
|
||||
|
||||
import org.eclipse.swt.SWT;
|
||||
import org.eclipse.swt.custom.ScrolledComposite;
|
||||
import org.eclipse.swt.graphics.Point;
|
||||
import org.eclipse.swt.graphics.Rectangle;
|
||||
import org.eclipse.swt.widgets.Canvas;
|
||||
import org.eclipse.swt.widgets.Composite;
|
||||
import org.eclipse.swt.widgets.Control;
|
||||
import org.eclipse.swt.widgets.Event;
|
||||
import org.eclipse.swt.widgets.Listener;
|
||||
import org.eclipse.swt.widgets.ScrollBar;
|
||||
|
||||
import com.common.debug.Debug;
|
||||
import com.foundation.tcv.swt.*;
|
||||
import com.foundation.tcv.view.*;
|
||||
import com.foundation.view.swt.layout.Layout;
|
||||
|
||||
public class Panel extends Container implements IPanel {
|
||||
/** The composite used to slide the contents around if the user has requested vertical and/or horizontal scrolling. */
|
||||
private ScrolledComposite scrolledComposite;
|
||||
/** The composite used to slide the contents around if the user has requested vertical and/or horizontal scrolling. */
|
||||
private Composite composite;
|
||||
/**
|
||||
* Panel constructor.
|
||||
*/
|
||||
public Panel() {
|
||||
super();
|
||||
}//Panel()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.view.swt.Container#getSwtParent()
|
||||
*/
|
||||
public org.eclipse.swt.widgets.Composite getSwtParent() {
|
||||
return scrolledComposite != null ? composite : getSwtComposite();
|
||||
}//getSwtParent()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.AbstractComponent#internalViewInitialize()
|
||||
*/
|
||||
protected void internalViewInitialize() {
|
||||
super.internalViewInitialize();
|
||||
}//internalViewInitialize()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.AbstractComponent#internalViewRelease()
|
||||
*/
|
||||
protected void internalViewRelease() {
|
||||
super.internalViewRelease();
|
||||
}//internalViewRelease()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.AbstractComponent#internalViewSynchronize()
|
||||
*/
|
||||
protected void internalViewSynchronize() {
|
||||
super.internalViewSynchronize();
|
||||
}//internalViewSynchronize()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.Container#internalLayout()
|
||||
*/
|
||||
protected void internalLayout() {
|
||||
if(scrolledComposite != null) {
|
||||
composite.setSize(composite.computeSize(-1, -1, true));
|
||||
}//if//
|
||||
|
||||
super.internalLayout();
|
||||
}//internalLayout()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.Container#postResize()
|
||||
*/
|
||||
public void postResize() {
|
||||
super.postResize();
|
||||
|
||||
if(scrolledComposite != null) {
|
||||
Rectangle interior = scrolledComposite.getClientArea();
|
||||
Rectangle interior2 = null;
|
||||
|
||||
scrolledComposite.setMinSize(0, 0);
|
||||
|
||||
while(!interior.equals(interior2)) {
|
||||
Point size = null;
|
||||
|
||||
composite.computeSize(0, 0, true);
|
||||
|
||||
if(composite.getLayout() instanceof com.foundation.view.swt.layout.Layout) {
|
||||
size = ((com.foundation.view.swt.layout.Layout) composite.getLayout()).computeCurrentSize(composite);
|
||||
}//if//
|
||||
else {
|
||||
Debug.log(new RuntimeException("Only Brainstorm based layouts may be used. The layout must extend " + Layout.class.getName()));
|
||||
}//else//
|
||||
|
||||
if(getSwtComposite().getHorizontalBar() != null) {
|
||||
scrolledComposite.setMinWidth(size.x);
|
||||
}//if//
|
||||
|
||||
if(getSwtComposite().getVerticalBar() != null) {
|
||||
scrolledComposite.setMinHeight(size.y);
|
||||
}//if//
|
||||
|
||||
interior2 = interior;
|
||||
interior = scrolledComposite.getClientArea();
|
||||
}//while//
|
||||
}//if//
|
||||
}//postResize()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.AbstractComponent#internalProcessMessage(com.foundation.tcv.model.ViewMessage)
|
||||
*/
|
||||
public Object internalProcessMessage(ViewMessage viewMessage) {
|
||||
Object result = null;
|
||||
|
||||
switch(viewMessage.getMessageNumber()) {
|
||||
case MESSAGE_INITIALIZE: {
|
||||
if(getSwtControl() == null) {
|
||||
int parent = viewMessage.getMessageInteger();
|
||||
int style = viewMessage.getMessageSecondaryInteger();
|
||||
boolean hScroll = ((style & SWT.H_SCROLL) != 0);
|
||||
boolean vScroll = ((style & SWT.V_SCROLL) != 0);
|
||||
|
||||
//Link to the parent container.//
|
||||
setContainer((Container) getComponent(parent));
|
||||
getContainer().addComponent(this);
|
||||
|
||||
if(hScroll || vScroll) {
|
||||
scrolledComposite = new ScrolledComposite(getContainer().getSwtParent(), style);
|
||||
scrolledComposite.setData(this);
|
||||
composite = new Composite(scrolledComposite, 0);
|
||||
composite.setData(this);
|
||||
scrolledComposite.setTabList(new Control[] {composite});
|
||||
scrolledComposite.setContent(composite);
|
||||
setSwtWidget(scrolledComposite);
|
||||
scrolledComposite.setAlwaysShowScrollBars(false);
|
||||
scrolledComposite.setExpandHorizontal(true);
|
||||
scrolledComposite.setExpandVertical(true);
|
||||
scrolledComposite.setMinSize(0, 0);
|
||||
|
||||
if(hScroll) {
|
||||
getSwtComposite().getHorizontalBar().setVisible(false);
|
||||
getSwtComposite().getHorizontalBar().setIncrement(20);
|
||||
}//if//
|
||||
|
||||
if(vScroll) {
|
||||
getSwtComposite().getVerticalBar().setVisible(false);
|
||||
getSwtComposite().getVerticalBar().setIncrement(20);
|
||||
}//if//
|
||||
}//if//
|
||||
else {
|
||||
setSwtWidget(new org.eclipse.swt.widgets.Composite(getContainer().getSwtParent(), style));
|
||||
getSwtWidget().setData(this);
|
||||
}//else//
|
||||
|
||||
//If the container has already been initialized then force the parent to re-layout so that this component will appear.//
|
||||
if(getContainer().isInitialized()) {
|
||||
getContainer().getSwtComposite().layout(true, true);
|
||||
}//if//
|
||||
}//if//
|
||||
break;
|
||||
}//case//
|
||||
default: {
|
||||
result = super.internalProcessMessage(viewMessage);
|
||||
}//default//
|
||||
}//switch//
|
||||
|
||||
return result;
|
||||
}//internalProcessMessage()//
|
||||
}//Panel//
|
||||
@@ -0,0 +1,111 @@
|
||||
/*
|
||||
* Copyright (c) 2005,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.tcv.swt.client;
|
||||
|
||||
import org.eclipse.swt.layout.FillLayout;
|
||||
import org.eclipse.swt.widgets.Control;
|
||||
|
||||
import com.foundation.tcv.swt.IPanelViewer;
|
||||
import com.foundation.tcv.view.ViewMessage;
|
||||
import com.foundation.view.swt.util.SwtUtilities;
|
||||
|
||||
public class PanelViewer extends Container implements IPanelViewer {
|
||||
/** The stored focus control which will be used to restore focus after altering the contents of the panel viewer. */
|
||||
private Control focusControl = null;
|
||||
/** Whether the panel viewer should allow the focus to change when the viewed contents change. */
|
||||
private boolean changeFocus = true;
|
||||
/**
|
||||
* PanelViewer constructor.
|
||||
*/
|
||||
public PanelViewer() {
|
||||
super();
|
||||
}//PanelViewer()//
|
||||
/**
|
||||
* Gets the SWT composite that represents this panel.
|
||||
* @return The SWT composite providing visualization for this panel.
|
||||
*/
|
||||
public org.eclipse.swt.widgets.Composite getSwtComposite() {
|
||||
return (org.eclipse.swt.widgets.Composite) getSwtWidget();
|
||||
}//getSwtComposite()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.AbstractComponent#internalViewInitialize()
|
||||
*/
|
||||
protected void internalViewInitialize() {
|
||||
super.internalViewInitialize();
|
||||
}//internalViewInitialize()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.AbstractComponent#internalViewRelease()
|
||||
*/
|
||||
protected void internalViewRelease() {
|
||||
super.internalViewRelease();
|
||||
}//internalViewRelease()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.AbstractComponent#internalViewSynchronize()
|
||||
*/
|
||||
protected void internalViewSynchronize() {
|
||||
super.internalViewSynchronize();
|
||||
}//internalViewSynchronize()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.AbstractComponent#internalProcessMessage(com.foundation.tcv.model.ViewMessage)
|
||||
*/
|
||||
public Object internalProcessMessage(ViewMessage viewMessage) {
|
||||
Object retVal = null;
|
||||
|
||||
switch(viewMessage.getMessageNumber()) {
|
||||
case MESSAGE_INITIALIZE: {
|
||||
if(getSwtControl() == null) {
|
||||
int style = viewMessage.getMessageSecondaryInteger();
|
||||
|
||||
//Link to the parent container.//
|
||||
setContainer((Container) getComponent(viewMessage.getMessageInteger()));
|
||||
getContainer().addComponent(this);
|
||||
//Create the SWT widget.//
|
||||
setSwtWidget(new org.eclipse.swt.widgets.Composite(getContainer().getSwtParent(), style));
|
||||
getSwtWidget().setData(this);
|
||||
getSwtComposite().setLayout(new FillLayout());
|
||||
|
||||
//If the container has already been initialized then force the parent to re-layout so that this component will appear.//
|
||||
if(getContainer().isInitialized()) {
|
||||
getContainer().getSwtComposite().layout(true, true);
|
||||
}//if//
|
||||
}//if//
|
||||
break;
|
||||
}//case//
|
||||
case MESSAGE_BEGIN_CHANGE_CONTENTS: {
|
||||
focusControl = getDisplay().getFocusControl();
|
||||
//SwtUtilities.setRedraw(getShell(), false);
|
||||
break;
|
||||
}//case//
|
||||
case MESSAGE_END_CHANGE_CONTENTS: {
|
||||
if(getComponents().getSize() == 1) {
|
||||
getSwtComposite().setTabList(new Control[] {((Component) getComponents().getFirst()).getSwtControl()});
|
||||
}//if//
|
||||
else {
|
||||
getSwtComposite().setTabList(null);
|
||||
}//else//
|
||||
|
||||
if((!changeFocus) && (focusControl != null) && (!focusControl.isDisposed())) {
|
||||
focusControl.forceFocus();
|
||||
}//if//
|
||||
|
||||
//SwtUtilities.setRedraw(getShell(), true);
|
||||
focusControl = null;
|
||||
break;
|
||||
}//case//
|
||||
case MESSAGE_SET_CHANGE_FOCUS: {
|
||||
this.changeFocus = ((Boolean) viewMessage.getMessageData()).booleanValue();
|
||||
break;
|
||||
}//case//
|
||||
default: {
|
||||
retVal = super.internalProcessMessage(viewMessage);
|
||||
}//default//
|
||||
}//switch//
|
||||
|
||||
return retVal;
|
||||
}//internalProcessMessage()//
|
||||
}//PanelViewer//
|
||||
@@ -0,0 +1,150 @@
|
||||
/*
|
||||
* Copyright (c) 2003,2008 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.tcv.swt.client;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
|
||||
import com.foundation.tcv.swt.*;
|
||||
import com.foundation.tcv.view.*;
|
||||
|
||||
public class Progress extends Component implements IProgress {
|
||||
/** The current progress in its original form. */
|
||||
private BigDecimal currentProgress = null;
|
||||
/** The multiplier used to generate an integer from the current progress value. */
|
||||
private BigDecimal multiplier = null;
|
||||
/**
|
||||
* Progress constructor.
|
||||
*/
|
||||
public Progress() {
|
||||
super();
|
||||
}//Progress()//
|
||||
/**
|
||||
* Gets the SWT progress bar that represents this progress.
|
||||
* @return The SWT progress bar providing visualization for this progress.
|
||||
*/
|
||||
public org.eclipse.swt.widgets.ProgressBar getSwtProgress() {
|
||||
return (org.eclipse.swt.widgets.ProgressBar) getSwtWidget();
|
||||
}//getSwtProgress()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.AbstractComponent#internalViewInitialize()
|
||||
*/
|
||||
protected void internalViewInitialize() {
|
||||
super.internalViewInitialize();
|
||||
}//internalViewInitialize()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.AbstractComponent#internalViewRelease()
|
||||
*/
|
||||
protected void internalViewRelease() {
|
||||
super.internalViewRelease();
|
||||
}//internalViewRelease()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.AbstractComponent#internalViewSynchronize()
|
||||
*/
|
||||
protected void internalViewSynchronize() {
|
||||
super.internalViewSynchronize();
|
||||
}//internalViewSynchronize()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.AbstractComponent#internalProcessMessage(com.foundation.tcv.model.ViewMessage)
|
||||
*/
|
||||
public Object internalProcessMessage(ViewMessage viewMessage) {
|
||||
Object result = null;
|
||||
|
||||
switch(viewMessage.getMessageNumber()) {
|
||||
case MESSAGE_INITIALIZE: {
|
||||
if(getSwtControl() == null) {
|
||||
int[] data = (int[]) viewMessage.getMessageData();
|
||||
int style = data[1];
|
||||
|
||||
//Link to the parent container.//
|
||||
setContainer((Container) getComponent(data[0]));
|
||||
getContainer().addComponent(this);
|
||||
//Create the SWT widget.//
|
||||
setSwtWidget(new org.eclipse.swt.widgets.ProgressBar(getContainer().getSwtParent(), style));
|
||||
getSwtWidget().setData(this);
|
||||
|
||||
//If the container has already been initialized then force the parent to re-layout so that this component will appear.//
|
||||
if(getContainer().isInitialized()) {
|
||||
getContainer().getSwtComposite().layout(true, true);
|
||||
}//if//
|
||||
}//if//
|
||||
break;
|
||||
}//case//
|
||||
case MESSAGE_SET_MAXIMUM: {
|
||||
getSwtProgress().setMaximum(((Number) viewMessage.getMessageData()).intValue());
|
||||
break;
|
||||
}//case//
|
||||
case MESSAGE_SET_MINIMUM: {
|
||||
getSwtProgress().setMinimum(((Number) viewMessage.getMessageData()).intValue());
|
||||
break;
|
||||
}//case//
|
||||
case MESSAGE_SET_PROGRESS: {
|
||||
setCurrentProgress((BigDecimal) viewMessage.getMessageData());
|
||||
controlUpdateSelection();
|
||||
break;
|
||||
}//case//
|
||||
case MESSAGE_SET_MULTIPLIER: {
|
||||
setMultiplier((BigDecimal) viewMessage.getMessageData());
|
||||
controlUpdateSelection();
|
||||
break;
|
||||
}//case//
|
||||
default: {
|
||||
result = super.internalProcessMessage(viewMessage);
|
||||
}//default//
|
||||
}//switch//
|
||||
|
||||
return result;
|
||||
}//internalProcessMessage()//
|
||||
/**
|
||||
* Updates the control's selection.
|
||||
*/
|
||||
protected void controlUpdateSelection() {
|
||||
BigDecimal progress = getCurrentProgress();
|
||||
BigDecimal multiplier = getMultiplier();
|
||||
int controlProgress;
|
||||
|
||||
if(progress == null) {
|
||||
controlProgress = getSwtProgress().getMinimum();
|
||||
}//if//
|
||||
else if(multiplier == null) {
|
||||
controlProgress = progress.intValue();
|
||||
}//else if//
|
||||
else {
|
||||
controlProgress = progress.multiply(multiplier).intValue();
|
||||
}//else//
|
||||
|
||||
getSwtProgress().setSelection(controlProgress);
|
||||
}//controlUpdateSelection()//
|
||||
/**
|
||||
* Gets the current progress.
|
||||
* @return The current progress in its original form.
|
||||
*/
|
||||
public BigDecimal getCurrentProgress() {
|
||||
return currentProgress;
|
||||
}//getCurrentProgress()//
|
||||
/**
|
||||
* Sets the current progress.
|
||||
* @param currentProgress The current progress in its original form.
|
||||
*/
|
||||
public void setCurrentProgress(BigDecimal currentProgress) {
|
||||
this.currentProgress = currentProgress;
|
||||
}//setCurrentProgress()//
|
||||
/**
|
||||
* Gets the multiplier used to construct an integer from the progress value.
|
||||
* @return The progress multiplier.
|
||||
*/
|
||||
public BigDecimal getMultiplier() {
|
||||
return multiplier;
|
||||
}//getMultiplier()//
|
||||
/**
|
||||
* Sets the multiplier used to construct an integer from the progress value.
|
||||
* @param multiplier The progress multiplier.
|
||||
*/
|
||||
public void setMultiplier(BigDecimal multiplier) {
|
||||
this.multiplier = multiplier;
|
||||
}//setMultiplier()//
|
||||
}//Progress//
|
||||
@@ -0,0 +1,62 @@
|
||||
/*
|
||||
* Copyright (c) 2003,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.tcv.swt.client;
|
||||
|
||||
import org.eclipse.swt.widgets.Shell;
|
||||
|
||||
import com.common.debug.*;
|
||||
import com.foundation.tcv.view.*;
|
||||
|
||||
/**
|
||||
* Maintains request information.
|
||||
*/
|
||||
class Request implements Runnable {
|
||||
private AbstractComponent component;
|
||||
private ViewMessage viewMessage;
|
||||
private Object returnValue = null;
|
||||
private boolean synchronous = false;
|
||||
/**
|
||||
* Request constructor.
|
||||
*/
|
||||
Request(AbstractComponent component, ViewMessage viewMessage, boolean synchronous) {
|
||||
this.component = component;
|
||||
this.viewMessage = viewMessage;
|
||||
this.synchronous = synchronous;
|
||||
}//Request()//
|
||||
/**
|
||||
* Runs the request (should only be called by the event thread).
|
||||
*/
|
||||
public void run() {
|
||||
Shell shell = component != null ? component.getShell() : null;
|
||||
|
||||
if(shell != null) {
|
||||
//shellSwtUtilities.setRedraw(, false);
|
||||
shell.setLayoutDeferred(true);
|
||||
}//if//
|
||||
|
||||
try {
|
||||
returnValue = component.processRequest(component, viewMessage, synchronous);
|
||||
}//try//
|
||||
catch(Throwable e) {
|
||||
Debug.log("Failed to complete the processing of a remote client swt view request.", e);
|
||||
}//catch//
|
||||
finally {
|
||||
if(shell != null) {
|
||||
//shellSwtUtilities.setRedraw(, true);
|
||||
shell.setLayoutDeferred(false);
|
||||
}//if//
|
||||
}//finally//
|
||||
}//run()//
|
||||
/**
|
||||
* Gets the request's result.
|
||||
* @return The return value for the request (only valid if synchronous).
|
||||
*/
|
||||
public Object getReturnValue() {
|
||||
return returnValue;
|
||||
}//getReturnValue()//
|
||||
}//Request//
|
||||
@@ -0,0 +1,136 @@
|
||||
/*
|
||||
* Copyright (c) 2007 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.tcv.swt.client;
|
||||
|
||||
import org.eclipse.swt.SWT;
|
||||
|
||||
import com.foundation.tcv.swt.IRowLayout;
|
||||
import com.foundation.tcv.view.ViewMessage;
|
||||
|
||||
public class RowLayout extends Layout implements IRowLayout {
|
||||
public int type = SWT.HORIZONTAL;
|
||||
public int marginWidth = 0;
|
||||
public int marginHeight = 0;
|
||||
public int spacing = 3;
|
||||
public boolean wrap = true;
|
||||
public boolean pack = true;
|
||||
public int alignment = SWT.BEGINNING;
|
||||
public boolean justify = false;
|
||||
public int marginLeft = 3;
|
||||
public int marginTop = 3;
|
||||
public int marginRight = 3;
|
||||
public int marginBottom = 3;
|
||||
/**
|
||||
* RowLayout constructor.
|
||||
*/
|
||||
public RowLayout() {
|
||||
}//RowLayout()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.Layout#createLayout(java.lang.Object)
|
||||
*/
|
||||
public org.eclipse.swt.widgets.Layout createLayout(Object rowObject) {
|
||||
com.foundation.view.swt.layout.RowLayout result = new com.foundation.view.swt.layout.RowLayout();
|
||||
|
||||
result.type = type;
|
||||
result.marginHeight = marginHeight;
|
||||
result.marginWidth = marginWidth;
|
||||
result.spacing = spacing;
|
||||
result.wrap = wrap;
|
||||
result.pack = pack;
|
||||
result.alignment = alignment;
|
||||
result.justify = justify;
|
||||
result.marginLeft = marginLeft;
|
||||
result.marginTop = marginTop;
|
||||
result.marginRight = marginRight;
|
||||
result.marginBottom = marginBottom;
|
||||
|
||||
return result;
|
||||
}//createLayout()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.Layout#initialize()
|
||||
*/
|
||||
public void initialize() {
|
||||
}//initialize()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.Layout#release()
|
||||
*/
|
||||
public void release() {
|
||||
}//release()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.Layout#synchronize()
|
||||
*/
|
||||
public void synchronize() {
|
||||
}//synchronize()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.Layout#processMessage(com.foundation.tcv.view.ViewMessage)
|
||||
*/
|
||||
public Object processMessage(ViewMessage viewMessage) {
|
||||
Object result = null;
|
||||
|
||||
switch(viewMessage.getMessageNumber()) {
|
||||
case MESSAGE_INITIALIZE: {
|
||||
setContainer((AbstractComponent) getComponent(viewMessage.getMessageInteger()));
|
||||
break;
|
||||
}//case//
|
||||
case MESSAGE_SET_TYPE: {
|
||||
this.type = viewMessage.getMessageInteger();
|
||||
break;
|
||||
}//case//
|
||||
case MESSAGE_SET_MARGIN_HEIGHT: {
|
||||
this.marginHeight = viewMessage.getMessageInteger();
|
||||
break;
|
||||
}//case//
|
||||
case MESSAGE_SET_MARGIN_WIDTH: {
|
||||
this.marginWidth = viewMessage.getMessageInteger();
|
||||
break;
|
||||
}//case//
|
||||
case MESSAGE_SET_SPACING: {
|
||||
this.spacing = viewMessage.getMessageInteger();
|
||||
break;
|
||||
}//case//
|
||||
case MESSAGE_SET_WRAP: {
|
||||
this.wrap = viewMessage.getMessageInteger() != 0;
|
||||
break;
|
||||
}//case//
|
||||
case MESSAGE_SET_PACK: {
|
||||
this.pack = viewMessage.getMessageInteger() != 0;
|
||||
break;
|
||||
}//case//
|
||||
case MESSAGE_SET_ALIGNMENT: {
|
||||
this.alignment = viewMessage.getMessageInteger() == 0 ? SWT.BEGINNING : viewMessage.getMessageInteger(); //The test is just to avoid version incompatibilities.//
|
||||
break;
|
||||
}//case//
|
||||
case MESSAGE_SET_JUSTIFY: {
|
||||
this.justify = viewMessage.getMessageInteger() != 0;
|
||||
break;
|
||||
}//case//
|
||||
case MESSAGE_SET_MARGIN_TOP: {
|
||||
this.marginTop = viewMessage.getMessageInteger();
|
||||
break;
|
||||
}//case//
|
||||
case MESSAGE_SET_MARGIN_BOTTOM: {
|
||||
this.marginBottom = viewMessage.getMessageInteger();
|
||||
break;
|
||||
}//case//
|
||||
case MESSAGE_SET_MARGIN_LEFT: {
|
||||
this.marginLeft = viewMessage.getMessageInteger();
|
||||
break;
|
||||
}//case//
|
||||
case MESSAGE_SET_MARGIN_RIGHT: {
|
||||
this.marginRight = viewMessage.getMessageInteger();
|
||||
break;
|
||||
}//case//
|
||||
default: {
|
||||
result = super.processMessage(viewMessage);
|
||||
break;
|
||||
}//default//
|
||||
}//switch//
|
||||
|
||||
return result;
|
||||
}//processMessage()//
|
||||
}//RowLayout//
|
||||
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
* 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.tcv.swt.client;
|
||||
|
||||
/**
|
||||
* Encapsulates a row containing data for an object in the indexed collection.
|
||||
*/
|
||||
public class RowObject {
|
||||
/** The object's server assigned identifier. -1 is an invalid value and indicates no value set. */
|
||||
public int objectId = -1;
|
||||
/** The hidden data, one object for each hidden data 'column' setup for the collection component. */
|
||||
public Object[] hiddenData = null;
|
||||
/** Maintains a count of how many times the row data exists in the collection control. */
|
||||
public int referenceCount = 1;
|
||||
|
||||
/**
|
||||
* RowObject constructor.
|
||||
* @param objectId The object identifier for the row which is used to identify the row on the client and server.
|
||||
* @param hiddenDataCount The number of hidden data elements to allocate.
|
||||
*/
|
||||
public RowObject(int objectId, int hiddenDataCount) {
|
||||
this.objectId = objectId;
|
||||
|
||||
if(hiddenDataCount > 0) {
|
||||
this.hiddenData = new Object[hiddenDataCount];
|
||||
}//if//
|
||||
}//RowObject()//
|
||||
/**
|
||||
* Gets the client/server shared id for this node.
|
||||
* @return The identifier for this node data which is shared with the server.
|
||||
*/
|
||||
public int getObjectId() {
|
||||
return objectId;
|
||||
}//getObjectId()//
|
||||
/**
|
||||
* Releases any resources held by the row object.
|
||||
*/
|
||||
public void dispose() {
|
||||
//Does nothing.//
|
||||
}//dispose()//
|
||||
}//RowObject//
|
||||
@@ -0,0 +1,150 @@
|
||||
/*
|
||||
* Copyright (c) 2003,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.tcv.swt.client;
|
||||
|
||||
import org.eclipse.swt.SWT;
|
||||
import org.eclipse.swt.events.*;
|
||||
import org.eclipse.swt.graphics.*;
|
||||
import com.foundation.tcv.swt.*;
|
||||
import com.foundation.tcv.view.*;
|
||||
|
||||
public class Sash extends Component implements SelectionListener, ISash {
|
||||
private boolean isVertical = false;
|
||||
/**
|
||||
* Sash constructor.
|
||||
*/
|
||||
public Sash() {
|
||||
super();
|
||||
}//Sash()//
|
||||
/**
|
||||
* Gets the SWT sash reference.
|
||||
* @return The sash represented in SWT.
|
||||
*/
|
||||
protected org.eclipse.swt.widgets.Sash getSwtSash() {
|
||||
return (org.eclipse.swt.widgets.Sash) getSwtWidget();
|
||||
}//getSwtSash()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.AbstractComponent#internalViewInitialize()
|
||||
*/
|
||||
protected void internalViewInitialize() {
|
||||
getSwtSash().addSelectionListener(this);
|
||||
super.internalViewInitialize();
|
||||
}//internalViewInitialize()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.AbstractComponent#internalViewRelease()
|
||||
*/
|
||||
protected void internalViewRelease() {
|
||||
if((getSwtSash() != null) && (!getSwtSash().isDisposed())) {
|
||||
getSwtSash().removeSelectionListener(this);
|
||||
}//if//
|
||||
|
||||
super.internalViewRelease();
|
||||
}//internalViewRelease()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.AbstractComponent#internalViewSynchronize()
|
||||
*/
|
||||
protected void internalViewSynchronize() {
|
||||
super.internalViewSynchronize();
|
||||
}//internalViewSynchronize()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.AbstractComponent#internalProcessMessage(com.foundation.tcv.model.ViewMessage)
|
||||
*/
|
||||
public Object internalProcessMessage(ViewMessage viewMessage) {
|
||||
Object retVal = null;
|
||||
|
||||
switch(viewMessage.getMessageNumber()) {
|
||||
case MESSAGE_INITIALIZE: {
|
||||
if(getSwtControl() == null) {
|
||||
int[] data = (int[]) viewMessage.getMessageData();
|
||||
int style = data[1];
|
||||
|
||||
//Link to the parent container.//
|
||||
setContainer((Container) getComponent(data[0]));
|
||||
getContainer().addComponent(this);
|
||||
//Create the SWT widget.//
|
||||
setSwtWidget(new org.eclipse.swt.widgets.Sash(getContainer().getSwtParent(), style));
|
||||
getSwtWidget().setData(this);
|
||||
//Initialize flags.//
|
||||
isVertical = ((style & STYLE_VERTICAL) > 0);
|
||||
|
||||
//If the container has already been initialized then force the parent to re-layout so that this component will appear.//
|
||||
if(getContainer().isInitialized()) {
|
||||
getContainer().getSwtComposite().layout(true, true);
|
||||
}//if//
|
||||
}//if//
|
||||
break;
|
||||
}//case//
|
||||
case MESSAGE_SET_ATTACHMENTS: {
|
||||
int[] data = (int[]) viewMessage.getMessageData();
|
||||
|
||||
if(data != null) {
|
||||
//attachment1 = (Component) getComponent(data[0]);
|
||||
//attachment2 = (Component) getComponent(data[1]);
|
||||
}//if//
|
||||
break;
|
||||
}//case//
|
||||
default: {
|
||||
retVal = super.internalProcessMessage(viewMessage);
|
||||
}//default//
|
||||
}//switch//
|
||||
|
||||
return retVal;
|
||||
}//internalProcessMessage()//
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.swt.events.SelectionListener#widgetDefaultSelected(org.eclipse.swt.events.SelectionEvent)
|
||||
*/
|
||||
public void widgetDefaultSelected(SelectionEvent e) {
|
||||
widgetSelected(e);
|
||||
}//widgetDefaultSelected()//
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.swt.events.SelectionListener#widgetSelected(org.eclipse.swt.events.SelectionEvent)
|
||||
*/
|
||||
public void widgetSelected(SelectionEvent event) {
|
||||
if(event.detail != SWT.DRAG) {
|
||||
Point point0 = getSwtSash().getLocation();
|
||||
|
||||
//TODO: Allow other layouts?//
|
||||
if(!isVertical) {
|
||||
int difference = event.y - point0.y;
|
||||
|
||||
if(getSwtSash().getLayoutData() instanceof com.foundation.view.swt.layout.FormData) {
|
||||
com.foundation.view.swt.layout.FormData formData = (com.foundation.view.swt.layout.FormData) getSwtSash().getLayoutData();
|
||||
|
||||
if(formData.top != null) {
|
||||
formData.top.offset += difference;
|
||||
}//if//
|
||||
|
||||
if(formData.bottom != null) {
|
||||
formData.bottom.offset += difference;
|
||||
}//if//
|
||||
}//if//
|
||||
}//if//
|
||||
else {
|
||||
int difference = event.x - point0.x;
|
||||
|
||||
if(getSwtSash().getLayoutData() instanceof com.foundation.view.swt.layout.FormData) {
|
||||
com.foundation.view.swt.layout.FormData formData = (com.foundation.view.swt.layout.FormData) getSwtSash().getLayoutData();
|
||||
|
||||
if(formData.top != null) {
|
||||
formData.top.offset += difference;
|
||||
}//if//
|
||||
|
||||
if(formData.bottom != null) {
|
||||
formData.bottom.offset += difference;
|
||||
}//if//
|
||||
}//if//
|
||||
}//else//
|
||||
|
||||
//TODO: Should I allow for null layouts?//
|
||||
//getSwtSash().setBounds(event.x, event.y, event.width, event.height);
|
||||
|
||||
//Resize the parent container.//
|
||||
getSwtSash().getParent().layout();
|
||||
}//if//
|
||||
}//widgetSelected()//
|
||||
}//Sash//
|
||||
@@ -0,0 +1,73 @@
|
||||
/*
|
||||
* Copyright (c) 2005,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.tcv.swt.client;
|
||||
|
||||
import com.common.debug.Debug;
|
||||
import com.foundation.tcv.swt.ISashForm;
|
||||
import com.foundation.tcv.view.ViewMessage;
|
||||
|
||||
/*
|
||||
* The sash form lays out the contained components and separates them by sashes.
|
||||
*/
|
||||
public class SashForm extends Container implements ISashForm {
|
||||
/**
|
||||
* SashForm constructor.
|
||||
*/
|
||||
public SashForm() {
|
||||
super();
|
||||
}//SashForm()//
|
||||
/**
|
||||
* Gets the SWT sash form that represents this sash form.
|
||||
* @return The SWT sash form providing visualization for this sash form.
|
||||
*/
|
||||
public org.eclipse.swt.custom.SashForm getSwtSashForm() {
|
||||
return (org.eclipse.swt.custom.SashForm) getSwtControl();
|
||||
}//getSwtSashForm()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.AbstractComponent#internalProcessMessage(com.foundation.tcv.model.ViewMessage)
|
||||
*/
|
||||
public Object internalProcessMessage(ViewMessage viewMessage) {
|
||||
Object retVal = null;
|
||||
|
||||
switch(viewMessage.getMessageNumber()) {
|
||||
case MESSAGE_INITIALIZE: {
|
||||
if(getSwtControl() == null) {
|
||||
int[] data = (int[]) viewMessage.getMessageData();
|
||||
int style = data[1];
|
||||
|
||||
//Link to the parent container.//
|
||||
setContainer((Container) getComponent(data[0]));
|
||||
getContainer().addComponent(this);
|
||||
//Create the SWT widget.//
|
||||
setSwtWidget(new org.eclipse.swt.custom.SashForm(getContainer().getSwtParent(), style));
|
||||
getSwtWidget().setData(this);
|
||||
|
||||
//If the container has already been initialized then force the parent to re-layout so that this component will appear.//
|
||||
if(getContainer().isInitialized()) {
|
||||
getContainer().getSwtComposite().layout(true, true);
|
||||
}//if//
|
||||
}//if//
|
||||
break;
|
||||
}//case//
|
||||
case MESSAGE_SET_WEIGHTS: {
|
||||
try {
|
||||
getSwtSashForm().setWeights((int[]) viewMessage.getMessageData());
|
||||
}//try//
|
||||
catch(Throwable e) {
|
||||
Debug.log(e, "Failed to set the sash form's weights.");
|
||||
}//catch//
|
||||
break;
|
||||
}//case//
|
||||
default: {
|
||||
retVal = super.internalProcessMessage(viewMessage);
|
||||
}//default//
|
||||
}//switch//
|
||||
|
||||
return retVal;
|
||||
}//internalProcessMessage()//
|
||||
}//SashForm//
|
||||
@@ -0,0 +1,16 @@
|
||||
/*
|
||||
* Copyright (c) 2003,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.tcv.swt.client;
|
||||
|
||||
public abstract class ScrollableComponent extends Component {
|
||||
/**
|
||||
* ScrollableComponent constructor.
|
||||
*/
|
||||
public ScrollableComponent() {
|
||||
}//ScrollableComponent()//
|
||||
}//ScrollableComponent//
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,215 @@
|
||||
/*
|
||||
* Copyright (c) 2006,2008 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.tcv.swt.client;
|
||||
|
||||
import org.eclipse.swt.events.SelectionEvent;
|
||||
import org.eclipse.swt.events.SelectionListener;
|
||||
|
||||
import com.common.thread.IRunnable;
|
||||
import com.foundation.tcv.swt.ISlider;
|
||||
import com.foundation.tcv.view.ViewMessage;
|
||||
|
||||
public class Slider extends Component implements ISlider, SelectionListener {
|
||||
/** Whether the selection should be automatically sent to the model. */
|
||||
private boolean autoSynchronizeSelection = false;
|
||||
/** The number of milliseconds of delay before auto synchronizing the selection. */
|
||||
private long autoSynchronizeSelectionDelay = 500;
|
||||
/** The task that auto synchronizes the selection after a short delay. */
|
||||
protected Task autoSynchronizeSelectionTask = null;
|
||||
/**
|
||||
* Slider constructor.
|
||||
*/
|
||||
public Slider() {
|
||||
super();
|
||||
}//Slider()//
|
||||
/**
|
||||
* Gets the SWT slider that represents this slider.
|
||||
* @return The SWT slider providing visualization for this slider.
|
||||
*/
|
||||
public org.eclipse.swt.widgets.Slider getSwtSlider() {
|
||||
return (org.eclipse.swt.widgets.Slider) getSwtWidget();
|
||||
}//getSwtSlider()//
|
||||
/**
|
||||
* Determines whether the control should automatically synchronize all selections.
|
||||
* @return Whether selections should automatically get sent to the server.
|
||||
*/
|
||||
protected boolean getAutoSynchronizeSelection() {
|
||||
return autoSynchronizeSelection;
|
||||
}//getAutoSynchronizeSelection()//
|
||||
/**
|
||||
* Gets the delay in milliseconds between the selection event and updating the model.
|
||||
* @return The number of milliseconds to wait before updating the model.
|
||||
*/
|
||||
protected long getAutoSynchronizeSelectionDelay() {
|
||||
return autoSynchronizeSelectionDelay;
|
||||
}//getAutoSynchronizeSelectionDelay()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.AbstractComponent#internalViewInitialize()
|
||||
*/
|
||||
protected void internalViewInitialize() {
|
||||
getSwtSlider().addSelectionListener(this);
|
||||
super.internalViewInitialize();
|
||||
}//internalViewInitialize()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.AbstractComponent#internalViewRelease()
|
||||
*/
|
||||
protected void internalViewRelease() {
|
||||
if(getSwtSlider() != null && !getSwtSlider().isDisposed()) {
|
||||
getSwtSlider().removeSelectionListener(this);
|
||||
}//if//
|
||||
|
||||
synchronized(this) {
|
||||
if(autoSynchronizeSelectionTask != null) {
|
||||
removeTask(autoSynchronizeSelectionTask);
|
||||
autoSynchronizeSelectionTask = null;
|
||||
}//if//
|
||||
}//synchronized//
|
||||
|
||||
super.internalViewRelease();
|
||||
}//internalViewRelease()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.AbstractComponent#internalViewSynchronize()
|
||||
*/
|
||||
protected void internalViewSynchronize() {
|
||||
super.internalViewSynchronize();
|
||||
|
||||
if(!getAutoSynchronizeSelection()) {
|
||||
int selection = getSwtSlider().getSelection();
|
||||
|
||||
sendMessage(MESSAGE_VIEW_SYNCHRONIZE_SELECTION, new Integer(selection));
|
||||
}//if//
|
||||
else {
|
||||
synchronized(this) {
|
||||
if(autoSynchronizeSelectionTask != null) {
|
||||
removeTask(autoSynchronizeSelectionTask);
|
||||
autoSynchronizeSelectionTask.execute();
|
||||
}//if//
|
||||
}//synchronized//
|
||||
}//else if//
|
||||
}//internalViewSynchronize()//
|
||||
/**
|
||||
* Synchronizes the selection(s) with the server.
|
||||
*/
|
||||
private void internalSynchronizeSelection() {
|
||||
if(getAutoSynchronizeSelection()) {
|
||||
if(autoSynchronizeSelectionDelay > 0) {
|
||||
//Start a task to send the text to the server after a short delay.//
|
||||
synchronized(this) {
|
||||
final Integer selection = new Integer(getSwtSlider().getSelection());
|
||||
|
||||
if(autoSynchronizeSelectionTask != null) {
|
||||
removeTask(autoSynchronizeSelectionTask);
|
||||
}//if//
|
||||
|
||||
autoSynchronizeSelectionTask = new Task() {
|
||||
boolean hasRun = false;
|
||||
|
||||
public void execute() {
|
||||
//Make sure that this task is still valid and is not being superceeded.//
|
||||
synchronized(Slider.this) {
|
||||
if((autoSynchronizeSelectionTask == this) && (!hasRun)) {
|
||||
hasRun = true;
|
||||
//Cleanup after the task.//
|
||||
autoSynchronizeSelectionTask = null;
|
||||
getEventLoop().executeAsync(new IRunnable() {
|
||||
public Object run() {
|
||||
sendMessage(MESSAGE_VIEW_SYNCHRONIZE_SELECTION, selection);
|
||||
return null;
|
||||
}//run()//
|
||||
});
|
||||
}//if//
|
||||
}//synchronized//
|
||||
}//run()//
|
||||
};
|
||||
addTask(autoSynchronizeSelectionTask, autoSynchronizeSelectionDelay);
|
||||
}//synchronized//
|
||||
}//if//
|
||||
else {
|
||||
sendMessage(MESSAGE_VIEW_SYNCHRONIZE_SELECTION, new Integer(getSwtSlider().getSelection()));
|
||||
}//else//
|
||||
}//if//
|
||||
}//internalSynchronizeSelection()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.AbstractComponent#internalProcessMessage(com.foundation.tcv.model.ViewMessage)
|
||||
*/
|
||||
public Object internalProcessMessage(ViewMessage viewMessage) {
|
||||
Object retVal = null;
|
||||
|
||||
switch(viewMessage.getMessageNumber()) {
|
||||
case MESSAGE_INITIALIZE: {
|
||||
if(getSwtControl() == null) {
|
||||
int[] data = (int[]) viewMessage.getMessageData();
|
||||
int style = data[1];
|
||||
|
||||
//Link to the parent container.//
|
||||
setContainer((Container) getComponent(data[0]));
|
||||
getContainer().addComponent(this);
|
||||
//Create the SWT widget.//
|
||||
setSwtWidget(new org.eclipse.swt.widgets.Slider(getContainer().getSwtParent(), style));
|
||||
getSwtWidget().setData(this);
|
||||
|
||||
//If the container has already been initialized then force the parent to re-layout so that this component will appear.//
|
||||
if(getContainer().isInitialized()) {
|
||||
getContainer().getSwtComposite().layout(true, true);
|
||||
}//if//
|
||||
}//if//
|
||||
break;
|
||||
}//case//
|
||||
case MESSAGE_SET_MAXIMUM: {
|
||||
getSwtSlider().setMaximum(((Number) viewMessage.getMessageData()).intValue());
|
||||
break;
|
||||
}//case//
|
||||
case MESSAGE_SET_MINIMUM: {
|
||||
getSwtSlider().setMinimum(((Number) viewMessage.getMessageData()).intValue());
|
||||
break;
|
||||
}//case//
|
||||
case MESSAGE_SET_SELECTION: {
|
||||
getSwtSlider().setSelection(((Number) viewMessage.getMessageData()).intValue());
|
||||
break;
|
||||
}//case//
|
||||
case MESSAGE_SET_INCREMENT: {
|
||||
getSwtSlider().setIncrement(((Number) viewMessage.getMessageData()).intValue());
|
||||
break;
|
||||
}//case//
|
||||
case MESSAGE_SET_PAGE_INCREMENT: {
|
||||
getSwtSlider().setPageIncrement(((Number) viewMessage.getMessageData()).intValue());
|
||||
break;
|
||||
}//case//
|
||||
case MESSAGE_SET_THUMB: {
|
||||
getSwtSlider().setThumb(((Number) viewMessage.getMessageData()).intValue());
|
||||
break;
|
||||
}//case//
|
||||
case MESSAGE_SET_AUTO_SYNCHRONIZE_SELECTION: {
|
||||
autoSynchronizeSelection = ((Boolean) viewMessage.getMessageData()).booleanValue();
|
||||
break;
|
||||
}//case//
|
||||
case MESSAGE_SET_AUTO_SYNCHRONIZE_SELECTION_DELAY: {
|
||||
autoSynchronizeSelectionDelay = ((Long) viewMessage.getMessageData()).longValue();
|
||||
break;
|
||||
}//case//
|
||||
default: {
|
||||
retVal = super.internalProcessMessage(viewMessage);
|
||||
}//default//
|
||||
}//switch//
|
||||
|
||||
return retVal;
|
||||
}//internalProcessMessage()//
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.swt.events.SelectionListener#widgetDefaultSelected(org.eclipse.swt.events.SelectionEvent)
|
||||
*/
|
||||
public void widgetDefaultSelected(SelectionEvent e) {
|
||||
widgetSelected(e);
|
||||
}//widgetDefaultSelected()//
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.swt.events.SelectionListener#widgetSelected(org.eclipse.swt.events.SelectionEvent)
|
||||
*/
|
||||
public void widgetSelected(SelectionEvent e) {
|
||||
//TODO: Is there some way to determine exactly what selection or deselection occured given the event object?//
|
||||
internalSynchronizeSelection();
|
||||
}//widgetSelected()//
|
||||
}//Slider//
|
||||
@@ -0,0 +1,211 @@
|
||||
/*
|
||||
* Copyright (c) 2006,2008 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.tcv.swt.client;
|
||||
|
||||
import org.eclipse.swt.events.SelectionEvent;
|
||||
import org.eclipse.swt.events.SelectionListener;
|
||||
|
||||
import com.common.thread.IRunnable;
|
||||
import com.foundation.tcv.swt.ISpinner;
|
||||
import com.foundation.tcv.view.ViewMessage;
|
||||
|
||||
public class Spinner extends Component implements ISpinner, SelectionListener {
|
||||
/** Whether the selection should be automatically sent to the model. */
|
||||
private boolean autoSynchronizeSelection = false;
|
||||
/** The number of milliseconds of delay before auto synchronizing the selection. */
|
||||
private long autoSynchronizeSelectionDelay = 500;
|
||||
/** The task that auto synchronizes the selection after a short delay. */
|
||||
protected Task autoSynchronizeSelectionTask = null;
|
||||
/**
|
||||
* Spinner constructor.
|
||||
*/
|
||||
public Spinner() {
|
||||
super();
|
||||
}//Spinner()//
|
||||
/**
|
||||
* Gets the SWT spinner that represents this spinner.
|
||||
* @return The SWT spinner providing visualization for this spinner.
|
||||
*/
|
||||
public org.eclipse.swt.widgets.Spinner getSwtSpinner() {
|
||||
return (org.eclipse.swt.widgets.Spinner) getSwtWidget();
|
||||
}//getSwtSpinner()//
|
||||
/**
|
||||
* Determines whether the control should automatically synchronize all selections.
|
||||
* @return Whether selections should automatically get sent to the server.
|
||||
*/
|
||||
protected boolean getAutoSynchronizeSelection() {
|
||||
return autoSynchronizeSelection;
|
||||
}//getAutoSynchronizeSelection()//
|
||||
/**
|
||||
* Gets the delay in milliseconds between the selection event and updating the model.
|
||||
* @return The number of milliseconds to wait before updating the model.
|
||||
*/
|
||||
protected long getAutoSynchronizeSelectionDelay() {
|
||||
return autoSynchronizeSelectionDelay;
|
||||
}//getAutoSynchronizeSelectionDelay()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.AbstractComponent#internalViewInitialize()
|
||||
*/
|
||||
protected void internalViewInitialize() {
|
||||
getSwtSpinner().addSelectionListener(this);
|
||||
super.internalViewInitialize();
|
||||
}//internalViewInitialize()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.AbstractComponent#internalViewRelease()
|
||||
*/
|
||||
protected void internalViewRelease() {
|
||||
if(getSwtSpinner() != null && !getSwtSpinner().isDisposed()) {
|
||||
getSwtSpinner().removeSelectionListener(this);
|
||||
}//if//
|
||||
|
||||
synchronized(this) {
|
||||
if(autoSynchronizeSelectionTask != null) {
|
||||
removeTask(autoSynchronizeSelectionTask);
|
||||
autoSynchronizeSelectionTask = null;
|
||||
}//if//
|
||||
}//synchronized//
|
||||
|
||||
super.internalViewRelease();
|
||||
}//internalViewRelease()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.AbstractComponent#internalViewSynchronize()
|
||||
*/
|
||||
protected void internalViewSynchronize() {
|
||||
super.internalViewSynchronize();
|
||||
|
||||
if(!getAutoSynchronizeSelection()) {
|
||||
int selection = getSwtSpinner().getSelection();
|
||||
|
||||
sendMessage(MESSAGE_VIEW_SYNCHRONIZE_SELECTION, new Integer(selection));
|
||||
}//if//
|
||||
else {
|
||||
synchronized(this) {
|
||||
if(autoSynchronizeSelectionTask != null) {
|
||||
removeTask(autoSynchronizeSelectionTask);
|
||||
autoSynchronizeSelectionTask.execute();
|
||||
}//if//
|
||||
}//synchronized//
|
||||
}//else if//
|
||||
}//internalViewSynchronize()//
|
||||
/**
|
||||
* Synchronizes the selection(s) with the server.
|
||||
*/
|
||||
private void internalSynchronizeSelection() {
|
||||
if(getAutoSynchronizeSelection()) {
|
||||
if(autoSynchronizeSelectionDelay > 0) {
|
||||
//Start a task to send the text to the server after a short delay.//
|
||||
synchronized(this) {
|
||||
final Integer selection = new Integer(getSwtSpinner().getSelection());
|
||||
|
||||
if(autoSynchronizeSelectionTask != null) {
|
||||
removeTask(autoSynchronizeSelectionTask);
|
||||
}//if//
|
||||
|
||||
autoSynchronizeSelectionTask = new Task() {
|
||||
boolean hasRun = false;
|
||||
|
||||
public void execute() {
|
||||
//Make sure that this task is still valid and is not being superceeded.//
|
||||
synchronized(Spinner.this) {
|
||||
if((autoSynchronizeSelectionTask == this) && (!hasRun)) {
|
||||
hasRun = true;
|
||||
//Cleanup after the task.//
|
||||
autoSynchronizeSelectionTask = null;
|
||||
getEventLoop().executeAsync(new IRunnable() {
|
||||
public Object run() {
|
||||
sendMessage(MESSAGE_VIEW_SYNCHRONIZE_SELECTION, selection);
|
||||
return null;
|
||||
}//run()//
|
||||
});
|
||||
}//if//
|
||||
}//synchronized//
|
||||
}//run()//
|
||||
};
|
||||
addTask(autoSynchronizeSelectionTask, autoSynchronizeSelectionDelay);
|
||||
}//synchronized//
|
||||
}//if//
|
||||
else {
|
||||
sendMessage(MESSAGE_VIEW_SYNCHRONIZE_SELECTION, new Integer(getSwtSpinner().getSelection()));
|
||||
}//else//
|
||||
}//if//
|
||||
}//internalSynchronizeSelection()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.AbstractComponent#internalProcessMessage(com.foundation.tcv.model.ViewMessage)
|
||||
*/
|
||||
public Object internalProcessMessage(ViewMessage viewMessage) {
|
||||
Object retVal = null;
|
||||
|
||||
switch(viewMessage.getMessageNumber()) {
|
||||
case MESSAGE_INITIALIZE: {
|
||||
if(getSwtControl() == null) {
|
||||
int[] data = (int[]) viewMessage.getMessageData();
|
||||
int style = data[1];
|
||||
|
||||
//Link to the parent container.//
|
||||
setContainer((Container) getComponent(data[0]));
|
||||
getContainer().addComponent(this);
|
||||
//Create the SWT widget.//
|
||||
setSwtWidget(new org.eclipse.swt.widgets.Spinner(getContainer().getSwtParent(), style));
|
||||
getSwtWidget().setData(this);
|
||||
|
||||
//If the container has already been initialized then force the parent to re-layout so that this component will appear.//
|
||||
if(getContainer().isInitialized()) {
|
||||
getContainer().getSwtComposite().layout(true, true);
|
||||
}//if//
|
||||
}//if//
|
||||
break;
|
||||
}//case//
|
||||
case MESSAGE_SET_MAXIMUM: {
|
||||
getSwtSpinner().setMaximum(((Number) viewMessage.getMessageData()).intValue());
|
||||
break;
|
||||
}//case//
|
||||
case MESSAGE_SET_MINIMUM: {
|
||||
getSwtSpinner().setMinimum(((Number) viewMessage.getMessageData()).intValue());
|
||||
break;
|
||||
}//case//
|
||||
case MESSAGE_SET_SELECTION: {
|
||||
getSwtSpinner().setSelection(((Number) viewMessage.getMessageData()).intValue());
|
||||
break;
|
||||
}//case//
|
||||
case MESSAGE_SET_INCREMENT: {
|
||||
getSwtSpinner().setIncrement(((Number) viewMessage.getMessageData()).intValue());
|
||||
break;
|
||||
}//case//
|
||||
case MESSAGE_SET_PAGE_INCREMENT: {
|
||||
getSwtSpinner().setPageIncrement(((Number) viewMessage.getMessageData()).intValue());
|
||||
break;
|
||||
}//case//
|
||||
case MESSAGE_SET_AUTO_SYNCHRONIZE_SELECTION: {
|
||||
autoSynchronizeSelection = ((Boolean) viewMessage.getMessageData()).booleanValue();
|
||||
break;
|
||||
}//case//
|
||||
case MESSAGE_SET_AUTO_SYNCHRONIZE_SELECTION_DELAY: {
|
||||
autoSynchronizeSelectionDelay = ((Long) viewMessage.getMessageData()).longValue();
|
||||
break;
|
||||
}//case//
|
||||
default: {
|
||||
retVal = super.internalProcessMessage(viewMessage);
|
||||
}//default//
|
||||
}//switch//
|
||||
|
||||
return retVal;
|
||||
}//internalProcessMessage()//
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.swt.events.SelectionListener#widgetDefaultSelected(org.eclipse.swt.events.SelectionEvent)
|
||||
*/
|
||||
public void widgetDefaultSelected(SelectionEvent e) {
|
||||
widgetSelected(e);
|
||||
}//widgetDefaultSelected()//
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.swt.events.SelectionListener#widgetSelected(org.eclipse.swt.events.SelectionEvent)
|
||||
*/
|
||||
public void widgetSelected(SelectionEvent e) {
|
||||
//TODO: Is there some way to determine exactly what selection or deselection occured given the event object?//
|
||||
internalSynchronizeSelection();
|
||||
}//widgetSelected()//
|
||||
}//Spinner//
|
||||
@@ -0,0 +1,91 @@
|
||||
/*
|
||||
* Copyright (c) 2005,2007 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.tcv.swt.client;
|
||||
|
||||
import org.eclipse.swt.custom.StackLayout;
|
||||
|
||||
import com.foundation.tcv.swt.*;
|
||||
import com.foundation.tcv.view.*;
|
||||
|
||||
/*
|
||||
* Displays components in a stack such that only one component is visible at a time.
|
||||
*/
|
||||
public class StackViewer extends Container implements IStackViewer {
|
||||
/**
|
||||
* StackViewer constructor.
|
||||
*/
|
||||
public StackViewer() {
|
||||
super();
|
||||
}//StackViewer()//
|
||||
/**
|
||||
* Gets the SWT composite that represents this wizard.
|
||||
* @return The SWT composite providing visualization for this wizard.
|
||||
*/
|
||||
public org.eclipse.swt.widgets.Composite getSwtComposite() {
|
||||
return (org.eclipse.swt.widgets.Composite) getSwtWidget();
|
||||
}//getSwtComposite()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.AbstractComponent#internalViewInitialize()
|
||||
*/
|
||||
protected void internalViewInitialize() {
|
||||
super.internalViewInitialize();
|
||||
}//internalViewInitialize()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.AbstractComponent#internalViewRelease()
|
||||
*/
|
||||
protected void internalViewRelease() {
|
||||
super.internalViewRelease();
|
||||
}//internalViewRelease()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.AbstractComponent#internalViewSynchronize()
|
||||
*/
|
||||
protected void internalViewSynchronize() {
|
||||
super.internalViewSynchronize();
|
||||
}//internalViewSynchronize()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.AbstractComponent#internalProcessMessage(com.foundation.tcv.model.ViewMessage)
|
||||
*/
|
||||
public Object internalProcessMessage(ViewMessage viewMessage) {
|
||||
Object retVal = null;
|
||||
|
||||
switch(viewMessage.getMessageNumber()) {
|
||||
case MESSAGE_INITIALIZE: {
|
||||
if(getSwtControl() == null) {
|
||||
int[] data = (int[]) viewMessage.getMessageData();
|
||||
int style = data[1];
|
||||
|
||||
//Link to the parent container.//
|
||||
setContainer((Container) getComponent(data[0]));
|
||||
getContainer().addComponent(this);
|
||||
//Create the SWT widget.//
|
||||
setSwtWidget(new org.eclipse.swt.widgets.Composite(getContainer().getSwtParent(), style));
|
||||
getSwtWidget().setData(this);
|
||||
getSwtComposite().setLayout(new StackLayout());
|
||||
|
||||
//If the container has already been initialized then force the parent to re-layout so that this component will appear.//
|
||||
if(getContainer().isInitialized()) {
|
||||
getContainer().getSwtComposite().layout(true, true);
|
||||
}//if//
|
||||
}//if//
|
||||
break;
|
||||
}//case//
|
||||
case MESSAGE_CHANGE_COMPONENT: {
|
||||
int index = viewMessage.getMessageInteger();
|
||||
|
||||
((StackLayout) getSwtComposite().getLayout()).topControl = getSwtComposite().getChildren()[index];
|
||||
getSwtComposite().layout(true, false);
|
||||
break;
|
||||
}//case//
|
||||
default: {
|
||||
retVal = super.internalProcessMessage(viewMessage);
|
||||
}//default//
|
||||
}//switch//
|
||||
|
||||
return retVal;
|
||||
}//internalProcessMessage()//
|
||||
}//StackViewer//
|
||||
@@ -0,0 +1,205 @@
|
||||
/*
|
||||
* Copyright (c) 2005,2007 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.tcv.swt.client;
|
||||
|
||||
import org.eclipse.swt.graphics.Image;
|
||||
import org.eclipse.swt.widgets.TabItem;
|
||||
|
||||
import com.common.util.LiteHashMap;
|
||||
import com.foundation.tcv.swt.ITabPanel;
|
||||
import com.foundation.tcv.view.ViewMessage;
|
||||
|
||||
public class TabPanel extends Container implements ITabPanel, Component.IComponentListener {
|
||||
/** A mapping of TabItem instances indexed by the Component displayed by the tab. */
|
||||
private LiteHashMap tabItemsByComponentMap = new LiteHashMap(15);
|
||||
/**
|
||||
* TabPanel constructor.
|
||||
*/
|
||||
public TabPanel() {
|
||||
super();
|
||||
}//TabPanel()//
|
||||
/**
|
||||
* Gets the SWT tab folder that represents this tab panel.
|
||||
* @return The SWT tab folder providing visualization for this tab panel.
|
||||
*/
|
||||
public org.eclipse.swt.widgets.TabFolder getSwtTabFolder() {
|
||||
return (org.eclipse.swt.widgets.TabFolder) getSwtWidget();
|
||||
}//getSwtTabFolder()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.AbstractComponent#internalViewInitialize()
|
||||
*/
|
||||
protected void internalViewInitialize() {
|
||||
super.internalViewInitialize();
|
||||
}//internalViewInitialize()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.AbstractComponent#internalViewRelease()
|
||||
*/
|
||||
protected void internalViewRelease() {
|
||||
super.internalViewRelease();
|
||||
}//internalViewRelease()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.AbstractComponent#internalViewSynchronize()
|
||||
*/
|
||||
protected void internalViewSynchronize() {
|
||||
super.internalViewSynchronize();
|
||||
}//internalViewSynchronize()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.AbstractComponent#internalProcessMessage(com.foundation.tcv.model.ViewMessage)
|
||||
*/
|
||||
public Object internalProcessMessage(ViewMessage viewMessage) {
|
||||
Object result = null;
|
||||
|
||||
switch(viewMessage.getMessageNumber()) {
|
||||
case MESSAGE_INITIALIZE: {
|
||||
if(getSwtControl() == null) {
|
||||
int[] data = (int[]) viewMessage.getMessageData();
|
||||
int style = data[1];
|
||||
|
||||
//Link to the parent container.//
|
||||
setContainer((Container) getComponent(data[0]));
|
||||
getContainer().addComponent(this);
|
||||
//Create the SWT widget.//
|
||||
setSwtWidget(new org.eclipse.swt.widgets.TabFolder(getContainer().getSwtParent(), style));
|
||||
getSwtWidget().setData(this);
|
||||
|
||||
//If the container has already been initialized then force the parent to re-layout so that this component will appear.//
|
||||
if(getContainer().isInitialized()) {
|
||||
getContainer().getSwtComposite().layout(true, true);
|
||||
}//if//
|
||||
}//if//
|
||||
break;
|
||||
}//case//
|
||||
case MESSAGE_ADD_TAB: {
|
||||
int componentNumber = ((int[]) viewMessage.getMessageData())[0];
|
||||
Component component = (Component) getComponent(componentNumber);
|
||||
String title = component.getContainerTitle();
|
||||
Image image = component.getContainerImage();
|
||||
String toolTipText = component.getToolTipText();
|
||||
TabItem tabItem = null;
|
||||
|
||||
if(((int[]) viewMessage.getMessageData()).length > 1) {
|
||||
tabItem = new TabItem(getSwtTabFolder(), 0, ((int[]) viewMessage.getMessageData())[1]);
|
||||
}//if//
|
||||
else {
|
||||
tabItem = new TabItem(getSwtTabFolder(), 0);
|
||||
}//else//
|
||||
|
||||
tabItem.setText(title == null ? "" : title);
|
||||
tabItem.setImage(image);
|
||||
tabItem.setToolTipText(toolTipText);
|
||||
tabItem.setData(component);
|
||||
tabItem.setControl(component.getSwtControl());
|
||||
tabItemsByComponentMap.put(component, tabItem);
|
||||
component.registerListener(this);
|
||||
break;
|
||||
}//case//
|
||||
case MESSAGE_REMOVE_TAB: {
|
||||
int componentNumber = ((Integer) viewMessage.getMessageData()).intValue();
|
||||
Component component = (Component) getComponent(componentNumber);
|
||||
|
||||
if(component != null) {
|
||||
TabItem tabItem = (TabItem) tabItemsByComponentMap.remove(component);
|
||||
|
||||
if(tabItem != null && !tabItem.isDisposed()) {
|
||||
//Note: Don't dispose of the image because it comes from the component's container-image property whose lifecycle is managed by the component.//
|
||||
tabItem.dispose();
|
||||
}//if//
|
||||
|
||||
component.unregisterListener(this);
|
||||
}//if//
|
||||
break;
|
||||
}//case//
|
||||
case MESSAGE_REPOSITION_TAB: {
|
||||
int componentNumber = ((int[]) viewMessage.getMessageData())[0];
|
||||
int newIndex = ((int[]) viewMessage.getMessageData())[1];
|
||||
Component component = (Component) getComponent(componentNumber);
|
||||
|
||||
if(component != null) {
|
||||
TabItem oldTabItem = (TabItem) tabItemsByComponentMap.remove(component);
|
||||
|
||||
if(oldTabItem != null && !oldTabItem.isDisposed()) {
|
||||
TabItem newTabItem = new TabItem(getSwtTabFolder(), 0, newIndex);
|
||||
|
||||
newTabItem.setText(oldTabItem.getText());
|
||||
newTabItem.setImage(oldTabItem.getImage());
|
||||
newTabItem.setToolTipText(oldTabItem.getToolTipText());
|
||||
newTabItem.setData(oldTabItem.getData());
|
||||
newTabItem.setControl(oldTabItem.getControl());
|
||||
oldTabItem.dispose();
|
||||
tabItemsByComponentMap.put(component, newTabItem);
|
||||
}//if//
|
||||
}//if//
|
||||
break;
|
||||
}//case//
|
||||
case MESSAGE_SORT_TABS: {
|
||||
int startIndex = ((Integer) ((Object[]) viewMessage.getMessageData())[0]).intValue();
|
||||
int[] mapping = (int[]) ((Object[]) viewMessage.getMessageData())[1];
|
||||
TabItem[] oldTabItems = new TabItem[mapping.length];
|
||||
int nextIndex = startIndex;
|
||||
|
||||
//Reorder the tab items by adding new tab items before the old ones.//
|
||||
for(int index = 0; index < mapping.length; index++) {
|
||||
int oldIndex = nextIndex + index + mapping[index];
|
||||
TabItem oldTabItem = getSwtTabFolder().getItem(oldIndex);
|
||||
TabItem tabItem = new org.eclipse.swt.widgets.TabItem(getSwtTabFolder(), 0, index);
|
||||
Component component = (Component) oldTabItem.getData();
|
||||
|
||||
tabItem.setText(oldTabItem.getText());
|
||||
tabItem.setImage(oldTabItem.getImage());
|
||||
tabItem.setToolTipText(oldTabItem.getToolTipText());
|
||||
tabItem.setControl(oldTabItem.getControl());
|
||||
tabItem.setData(oldTabItem.getData());
|
||||
oldTabItems[index] = oldTabItem;
|
||||
tabItemsByComponentMap.put(component, tabItem);
|
||||
nextIndex++;
|
||||
}//for//
|
||||
|
||||
//Remove the old tab items.//
|
||||
for(int index = 0; index < oldTabItems.length; index++) {
|
||||
oldTabItems[index].dispose();
|
||||
}//for//
|
||||
break;
|
||||
}//case//
|
||||
default: {
|
||||
result = super.internalProcessMessage(viewMessage);
|
||||
}//default//
|
||||
}//switch//
|
||||
|
||||
return result;
|
||||
}//internalProcessMessage()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.Component.IComponentListener#toolTipTextChanged(com.foundation.tcv.swt.client.Component, java.lang.String)
|
||||
*/
|
||||
public void toolTipTextChanged(Component component, String newToolTipText) {
|
||||
TabItem tabItem = (TabItem) tabItemsByComponentMap.get(component);
|
||||
|
||||
if(tabItem != null && !tabItem.isDisposed()) {
|
||||
tabItem.setToolTipText(newToolTipText);
|
||||
}//if//
|
||||
}//toolTipTextChanged()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.Component.IComponentListener#imageChanged(com.foundation.tcv.swt.client.Component, org.eclipse.swt.graphics.Image)
|
||||
*/
|
||||
public void imageChanged(Component component, Image image) {
|
||||
TabItem tabItem = (TabItem) tabItemsByComponentMap.get(component);
|
||||
|
||||
if(tabItem != null && !tabItem.isDisposed()) {
|
||||
tabItem.setImage(image);
|
||||
}//if//
|
||||
}//imageChanged()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.Component.IComponentListener#titleChanged(com.foundation.tcv.swt.client.Component, java.lang.String)
|
||||
*/
|
||||
public void titleChanged(Component component, String newTitle) {
|
||||
TabItem tabItem = (TabItem) tabItemsByComponentMap.get(component);
|
||||
|
||||
if(tabItem != null && !tabItem.isDisposed()) {
|
||||
tabItem.setText(newTitle);
|
||||
}//if//
|
||||
}//titleChanged()//
|
||||
}//TabPanel//
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,687 @@
|
||||
/*
|
||||
* 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.tcv.swt.client;
|
||||
|
||||
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.tcv.client.view.ResourceHolder;
|
||||
import com.foundation.tcv.model.LinkInfo;
|
||||
import com.foundation.tcv.swt.IToolBar;
|
||||
import com.foundation.tcv.view.ViewMessage;
|
||||
import com.foundation.view.JefImage;
|
||||
import com.foundation.view.LinkData;
|
||||
import com.foundation.view.swt.util.SwtUtilities;
|
||||
|
||||
public class ToolBar extends Container implements IToolBar {
|
||||
/** 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 implements IToolBar.IAbstractToolItem {
|
||||
private Container container = null;
|
||||
/** Whether this is a stateful item. */
|
||||
protected boolean isStateful = false;
|
||||
/** Whether this is a separator. */
|
||||
protected boolean isSeparator = false;
|
||||
/** Whether this is a separator. */
|
||||
protected boolean isDropDown = false;
|
||||
/** 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;
|
||||
/** A holder for the value of the tool tip text. */
|
||||
private ResourceHolder toolTipTextHolder = new ResourceHolder(this);
|
||||
/** A holder for the value of the enabled state flag. */
|
||||
private ResourceHolder isEnabledHolder = new ResourceHolder(this);
|
||||
|
||||
/**
|
||||
* AbstractToolItem constructor.
|
||||
*/
|
||||
public AbstractToolItem() {
|
||||
}//AbstractToolItem()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.view.IAbstractComponent#getContainer()
|
||||
*/
|
||||
public Container getContainer() {
|
||||
return container;
|
||||
}//getContainer()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.view.swt.IInternalAbstractComponent#getShell()
|
||||
*/
|
||||
public Shell getShell() {
|
||||
return container != null ? container.getShell() : null;
|
||||
}//getShell()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.AbstractComponent#internalProcessMessage(com.foundation.tcv.view.ViewMessage)
|
||||
*/
|
||||
public Object internalProcessMessage(ViewMessage viewMessage) {
|
||||
Object result = null;
|
||||
|
||||
switch(viewMessage.getMessageNumber()) {
|
||||
case MESSAGE_INITIALIZE: {
|
||||
if(getSwtToolItem() == null) {
|
||||
int[] data = (int[]) viewMessage.getMessageData();
|
||||
int style = data[1];
|
||||
|
||||
//Link to the parent container.//
|
||||
this.container = (Container) getComponent(data[0]);
|
||||
((ToolBar) getContainer()).addToolItem(this);
|
||||
//Create the SWT widget.//
|
||||
setSwtWidget(new org.eclipse.swt.widgets.ToolItem(((ToolBar) getContainer()).getSwtToolBar(), style));
|
||||
getSwtWidget().setData(this);
|
||||
isStateful = ((style & STYLE_RADIO) > 0) || ((style & STYLE_CHECK) > 0);
|
||||
isSeparator = ((style & STYLE_SEPARATOR) > 0);
|
||||
isDropDown = ((style & STYLE_DROP_DOWN) > 0);
|
||||
}//if//
|
||||
break;
|
||||
}//case//
|
||||
case MESSAGE_SET_IS_ENABLED: {
|
||||
isEnabledHolder.setValue(viewMessage.getMessageData());
|
||||
break;
|
||||
}//case//
|
||||
case MESSAGE_SET_TOOL_TIP_TEXT: {
|
||||
toolTipTextHolder.setValue(viewMessage.getMessageData());
|
||||
break;
|
||||
}//case//
|
||||
default: {
|
||||
result = super.internalProcessMessage(viewMessage);
|
||||
}//default//
|
||||
}//switch//
|
||||
|
||||
return result;
|
||||
}//internalProcessMessage()//
|
||||
/* (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()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.AbstractComponent#internalResourceHolderChanged(com.foundation.tcv.client.view.ResourceHolder, java.lang.Object, java.lang.Object, int)
|
||||
*/
|
||||
protected void internalResourceHolderChanged(ResourceHolder resource, Object oldValue, Object newValue, int flags) {
|
||||
if(resource == toolTipTextHolder) {
|
||||
getSwtToolItem().setToolTipText((String) newValue);
|
||||
}//if//
|
||||
else if(resource == isEnabledHolder) {
|
||||
internalSetEnabledState(((Boolean) newValue).booleanValue());
|
||||
//TODO: Determine whether the size will change before resizing. This can help eliminate flashing.
|
||||
//resize();
|
||||
}//else if//
|
||||
else {
|
||||
super.internalResourceHolderChanged(resource, oldValue, newValue, flags);
|
||||
}//else//
|
||||
}//internalOnAssociationChanged()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.AbstractComponent#internalViewRelease()
|
||||
*/
|
||||
protected void internalViewRelease() {
|
||||
toolTipTextHolder.release();
|
||||
isEnabledHolder.release();
|
||||
|
||||
if(!getSwtToolItem().isDisposed()) {
|
||||
getSwtToolItem().dispose();
|
||||
}//if//
|
||||
|
||||
super.internalViewRelease();
|
||||
}//internalViewRelease()//
|
||||
/**
|
||||
* 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()//
|
||||
/**
|
||||
* 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()//
|
||||
/**
|
||||
* 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()//
|
||||
}//AbstractToolItem//
|
||||
|
||||
/**
|
||||
* Encapsulates an item in the bar.
|
||||
*/
|
||||
public static class ToolItem extends AbstractToolItem implements IToolBar.IToolItem, SelectionListener {
|
||||
/** The custom control displayed by the tool item. */
|
||||
private Component control = null;
|
||||
/** The popup menu displayed when the tool item is a drop down. */
|
||||
private Menu menu = null;
|
||||
/** The linkage for the selection. */
|
||||
private Linkage selectionLinkage = new Linkage();
|
||||
/** The task that auto synchronizes the selection after a short delay. */
|
||||
private Task autoSynchronizeSelectionTask = 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;
|
||||
/** Whether the item has a custom width. */
|
||||
private boolean customWidth = false;
|
||||
/** The last selection state in the model, known to the component. Used to reduce method calling & round trip messages. */
|
||||
private boolean selectionState = false;
|
||||
/** Whether selection notifications to the server will block for a response. */
|
||||
private boolean blockOnSelections = false;
|
||||
/** 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.
|
||||
*/
|
||||
public ToolItem() {
|
||||
}//ToolItem()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.AbstractComponent#internalProcessMessage(com.foundation.tcv.view.ViewMessage)
|
||||
*/
|
||||
public Object internalProcessMessage(ViewMessage viewMessage) {
|
||||
Object result = null;
|
||||
|
||||
switch(viewMessage.getMessageNumber()) {
|
||||
case MESSAGE_SET_BLOCK_ON_SELECTIONS: {
|
||||
blockOnSelections = ((Boolean) viewMessage.getMessageData()).booleanValue();
|
||||
break;
|
||||
}//case//
|
||||
case MESSAGE_AUTO_SIZE: {
|
||||
//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//
|
||||
break;
|
||||
}//case//
|
||||
case MESSAGE_SET_TEXT: {
|
||||
textHolder.setValue(viewMessage.getMessageData());
|
||||
break;
|
||||
}//case//
|
||||
case MESSAGE_SET_IMAGE: {
|
||||
imageHolder.setValue(viewMessage.getMessageData());
|
||||
break;
|
||||
}//case//
|
||||
case MESSAGE_SET_HOT_IMAGE: {
|
||||
hotImageHolder.setValue(viewMessage.getMessageData());
|
||||
break;
|
||||
}//case//
|
||||
case MESSAGE_SET_DISABLED_IMAGE: {
|
||||
disabledImageHolder.setValue(viewMessage.getMessageData());
|
||||
break;
|
||||
}//case//
|
||||
case MESSAGE_SET_IS_SELECTED: {
|
||||
Boolean isSelected = (Boolean) viewMessage.getMessageData();
|
||||
|
||||
//Only set the selection if it has changed.//
|
||||
if(isSelected.booleanValue() != getSwtToolItem().getSelection()) {
|
||||
getSwtToolItem().setSelection(isSelected.booleanValue());
|
||||
selectionState = isSelected.booleanValue();
|
||||
|
||||
//Send feedback to the server so that it will properly maintain state.//
|
||||
if(autoSynchronizeSelection) {
|
||||
sendMessage(MESSAGE_VIEW_SYNCHRONIZE_SELECTION, isSelected);
|
||||
}//if//
|
||||
|
||||
selectionLinkage.invoke(isSelected);
|
||||
}//if//
|
||||
break;
|
||||
}//case//
|
||||
case MESSAGE_SET_AUTO_SYNCHRONIZE_SELECTION: {
|
||||
autoSynchronizeSelection = ((Boolean) viewMessage.getMessageData()).booleanValue();
|
||||
break;
|
||||
}//case//
|
||||
case MESSAGE_SET_AUTO_SYNCHRONIZE_SELECTION_DELAY: {
|
||||
autoSynchronizeSelectionDelay = ((Long) viewMessage.getMessageData()).longValue();
|
||||
break;
|
||||
}//case//
|
||||
case MESSAGE_ADD_SELECTION_LINK: {
|
||||
LinkInfo info = (LinkInfo) viewMessage.getMessageData();
|
||||
|
||||
selectionLinkage.add(new LinkData(getComponent(info.getComponent()), info.getTarget(), info.getData(), info.isBoolean(), info.invertLogic(), info.nullValue()));
|
||||
break;
|
||||
}//case//
|
||||
case MESSAGE_SET_CONTROL: {
|
||||
int[] data = (int[]) viewMessage.getMessageData();
|
||||
|
||||
control = (Component) getComponent(data[0]);
|
||||
//TODO: If we are already initialized we should swap controls. Currently this could not happen, but we may allow it in the future.
|
||||
break;
|
||||
}//case//
|
||||
case MESSAGE_SET_MENU: {
|
||||
int[] data = (int[]) viewMessage.getMessageData();
|
||||
|
||||
menu = (Menu) getComponent(data[0]);
|
||||
break;
|
||||
}//case//
|
||||
case MESSAGE_SET_WIDTH: {
|
||||
customWidth = true;
|
||||
getSwtToolItem().setWidth(((Integer) viewMessage.getMessageData()).intValue());
|
||||
break;
|
||||
}//case//
|
||||
default: {
|
||||
result = super.internalProcessMessage(viewMessage);
|
||||
}//default//
|
||||
}//switch//
|
||||
|
||||
return result;
|
||||
}//internalProcessMessage()//
|
||||
/* (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()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.AbstractComponent#internalResourceHolderChanged(com.foundation.tcv.client.view.ResourceHolder, java.lang.Object, java.lang.Object, int)
|
||||
*/
|
||||
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 com.foundation.view.swt.AbstractComponent#internalViewInitialize()
|
||||
*/
|
||||
protected void internalViewInitialize() {
|
||||
getSwtToolItem().addSelectionListener(this);
|
||||
super.internalViewInitialize();
|
||||
|
||||
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//
|
||||
|
||||
textHolder.release();
|
||||
imageHolder.release();
|
||||
hotImageHolder.release();
|
||||
disabledImageHolder.release();
|
||||
|
||||
super.internalViewRelease();
|
||||
}//internalViewRelease()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.AbstractComponent#internalViewSynchronize()
|
||||
*/
|
||||
protected void internalViewSynchronize() {
|
||||
super.internalViewSynchronize();
|
||||
|
||||
if(!autoSynchronizeSelection) {
|
||||
boolean selection = getSwtToolItem().getSelection();
|
||||
|
||||
if(selectionState != selection) {
|
||||
selectionState = selection;
|
||||
sendMessage(MESSAGE_VIEW_SYNCHRONIZE_SELECTION, selection ? Boolean.TRUE : Boolean.FALSE);
|
||||
}//if//
|
||||
}//if//
|
||||
}//internalViewSynchronize()//
|
||||
/**
|
||||
* Sets the control used by the tool item.
|
||||
* @param control The tool item's control.
|
||||
*/
|
||||
public void setControl(Component control) {
|
||||
this.control = control;
|
||||
}//setControl()//
|
||||
/* (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) {
|
||||
//Handle the button selection.//
|
||||
if((blockOnSelections) || (autoSynchronizeSelection)) {
|
||||
if((!blockOnSelections) && (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() {
|
||||
sendMessage(MESSAGE_VIEW_SYNCHRONIZE_SELECTION, isSelected ? Boolean.TRUE : Boolean.FALSE);
|
||||
return null;
|
||||
}//run()//
|
||||
});
|
||||
}//if//
|
||||
}//synchronized//
|
||||
}//run()//
|
||||
};
|
||||
addTask(autoSynchronizeSelectionTask, autoSynchronizeSelectionDelay);
|
||||
}//synchronized//
|
||||
}//if//
|
||||
else {
|
||||
if(blockOnSelections) {
|
||||
sendRoundTripMessage(MESSAGE_VIEW_SYNCHRONIZE_SELECTION, isSelected ? Boolean.TRUE : Boolean.FALSE, null);
|
||||
}//if//
|
||||
else {
|
||||
sendMessage(MESSAGE_VIEW_SYNCHRONIZE_SELECTION, isSelected ? Boolean.TRUE : Boolean.FALSE);
|
||||
}//else//
|
||||
}//else//
|
||||
}//if//
|
||||
|
||||
selectionLinkage.invoke(isStateful ? isSelected ? Boolean.TRUE : Boolean.FALSE : null);
|
||||
}//selectionChanged()//
|
||||
}//ToolItem//
|
||||
/**
|
||||
* ToolBar constructor.
|
||||
*/
|
||||
public ToolBar() {
|
||||
super();
|
||||
}//ToolBar()//
|
||||
/**
|
||||
* Adds a tool item to the bar.
|
||||
* @param toolItem The item to be added.
|
||||
*/
|
||||
protected void addToolItem(AbstractToolItem toolItem) {
|
||||
toolItems.add(toolItem); //TODO: Is this necessary?
|
||||
|
||||
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.tcv.swt.client.AbstractComponent#internalProcessMessage(com.foundation.tcv.view.ViewMessage)
|
||||
*/
|
||||
public Object internalProcessMessage(ViewMessage viewMessage) {
|
||||
Object result = null;
|
||||
|
||||
switch(viewMessage.getMessageNumber()) {
|
||||
case MESSAGE_INITIALIZE: {
|
||||
if(getSwtToolBar() == null) {
|
||||
int[] data = (int[]) viewMessage.getMessageData();
|
||||
int style = data[1];
|
||||
|
||||
//Link to the parent container.//
|
||||
setContainer((Container) getComponent(data[0]));
|
||||
getContainer().addComponent(this);
|
||||
//Create the SWT widget.//
|
||||
setSwtWidget(new org.eclipse.swt.widgets.ToolBar(getContainer().getSwtParent(), style));
|
||||
getSwtWidget().setData(this);
|
||||
|
||||
//If the container has already been initialized then force the parent to re-layout so that this component will appear.//
|
||||
if(getContainer().isInitialized()) {
|
||||
getContainer().getSwtComposite().layout(true, true);
|
||||
}//if//
|
||||
}//if//
|
||||
break;
|
||||
}//case//
|
||||
default: {
|
||||
result = super.internalProcessMessage(viewMessage);
|
||||
}//default//
|
||||
}//switch//
|
||||
|
||||
return result;
|
||||
}//internalProcessMessage()//
|
||||
/**
|
||||
* 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.tcv.swt.client.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.tcv.swt.client.AbstractComponent#internalViewRelease()
|
||||
*/
|
||||
protected void internalViewRelease() {
|
||||
super.internalViewRelease();
|
||||
}//internalViewRelease()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.AbstractComponent#internalViewInitializeAll()
|
||||
*/
|
||||
protected 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.tcv.swt.client.AbstractComponent#internalViewReleaseAll()
|
||||
*/
|
||||
protected 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.tcv.swt.client.AbstractComponent#internalViewSynchronizeAll()
|
||||
*/
|
||||
protected 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.tcv.swt.client.Component#setMenu(com.foundation.tcv.swt.client.Menu)
|
||||
*/
|
||||
public void setMenu(Menu menu) {
|
||||
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//
|
||||
@@ -0,0 +1,798 @@
|
||||
/*
|
||||
* 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.tcv.swt.client;
|
||||
|
||||
import org.eclipse.swt.SWT;
|
||||
import org.eclipse.swt.events.ControlEvent;
|
||||
import org.eclipse.swt.events.ControlListener;
|
||||
import org.eclipse.swt.events.MouseEvent;
|
||||
import org.eclipse.swt.events.MouseListener;
|
||||
import org.eclipse.swt.events.MouseTrackListener;
|
||||
import org.eclipse.swt.events.SelectionEvent;
|
||||
import org.eclipse.swt.events.SelectionListener;
|
||||
import org.eclipse.swt.events.ShellEvent;
|
||||
import org.eclipse.swt.events.ShellListener;
|
||||
import org.eclipse.swt.events.TraverseEvent;
|
||||
import org.eclipse.swt.events.TraverseListener;
|
||||
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.RGB;
|
||||
import org.eclipse.swt.graphics.Rectangle;
|
||||
import com.foundation.view.swt.layout.GridData;
|
||||
import com.foundation.view.swt.layout.GridLayout;
|
||||
import org.eclipse.swt.widgets.ColorDialog;
|
||||
import org.eclipse.swt.widgets.Control;
|
||||
import org.eclipse.swt.widgets.Event;
|
||||
import org.eclipse.swt.widgets.Label;
|
||||
import org.eclipse.swt.widgets.Listener;
|
||||
import org.eclipse.swt.widgets.Shell;
|
||||
|
||||
import com.common.comparison.Comparator;
|
||||
import com.common.debug.Debug;
|
||||
import com.foundation.tcv.client.view.ResourceHolder;
|
||||
import com.foundation.tcv.model.LinkInfo;
|
||||
import com.foundation.tcv.swt.IToolItemDropColor;
|
||||
import com.foundation.tcv.swt.client.ToolBar.AbstractToolItem;
|
||||
import com.foundation.tcv.view.ViewMessage;
|
||||
import com.foundation.view.JefColor;
|
||||
import com.foundation.view.LinkData;
|
||||
import com.foundation.view.resource.ResourceReference;
|
||||
import com.foundation.view.swt.util.SwtUtilities;
|
||||
|
||||
public class ToolItemDropColor extends AbstractToolItem implements SelectionListener, IToolItemDropColor {
|
||||
/** The linkage for the selected color. */
|
||||
private Linkage colorLinkage = new Linkage();
|
||||
/** The width for the color swatch image. */
|
||||
private int width = 17;
|
||||
/** The height for the color swatch image. */
|
||||
private int height = 17;
|
||||
/** The color used if no color is selected. This should be null if no color is a valid option. */
|
||||
private JefColor defaultColor = null;
|
||||
/** The currently selected color. */
|
||||
private JefColor selectedColor = null;
|
||||
/** The currently selected color image. */
|
||||
private Image selectedColorImage = null;
|
||||
/** Whether the selection state is auto synchronized. */
|
||||
private boolean autoSynchronizeSelection = true;
|
||||
/** The drop down display. */
|
||||
private DropDown dropDown = null;
|
||||
|
||||
/**
|
||||
* The drop down display allowing the user to select from a palette of colors.
|
||||
*/
|
||||
private class DropDown implements MouseTrackListener, MouseListener, ShellListener {
|
||||
private static final String STANDARD = "standard";
|
||||
private static final String SELECTED = "selected";
|
||||
private static final String HOVER = "hover";
|
||||
private static final String COLOR = "color";
|
||||
private static final int imageSize = 10;
|
||||
private static final int labelSize = 16; //(labelSize - imageSize) must be evenly dividable by 2.//
|
||||
private static final int imageBorder = (labelSize - imageSize) >> 1;
|
||||
private static final int columns = 8;
|
||||
private static final int rows = 5;
|
||||
private final JefColor[][] colors = new JefColor[][] {
|
||||
{new JefColor(0, 0, 0), new JefColor(128, 0, 0), new JefColor(255, 0, 0), new JefColor(255, 0, 255), new JefColor(255, 153, 204)},
|
||||
{new JefColor(153, 51, 0), new JefColor(255, 102, 0), new JefColor(255, 153, 0), new JefColor(255, 204, 0), new JefColor(255, 204, 153)},
|
||||
{new JefColor(51, 51, 0), new JefColor(128, 128, 0), new JefColor(0, 153, 204), new JefColor(255, 255, 0), new JefColor(255, 255, 203)},
|
||||
{new JefColor(0, 51, 0), new JefColor(0, 128, 0), new JefColor(51, 153, 102), new JefColor(0, 255, 0), new JefColor(204, 255, 204)},
|
||||
{new JefColor(0, 51, 102), new JefColor(0, 128, 128), new JefColor(51, 204, 204), new JefColor(0, 255, 255), new JefColor(204, 255, 255)},
|
||||
{new JefColor(0, 0, 128), new JefColor(0, 0, 255), new JefColor(51, 102, 255), new JefColor(0, 204, 255), new JefColor(153, 204, 255)},
|
||||
{new JefColor(51, 51, 153), new JefColor(102, 102, 153), new JefColor(128, 0, 128), new JefColor(153, 51, 102), new JefColor(204, 153, 255)},
|
||||
{new JefColor(51, 51, 51), new JefColor(128, 128, 128), new JefColor(153, 153, 153), new JefColor(192, 192, 192), new JefColor(255, 255, 255)},
|
||||
};
|
||||
private final JefColor outerBorderColor = new JefColor(0, 0, 255, 255);
|
||||
private final JefColor innerBorderColor = new JefColor(92, 92, 92);
|
||||
private final JefColor hoverFillColor = new JefColor(0, 0, 255, 42);
|
||||
private final JefColor selectedFillColor = new JefColor(0, 0, 255, 72);
|
||||
private final JefColor noColor = new JefColor(255, 255, 255, 0);
|
||||
|
||||
private Shell dropShell = new Shell(SWT.NO_TRIM | SWT.TOOL | SWT.ON_TOP | SWT.NO_FOCUS);
|
||||
private Label noColorLabel = null;
|
||||
private Label moreLabel = null;
|
||||
private Label[][] colorLabels = new Label[columns][rows];
|
||||
private JefColor selectedColor = null;
|
||||
private boolean isMouseDown = false;
|
||||
private Label mouseDownLabel = null;
|
||||
private Label mouseOverLabel = null;
|
||||
private Label selectedLabel = null;
|
||||
|
||||
/**
|
||||
* DropDown constructor.
|
||||
*/
|
||||
public DropDown() {
|
||||
GridLayout gridLayout = new GridLayout(8, false);
|
||||
GridData gridData;
|
||||
int totalWidth = columns * labelSize;
|
||||
|
||||
gridLayout.horizontalSpacing = 0;
|
||||
gridLayout.verticalSpacing = 0;
|
||||
gridLayout.marginHeight = 0;
|
||||
gridLayout.marginWidth = 0;
|
||||
gridLayout.marginRight = 0;
|
||||
gridLayout.marginBottom = 0;
|
||||
dropShell.setLayout(gridLayout);
|
||||
dropShell.setBackgroundMode(SWT.INHERIT_FORCE);
|
||||
dropShell.setBackground(SwtUtilities.getColor(dropShell.getDisplay(), noColor));
|
||||
|
||||
if(defaultColor == null) {
|
||||
gridData = new GridData(SWT.FILL, SWT.CENTER, false, false, 8, 1);
|
||||
gridData.minimumHeight = labelSize;
|
||||
gridData.heightHint = labelSize;
|
||||
noColorLabel = new Label(dropShell, SWT.NONE);
|
||||
noColorLabel.setText("None");
|
||||
noColorLabel.setAlignment(SWT.CENTER);
|
||||
noColorLabel.setLayoutData(gridData);
|
||||
noColorLabel.setVisible(true);
|
||||
noColorLabel.setData(STANDARD, createColorImage(totalWidth, labelSize, imageBorder, noColor, null, null, null));
|
||||
noColorLabel.setData(HOVER, createColorImage(totalWidth, labelSize, imageBorder, hoverFillColor, null, outerBorderColor, hoverFillColor));
|
||||
noColorLabel.setData(SELECTED, createColorImage(totalWidth, labelSize, imageBorder, selectedFillColor, null, outerBorderColor, selectedFillColor));
|
||||
noColorLabel.setData(COLOR, null);
|
||||
noColorLabel.addMouseListener(this);
|
||||
noColorLabel.addMouseTrackListener(this);
|
||||
}//if//
|
||||
|
||||
for(int y = 0; y < rows; y++) {
|
||||
for(int x = 0; x < columns; x++) {
|
||||
Label colorLabel = new Label(dropShell, SWT.NONE);
|
||||
|
||||
gridData = new GridData(SWT.CENTER, SWT.CENTER, false, false, 1, 1);
|
||||
gridData.minimumWidth = labelSize;
|
||||
gridData.minimumHeight = labelSize;
|
||||
colorLabel.setLayoutData(gridData);
|
||||
colorLabel.setData(STANDARD, createColorImage(labelSize, labelSize, imageBorder, colors[x][y], innerBorderColor, null, null));
|
||||
colorLabel.setData(HOVER, createColorImage(labelSize, labelSize, imageBorder, colors[x][y], innerBorderColor, outerBorderColor, hoverFillColor));
|
||||
colorLabel.setData(SELECTED, createColorImage(labelSize, labelSize, imageBorder, colors[x][y], innerBorderColor, outerBorderColor, selectedFillColor));
|
||||
colorLabel.setData(COLOR, colors[x][y]);
|
||||
colorLabel.setImage((Image) colorLabel.getData(STANDARD));
|
||||
colorLabels[x][y] = colorLabel;
|
||||
colorLabel.addMouseListener(this);
|
||||
colorLabel.addMouseTrackListener(this);
|
||||
}//for//
|
||||
}//for//
|
||||
|
||||
gridData = new GridData(SWT.FILL, SWT.CENTER, false, false, 8, 1);
|
||||
gridData.minimumHeight = labelSize;
|
||||
gridData.heightHint = labelSize;
|
||||
moreLabel = new Label(dropShell, SWT.NONE);
|
||||
moreLabel.setBackground(SwtUtilities.getColor(dropShell.getDisplay(), noColor));
|
||||
moreLabel.setText("More...");
|
||||
moreLabel.setAlignment(SWT.CENTER);
|
||||
moreLabel.setLayoutData(gridData);
|
||||
moreLabel.setData(STANDARD, createColorImage(totalWidth, labelSize, imageBorder, noColor, null, null, null));
|
||||
moreLabel.setData(HOVER, createColorImage(totalWidth, labelSize, imageBorder, hoverFillColor, null, outerBorderColor, hoverFillColor));
|
||||
moreLabel.setData(SELECTED, createColorImage(totalWidth, labelSize, imageBorder, selectedFillColor, null, outerBorderColor, selectedFillColor));
|
||||
moreLabel.setData(COLOR, null);
|
||||
moreLabel.addMouseListener(this);
|
||||
moreLabel.addMouseTrackListener(this);
|
||||
|
||||
dropShell.addMouseTrackListener(this);
|
||||
dropShell.addMouseListener(this);
|
||||
dropShell.addShellListener(this);
|
||||
dropShell.layout(true, true);
|
||||
dropShell.pack(true);
|
||||
}//DropDown()//
|
||||
/**
|
||||
* Disposes of all resources associated with this drop down.
|
||||
*/
|
||||
public void dispose() {
|
||||
if((noColorLabel != null) && (!noColorLabel.isDisposed())) {
|
||||
((Image) noColorLabel.getData(SELECTED)).dispose();
|
||||
((Image) noColorLabel.getData(HOVER)).dispose();
|
||||
((Image) noColorLabel.getData(STANDARD)).dispose();
|
||||
noColorLabel.dispose();
|
||||
}//if//
|
||||
|
||||
for(int y = 0; y < rows; y++) {
|
||||
for(int x = 0; x < columns; x++) {
|
||||
if((colorLabels[x][y] != null) && (!colorLabels[x][y].isDisposed())) {
|
||||
((Image) colorLabels[x][y].getData(SELECTED)).dispose();
|
||||
((Image) colorLabels[x][y].getData(HOVER)).dispose();
|
||||
((Image) colorLabels[x][y].getData(STANDARD)).dispose();
|
||||
colorLabels[x][y].dispose();
|
||||
}//if//
|
||||
}//for//
|
||||
}//for//
|
||||
|
||||
if((moreLabel != null) && (!moreLabel.isDisposed())) {
|
||||
((Image) moreLabel.getData(SELECTED)).dispose();
|
||||
((Image) moreLabel.getData(HOVER)).dispose();
|
||||
((Image) moreLabel.getData(STANDARD)).dispose();
|
||||
moreLabel.dispose();
|
||||
}//if//
|
||||
|
||||
if((dropShell != null) && (!dropShell.isDisposed())) {
|
||||
dropShell.dispose();
|
||||
}//if//
|
||||
}//dispose()//
|
||||
/**
|
||||
* Opens the color dialog allowing the user to choose from a wider range of colors.
|
||||
*/
|
||||
protected void openColorDialog() {
|
||||
ColorDialog dialog = new ColorDialog(getShell(), 0);
|
||||
RGB result = null;
|
||||
|
||||
dialog.setText("Colors");
|
||||
dialog.setRGB(selectedColor != null ? new RGB(selectedColor.getRed() & 0xFF, selectedColor.getGreen() & 0xFF, selectedColor.getBlue() & 0xFF) : new RGB(255, 255, 255));
|
||||
result = dialog.open();
|
||||
|
||||
if(result != null) {
|
||||
setSelectedColor(new JefColor(result.red, result.green, result.blue), true);
|
||||
}//if//
|
||||
}//openColorDialog()//
|
||||
/**
|
||||
* Shows the drop down at the given location with the given color selected.
|
||||
* @param location The location to display the shell in screen coordinates.
|
||||
* @param selectedColor The color to be selected.
|
||||
*/
|
||||
public void show(Point location, JefColor selectedColor) {
|
||||
//Set the initial selection.//
|
||||
this.selectedColor = selectedColor;
|
||||
//Reset the images for the labels.//
|
||||
setLabelImage(noColorLabel, (Image) noColorLabel.getData(STANDARD));
|
||||
setLabelImage(moreLabel, (Image) moreLabel.getData(STANDARD));
|
||||
|
||||
//Reset the images for the color labels.//
|
||||
for(int y = 0; y < rows; y++) {
|
||||
for(int x = 0; x < columns; x++) {
|
||||
setLabelImage(colorLabels[x][y], (Image) colorLabels[x][y].getData(STANDARD));
|
||||
}//for//
|
||||
}//for//
|
||||
|
||||
//Select the currently selected label if there is one.//
|
||||
if(selectedColor == null) {
|
||||
noColorLabel.setBackgroundImage((Image) noColorLabel.getData(SELECTED));
|
||||
selectedLabel = noColorLabel;
|
||||
}//if//
|
||||
else {
|
||||
selectedLabel = null;
|
||||
|
||||
for(int y = 0; (selectedLabel == null) && (y < rows); y++) {
|
||||
for(int x = 0; (selectedLabel == null) && (x < columns); x++) {
|
||||
if(Comparator.equals(selectedColor, colors[x][y])) {
|
||||
colorLabels[x][y].setImage((Image) colorLabels[x][y].getData(SELECTED));
|
||||
selectedLabel = colorLabels[x][y];
|
||||
}//if//
|
||||
}//for//
|
||||
}//for//
|
||||
}//else//
|
||||
|
||||
dropShell.setLocation(location);
|
||||
dropShell.setVisible(true);
|
||||
dropShell.setActive();
|
||||
//dropShell.setFocus();
|
||||
}//show()//
|
||||
/**
|
||||
* Hides the drop down shell.
|
||||
* @param synchronize Whether the selection changes should be synchronized.
|
||||
*/
|
||||
public void hide(boolean synchronize) {
|
||||
if(synchronize) {
|
||||
setSelectedColor(selectedColor, true);
|
||||
}//if//
|
||||
|
||||
dropShell.setVisible(false);
|
||||
}//hide()//
|
||||
/**
|
||||
* Sets the image for the label.
|
||||
* @param label The label.
|
||||
* @param image The label's image.
|
||||
*/
|
||||
private void setLabelImage(Label label, Image image) {
|
||||
if((label == moreLabel) || (label == noColorLabel)) {
|
||||
label.setBackgroundImage(image);
|
||||
}//if//
|
||||
else {
|
||||
label.setImage(image);
|
||||
}//else//
|
||||
}//setLabelImage()//
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.swt.events.MouseTrackListener#mouseHover(org.eclipse.swt.events.MouseEvent)
|
||||
*/
|
||||
public void mouseHover(MouseEvent event) {
|
||||
}//mouseHover()//
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.swt.events.MouseTrackListener#mouseExit(org.eclipse.swt.events.MouseEvent)
|
||||
*/
|
||||
public void mouseExit(MouseEvent event) {
|
||||
if(event.widget instanceof Label) {
|
||||
Label label = (Label) event.widget;
|
||||
|
||||
if(mouseOverLabel == label) {
|
||||
if(selectedLabel != label) {
|
||||
//Change the control's image back to the standard image.//
|
||||
setLabelImage(label, (Image) label.getData(STANDARD));
|
||||
}//if//
|
||||
|
||||
mouseOverLabel = null;
|
||||
}//if//
|
||||
}//if//
|
||||
}//mouseExit()//
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.swt.events.MouseTrackListener#mouseEnter(org.eclipse.swt.events.MouseEvent)
|
||||
*/
|
||||
public void mouseEnter(MouseEvent event) {
|
||||
if(!isMouseDown) {
|
||||
if(event.widget instanceof Label) {
|
||||
Label label = (Label) event.widget;
|
||||
|
||||
if(mouseOverLabel != label) {
|
||||
if(mouseOverLabel != null) {
|
||||
if(selectedLabel != mouseOverLabel) {
|
||||
setLabelImage(mouseOverLabel, (Image) mouseOverLabel.getData(STANDARD));
|
||||
}//if//
|
||||
|
||||
mouseOverLabel = null;
|
||||
}//if//
|
||||
|
||||
if(selectedLabel != label) {
|
||||
//Change the control's image to the hover image.//
|
||||
setLabelImage(label, (Image) label.getData(HOVER));
|
||||
mouseOverLabel = label;
|
||||
}//if//
|
||||
}//if//
|
||||
}//if//
|
||||
}//if//
|
||||
}//mouseEnter()//
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.swt.events.MouseListener#mouseUp(org.eclipse.swt.events.MouseEvent)
|
||||
*/
|
||||
public void mouseUp(MouseEvent event) {
|
||||
if(event.widget instanceof Label) {
|
||||
Label label = (Label) event.widget;
|
||||
|
||||
if(label == mouseDownLabel) {
|
||||
if(label == moreLabel) {
|
||||
setLabelImage(label, (Image) label.getData(HOVER));
|
||||
//Open the more dialog.//
|
||||
hide(false);
|
||||
openColorDialog();
|
||||
}//if//
|
||||
else {
|
||||
if(label != selectedLabel) {
|
||||
if(selectedLabel != null) {
|
||||
setLabelImage(selectedLabel, (Image) selectedLabel.getData(STANDARD));
|
||||
}//if//
|
||||
|
||||
selectedColor = (JefColor) label.getData(COLOR);
|
||||
selectedLabel = label;
|
||||
}//if//
|
||||
}//else//
|
||||
}//if//
|
||||
}//if//
|
||||
|
||||
isMouseDown = false;
|
||||
mouseDownLabel = null;
|
||||
}//mouseUp()//
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.swt.events.MouseListener#mouseDown(org.eclipse.swt.events.MouseEvent)
|
||||
*/
|
||||
public void mouseDown(MouseEvent event) {
|
||||
isMouseDown = true;
|
||||
|
||||
if(event.widget instanceof Label) {
|
||||
Label label = (Label) event.widget;
|
||||
|
||||
if((label != selectedLabel) || (label == moreLabel)) {
|
||||
//Set the selection, but don't close the view.//
|
||||
setLabelImage(label, (Image) label.getData(SELECTED));
|
||||
}//if//
|
||||
|
||||
mouseDownLabel = label;
|
||||
}//if//
|
||||
}//mouseDown()//
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.swt.events.MouseListener#mouseDoubleClick(org.eclipse.swt.events.MouseEvent)
|
||||
*/
|
||||
public void mouseDoubleClick(MouseEvent event) {
|
||||
if(event.widget instanceof Label) {
|
||||
Label label = (Label) event.widget;
|
||||
|
||||
//Clear the selected label's highlighting.//
|
||||
if(selectedLabel != label) {
|
||||
setLabelImage(selectedLabel, (Image) selectedLabel.getData(STANDARD));
|
||||
}//if//
|
||||
|
||||
if(label == moreLabel) {
|
||||
label.setBackgroundImage((Image) label.getData(HOVER));
|
||||
//Open the more dialog.//
|
||||
hide(false);
|
||||
openColorDialog();
|
||||
}//if//
|
||||
else {
|
||||
selectedColor = (JefColor) label.getData(COLOR);
|
||||
hide(true);
|
||||
}//else//
|
||||
}//if//
|
||||
}//mouseDoubleClick()//
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.swt.events.ShellListener#shellActivated(org.eclipse.swt.events.ShellEvent)
|
||||
*/
|
||||
public void shellActivated(ShellEvent event) {
|
||||
}//shellActivated()//
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.swt.events.ShellListener#shellClosed(org.eclipse.swt.events.ShellEvent)
|
||||
*/
|
||||
public void shellClosed(ShellEvent event) {
|
||||
}//shellClosed()//
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.swt.events.ShellListener#shellDeactivated(org.eclipse.swt.events.ShellEvent)
|
||||
*/
|
||||
public void shellDeactivated(ShellEvent event) {
|
||||
hide(true);
|
||||
}//shellDeactivated()//
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.swt.events.ShellListener#shellDeiconified(org.eclipse.swt.events.ShellEvent)
|
||||
*/
|
||||
public void shellDeiconified(ShellEvent event) {
|
||||
}//shellDeiconified()//
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.swt.events.ShellListener#shellIconified(org.eclipse.swt.events.ShellEvent)
|
||||
*/
|
||||
public void shellIconified(ShellEvent event) {
|
||||
}//shellIconified()//
|
||||
}//DropDown//
|
||||
/**
|
||||
* ToolItemDropColor constructor.
|
||||
*/
|
||||
public ToolItemDropColor() {
|
||||
super();
|
||||
}//ToolItemDropColor()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.AbstractComponent#internalViewInitialize()
|
||||
*/
|
||||
protected void internalViewInitialize() {
|
||||
getSwtToolItem().addSelectionListener(this);
|
||||
super.internalViewInitialize();
|
||||
dropDown = new DropDown();
|
||||
|
||||
//Set an initial image.//
|
||||
selectedColorImage = createColorImage(selectedColor);
|
||||
getSwtToolItem().setImage(selectedColorImage);
|
||||
|
||||
//Setup listeners to close the drop down when appropriate.//
|
||||
TraverseListener traverseListener = new TraverseListener() {
|
||||
public void keyTraversed(TraverseEvent event) {
|
||||
switch(event.detail) {
|
||||
case SWT.TRAVERSE_RETURN:
|
||||
case SWT.TRAVERSE_TAB_PREVIOUS:
|
||||
case SWT.TRAVERSE_TAB_NEXT:
|
||||
case SWT.TRAVERSE_ARROW_PREVIOUS:
|
||||
case SWT.TRAVERSE_PAGE_PREVIOUS:
|
||||
case SWT.TRAVERSE_PAGE_NEXT:
|
||||
if(isShowingDrop()) {
|
||||
hideDrop(true);
|
||||
event.doit = true;
|
||||
}//if//
|
||||
break;
|
||||
case SWT.TRAVERSE_ESCAPE:
|
||||
if(isShowingDrop()) {
|
||||
hideDrop(false);
|
||||
event.doit = false;
|
||||
}//if//
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}//switch//
|
||||
}//keyTraversed()//
|
||||
};
|
||||
|
||||
//Add a listener to the shells to hide the drop down shell if a traveral event occurs.//
|
||||
getShell().addTraverseListener(traverseListener);
|
||||
dropDown.dropShell.addTraverseListener(traverseListener);
|
||||
|
||||
//Hide the drop shell if the user clicks outside of the drop down.//
|
||||
getShell().getDisplay().addFilter(SWT.MouseDown, new Listener() {
|
||||
public void handleEvent(Event event) {
|
||||
if(isShowingDrop()) {
|
||||
if(event.widget instanceof Control) {
|
||||
Control control = (Control) event.widget;
|
||||
|
||||
//If the mouse event occured outside the drop shell then close the drop shell.//
|
||||
if(!dropDown.dropShell.getBounds().contains(getShell().getDisplay().map(control, null, event.x, event.y))) {
|
||||
hideDrop(true);
|
||||
event.type = 0;
|
||||
}//if//
|
||||
}//if//
|
||||
}//if//
|
||||
}//handleEvent//
|
||||
});
|
||||
|
||||
//if the outer most shell is deactivated or iconified, then stop showing the drop down shell.//
|
||||
getShell().addShellListener(new ShellListener() {
|
||||
public void shellActivated(ShellEvent event) {
|
||||
}//shellActivated()//
|
||||
public void shellClosed(ShellEvent event) {
|
||||
}//shellClosed()//
|
||||
public void shellDeactivated(ShellEvent event) {
|
||||
if(!getSwtToolItem().isDisposed()) {
|
||||
getShell().getDisplay().asyncExec(new Runnable() {
|
||||
public void run() {
|
||||
if((isShowingDrop()) && (dropDown.dropShell != getShell().getDisplay().getActiveShell())) {
|
||||
getShell().setActive();
|
||||
hideDrop(true);
|
||||
}//if//
|
||||
}//run()//
|
||||
});
|
||||
}//if//
|
||||
}//shellDeactivated()//
|
||||
public void shellDeiconified(ShellEvent event) {
|
||||
}//shellDeiconified()//
|
||||
public void shellIconified(ShellEvent event) {
|
||||
if(isShowingDrop()) {
|
||||
hideDrop(false);
|
||||
}//if//
|
||||
}//shellIconified()//
|
||||
});
|
||||
getShell().addControlListener(new ControlListener() {
|
||||
public void controlMoved(ControlEvent event) {
|
||||
if(isShowingDrop()) {
|
||||
hideDrop(false);
|
||||
}//if//
|
||||
}//controlMoved()//
|
||||
public void controlResized(ControlEvent event) {
|
||||
if(isShowingDrop()) {
|
||||
hideDrop(false);
|
||||
}//if//
|
||||
}//controlResized()//
|
||||
});
|
||||
}//internalViewInitialize()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.AbstractComponent#internalViewRelease()
|
||||
*/
|
||||
protected void internalViewRelease() {
|
||||
if(getSwtToolItem() != null && !getSwtToolItem().isDisposed()) {
|
||||
getSwtToolItem().removeSelectionListener(this);
|
||||
}//if//
|
||||
|
||||
dropDown.dispose();
|
||||
|
||||
if((selectedColorImage != null) && (!selectedColorImage.isDisposed())) {
|
||||
selectedColorImage.dispose();
|
||||
selectedColorImage = null;
|
||||
}//if//
|
||||
|
||||
super.internalViewRelease();
|
||||
}//internalViewRelease()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.AbstractComponent#internalViewSynchronize()
|
||||
*/
|
||||
protected void internalViewSynchronize() {
|
||||
super.internalViewSynchronize();
|
||||
|
||||
if(!autoSynchronizeSelection) {
|
||||
sendMessage(MESSAGE_SYNCHRONIZE_SELECTION, selectedColor);
|
||||
}//if//
|
||||
}//internalViewSynchronize()//
|
||||
/* (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(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);
|
||||
dropDown.show(point, selectedColor);
|
||||
}//if//
|
||||
}//widgetSelected()//
|
||||
/**
|
||||
* Creates a color swatch image for the required color.
|
||||
* @param color The color to generate an image for, or null for an image of no color (a red slash or other appropriate graphic).
|
||||
* @return The color swatch image.
|
||||
*/
|
||||
protected Image createColorImage(JefColor swatchColor) {
|
||||
return createColorImage(width, height, 0, swatchColor, null, null, null);
|
||||
}//createColorImage()//
|
||||
/**
|
||||
* Creates a color swatch image for the required color.
|
||||
* @param width The number of pixels across the whole image.
|
||||
* @param height The number of pixels down the whole image.
|
||||
* @param fillBorder The number of pixels of filler border around the swatch.
|
||||
* @param swatchColor The color to generate an image for, or null for an image of no color (a red slash or other appropriate graphic).
|
||||
* @param innerBorderColor The color of the border around the swatch. This is a one pixel border if this is non null.
|
||||
* @param outerBorderColor The color of the border around the whole image. This is a one pixel border if this is non-null.
|
||||
* @param fillColor The color of the fill between the swatch and the edges of the image. This should likely be a semi-transparent color.
|
||||
* @return The color swatch image.
|
||||
*/
|
||||
protected Image createColorImage(int width, int height, int fillBorder, JefColor swatchColor, JefColor innerBorderColor, JefColor outerBorderColor, JefColor fillColor) {
|
||||
Image image = new Image(getSwtToolItem().getDisplay(), width, height);
|
||||
GC gc = new GC(image);
|
||||
int swatchX = fillBorder;
|
||||
int swatchY = fillBorder;
|
||||
int swatchWidth = width - (fillBorder << 1) - 1;
|
||||
int swatchHeight = height - (fillBorder << 1) - 1;
|
||||
|
||||
//Draw the fill.//
|
||||
if(fillColor != null) {
|
||||
Color swtColor = SwtUtilities.getColor(image.getDevice(), fillColor);
|
||||
|
||||
gc.setAlpha(fillColor.getAlpha() & 0xFF);
|
||||
gc.setBackground(swtColor);
|
||||
gc.fillRectangle(0, 0, width - 1, height - 1);
|
||||
swtColor.dispose();
|
||||
}//if//
|
||||
else {
|
||||
gc.setAlpha(0);
|
||||
gc.fillRectangle(0, 0, width, height);
|
||||
}//else//
|
||||
|
||||
//Draw the outer border.//
|
||||
if(outerBorderColor != null) {
|
||||
Color swtColor = SwtUtilities.getColor(image.getDevice(), outerBorderColor);
|
||||
|
||||
gc.setLineWidth(1);
|
||||
gc.setForeground(swtColor);
|
||||
gc.setAlpha(outerBorderColor.getAlpha() & 0xFF);
|
||||
gc.drawRectangle(0, 0, width - 1, height - 1);
|
||||
swtColor.dispose();
|
||||
}//if//
|
||||
|
||||
//Draw the swatch.//
|
||||
if(swatchColor == null) {
|
||||
Color swtColor = SwtUtilities.getColor(image.getDevice(), new JefColor(JefColor.COLOR_RED));
|
||||
|
||||
gc.setAlpha(255);
|
||||
gc.setForeground(swtColor);
|
||||
gc.setLineWidth(2);
|
||||
gc.setLineCap(SWT.CAP_ROUND);
|
||||
gc.drawLine(width - (fillBorder << 1), fillBorder, fillBorder, height - (fillBorder << 1));
|
||||
swtColor.dispose();
|
||||
}//if//
|
||||
else if((swatchColor.getAlpha() & 0xFF) != 0) {
|
||||
Color swtColor = SwtUtilities.getColor(image.getDevice(), swatchColor);
|
||||
|
||||
gc.setAlpha(swatchColor.getAlpha() & 0xFF);
|
||||
gc.setBackground(swtColor);
|
||||
gc.fillRectangle(swatchX, swatchY, swatchWidth, swatchHeight);
|
||||
swtColor.dispose();
|
||||
}//else if//
|
||||
|
||||
//Draw the inner border.//
|
||||
if(innerBorderColor != null) {
|
||||
Color swtColor = SwtUtilities.getColor(image.getDevice(), innerBorderColor);
|
||||
|
||||
gc.setLineWidth(1);
|
||||
gc.setForeground(swtColor);
|
||||
gc.setAlpha(innerBorderColor.getAlpha() & 0xFF);
|
||||
gc.drawRectangle(swatchX, swatchY, swatchWidth, swatchHeight);
|
||||
swtColor.dispose();
|
||||
}//if//
|
||||
|
||||
gc.dispose();
|
||||
|
||||
return image;
|
||||
}//createColorImage()//
|
||||
/**
|
||||
* Sets the currently selected color, displays the color, and updates any linkages.
|
||||
* @param selectedColor The color to be selected.
|
||||
* @param updateModel Whether the model should be updated. This should only be false if being called due to a model change.
|
||||
*/
|
||||
protected void setSelectedColor(JefColor selectedColor, boolean updateModel) {
|
||||
if(selectedColor == null) {
|
||||
selectedColor = defaultColor;
|
||||
}//if//
|
||||
|
||||
if(!Comparator.equals(this.selectedColor, selectedColor)) {
|
||||
this.selectedColor = selectedColor;
|
||||
|
||||
if(isInitialized()) {
|
||||
//Dispose of the old color image.//
|
||||
if(selectedColorImage != null) {
|
||||
getSwtToolItem().setImage(null);
|
||||
selectedColorImage.dispose();
|
||||
}//if//
|
||||
|
||||
selectedColorImage = createColorImage(selectedColor);
|
||||
getSwtToolItem().setImage(selectedColorImage);
|
||||
|
||||
if(updateModel && autoSynchronizeSelection) {
|
||||
sendMessage(MESSAGE_SYNCHRONIZE_SELECTION, selectedColor);
|
||||
}//if//
|
||||
}//if//
|
||||
|
||||
colorLinkage.invoke(selectedColor);
|
||||
}//if//
|
||||
}//setSelectedColor()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.AbstractComponent#internalOnLinkInvoked(int, java.lang.Object)
|
||||
*/
|
||||
protected void internalOnLinkInvoked(int linkTarget, Object data) {
|
||||
switch(linkTarget) {
|
||||
case LINK_TARGET_SELECTION: {
|
||||
JefColor color = data instanceof JefColor ? (JefColor) data : null;
|
||||
|
||||
setSelectedColor(color, true);
|
||||
break;
|
||||
}//case//
|
||||
default: {
|
||||
super.internalOnLinkInvoked(linkTarget, data);
|
||||
break;
|
||||
}//default//
|
||||
}//switch//
|
||||
}//internalOnLinkInvoked()//
|
||||
/**
|
||||
* Determines whether the drop down shell is currently being shown.
|
||||
* @return Whether we are currently showing the drop control.
|
||||
*/
|
||||
protected boolean isShowingDrop() {
|
||||
return dropDown != null && !dropDown.dropShell.isDisposed() && dropDown.dropShell.isVisible();
|
||||
}//isShowingDrop()//
|
||||
/**
|
||||
* Shows the drop down shell.
|
||||
*/
|
||||
protected final void showDrop(Point location) {
|
||||
if(!isShowingDrop()) {
|
||||
dropDown.show(location, selectedColor);
|
||||
}//if//
|
||||
}//showDrop()//
|
||||
/**
|
||||
* Hides the drop down shell.
|
||||
* @param synchronize Whether the drop control should synchronize its data with the tool item.
|
||||
*/
|
||||
protected final void hideDrop(boolean synchronize) {
|
||||
if(isShowingDrop()) {
|
||||
dropDown.hide(synchronize);
|
||||
}//if//
|
||||
}//hideDrop()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.AbstractComponent#internalProcessMessage(com.foundation.tcv.model.ViewMessage)
|
||||
*/
|
||||
public Object internalProcessMessage(ViewMessage viewMessage) {
|
||||
Object retVal = null;
|
||||
|
||||
switch(viewMessage.getMessageNumber()) {
|
||||
case MESSAGE_SET_WIDTH: {
|
||||
width = ((Integer) viewMessage.getMessageData()).intValue();
|
||||
break;
|
||||
}//case//
|
||||
case MESSAGE_SET_HEIGHT: {
|
||||
width = ((Integer) viewMessage.getMessageData()).intValue();
|
||||
break;
|
||||
}//case//
|
||||
case MESSAGE_SET_AUTO_SYNCHRONIZE_SELECTION: {
|
||||
autoSynchronizeSelection = ((Boolean) viewMessage.getMessageData()).booleanValue();
|
||||
break;
|
||||
}//case//
|
||||
case MESSAGE_REFRESH_SELECTION: {
|
||||
Object color = viewMessage.getMessageData();
|
||||
|
||||
if(color instanceof ResourceReference) {
|
||||
color = ResourceHolder.getResourceValue(this, (ResourceReference) color);
|
||||
}//if//
|
||||
|
||||
if(color instanceof JefColor) {
|
||||
setSelectedColor((JefColor) color, false);
|
||||
}//if//
|
||||
else {
|
||||
Debug.log(new RuntimeException("Invalid data type."));
|
||||
}//else//
|
||||
break;
|
||||
}//case//
|
||||
case MESSAGE_ADD_COLOR_LINK: {
|
||||
LinkInfo info = (LinkInfo) viewMessage.getMessageData();
|
||||
|
||||
colorLinkage.add(new LinkData(getComponent(info.getComponent()), info.getTarget(), info.getData(), info.isBoolean(), info.invertLogic(), info.nullValue()));
|
||||
break;
|
||||
}//case//
|
||||
default: {
|
||||
retVal = super.internalProcessMessage(viewMessage);
|
||||
}//default//
|
||||
}//switch//
|
||||
|
||||
return retVal;
|
||||
}//internalProcessMessage()//
|
||||
}//ToolItemDropColor//
|
||||
@@ -0,0 +1,273 @@
|
||||
/*
|
||||
* Copyright (c) 2007,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.tcv.swt.client;
|
||||
|
||||
import org.eclipse.swt.SWT;
|
||||
import org.eclipse.swt.events.SelectionEvent;
|
||||
import org.eclipse.swt.events.SelectionListener;
|
||||
import org.eclipse.swt.graphics.Image;
|
||||
import org.eclipse.swt.widgets.Event;
|
||||
import org.eclipse.swt.widgets.Listener;
|
||||
import org.eclipse.swt.widgets.Shell;
|
||||
|
||||
import com.common.comparison.Comparator;
|
||||
import com.foundation.tcv.client.view.ResourceHolder;
|
||||
import com.foundation.tcv.model.LinkInfo;
|
||||
import com.foundation.tcv.swt.ITrayItem;
|
||||
import com.foundation.tcv.swt.client.AbstractComponent.Linkage;
|
||||
import com.foundation.tcv.view.ViewMessage;
|
||||
import com.foundation.view.JefImage;
|
||||
import com.foundation.view.LinkData;
|
||||
import com.foundation.view.swt.SwtViewContext;
|
||||
|
||||
public class TrayItem extends AbstractComponent implements ITrayItem {
|
||||
/** The reference to the popup menu. Not all components must allow a popup menu. */
|
||||
private Menu menu = null;
|
||||
/** A holder for the value of the tool tip text. */
|
||||
private ResourceHolder toolTipTextHolder = new ResourceHolder(this);
|
||||
/** A holder for the value of the visibility flag. */
|
||||
private ResourceHolder isVisibleHolder = new ResourceHolder(this);
|
||||
/** A holder for the value of the image. */
|
||||
private ResourceHolder imageHolder = new ResourceHolder(this);
|
||||
/** The swt image. */
|
||||
private Image swtImage = null;
|
||||
/** A shell used only to support the menu used by the tray item. */
|
||||
private Shell shell = null;
|
||||
/** Whether selection notifications are sent to the server. */
|
||||
private boolean synchronizeSelections = false;
|
||||
/** The linkage for the selection. */
|
||||
private Linkage selectionLinkage = new Linkage();
|
||||
/**
|
||||
* TrayItem constructor.
|
||||
*/
|
||||
public TrayItem() {
|
||||
}//TrayItem()//
|
||||
/* (non-Javadoc)
|
||||
* @see AbstractComponent#destroy()
|
||||
*/
|
||||
protected void destroy() {
|
||||
if(getSwtTrayItem() != null) {
|
||||
if(!getSwtTrayItem().isDisposed()) {
|
||||
getSwtTrayItem().setVisible(false);
|
||||
}//if//
|
||||
|
||||
super.destroy();
|
||||
}//if//
|
||||
}//destroy()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.view.swt.IDecoration#getMenuBar()
|
||||
*/
|
||||
public Menu getMenu() {
|
||||
return menu;
|
||||
}//getMenuBar()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.view.swt.IDecoration#setMenuBar(com.foundation.view.swt.Menu)
|
||||
*/
|
||||
public void setMenu(Menu menu) {
|
||||
this.menu = menu;
|
||||
}//setMenu()//
|
||||
/**
|
||||
* Gets the widget encapsulated by this component.
|
||||
* @return The encapsulated widget, or null if this component does not have a viewable element.
|
||||
*/
|
||||
public org.eclipse.swt.widgets.TrayItem getSwtTrayItem() {
|
||||
return (org.eclipse.swt.widgets.TrayItem) getSwtWidget();
|
||||
}//getSwtTrayItem()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.AbstractComponent#getContainer()
|
||||
*/
|
||||
public Container getContainer() {
|
||||
return null;
|
||||
}//getContainer()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.AbstractComponent#getShell()
|
||||
*/
|
||||
public Shell getShell() {
|
||||
return shell;
|
||||
}//getShell()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.AbstractComponent#inernalViewInitializeAll()
|
||||
*/
|
||||
protected void internalViewInitializeAll() {
|
||||
if(getMenu() != null) {
|
||||
getMenu().internalViewInitializeAll();
|
||||
}//if//
|
||||
|
||||
super.internalViewInitializeAll();
|
||||
}//inernalViewInitializeAll()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.AbstractComponent#internalViewReleaseAll()
|
||||
*/
|
||||
protected void internalViewReleaseAll() {
|
||||
if(getMenu() != null) {
|
||||
getMenu().internalViewReleaseAll();
|
||||
}//if//
|
||||
|
||||
super.internalViewReleaseAll();
|
||||
}//internalViewReleaseAll()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.AbstractComponent#internalViewSynchronizeAll()
|
||||
*/
|
||||
protected void internalViewSynchronizeAll() {
|
||||
if(getMenu() != null) {
|
||||
getMenu().internalViewSynchronizeAll();
|
||||
}//if//
|
||||
|
||||
super.internalViewSynchronizeAll();
|
||||
}//internalViewSynchronizeAll()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.AbstractComponent#internalViewInitialize()
|
||||
*/
|
||||
protected void internalViewInitialize() {
|
||||
getSwtTrayItem().addListener(SWT.MenuDetect, new Listener() {
|
||||
public void handleEvent(Event event) {
|
||||
if(menu != null) {
|
||||
menu.getSwtMenu().setVisible(true);
|
||||
}//if//
|
||||
}//handleEvent()//
|
||||
});
|
||||
getSwtTrayItem().addSelectionListener(new SelectionListener() {
|
||||
public void widgetSelected(SelectionEvent e) {
|
||||
if(synchronizeSelections) {
|
||||
sendRoundTripMessage(MESSAGE_VIEW_SYNCHRONIZE_SELECTION, null, null, e.x, e.y, null);
|
||||
}//if//
|
||||
else if(menu != null) {
|
||||
menu.getSwtMenu().setVisible(true);
|
||||
}//else if//
|
||||
|
||||
selectionLinkage.invoke(null);
|
||||
}//widgetSelected()//
|
||||
public void widgetDefaultSelected(SelectionEvent e) {
|
||||
}//widgetDefaultSelected()//
|
||||
});
|
||||
|
||||
super.internalViewInitialize();
|
||||
}//internalViewInitialize()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.AbstractComponent#internalViewRelease()
|
||||
*/
|
||||
protected void internalViewRelease() {
|
||||
destroyImage(swtImage);
|
||||
|
||||
if(getContainer() != null) {
|
||||
getContainer().getComponents().remove(this);
|
||||
}//if//
|
||||
|
||||
toolTipTextHolder.release();
|
||||
isVisibleHolder.release();
|
||||
imageHolder.release();
|
||||
|
||||
super.internalViewRelease();
|
||||
}//internalViewRelease()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.AbstractComponent#internalResourceHolderChanged(com.foundation.tcv.client.view.ResourceHolder, java.lang.Object, java.lang.Object, int)
|
||||
*/
|
||||
protected void internalResourceHolderChanged(ResourceHolder resourceHolder, Object oldValue, Object newValue, int flags) {
|
||||
if(resourceHolder == toolTipTextHolder) {
|
||||
setToolTipText((String) newValue);
|
||||
}//if//
|
||||
else if(resourceHolder == imageHolder) {
|
||||
destroyImage(swtImage);
|
||||
|
||||
if(!getSwtTrayItem().isDisposed()) {
|
||||
swtImage = createImage((JefImage) imageHolder.getValue());
|
||||
getSwtTrayItem().setImage(swtImage);
|
||||
}//if//
|
||||
}//else if//
|
||||
else if(resourceHolder == isVisibleHolder) {
|
||||
if(!getSwtTrayItem().isDisposed()) {
|
||||
getSwtTrayItem().setVisible(((Boolean) newValue).booleanValue());
|
||||
}//if//
|
||||
}//else if//
|
||||
else {
|
||||
super.internalResourceHolderChanged(resourceHolder, oldValue, newValue, flags);
|
||||
}//else//
|
||||
}//internalOnAssociationChanged()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.AbstractComponent#internalOnLinkInvoked(int, java.lang.Object)
|
||||
*/
|
||||
protected void internalOnLinkInvoked(int linkTarget, Object data) {
|
||||
switch(linkTarget) {
|
||||
case LINK_TARGET_IS_VISIBLE: {
|
||||
getSwtTrayItem().setVisible(data != null && data instanceof Boolean ? ((Boolean) data).booleanValue() : false);
|
||||
break;
|
||||
}//case//
|
||||
case LINK_TARGET_TOOL_TIP_TEXT: {
|
||||
getSwtTrayItem().setToolTipText(data instanceof String ? (String) data : "");
|
||||
break;
|
||||
}//case//
|
||||
default: {
|
||||
super.internalOnLinkInvoked(linkTarget, data);
|
||||
break;
|
||||
}//default//
|
||||
}//switch//
|
||||
}//internalOnLinkInvoked()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.AbstractComponent#internalProcessMessage(com.foundation.tcv.model.ViewMessage)
|
||||
*/
|
||||
public Object internalProcessMessage(ViewMessage viewMessage) {
|
||||
Object result = null;
|
||||
|
||||
switch(viewMessage.getMessageNumber()) {
|
||||
case MESSAGE_INITIALIZE: {
|
||||
if(getSwtTrayItem() == null) {
|
||||
int style = viewMessage.getMessageInteger();
|
||||
|
||||
//Create the SWT widget.//
|
||||
setSwtWidget(new org.eclipse.swt.widgets.TrayItem(SwtViewContext.getSingleton().getDisplay().getSystemTray(), style));
|
||||
getSwtWidget().setData(this);
|
||||
shell = new Shell(SwtViewContext.getSingleton().getDisplay());
|
||||
}//if//
|
||||
break;
|
||||
}//case//
|
||||
case MESSAGE_SET_IS_VISIBLE: {
|
||||
isVisibleHolder.setValue(viewMessage.getMessageData());
|
||||
break;
|
||||
}//case//
|
||||
case MESSAGE_SET_TOOL_TIP_TEXT: {
|
||||
toolTipTextHolder.setValue(viewMessage.getMessageData());
|
||||
break;
|
||||
}//case//
|
||||
case MESSAGE_SET_IMAGE: {
|
||||
imageHolder.setValue(viewMessage.getMessageData());
|
||||
break;
|
||||
}//case//
|
||||
case MESSAGE_SET_SYNCHRONIZE_SELECTIONS: {
|
||||
synchronizeSelections = ((Boolean) viewMessage.getMessageData()).booleanValue();
|
||||
break;
|
||||
}//case//
|
||||
case MESSAGE_ADD_SELECTION_LINK: {
|
||||
LinkInfo info = (LinkInfo) viewMessage.getMessageData();
|
||||
|
||||
selectionLinkage.add(new LinkData(getComponent(info.getComponent()), info.getTarget(), info.getData(), info.isBoolean(), info.invertLogic(), info.nullValue()));
|
||||
break;
|
||||
}//case//
|
||||
default: {
|
||||
result = super.internalProcessMessage(viewMessage);
|
||||
}//case//
|
||||
}//switch//
|
||||
|
||||
return result;
|
||||
}//internalProcessMessage()//
|
||||
/**
|
||||
* Gets this component's assigned tool tip text.
|
||||
* @return The tool tip for this component.
|
||||
*/
|
||||
public String getToolTipText() {
|
||||
return (String) toolTipTextHolder.getValue();
|
||||
}//getToolTipText()//
|
||||
/**
|
||||
* Sets this component's assigned tool tip text.
|
||||
* @param toolTipText The tool tip for this component.
|
||||
*/
|
||||
public void setToolTipText(String toolTipText) {
|
||||
if(!Comparator.equals(toolTipText, getSwtTrayItem().getToolTipText())) {
|
||||
getSwtTrayItem().setToolTipText(toolTipText);
|
||||
}//if//
|
||||
}//setToolTipText()//
|
||||
}//TrayItem//
|
||||
@@ -0,0 +1,834 @@
|
||||
/*
|
||||
* Copyright (c) 2004,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.tcv.swt.client;
|
||||
|
||||
import org.eclipse.swt.events.SelectionListener;
|
||||
|
||||
import com.common.comparison.Comparator;
|
||||
import com.common.debug.Debug;
|
||||
import com.common.thread.IRunnable;
|
||||
import com.common.util.IList;
|
||||
import com.common.util.LiteHashSet;
|
||||
import com.common.util.LiteList;
|
||||
import com.foundation.tcv.view.ViewMessage;
|
||||
|
||||
public abstract class TreeComponent extends CollectionComponent implements SelectionListener, com.foundation.tcv.swt.ITreeComponent {
|
||||
/** The currently selected index (on the server) if auto synchronizing and allowing only a single selection. */
|
||||
private int currentlySelectedObjectId = -1;
|
||||
|
||||
protected static class NodeData extends RowObject {
|
||||
/** The collection of child NodeData instances, or null if currently unknown. */
|
||||
private IList children = null;
|
||||
/** The collection of nodes in the display tree (ie TreeItem) which are displaying this node and its data. */
|
||||
private IList controlItems = new LiteList(1, 25); //TODO: Make this a map so that replacing is fast.
|
||||
/** The count of parents referencing this node as a child. The node data should not be discarded until this count reaches zero (unless it is a root). */
|
||||
private int parentCount = 0;
|
||||
/** The data used to display the node in the tree. */
|
||||
private Object[] data = null;
|
||||
/** Whether the node could possibly have children. */
|
||||
private boolean canHaveChildren = false;
|
||||
|
||||
/**
|
||||
* NodeData constructor.
|
||||
* @param objectId The object identifier which maps this node to the one on the server.
|
||||
* @param hiddenDataCount The number of hidden data columns used by the component.
|
||||
*/
|
||||
public NodeData(int objectId, int hiddenDataCount) {
|
||||
super(objectId, hiddenDataCount);
|
||||
}//NodeData()//
|
||||
/**
|
||||
* Gets the child node data instances if known.
|
||||
* @return The collection of child NodeData instances, or null if currently unknown.
|
||||
*/
|
||||
public IList getChildren() {
|
||||
return children;
|
||||
}//getChildren()//
|
||||
/**
|
||||
* Gets the child node data instances if known.
|
||||
* @param children The collection of child NodeData instances, or null if currently unknown.
|
||||
*/
|
||||
public void setChildren(IList children) {
|
||||
this.children = children;
|
||||
}//setChildren()//
|
||||
/**
|
||||
* Gets the display components that are rendering this node.
|
||||
* @return The collection of nodes in the display tree which are displaying this node and its data.
|
||||
*/
|
||||
public IList getDisplayNodes() {
|
||||
return controlItems;
|
||||
}//getDisplayNodes()//
|
||||
/**
|
||||
* Gets the count of parents referencing this node.
|
||||
* @return The count of parents referencing this node as a child. The node data should not be discarded until this count reaches zero (unless it is a root).
|
||||
*/
|
||||
public int getParentCount() {
|
||||
return parentCount;
|
||||
}//getParentCount()//
|
||||
/**
|
||||
* Increments the parent count.
|
||||
*/
|
||||
public void incrementParentCount() {
|
||||
parentCount++;
|
||||
}//incrementParentCount()//
|
||||
/**
|
||||
* Decrements the parent count.
|
||||
*/
|
||||
public void decrementParentCount() {
|
||||
parentCount--;
|
||||
}//decrementParentCount()//
|
||||
/**
|
||||
* Gets the data for the node.
|
||||
* @return The data used to display the node in the tree.
|
||||
*/
|
||||
public Object[] getData() {
|
||||
return data;
|
||||
}//getData()//
|
||||
/**
|
||||
* Sets the data for the node.
|
||||
* @param data The data used to display the node in the tree.
|
||||
*/
|
||||
public void setData(Object[] data) {
|
||||
this.data = data;
|
||||
}//setData()//
|
||||
/**
|
||||
* Determines whether the node can possibly have children.
|
||||
* @return Whether the node may have children.
|
||||
*/
|
||||
public boolean canHaveChildren() {
|
||||
return canHaveChildren;
|
||||
}//canHaveChildren()//
|
||||
/**
|
||||
* Determines whether the node can possibly have children.
|
||||
* @param canHaveChildren Whether the node may have children.
|
||||
*/
|
||||
public void canHaveChildren(boolean canHaveChildren) {
|
||||
this.canHaveChildren = canHaveChildren;
|
||||
}//canHaveChildren()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.RowObject#dispose()
|
||||
*/
|
||||
public void dispose() {
|
||||
super.dispose();
|
||||
}//dispose()//
|
||||
}//NodeData//
|
||||
/**
|
||||
* TreeComponent constructor.
|
||||
*/
|
||||
public TreeComponent() {
|
||||
super();
|
||||
}//TreeComponent()//
|
||||
/**
|
||||
* Gets the number of columns in the tree table.
|
||||
* @return The count of columns.
|
||||
*/
|
||||
protected abstract int getColumnCount();
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.AbstractComponent#internalViewSynchronize()
|
||||
*/
|
||||
protected void internalViewSynchronize() {
|
||||
super.internalViewSynchronize();
|
||||
|
||||
if(!getAutoSynchronizeSelection()) {
|
||||
if(getAllowMultiSelection()) {
|
||||
int[] selectionObjectIds = controlGetSelections();
|
||||
|
||||
if(selectionObjectIds.length == 0) {
|
||||
selectionObjectIds = null;
|
||||
}//if//
|
||||
|
||||
sendMessage(MESSAGE_VIEW_SYNCHRONIZE_SELECTION, (Object) selectionObjectIds);
|
||||
}//if//
|
||||
else {
|
||||
int selectionObjectId = controlGetSelection();
|
||||
|
||||
sendMessage(MESSAGE_VIEW_SYNCHRONIZE_SELECTION, selectionObjectId != -1 ? new Integer(selectionObjectId) : null);
|
||||
}//else//
|
||||
}//if//
|
||||
else {
|
||||
synchronized(this) {
|
||||
if(autoSynchronizeSelectionTask != null) {
|
||||
removeTask(autoSynchronizeSelectionTask);
|
||||
autoSynchronizeSelectionTask.execute();
|
||||
}//if//
|
||||
}//synchronized//
|
||||
}//else//
|
||||
}//internalViewSynchronize()//
|
||||
/**
|
||||
* Synchronizes the selection(s) with the server if the selection(s) have changed.
|
||||
* <p>The message to the server will be delayed so that rapid changes result in only one server message. Multi-select collections will send all selections instead of optimizing and only sending changes.</p>
|
||||
*/
|
||||
protected void synchronizeSelection() {
|
||||
int selectionObjectId = getAllowMultiSelection() ? -1 : controlGetSelection();
|
||||
int[] selectionObjectIds = getAllowMultiSelection() ? controlGetSelections() : null;
|
||||
|
||||
//TODO: Is there any point in trying to optimize things by only sending changes in a multi-select scenario? The problem is the message ordering on the server is unknown.//
|
||||
|
||||
if(selectionObjectIds != null) {
|
||||
if(selectionObjectIds.length == 0) {
|
||||
selectionObjectIds = null;
|
||||
}//if//
|
||||
}//if//
|
||||
|
||||
//Called when the user picks a selection.//
|
||||
if(getAutoSynchronizeSelection()) {
|
||||
if((getAllowMultiSelection()) || (currentlySelectedObjectId != selectionObjectId)) {
|
||||
currentlySelectedObjectId = selectionObjectId;
|
||||
|
||||
if(getAutoSynchronizeSelectionDelay() > 0) {
|
||||
//Start a task to send the selections to the server after a short delay.//
|
||||
synchronized(this) {
|
||||
final int taskSelectionObjectId = selectionObjectId;
|
||||
final int[] taskSelectionObjectIds = selectionObjectIds;
|
||||
|
||||
if(autoSynchronizeSelectionTask != null) {
|
||||
removeTask(autoSynchronizeSelectionTask);
|
||||
}//if//
|
||||
|
||||
autoSynchronizeSelectionTask = new Task() {
|
||||
boolean hasRun = false;
|
||||
|
||||
public void execute() {
|
||||
//Make sure that this task is still valid and is not being superceeded.//
|
||||
synchronized(TreeComponent.this) {
|
||||
if((autoSynchronizeSelectionTask == this) && (!hasRun)) {
|
||||
hasRun = true;
|
||||
//Cleanup after the task.//
|
||||
autoSynchronizeSelectionTask = null;
|
||||
getEventLoop().executeAsync(new IRunnable() {
|
||||
public Object run() {
|
||||
sendMessage(MESSAGE_VIEW_SYNCHRONIZE_SELECTION, getAllowMultiSelection() ? (Object) taskSelectionObjectIds : new Integer(taskSelectionObjectId));
|
||||
return null;
|
||||
}//run()//
|
||||
});
|
||||
}//if//
|
||||
}//synchronized//
|
||||
}//run()//
|
||||
};
|
||||
addTask(autoSynchronizeSelectionTask, getAutoSynchronizeSelectionDelay());
|
||||
}//synchronized//
|
||||
}//if//
|
||||
else {
|
||||
sendMessage(MESSAGE_VIEW_SYNCHRONIZE_SELECTION, getAllowMultiSelection() ? (Object) selectionObjectIds : new Integer(selectionObjectId));
|
||||
}//else//
|
||||
}//if//
|
||||
}//if//
|
||||
}//internalSynchronizeSelection()//
|
||||
/**
|
||||
* Adds an item to the tree component.
|
||||
* @param objectId The item's object identifier used to reference the item in the future.
|
||||
* @param data The data associated with the item and the columns.
|
||||
* @param hiddenData The hidden data associated with the item and the hidden columns.
|
||||
* @param canHaveChildren Whether the item might have children.
|
||||
*/
|
||||
protected void addItem(int objectId, Object[] data, Object[] hiddenData, boolean canHaveChildren) {
|
||||
NodeData nodeData = (NodeData) createRowObject(objectId);
|
||||
|
||||
//Setup the node mappings.//
|
||||
addRowObject(nodeData);
|
||||
//Initialize the node data.//
|
||||
nodeData.setData(data);
|
||||
nodeData.canHaveChildren(canHaveChildren);
|
||||
|
||||
if(getHiddenDataCount() > 0) {
|
||||
//Copy the hidden data.//
|
||||
System.arraycopy(hiddenData, 0, nodeData.hiddenData, 0, hiddenData.length);
|
||||
}//if//
|
||||
}//addItem()//
|
||||
/**
|
||||
* Removes an item from the tree component.
|
||||
* @param nodeData The node representing the item on the client.
|
||||
*/
|
||||
protected void removeItem(NodeData nodeData) {
|
||||
int childCount = nodeData.getChildren() == null ? 0 : nodeData.getChildren().getSize();
|
||||
|
||||
//Remove the node mappings.//
|
||||
removeRowObject(nodeData.objectId);
|
||||
|
||||
//Remove all children that are no longer referenced.//
|
||||
for(int index = 0; index < childCount; index++) {
|
||||
NodeData child = (NodeData) nodeData.getChildren().get(index);
|
||||
|
||||
child.decrementParentCount();
|
||||
|
||||
if(child.getParentCount() == 0) {
|
||||
removeItem(child);
|
||||
}//if//
|
||||
}//for//
|
||||
}//removeItem()//
|
||||
/**
|
||||
* Removes all the items from the component.
|
||||
*/
|
||||
protected void removeItems() {
|
||||
currentlySelectedObjectId = -1;
|
||||
controlRemoveAll();
|
||||
forceSelectionEvent();
|
||||
removeRowObjects();
|
||||
}//removeItems()//
|
||||
/**
|
||||
* Generates a mapping array of current column indices indexed by the column index as assigned by the server when the column was created.
|
||||
* <p>TODO: Store the result and reuse. Invalid the mapping when the columns are re-ordered.</p>
|
||||
* @return The array of current column indices indexed by the server side column index.
|
||||
*/
|
||||
protected abstract int[] createServerToClientColumnMapping();
|
||||
/**
|
||||
* Generates a mapping array of column indices as set when the column was created, indexed by the current column index.
|
||||
* <p>TODO: Store the result and reuse. Invalid the mapping when the columns are re-ordered.</p>
|
||||
* @return The array of server side column indices indexed by the current client side column index.
|
||||
*/
|
||||
protected abstract int[] createClientToServerColumnMapping();
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.AbstractComponent#internalProcessMessage(com.foundation.tcv.model.ViewMessage)
|
||||
*/
|
||||
public Object internalProcessMessage(ViewMessage viewMessage) {
|
||||
Object retVal = null;
|
||||
|
||||
switch(viewMessage.getMessageNumber()) {
|
||||
case MESSAGE_SAVE_VIEW_STATE: {
|
||||
controlSaveViewState();
|
||||
break;
|
||||
}//case//
|
||||
case MESSAGE_RESTORE_VIEW_STATE: {
|
||||
controlRestoreViewState();
|
||||
break;
|
||||
}//case//
|
||||
case MESSAGE_ADD_NODE_LINK: {
|
||||
NodeData parent = getNodeData(viewMessage.getMessageInteger());
|
||||
NodeData child = getNodeData(viewMessage.getMessageSecondaryInteger());
|
||||
int[] columnMapping = createServerToClientColumnMapping();
|
||||
|
||||
controlAddNodeLink(parent, child, columnMapping);
|
||||
break;
|
||||
}//case//
|
||||
case MESSAGE_REMOVE_NODE_LINK: {
|
||||
NodeData parent = getNodeData(viewMessage.getMessageInteger());
|
||||
NodeData child = getNodeData(viewMessage.getMessageSecondaryInteger());
|
||||
|
||||
controlRemoveNodeLink(parent, child);
|
||||
break;
|
||||
}//case//
|
||||
case MESSAGE_ADD_ITEM: {
|
||||
addItem(viewMessage.getMessageInteger(), (Object[]) viewMessage.getMessageData(), (Object[]) viewMessage.getMessageSecondaryData(), viewMessage.getMessageSecondaryInteger() == 0 ? false : true);
|
||||
break;
|
||||
}//case//
|
||||
case MESSAGE_REMOVE_ITEM: {
|
||||
removeItem(getNodeData(viewMessage.getMessageInteger()));
|
||||
break;
|
||||
}//case//
|
||||
case MESSAGE_REMOVE_ALL: {
|
||||
removeItems();
|
||||
break;
|
||||
}//case//
|
||||
case MESSAGE_SET_SELECTION: {
|
||||
Object messageData = viewMessage.getMessageData();
|
||||
int[] selectionObjectIds = (int[]) messageData;
|
||||
|
||||
//For single-selection collections, set the currently selected id.//
|
||||
if(!getAllowMultiSelection()) {
|
||||
if((selectionObjectIds != null) && (selectionObjectIds.length > 1)) {
|
||||
currentlySelectedObjectId = -1;
|
||||
//Error: Invalid message value!//
|
||||
Debug.log(new RuntimeException("Error: Invalid message parameter! MESSAGE_SET_SELECTION"));
|
||||
}//if//
|
||||
else {
|
||||
currentlySelectedObjectId = ((selectionObjectIds == null) || (selectionObjectIds.length == 0)) ? -1 : selectionObjectIds[0];
|
||||
}//else//
|
||||
|
||||
if(currentlySelectedObjectId != -1) {
|
||||
NodeData nodeData = getNodeData(currentlySelectedObjectId);
|
||||
|
||||
if(nodeData != null) {
|
||||
//Ignore the selection if it is already selected or if there are no display nodes.//
|
||||
if((controlGetSelection() != currentlySelectedObjectId) && (nodeData.getDisplayNodes().getSize() > 0)) {
|
||||
controlSetSelection(nodeData.getDisplayNodes().getFirst());
|
||||
}//if//
|
||||
}//if//
|
||||
else {
|
||||
//TODO: Output the control name for easier identification.
|
||||
Debug.log("Error: Couldn't find the requested node data. " + this);
|
||||
}//else//
|
||||
}//if//
|
||||
else {
|
||||
controlRemoveAllSelections();
|
||||
}//else//
|
||||
}//if//
|
||||
else { //Allow multiple selections.//
|
||||
if((selectionObjectIds == null) || (selectionObjectIds.length == 0)) {
|
||||
//Clear all selections.//
|
||||
controlRemoveAllSelections();
|
||||
}//if//
|
||||
else {
|
||||
NodeData[] selectedNodes = new NodeData[selectionObjectIds.length];
|
||||
LiteHashSet selectedNodeDataSet = new LiteHashSet(selectionObjectIds.length, LiteHashSet.DEFAULT_LOAD_FACTOR, Comparator.getIdentityComparator(), LiteHashSet.STYLE_COUNT_DUPLICATES);
|
||||
IList selectedControlItems = new LiteList(selectionObjectIds.length);
|
||||
|
||||
//Setup the selected nodes.//
|
||||
for(int index = 0; index < selectedNodes.length; index++) {
|
||||
selectedNodes[index] = getNodeData(selectionObjectIds[index]);
|
||||
}//for//
|
||||
|
||||
//Sort through the selections to see which requiring adding control selection, removing control selections, or are already selected in the control.//
|
||||
for(int index = 0; index < selectedNodes.length; index++) {
|
||||
NodeData nodeData = selectedNodes[index];
|
||||
int alreadySelectedCount = selectedNodeDataSet.getCount(nodeData); //Gets the number of times the node data has already been added to the selection.//
|
||||
|
||||
if(nodeData.getDisplayNodes().getSize() > 1) {
|
||||
IList items = (IList) nodeData.getDisplayNodes();
|
||||
Object firstNonSelectedDisplayNode = null;
|
||||
boolean addSelection = true;
|
||||
|
||||
//Look for the first non-selected display node and check to see if there is a node already selected (also track the count since a node could exist more than once and could be selected more than once).//
|
||||
for(int displayNodeIndex = 0; (addSelection) && (displayNodeIndex < items.getSize()); displayNodeIndex++) {
|
||||
Object displayNode = items.get(displayNodeIndex);
|
||||
|
||||
if(!controlIsSelected(displayNode)) {
|
||||
//Make sure we haven't already identified the first non-selected display node and that the node is not already added to become selected.//
|
||||
if((firstNonSelectedDisplayNode == null) && (!selectedControlItems.containsValue(displayNode))) {
|
||||
firstNonSelectedDisplayNode = displayNode;
|
||||
}//if//
|
||||
}//if//
|
||||
else {
|
||||
if(alreadySelectedCount == 0) {
|
||||
addSelection = false;
|
||||
selectedControlItems.add(displayNode);
|
||||
}//if//
|
||||
else {
|
||||
//Decrement the already selected count. This tracks the number of already selected nodes that we have re-selected.//
|
||||
alreadySelectedCount--;
|
||||
}//else//
|
||||
}//else//
|
||||
}//for//
|
||||
|
||||
//If an additional selection is required then add it.//
|
||||
if(addSelection && (firstNonSelectedDisplayNode != null)) {
|
||||
selectedControlItems.add(firstNonSelectedDisplayNode);
|
||||
}//if//
|
||||
}//if//
|
||||
else if(nodeData.getDisplayNodes().getSize() == 1) {
|
||||
selectedControlItems.add(nodeData.getDisplayNodes().getFirst());
|
||||
}//else if//
|
||||
|
||||
selectedNodeDataSet.add(nodeData);
|
||||
}//for//
|
||||
|
||||
//TODO: We should get the current selections and verify they are not identical to the selections we are about to make.
|
||||
//Set the selections.//
|
||||
controlSetSelections(selectedControlItems);
|
||||
}//else//
|
||||
}//else//
|
||||
|
||||
//Update the linkages that connect to the selection.//
|
||||
updateSelectionLinks();
|
||||
break;
|
||||
}//case//
|
||||
case MESSAGE_ADD_SELECTIONS: {
|
||||
int[] selectionObjectIds = (int[]) viewMessage.getMessageData();
|
||||
|
||||
internalAddSelections(selectionObjectIds);
|
||||
break;
|
||||
}//case//
|
||||
case MESSAGE_REMOVE_SELECTIONS: {
|
||||
int[] selectionObjectIds = (int[]) viewMessage.getMessageData();
|
||||
|
||||
internalRemoveSelections(selectionObjectIds);
|
||||
break;
|
||||
}//case//
|
||||
case MESSAGE_ADD_SELECTION: {
|
||||
int selectionObjectId = viewMessage.getMessageInteger();
|
||||
|
||||
internalAddSelection(selectionObjectId);
|
||||
break;
|
||||
}//case//
|
||||
case MESSAGE_REMOVE_SELECTION: {
|
||||
int selectionObjectId = viewMessage.getMessageInteger();
|
||||
|
||||
internalRemoveSelection(selectionObjectId);
|
||||
break;
|
||||
}//case//
|
||||
case MESSAGE_REMOVE_ALL_SELECTIONS: {
|
||||
currentlySelectedObjectId = -1;
|
||||
controlRemoveAllSelections();
|
||||
break;
|
||||
}//case//
|
||||
case MESSAGE_ADD_COLUMN: {
|
||||
Integer columnIndex = (Integer) viewMessage.getMessageData(); //The optional index for the column.//
|
||||
|
||||
if(columnIndex != null) {
|
||||
controlAddColumn(columnIndex.intValue());
|
||||
}//if//
|
||||
else {
|
||||
controlAddColumn();
|
||||
}//else//
|
||||
break;
|
||||
}//case//
|
||||
case MESSAGE_REMOVE_COLUMN: {
|
||||
Integer columnIndex = (Integer) viewMessage.getMessageData();
|
||||
|
||||
if(columnIndex != null) {
|
||||
controlRemoveColumn(columnIndex.intValue());
|
||||
}//if//
|
||||
break;
|
||||
}//case//
|
||||
case MESSAGE_SET_COLUMN_HEADER_IMAGE: {
|
||||
Object image = viewMessage.getMessageData();
|
||||
int columnIndex = viewMessage.getMessageInteger();
|
||||
|
||||
controlSetColumnHeaderImage(columnIndex, image);
|
||||
break;
|
||||
}//case//
|
||||
case MESSAGE_SET_COLUMN_HEADER_TEXT: {
|
||||
Object text = viewMessage.getMessageData();
|
||||
int columnIndex = viewMessage.getMessageInteger();
|
||||
|
||||
controlSetColumnHeaderText(columnIndex, text);
|
||||
break;
|
||||
}//case//
|
||||
case MESSAGE_SET_CELL_TEXT: {
|
||||
Object data = viewMessage.getMessageData();
|
||||
int columnIndex = viewMessage.getMessageInteger();
|
||||
int objectId = viewMessage.getMessageSecondaryInteger();
|
||||
|
||||
controlSetCellText(getNodeData(objectId), columnIndex, data);
|
||||
break;
|
||||
}//case//
|
||||
case MESSAGE_SET_CELL_IMAGE: {
|
||||
Object data = viewMessage.getMessageData();
|
||||
int columnIndex = viewMessage.getMessageInteger();
|
||||
int objectId = viewMessage.getMessageSecondaryInteger();
|
||||
|
||||
controlSetCellImage(getNodeData(objectId), columnIndex, data);
|
||||
break;
|
||||
}//case//
|
||||
case MESSAGE_SET_CELL_BACKGROUND_COLOR: {
|
||||
Object data = viewMessage.getMessageData();
|
||||
int columnIndex = viewMessage.getMessageInteger();
|
||||
int objectId = viewMessage.getMessageSecondaryInteger();
|
||||
|
||||
controlSetCellBackgroundColor(getNodeData(objectId), columnIndex, data);
|
||||
break;
|
||||
}//case//
|
||||
case MESSAGE_SET_CELL_FOREGROUND_COLOR: {
|
||||
Object data = viewMessage.getMessageData();
|
||||
int columnIndex = viewMessage.getMessageInteger();
|
||||
int objectId = viewMessage.getMessageSecondaryInteger();
|
||||
|
||||
controlSetCellForegroundColor(getNodeData(objectId), columnIndex, data);
|
||||
break;
|
||||
}//case//
|
||||
case MESSAGE_SET_CELL_FONT: {
|
||||
Object data = viewMessage.getMessageData();
|
||||
int columnIndex = viewMessage.getMessageInteger();
|
||||
int objectId = viewMessage.getMessageSecondaryInteger();
|
||||
|
||||
controlSetCellFont(getNodeData(objectId), columnIndex, data);
|
||||
break;
|
||||
}//case//
|
||||
case MESSAGE_SET_ROW_BACKGROUND_COLOR: {
|
||||
Object data = viewMessage.getMessageData();
|
||||
int objectId = viewMessage.getMessageInteger();
|
||||
|
||||
controlSetCellBackgroundColor(getNodeData(objectId), -1, data);
|
||||
break;
|
||||
}//case//
|
||||
case MESSAGE_SET_ROW_FOREGROUND_COLOR: {
|
||||
Object data = viewMessage.getMessageData();
|
||||
int objectId = viewMessage.getMessageInteger();
|
||||
|
||||
controlSetCellForegroundColor(getNodeData(objectId), -1, data);
|
||||
break;
|
||||
}//case//
|
||||
case MESSAGE_SET_ROW_FONT: {
|
||||
Object data = viewMessage.getMessageData();
|
||||
int objectId = viewMessage.getMessageInteger();
|
||||
|
||||
controlSetCellFont(getNodeData(objectId), -1, data);
|
||||
break;
|
||||
}//case//
|
||||
default: {
|
||||
retVal = super.internalProcessMessage(viewMessage);
|
||||
break;
|
||||
}//default//
|
||||
}//switch//
|
||||
|
||||
return retVal;
|
||||
}//internalProcessMessage()//
|
||||
/**
|
||||
* Adds the selections to the currently selected set.
|
||||
* @param objectIds The object identifiers to be selected.
|
||||
*/
|
||||
private void internalAddSelections(int[] objectIds) {
|
||||
for(int index = 0; index < objectIds.length; index++) {
|
||||
internalAddSelection(objectIds[index]);
|
||||
}//for//
|
||||
}//internalAddSelections()//
|
||||
/**
|
||||
* Removes the selections from the currently selected set.
|
||||
* @param objectIds The object identifiers to no longer be selected.
|
||||
*/
|
||||
private void internalRemoveSelections(int[] objectIds) {
|
||||
for(int index = 0; index < objectIds.length; index++) {
|
||||
internalRemoveSelection(objectIds[index]);
|
||||
}//for//
|
||||
}//internalRemoveSelections()//
|
||||
/**
|
||||
* Adds the selection to the currently selected set.
|
||||
* @param objectId The object identifier to be selected.
|
||||
*/
|
||||
private void internalAddSelection(int objectId) {
|
||||
NodeData node = getNodeData(objectId);
|
||||
|
||||
if(node.getDisplayNodes().getSize() > 1) {
|
||||
//Search for the first node that isn't selected.//
|
||||
for(int index = 0; index < node.getDisplayNodes().getSize(); index++) {
|
||||
Object item = node.getDisplayNodes().get(index);
|
||||
|
||||
if(!controlIsSelected(item)) {
|
||||
controlAddSelection(item);
|
||||
break;
|
||||
}//if//
|
||||
}//while//
|
||||
}//if//
|
||||
else if(node.getDisplayNodes().getSize() == 1) {
|
||||
controlAddSelection(node.getDisplayNodes().getFirst());
|
||||
}//else//
|
||||
}//internalAddSelections()//
|
||||
/**
|
||||
* Removes the selection from the currently selected set.
|
||||
* @param objectId The object identifier to no longer be selected.
|
||||
*/
|
||||
private void internalRemoveSelection(int objectId) {
|
||||
NodeData node = getNodeData(objectId);
|
||||
|
||||
if(node.getDisplayNodes().getSize() > 1) {
|
||||
//Search for the last node that is selected.//
|
||||
for(int index = node.getDisplayNodes().getSize() - 1; index >= 0; index--) {
|
||||
Object item = node.getDisplayNodes().get(index);
|
||||
|
||||
if(controlIsSelected(item)) {
|
||||
controlRemoveSelection(item);
|
||||
break;
|
||||
}//if//
|
||||
}//for//
|
||||
}//if//
|
||||
else if(node.getDisplayNodes().getSize() == 1) {
|
||||
controlRemoveSelection(node.getDisplayNodes().getFirst());
|
||||
}//else//
|
||||
}//internalRemoveSelection()//
|
||||
/**
|
||||
* Gets the node data associated with the given object identifier.
|
||||
* @param objectId The identifier which is used by the client and server to reference node data.
|
||||
* @return The node data for the identifier, or null.
|
||||
*/
|
||||
protected NodeData getNodeData(int objectId) {
|
||||
return (NodeData) getRowObject(objectId);
|
||||
}//getNodeData()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.CollectionComponent#createRowObject(int)
|
||||
*/
|
||||
protected RowObject createRowObject(int objectId) {
|
||||
return new NodeData(objectId, getHiddenDataCount());
|
||||
}//createRowObject()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.CollectionComponent#updateHiddenData(com.foundation.tcv.swt.client.CollectionComponent.RowObject, int, java.lang.Object)
|
||||
*/
|
||||
protected void updateHiddenData(RowObject object, int hiddenDataIndex, Object value) {
|
||||
object.hiddenData[hiddenDataIndex] = value;
|
||||
|
||||
if(getAllowMultiSelection()) {
|
||||
boolean updateSelectionLinks = false;
|
||||
int[] selectedObjectIds = controlGetSelections();
|
||||
|
||||
if((selectedObjectIds != null) && (selectedObjectIds.length > 0)) {
|
||||
//Determine whether any of the selections match with the hidden data's object to see whether we need to update any hidden data linkages.//
|
||||
for(int selectionIndex = 0; (!updateSelectionLinks) && (selectionIndex < selectedObjectIds.length); selectionIndex++) {
|
||||
updateSelectionLinks = selectedObjectIds[selectionIndex] == object.objectId;
|
||||
}//for//
|
||||
}//if//
|
||||
|
||||
if(updateSelectionLinks) {
|
||||
updateSelectionLinks();
|
||||
}//if//
|
||||
}//if//
|
||||
else {
|
||||
int selectedObjectId = controlGetSelection();
|
||||
|
||||
if((selectedObjectId != INVALID_OBJECT_ID) && (selectedObjectId == object.objectId)) {
|
||||
updateSelectionLinks();
|
||||
}//if//
|
||||
}//else//
|
||||
}//updateHiddenData()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.CollectionComponent#updateSelectionLinks()
|
||||
*/
|
||||
protected void updateSelectionLinks() {
|
||||
super.updateSelectionLinks();
|
||||
|
||||
if(getHiddenDataCount() > 0) {
|
||||
if(getAllowMultiSelection()) {
|
||||
int[] selectedObjectIds = controlGetSelections();
|
||||
RowObject[] selectedObjects = selectedObjectIds != null && selectedObjectIds.length > 0 ? new RowObject[selectedObjectIds.length] : null;
|
||||
|
||||
if(selectedObjects != null) {
|
||||
//Collect the selected values.//
|
||||
for(int selectionIndex = 0; selectionIndex < selectedObjectIds.length; selectionIndex++) {
|
||||
selectedObjects[selectionIndex] = getRowObject(selectedObjectIds[selectionIndex]);
|
||||
}//for//
|
||||
}//if//
|
||||
|
||||
//Update the hidden data linkages.//
|
||||
for(int hiddenDataIndex = 0; hiddenDataIndex < getHiddenDataCount(); hiddenDataIndex++) {
|
||||
getHiddenData(hiddenDataIndex).invokeLinkage(selectedObjects);
|
||||
}//for//
|
||||
}//if//
|
||||
else {
|
||||
int selectedObjectId = controlGetSelection();
|
||||
RowObject selectedObject = selectedObjectId != -1 ? getRowObject(selectedObjectId) : null;
|
||||
|
||||
//Update the hidden data linkages.//
|
||||
for(int hiddenDataIndex = 0; hiddenDataIndex < getHiddenDataCount(); hiddenDataIndex++) {
|
||||
getHiddenData(hiddenDataIndex).invokeLinkage(selectedObject);
|
||||
}//for//
|
||||
}//else//
|
||||
}//if//
|
||||
}//updateSelectionLinks()//
|
||||
/**
|
||||
* Removes all displayed items from the control.
|
||||
*/
|
||||
protected abstract void controlRemoveAll();
|
||||
/**
|
||||
* Adds a link between the parent and child node data's. This must update the display to show the relationship.
|
||||
* <p>Warning: It is possible to have a child displayed more than once under a single parent.</p>
|
||||
* @param parent The parent node. This must be null if the parent is the root node.
|
||||
* @param child The new child node.
|
||||
* @param columnIndexMap The map of client side column indices indexed by the server side column index.
|
||||
*/
|
||||
protected abstract void controlAddNodeLink(NodeData parent, NodeData child, int[] columnIndexMap);
|
||||
/**
|
||||
* Removes a link between the parent and child node data's. This must update the display to show the relationship.
|
||||
* <p>Warning: It is possible to have a child displayed more than once under a single parent.</p>
|
||||
* @param parent The parent node.
|
||||
* @param child The old child node.
|
||||
*/
|
||||
protected abstract void controlRemoveNodeLink(NodeData parent, NodeData child);
|
||||
/**
|
||||
* Sets the text displayed by the node cell.
|
||||
* @param nodeData The object encapsulating the data for the node. The node data may reference multiple display components which must be updated to reflect the new state.
|
||||
* @param columnIndex The index of the affected column.
|
||||
* @param data The data to be displayed by the cell(s).
|
||||
*/
|
||||
protected abstract void controlSetCellText(NodeData nodeData, int columnIndex, Object data);
|
||||
/**
|
||||
* Sets the image displayed by the node cell.
|
||||
* @param nodeData The object encapsulating the data for the node. The node data may reference multiple display components which must be updated to reflect the new state.
|
||||
* @param columnIndex The index of the affected column.
|
||||
* @param data The data to be displayed by the cell(s).
|
||||
*/
|
||||
protected abstract void controlSetCellImage(NodeData nodeData, int columnIndex, Object data);
|
||||
/**
|
||||
* Sets the background color displayed by the node cell.
|
||||
* @param nodeData The object encapsulating the data for the node. The node data may reference multiple display components which must be updated to reflect the new state.
|
||||
* @param columnIndex The index of the affected column. This may be -1 if setting the background color for the row.
|
||||
* @param data The data to be displayed by the cell(s).
|
||||
*/
|
||||
protected abstract void controlSetCellBackgroundColor(NodeData nodeData, int columnIndex, Object data);
|
||||
/**
|
||||
* Sets the foreground color displayed by the node cell.
|
||||
* @param nodeData The object encapsulating the data for the node. The node data may reference multiple display components which must be updated to reflect the new state.
|
||||
* @param columnIndex The index of the affected column. This may be -1 if setting the foreground color for the row.
|
||||
* @param data The data to be displayed by the cell(s).
|
||||
*/
|
||||
protected abstract void controlSetCellForegroundColor(NodeData nodeData, int columnIndex, Object data);
|
||||
/**
|
||||
* Sets the font displayed by the node cell.
|
||||
* @param nodeData The object encapsulating the data for the node. The node data may reference multiple display components which must be updated to reflect the new state.
|
||||
* @param columnIndex The index of the affected column. This may be -1 if setting the font for the row.
|
||||
* @param data The data to be displayed by the cell(s).
|
||||
*/
|
||||
protected abstract void controlSetCellFont(NodeData nodeData, int columnIndex, Object data);
|
||||
/**
|
||||
* Saves some state information about the view to allow restoration of the view state when a rebuild of the view is completed.
|
||||
*/
|
||||
protected abstract void controlSaveViewState();
|
||||
/**
|
||||
* Restores the view state after rebuilding the view.
|
||||
*/
|
||||
protected abstract void controlRestoreViewState();
|
||||
/**
|
||||
* Adds a column to the right of existing columns.
|
||||
*/
|
||||
protected abstract void controlAddColumn();
|
||||
/**
|
||||
* Adds a column at the index in the set of existing columns.
|
||||
* @param columnIndex The index of the affected column.
|
||||
*/
|
||||
protected abstract void controlAddColumn(int columnIndex);
|
||||
/**
|
||||
* Removes the specified column.
|
||||
* @param columnIndex The index of the affected column.
|
||||
*/
|
||||
protected abstract void controlRemoveColumn(int columnIndex);
|
||||
/**
|
||||
* Sets the data displayed by a column in its header.
|
||||
* @param columnIndex The index of the affected column.
|
||||
* @param text The text (String or ResourceReference) to be displayed by the column header.
|
||||
*/
|
||||
protected abstract void controlSetColumnHeaderText(int columnIndex, Object text);
|
||||
/**
|
||||
* Sets the data displayed by a column in its header.
|
||||
* @param columnIndex The index of the affected column.
|
||||
* @param image The image (JefImage or ResourceReference) to be displayed by the column header.
|
||||
*/
|
||||
protected abstract void controlSetColumnHeaderImage(int columnIndex, Object image);
|
||||
/**
|
||||
* Gets the indices selected within the control.
|
||||
* @return The collection of objectId's for the currently selected rows, or null if empty.
|
||||
*/
|
||||
protected abstract int[] controlGetSelections();
|
||||
/**
|
||||
* Gets the row index selected.
|
||||
*/
|
||||
protected abstract int controlGetSelection();
|
||||
/**
|
||||
* Sets the selected values in the control.
|
||||
* @param itemData The table item objects representing the selected rows. The list contents are control dependant.
|
||||
*/
|
||||
protected abstract void controlSetSelections(IList itemData);
|
||||
/**
|
||||
* Sets the selected value in the control.
|
||||
* @param itemData The table item object representing the selected row. The type is control dependant.
|
||||
*/
|
||||
protected abstract void controlSetSelection(Object itemData);
|
||||
/**
|
||||
* Adds a selected value in the control.
|
||||
* @param itemData The table item object representing the selected row. The type is control dependant.
|
||||
*/
|
||||
protected abstract void controlAddSelection(Object itemData);
|
||||
/**
|
||||
* Deselects a value in the control.
|
||||
* @param itemData The table item object representing the selected row. The type is control dependant.
|
||||
*/
|
||||
protected abstract void controlRemoveSelection(Object itemData);
|
||||
/**
|
||||
* Deselects all rows in the control.
|
||||
*/
|
||||
protected abstract void controlRemoveAllSelections();
|
||||
/**
|
||||
* Checks to see if a value is selected.
|
||||
* @param itemData The table item object representing the possibly selected row. The type is control dependant.
|
||||
* @return Whether the row is currently selected.
|
||||
*/
|
||||
protected abstract boolean controlIsSelected(Object itemData);
|
||||
/**
|
||||
* Gets all the object ids for all the rows in the table.
|
||||
* @return The array of all row object identifiers, or null if empty.
|
||||
*/
|
||||
protected abstract int[] controlGetObjectIds();
|
||||
/**
|
||||
* Forces the selection event handler to be called.
|
||||
*/
|
||||
protected abstract void forceSelectionEvent(); //Should call widgetSelected implemented by the subclass. This name may need to change.//
|
||||
}//TreeComponent//
|
||||
@@ -0,0 +1,428 @@
|
||||
/*
|
||||
* Copyright (c) 2007,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.tcv.swt.client;
|
||||
|
||||
import java.lang.reflect.Constructor;
|
||||
|
||||
import org.eclipse.swt.layout.FillLayout;
|
||||
import org.eclipse.swt.widgets.Composite;
|
||||
import org.eclipse.swt.widgets.Control;
|
||||
import org.eclipse.swt.widgets.Shell;
|
||||
|
||||
import com.common.debug.Debug;
|
||||
import com.common.thread.IRunnable;
|
||||
import com.common.util.IList;
|
||||
import com.common.util.LiteList;
|
||||
import com.foundation.controller.AbstractViewController;
|
||||
import com.foundation.controller.DecorationManager;
|
||||
import com.foundation.controller.ViewController;
|
||||
import com.foundation.event.IRequestHandler;
|
||||
import com.foundation.tcv.swt.IViewContainer;
|
||||
import com.foundation.tcv.view.ViewMessage;
|
||||
import com.foundation.view.AbstractDecoration;
|
||||
import com.foundation.view.IAbstractComponent;
|
||||
import com.foundation.view.IAbstractContainer;
|
||||
import com.foundation.view.IEventAssociation;
|
||||
import com.foundation.view.IView;
|
||||
import com.foundation.view.IViewContext;
|
||||
import com.foundation.view.ResourceAssociation;
|
||||
import com.foundation.view.resource.AbstractResourceService;
|
||||
import com.foundation.view.swt.Component;
|
||||
import com.foundation.view.swt.IAbstractSwtContainer;
|
||||
import com.foundation.view.swt.SwtViewContext;
|
||||
import com.foundation.view.swt.util.SwtUtilities;
|
||||
|
||||
public class ViewContainer extends Container implements IViewContainer {
|
||||
/** The component being displayed. */
|
||||
private com.foundation.view.swt.AbstractComponent component = null;
|
||||
/** The name of the view controller class that will be opened in this panel. */
|
||||
private String controllerClassName = null;
|
||||
/** The container shell used to represent this thin client control as a thick client control. */
|
||||
private SwtContainer swtContainer = new SwtContainer();
|
||||
/** The contained view's view controller. */
|
||||
private ViewController controller = null;
|
||||
|
||||
private class SwtContainer extends com.foundation.view.swt.AbstractComponent implements IAbstractSwtContainer {
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.view.swt.AbstractComponent#internalGetViewContext()
|
||||
*/
|
||||
protected IViewContext internalGetViewContext() {
|
||||
return ViewContainer.this.getViewContext();
|
||||
}//internalGetViewContext()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.view.swt.AbstractComponent#getShell()
|
||||
*/
|
||||
public Shell getShell() {
|
||||
return ViewContainer.this.getShell();
|
||||
}//getShell()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.view.swt.IAbstractSwtContainer#getSwtParent()
|
||||
*/
|
||||
public Composite getSwtParent() {
|
||||
return getSwtComposite();
|
||||
}//getSwtParent()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.view.swt.AbstractComponent#initializeControl(int)
|
||||
*/
|
||||
protected void initializeControl(int style, Object data) {
|
||||
}//initializeControl()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.view.swt.IAbstractSwtContainer#getSwtComposite()
|
||||
*/
|
||||
public Composite getSwtComposite() {
|
||||
return ViewContainer.this.getSwtComposite();
|
||||
}//getSwtComposite()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.view.IAbstractContainer#getComponents()
|
||||
*/
|
||||
public IList getComponents() {
|
||||
return component != null ? new LiteList(component) : LiteList.EMPTY_LIST;
|
||||
}//getComponents()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.view.IAbstractComponent#getContainer()
|
||||
*/
|
||||
public IAbstractContainer getContainer() {
|
||||
return null;
|
||||
}//getContainer()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.view.IView#execute(com.common.thread.IRunnable)
|
||||
*/
|
||||
public Object execute(IRunnable runnable) {
|
||||
return getEventLoop().execute(runnable, true);
|
||||
}//execute()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.view.IView#executeAsynch(com.common.thread.IRunnable)
|
||||
*/
|
||||
public void executeAsync(IRunnable runnable) {
|
||||
getEventLoop().executeAsync(runnable);
|
||||
}//executeAsynch()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.view.IView#getRequestHandler()
|
||||
*/
|
||||
public IRequestHandler getRequestHandler() {
|
||||
return getEventLoop();
|
||||
}//getRequestHandler()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.view.IView#getViewContext()
|
||||
*/
|
||||
public IViewContext getViewContext() {
|
||||
return ViewContainer.this.getViewContext();
|
||||
}//getViewContext()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.view.IView#isViewThread()
|
||||
*/
|
||||
public boolean isViewThread() {
|
||||
return true;
|
||||
}//isViewThread()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.view.IAbstractContainer#addComponent(com.foundation.view.IAbstractComponent)
|
||||
*/
|
||||
public void addComponent(IAbstractComponent component) {
|
||||
if(ViewContainer.this.component == null) {
|
||||
ViewContainer.this.component = (com.foundation.view.swt.AbstractComponent) component;
|
||||
}//if//
|
||||
else {
|
||||
Debug.log(new RuntimeException("Cannot set the component more than once."));
|
||||
}//else//
|
||||
}//addComponent()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.view.IAbstractContainer#removeComponent(com.foundation.view.IAbstractComponent)
|
||||
*/
|
||||
public void removeComponent(IAbstractComponent component) {
|
||||
ViewContainer.this.component = null;
|
||||
}//removeComponent()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.view.IView#maximize()
|
||||
*/
|
||||
public void maximize() {
|
||||
//Non-functional.//
|
||||
}//maximize()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.view.IView#minimize()
|
||||
*/
|
||||
public void minimize() {
|
||||
//Non-functional.//
|
||||
}//minimize()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.view.IView#pack()
|
||||
*/
|
||||
public void pack() {
|
||||
//Non-functional.//
|
||||
}//pack()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.view.IView#layout()
|
||||
*/
|
||||
public void layout() {
|
||||
//Non-functional.//
|
||||
}//layout()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.view.IView#setController(com.foundation.controller.AbstractViewController)
|
||||
*/
|
||||
public void setController(AbstractViewController controller) {
|
||||
//Non-functional.//
|
||||
}//setController()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.view.IView#setFocus()
|
||||
*/
|
||||
public void setFocus() {
|
||||
//Non-functional.//
|
||||
}//setFocus()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.view.IView#setIsEnabled(boolean)
|
||||
*/
|
||||
public void setIsEnabled(boolean isEnabled) {
|
||||
//Non-functional.//
|
||||
}//setIsEnabled()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.view.IView#setIsVisible(boolean)
|
||||
*/
|
||||
public void setIsVisible(boolean isVisible) {
|
||||
//Non-functional.//
|
||||
}//setIsVisible()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.view.IView#show()
|
||||
*/
|
||||
public void show() {
|
||||
//Non-functional.//
|
||||
}//show()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.view.IView#viewInitializeAll()
|
||||
*/
|
||||
public void viewInitializeAll() {
|
||||
//Non-functional.//
|
||||
}//viewInitializeAll()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.view.IView#viewRefreshAll()
|
||||
*/
|
||||
public void viewRefreshAll() {
|
||||
//Non-functional.//
|
||||
}//viewRefreshAll()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.view.IView#viewReleaseAll()
|
||||
*/
|
||||
public void viewReleaseAll() {
|
||||
//Non-functional.//
|
||||
}//viewReleaseAll()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.view.IView#viewSynchronizeAll()
|
||||
*/
|
||||
public void viewSynchronizeAll() {
|
||||
//Non-functional.//
|
||||
}//viewSynchronizeAll()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.view.IAbstractComponent#getName()
|
||||
*/
|
||||
public String getName() {
|
||||
//Non-functional.//
|
||||
return null;
|
||||
}//getName()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.view.IAbstractComponent#verifyThread()
|
||||
*/
|
||||
public void verifyThread() {
|
||||
//Non-functional.//
|
||||
}//verifyThread()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.view.IView#center(com.foundation.view.IView)
|
||||
*/
|
||||
public void center(IView centerOnView) {
|
||||
//Non-functional.//
|
||||
}//center()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.Container#center()
|
||||
*/
|
||||
public void center() {
|
||||
//Non-functional.//
|
||||
}//center()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.view.IView#getController()
|
||||
*/
|
||||
public AbstractViewController getController() {
|
||||
//Non-functional.//
|
||||
return null;
|
||||
}//getController()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.view.IAbstractComponent#onEventFired(com.foundation.view.IEventAssociation, java.lang.Object[])
|
||||
*/
|
||||
public void onEventFired(IEventAssociation eventAssociation, Object[] eventArguments) {
|
||||
//Non-functional.//
|
||||
}//onEventFired()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.view.ISingleResourceAssociationChangeListener#onValueChanged(com.foundation.view.ResourceAssociation, int)
|
||||
*/
|
||||
public void onValueChanged(ResourceAssociation resourceAssociation, int flags) {
|
||||
//Non-functional.//
|
||||
}//onValueChanged()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.view.IMultiResourceAssociationChangeListener#onValueChanged(com.foundation.view.ResourceAssociation, java.lang.Object, boolean)
|
||||
*/
|
||||
public void onValueChanged(ResourceAssociation resourceAssociation, Object alteredItem, boolean isUpdate) {
|
||||
//Non-functional.//
|
||||
}//onValueChanged()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.view.ISingleResourceAssociationChangeListener#getDecorationManager()
|
||||
*/
|
||||
public DecorationManager getDecorationManager() {
|
||||
//Non-functional.//
|
||||
return null;
|
||||
}//getDecorationManager()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.view.ISingleResourceAssociationChangeListener#addDecoration(com.foundation.view.ResourceAssociation, com.foundation.view.AbstractDecoration)
|
||||
*/
|
||||
public void addDecoration(ResourceAssociation association, AbstractDecoration decoration) {
|
||||
//Non-functional.//
|
||||
}//addDecoration()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.view.IMultiResourceAssociationChangeListener#addDecoration(com.foundation.view.ResourceAssociation, java.lang.Object, com.foundation.view.AbstractDecoration)
|
||||
*/
|
||||
public void addDecoration(ResourceAssociation association, Object row, Object data, AbstractDecoration decoration) {
|
||||
//Non-functional.//
|
||||
}//addDecoration()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.view.ISingleResourceAssociationChangeListener#removeDecoration(com.foundation.view.ResourceAssociation, com.foundation.view.AbstractDecoration)
|
||||
*/
|
||||
public void removeDecoration(ResourceAssociation association, AbstractDecoration decoration) {
|
||||
//Non-functional.//
|
||||
}//removeDecoration()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.view.IMultiResourceAssociationChangeListener#removeDecoration(com.foundation.view.ResourceAssociation, java.lang.Object, com.foundation.view.AbstractDecoration)
|
||||
*/
|
||||
public void removeDecoration(ResourceAssociation association, Object row, Object data, AbstractDecoration decoration) {
|
||||
//Non-functional.//
|
||||
}//removeDecoration()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.view.IAbstractComponent#getResourceService()
|
||||
*/
|
||||
public AbstractResourceService getResourceService() {
|
||||
//Non-functional.//
|
||||
return null;
|
||||
}//getResourceService()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.view.ISingleResourceAssociationChangeListener#addMessageHold()
|
||||
*/
|
||||
public void addMessageHold() {
|
||||
//Non-functional.//
|
||||
}//addMessageHold()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.view.ISingleResourceAssociationChangeListener#removeMessageHold()
|
||||
*/
|
||||
public void removeMessageHold() {
|
||||
//Non-functional.//
|
||||
}//removeMessageHold()//
|
||||
}//SwtContainer//
|
||||
/**
|
||||
* ViewContainer constructor.
|
||||
*/
|
||||
public ViewContainer() {
|
||||
super();
|
||||
}//ViewContainer()//
|
||||
/**
|
||||
* Gets the SWT composite that represents this panel.
|
||||
* @return The SWT composite providing visualization for this panel.
|
||||
*/
|
||||
public org.eclipse.swt.widgets.Composite getSwtComposite() {
|
||||
return (org.eclipse.swt.widgets.Composite) getSwtWidget();
|
||||
}//getSwtComposite()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.AbstractComponent#internalViewInitialize()
|
||||
*/
|
||||
protected void internalViewInitialize() {
|
||||
super.internalViewInitialize();
|
||||
|
||||
if(controllerClassName != null) {
|
||||
try {
|
||||
Control focusControl = getDisplay().getFocusControl();
|
||||
|
||||
SwtUtilities.setRedraw(getShell(), false);
|
||||
|
||||
try {
|
||||
Class type = getSessionViewController().getSessionController().getCacheLoader().loadClass(controllerClassName);
|
||||
Constructor constructor = type.getConstructor(new Class[] {IViewContext.class});
|
||||
|
||||
controller = (ViewController) constructor.newInstance(new Object[] {SwtViewContext.getSingleton()});
|
||||
controller.openPartial(swtContainer, SwtViewContext.getSingleton());
|
||||
|
||||
//TODO: Is this desired?
|
||||
if(focusControl != null) {
|
||||
focusControl.forceFocus();
|
||||
}//if//
|
||||
|
||||
if(getComponents().getSize() == 1) {
|
||||
getSwtComposite().setTabList(new Control[] {((Component) getComponents().getFirst()).getSwtControl()});
|
||||
}//if//
|
||||
else {
|
||||
getSwtComposite().setTabList(null);
|
||||
}//else//
|
||||
}//try//
|
||||
finally {
|
||||
SwtUtilities.setRedraw(getShell(), true);
|
||||
}//finally//
|
||||
}//try//
|
||||
catch(Throwable e) {
|
||||
Debug.log(e);
|
||||
}//catch//
|
||||
}//if//
|
||||
}//internalViewInitialize()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.AbstractComponent#internalViewRelease()
|
||||
*/
|
||||
protected void internalViewRelease() {
|
||||
if(component != null) {
|
||||
controller.close();
|
||||
}//if//
|
||||
|
||||
super.internalViewRelease();
|
||||
}//internalViewRelease()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.AbstractComponent#internalViewSynchronize()
|
||||
*/
|
||||
protected void internalViewSynchronize() {
|
||||
super.internalViewSynchronize();
|
||||
|
||||
if(component != null) {
|
||||
controller.synchronize();
|
||||
}//if//
|
||||
}//internalViewSynchronize()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.AbstractComponent#internalProcessMessage(com.foundation.tcv.model.ViewMessage)
|
||||
*/
|
||||
public Object internalProcessMessage(ViewMessage viewMessage) {
|
||||
Object result = null;
|
||||
|
||||
switch(viewMessage.getMessageNumber()) {
|
||||
case MESSAGE_INITIALIZE: {
|
||||
if(getSwtControl() == null) {
|
||||
int style = viewMessage.getMessageSecondaryInteger();
|
||||
|
||||
//Link to the parent container.//
|
||||
setContainer((Container) getComponent(viewMessage.getMessageInteger()));
|
||||
getContainer().addComponent(this);
|
||||
//Create the SWT widget.//
|
||||
setSwtWidget(new org.eclipse.swt.widgets.Composite(getContainer().getSwtParent(), style));
|
||||
getSwtWidget().setData(this);
|
||||
getSwtComposite().setLayout(new FillLayout());
|
||||
|
||||
//If the container has already been initialized then force the parent to re-layout so that this component will appear.//
|
||||
if(getContainer().isInitialized()) {
|
||||
getContainer().getSwtComposite().layout(true, true);
|
||||
}//if//
|
||||
}//if//
|
||||
break;
|
||||
}//case//
|
||||
case MESSAGE_SET_CONTROLLER_CLASS_NAME: {
|
||||
controllerClassName = (String) viewMessage.getMessageData();
|
||||
break;
|
||||
}//case//
|
||||
default: {
|
||||
result = super.internalProcessMessage(viewMessage);
|
||||
}//default//
|
||||
}//switch//
|
||||
|
||||
return result;
|
||||
}//internalProcessMessage()//
|
||||
}//ViewContainer//
|
||||
@@ -0,0 +1,192 @@
|
||||
/*
|
||||
* Copyright (c) 2003,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.tcv.swt.client;
|
||||
|
||||
import org.eclipse.swt.events.*;
|
||||
import org.eclipse.swt.graphics.*;
|
||||
import org.eclipse.swt.widgets.Composite;
|
||||
import org.eclipse.swt.widgets.Control;
|
||||
|
||||
import com.foundation.tcv.swt.*;
|
||||
import com.foundation.tcv.view.*;
|
||||
import com.foundation.tcv.client.controller.SessionViewController;
|
||||
|
||||
public class Window extends Frame implements ShellListener, IWindow {
|
||||
private Window parent = null; //The parent in this case is not the container, but used for dialog like functionality.//
|
||||
private boolean setInitialVisibility = true;
|
||||
private boolean setInitialFocus = true;
|
||||
/**
|
||||
* Window constructor.
|
||||
*/
|
||||
public Window() {
|
||||
super();
|
||||
}//Window()//
|
||||
/**
|
||||
* Gets the SWT shell that represents this frame.
|
||||
* @return The shell providing visualization for this frame.
|
||||
*/
|
||||
public org.eclipse.swt.widgets.Shell getSwtShell() {
|
||||
return (org.eclipse.swt.widgets.Shell) getSwtControl();
|
||||
}//getSwtShell()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.Frame#registerShellListeners()
|
||||
*/
|
||||
protected void registerShellListeners() {
|
||||
//Add this component as a shell listener so we get shell events.//
|
||||
getSwtShell().addShellListener(this);
|
||||
}//registerShellListeners()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.AbstractComponent#internalViewInitialize()
|
||||
*/
|
||||
protected void internalViewInitialize() {
|
||||
super.internalViewInitialize();
|
||||
}//internalViewInitialize()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.AbstractComponent#internalViewRelease()
|
||||
*/
|
||||
protected void internalViewRelease() {
|
||||
try {
|
||||
if((getSwtShell() != null) && (!getSwtShell().isDisposed())) {
|
||||
//Add this component as a shell listener so we get shell events.//
|
||||
getSwtShell().addShellListener(this);
|
||||
}//if//
|
||||
|
||||
super.internalViewRelease();
|
||||
}//try//
|
||||
finally {
|
||||
if(parent != null) {
|
||||
//TODO: Find a way to bring the window to the forefront.//
|
||||
// parent.getSwtShell().setEnabled(true);
|
||||
parent.getSwtShell().setFocus();
|
||||
parent = null;
|
||||
}//if//
|
||||
}//finally//
|
||||
}//internalViewRelease()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.AbstractComponent#internalProcessMessage(com.foundation.tcv.model.ViewMessage)
|
||||
*/
|
||||
public Object internalProcessMessage(ViewMessage viewMessage) {
|
||||
Object retVal = null;
|
||||
|
||||
switch(viewMessage.getMessageNumber()) {
|
||||
case MESSAGE_INITIALIZE: {
|
||||
if(getSwtWidget() == null) {
|
||||
long[] parentId = (long[]) viewMessage.getMessageData();
|
||||
int style = viewMessage.getMessageInteger();
|
||||
Window parent = (Window) (parentId != null ? getComponent(parentId) : null);
|
||||
|
||||
if(parent != null) {
|
||||
this.parent = parent;
|
||||
// parent.getSwtShell().setEnabled(false);
|
||||
setSwtWidget(new org.eclipse.swt.widgets.Shell(parent.getSwtShell(), style));
|
||||
}//if//
|
||||
else {
|
||||
setSwtWidget(new org.eclipse.swt.widgets.Shell(getDisplay(), style));
|
||||
}//else//
|
||||
|
||||
getSwtWidget().setData(this);
|
||||
}//if//
|
||||
break;
|
||||
}//case//
|
||||
case MESSAGE_SET_IS_VISIBLE: {
|
||||
if(setInitialVisibility && ((Boolean) viewMessage.getMessageData()).booleanValue()) {
|
||||
setInitialVisibility = false;
|
||||
centerOnParent();
|
||||
}//if//
|
||||
|
||||
retVal = super.internalProcessMessage(viewMessage);
|
||||
break;
|
||||
}//case//
|
||||
case MESSAGE_SET_FOCUS: {
|
||||
grabFocus();
|
||||
break;
|
||||
}//case//
|
||||
default: {
|
||||
retVal = super.internalProcessMessage(viewMessage);
|
||||
}//default//
|
||||
}//switch//
|
||||
|
||||
return retVal;
|
||||
}//internalProcessMessage()//
|
||||
/**
|
||||
* Grabs focus.
|
||||
*/
|
||||
protected void grabFocus() {
|
||||
if(setInitialFocus) {
|
||||
Control focusControl = locateInitialFocusControl(getSwtComposite());
|
||||
|
||||
setInitialFocus = false;
|
||||
|
||||
if(focusControl != null) {
|
||||
focusControl.setFocus();
|
||||
}//if//
|
||||
}//if//
|
||||
else {
|
||||
getSwtDecorations().setFocus();
|
||||
}//else//
|
||||
}//grabFocus()//
|
||||
/**
|
||||
* Recursively searches for the initial focus control.
|
||||
* @param parent The parent composite to look in.
|
||||
* @return The initial focus control.
|
||||
*/
|
||||
private Control locateInitialFocusControl(Composite parent) {
|
||||
Control[] tabList = parent.getTabList();
|
||||
Control result = null;
|
||||
|
||||
if(tabList != null && tabList.length > 0) {
|
||||
for(int index = 0; result == null && index < tabList.length; index++) {
|
||||
if(tabList[index] instanceof Composite) {
|
||||
result = locateInitialFocusControl((Composite) tabList[index]);
|
||||
}//if//
|
||||
else {
|
||||
result = tabList[index];
|
||||
}//else//
|
||||
}//for//
|
||||
}//if//
|
||||
|
||||
return result;
|
||||
}//locateInitialFocusControl()//
|
||||
/**
|
||||
* Centers the view on its parent if there is one.
|
||||
*/
|
||||
protected void centerOnParent() {
|
||||
if(parent != null) { //Center the window on the parent if there is one. TODO: Allow a way to turn this centering off?//
|
||||
Rectangle parentBounds = parent.getShell().getBounds();
|
||||
Point size = getSwtShell().getSize();
|
||||
Rectangle displayArea = getSwtShell().getDisplay().getClientArea();
|
||||
int x = ((parentBounds.width - size.x) >> 1) + parentBounds.x;
|
||||
int y = ((parentBounds.height - size.y) >> 1) + parentBounds.y;
|
||||
|
||||
if((x + size.x) - parentBounds.x > displayArea.width) {
|
||||
x = (displayArea.width - size.x) + parentBounds.x;
|
||||
}//if//
|
||||
|
||||
if((y + size.y) - parentBounds.y > displayArea.height) {
|
||||
y = (displayArea.height - size.y) + parentBounds.y;
|
||||
}//if//
|
||||
|
||||
if(x - parentBounds.x < 0) {
|
||||
x = parentBounds.x;
|
||||
}//if//
|
||||
|
||||
if(y - parentBounds.y < 0) {
|
||||
y = parentBounds.y;
|
||||
}//if//
|
||||
|
||||
getSwtShell().setLocation(x, y);
|
||||
}//if//
|
||||
}//centerOnParent()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.client.view.IAbstractClientViewComponent#initialize(int, com.foundation.tcv.client.controller.SessionViewController)
|
||||
*/
|
||||
public void initialize(int number, SessionViewController sessionViewController) {
|
||||
//Perform the general initialization first.//
|
||||
super.initialize(number, sessionViewController);
|
||||
}//initialize()//
|
||||
}//Window//
|
||||
@@ -0,0 +1,91 @@
|
||||
/*
|
||||
* Copyright (c) 2003,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.tcv.swt.client;
|
||||
|
||||
import org.eclipse.swt.custom.StackLayout;
|
||||
|
||||
import com.common.util.IList;
|
||||
import com.foundation.tcv.swt.*;
|
||||
import com.foundation.tcv.view.*;
|
||||
|
||||
public class Wizard extends Container implements IWizard {
|
||||
/**
|
||||
* Wizard constructor.
|
||||
*/
|
||||
public Wizard() {
|
||||
super();
|
||||
}//Wizard()//
|
||||
/**
|
||||
* Gets the SWT composite that represents this wizard.
|
||||
* @return The SWT composite providing visualization for this wizard.
|
||||
*/
|
||||
public org.eclipse.swt.widgets.Composite getSwtComposite() {
|
||||
return (org.eclipse.swt.widgets.Composite) getSwtWidget();
|
||||
}//getSwtComposite()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.AbstractComponent#internalViewInitialize()
|
||||
*/
|
||||
protected void internalViewInitialize() {
|
||||
super.internalViewInitialize();
|
||||
}//internalViewInitialize()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.AbstractComponent#internalViewRelease()
|
||||
*/
|
||||
protected void internalViewRelease() {
|
||||
super.internalViewRelease();
|
||||
}//internalViewRelease()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.AbstractComponent#internalViewSynchronize()
|
||||
*/
|
||||
protected void internalViewSynchronize() {
|
||||
super.internalViewSynchronize();
|
||||
}//internalViewSynchronize()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.AbstractComponent#internalProcessMessage(com.foundation.tcv.model.ViewMessage)
|
||||
*/
|
||||
public Object internalProcessMessage(ViewMessage viewMessage) {
|
||||
Object retVal = null;
|
||||
|
||||
switch(viewMessage.getMessageNumber()) {
|
||||
case MESSAGE_INITIALIZE: {
|
||||
if(getSwtControl() == null) {
|
||||
int[] data = (int[]) viewMessage.getMessageData();
|
||||
int style = data[1];
|
||||
|
||||
//Link to the parent container.//
|
||||
setContainer((Container) getComponent(data[0]));
|
||||
getContainer().addComponent(this);
|
||||
//Create the SWT widget.//
|
||||
setSwtWidget(new org.eclipse.swt.widgets.Composite(getContainer().getSwtParent(), style));
|
||||
getSwtWidget().setData(this);
|
||||
getSwtComposite().setLayout(new StackLayout());
|
||||
|
||||
//If the container has already been initialized then force the parent to re-layout so that this component will appear.//
|
||||
if(getContainer().isInitialized()) {
|
||||
getContainer().getSwtComposite().layout(true, true);
|
||||
}//if//
|
||||
}//if//
|
||||
break;
|
||||
}//case//
|
||||
case MESSAGE_CHANGE_PAGE: {
|
||||
Integer pageNumber = (Integer) viewMessage.getMessageData();
|
||||
int currentPageNumber = pageNumber.intValue();
|
||||
|
||||
((StackLayout) getSwtComposite().getLayout()).topControl = ((Component) ((IList) getComponents()).get(currentPageNumber)).getSwtControl();
|
||||
getSwtComposite().layout();
|
||||
((Component) ((IList) getComponents()).get(currentPageNumber)).getSwtControl().setFocus();
|
||||
break;
|
||||
}//case//
|
||||
default: {
|
||||
retVal = super.internalProcessMessage(viewMessage);
|
||||
}//default//
|
||||
}//switch//
|
||||
|
||||
return retVal;
|
||||
}//internalProcessMessage()//
|
||||
}//Wizard//
|
||||
@@ -0,0 +1,476 @@
|
||||
/*
|
||||
* 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.tcv.swt.client.cell;
|
||||
|
||||
import org.eclipse.swt.SWT;
|
||||
import org.eclipse.swt.events.SelectionEvent;
|
||||
import org.eclipse.swt.events.SelectionListener;
|
||||
import org.eclipse.swt.graphics.GC;
|
||||
import org.eclipse.swt.graphics.Image;
|
||||
import org.eclipse.swt.widgets.Button;
|
||||
|
||||
import com.common.thread.IRunnable;
|
||||
import com.common.util.IIterator;
|
||||
import com.foundation.tcv.client.view.ResourceHolder;
|
||||
import com.foundation.tcv.swt.cell.ICellButton;
|
||||
import com.foundation.tcv.swt.client.ICellContainer;
|
||||
import com.foundation.tcv.swt.client.RowObject;
|
||||
import com.foundation.tcv.view.ViewMessage;
|
||||
import com.foundation.view.AbstractResourceHolder;
|
||||
import com.foundation.view.JefImage;
|
||||
import com.foundation.view.swt.util.SwtUtilities;
|
||||
|
||||
public class CellButton extends CellComponent implements ICellButton {
|
||||
/** The control style. */
|
||||
private int style = 0;
|
||||
/** The control's default selection state. */
|
||||
private Boolean selection = Boolean.FALSE;
|
||||
/** Whether selection notifications to the server will block for a response. */
|
||||
private boolean blockOnSelections = false;
|
||||
/** Whether the selection state should be auto-synchronized. */
|
||||
private boolean autoSynchronizeSelection = true;
|
||||
/** The delay to be used when auto synchronizing changes. */
|
||||
private long autoSynchronizeSelectionDelay = 500;
|
||||
/** 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);
|
||||
/** The swt image last held by the image holder. */
|
||||
private Image swtImage = null;
|
||||
|
||||
/**
|
||||
* Maintains the cell data for the control. A control may only exist if it is visible, but the data must be maintained regardless.
|
||||
*/
|
||||
public class ButtonCellControlData extends CellControlData {
|
||||
/** The control's selection state. */
|
||||
private Boolean selection = null;
|
||||
/** The control's text. */
|
||||
private Object text = null;
|
||||
/** The control's image. */
|
||||
private Object image = null;
|
||||
|
||||
/**
|
||||
* ButtonCellControlData constructor.
|
||||
* @param rowObject The row for the cell.
|
||||
*/
|
||||
public ButtonCellControlData(RowObject rowObject) {
|
||||
super(rowObject);
|
||||
}//ButtonCellControlData()//
|
||||
}//ButtonCellControlData//
|
||||
|
||||
/**
|
||||
* Encapsulates a control with related data such as listeners and the data model for the cell.
|
||||
*/
|
||||
public class ButtonCellControl extends CellControl implements SelectionListener {
|
||||
/** The last set image. This will be used to dispose of the image. */
|
||||
private Image swtImage = null;
|
||||
/** The resource holder for the text. */
|
||||
private ResourceHolder textHolder = new ResourceHolder(this);
|
||||
/** The resource holder for the image. */
|
||||
private ResourceHolder imageHolder = new ResourceHolder(this);
|
||||
/** Whether the button tracks a state. */
|
||||
private final boolean isStateful;
|
||||
/** The task that auto synchronizes the selection state after a short delay. */
|
||||
private Task autoSynchronizeSelectionTask = null;
|
||||
|
||||
/**
|
||||
* ButtonCellControl constructor.
|
||||
* @param control The control being encapsulated.
|
||||
* @param cellData The cell's data.
|
||||
*/
|
||||
public ButtonCellControl(Button control, ButtonCellControlData cellData) {
|
||||
super(control, cellData);
|
||||
isStateful = ((control.getStyle() & SWT.CHECK) > 0) || ((control.getStyle() & SWT.RADIO) > 0) || ((control.getStyle() & SWT.TOGGLE) > 0);
|
||||
getSwtButton().addSelectionListener(this);
|
||||
}//ButtonCellControl()//
|
||||
/**
|
||||
* Gets the button cell data for the control.
|
||||
* @return The cell data for the button control.
|
||||
*/
|
||||
public ButtonCellControlData getButtonCellControlData() {
|
||||
return (ButtonCellControlData) getCellControlData();
|
||||
}//getButtonCellControlData()//
|
||||
/**
|
||||
* Gets the button control.
|
||||
* @return The button being encapsulated.
|
||||
*/
|
||||
public Button getSwtButton() {
|
||||
return (Button) getSwtControl();
|
||||
}//getSwtButton()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.cell.CellComponent.CellControl#initialize()
|
||||
*/
|
||||
public void initialize() {
|
||||
super.initialize();
|
||||
}//initialize()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.cell.CellComponent.CellControl#refresh()
|
||||
*/
|
||||
public void refresh() {
|
||||
super.refresh();
|
||||
refreshImage();
|
||||
refreshSelection();
|
||||
refreshText();
|
||||
}//refresh()//
|
||||
/**
|
||||
* Refreshes the image value.
|
||||
*/
|
||||
public void refreshImage() {
|
||||
imageHolder.setValue(getButtonCellControlData().image != null ? getButtonCellControlData().image : CellButton.this.imageHolder.getValue());
|
||||
}//refreshImage()//
|
||||
/**
|
||||
* Refreshes the selection value.
|
||||
*/
|
||||
public void refreshSelection() {
|
||||
if(isStateful) {
|
||||
controlSetSelection(getButtonCellControlData().selection != null ? getButtonCellControlData().selection.booleanValue() : CellButton.this.selection != null ? CellButton.this.selection.booleanValue() : false);
|
||||
}//if//
|
||||
}//refreshSelection()//
|
||||
/**
|
||||
* Refreshes the text value.
|
||||
*/
|
||||
public void refreshText() {
|
||||
textHolder.setValue(getButtonCellControlData().text != null ? getButtonCellControlData().text : CellButton.this.textHolder.getValue());
|
||||
}//refreshText()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.view.swt.cell.CellComponent.CellControl#release()
|
||||
*/
|
||||
public void release() {
|
||||
if(textHolder != null) {
|
||||
textHolder.release();
|
||||
}//if//
|
||||
|
||||
if(imageHolder != null) {
|
||||
imageHolder.release();
|
||||
}//if//
|
||||
|
||||
if((swtImage != null) && (!swtImage.isDisposed())) {
|
||||
swtImage.dispose();
|
||||
}//if//
|
||||
|
||||
if(!getSwtButton().isDisposed()) {
|
||||
getSwtButton().removeSelectionListener(this);
|
||||
}//if//
|
||||
|
||||
//Ignore any pending synchronizations.//
|
||||
synchronized(this) {
|
||||
if(autoSynchronizeSelectionTask != null) {
|
||||
removeTask(autoSynchronizeSelectionTask);
|
||||
autoSynchronizeSelectionTask = null;
|
||||
}//if//
|
||||
}//synchronized//
|
||||
|
||||
super.release();
|
||||
}//release()//
|
||||
/**
|
||||
* Forces any pending synchronizations to complete.
|
||||
*/
|
||||
public void synchronize() {
|
||||
if(autoSynchronizeSelectionTask != null) {
|
||||
removeTask(autoSynchronizeSelectionTask);
|
||||
autoSynchronizeSelectionTask.execute();
|
||||
autoSynchronizeSelectionTask = null;
|
||||
}//if//
|
||||
}//synchronize()//
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.swt.events.SelectionListener#widgetDefaultSelected(org.eclipse.swt.events.SelectionEvent)
|
||||
*/
|
||||
public void widgetDefaultSelected(SelectionEvent event) {
|
||||
}//widgetDefaultSelected()//
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.swt.events.SelectionListener#widgetSelected(org.eclipse.swt.events.SelectionEvent)
|
||||
*/
|
||||
public void widgetSelected(SelectionEvent event) {
|
||||
selectionChanged(getSwtButton().getSelection());
|
||||
}//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(blockOnSelections || autoSynchronizeSelection) {
|
||||
if((!blockOnSelections) && (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(ButtonCellControl.this) {
|
||||
if(autoSynchronizeSelectionTask == this) {
|
||||
//Cleanup after the task.//
|
||||
autoSynchronizeSelectionTask = null;
|
||||
getEventLoop().executeAsync(new IRunnable() {
|
||||
public Object run() {
|
||||
sendMessage(MESSAGE_VIEW_SYNCHRONIZE_SELECTION, isSelected ? Boolean.TRUE : Boolean.FALSE, null, getButtonCellControlData().getRowObject().getObjectId(), 0);
|
||||
return null;
|
||||
}//run()//
|
||||
});
|
||||
}//if//
|
||||
}//synchronized//
|
||||
}//run()//
|
||||
};
|
||||
addTask(autoSynchronizeSelectionTask, autoSynchronizeSelectionDelay);
|
||||
}//synchronized//
|
||||
}//if//
|
||||
else {
|
||||
if(blockOnSelections) {
|
||||
sendRoundTripMessage(MESSAGE_VIEW_SYNCHRONIZE_SELECTION, isSelected ? Boolean.TRUE : Boolean.FALSE, null, getButtonCellControlData().getRowObject().getObjectId(), 0, null);
|
||||
}//if//
|
||||
else {
|
||||
sendMessage(MESSAGE_VIEW_SYNCHRONIZE_SELECTION, isSelected ? Boolean.TRUE : Boolean.FALSE, null, getButtonCellControlData().getRowObject().getObjectId(), 0);
|
||||
}//else//
|
||||
}//else//
|
||||
}//if//
|
||||
|
||||
if(isStateful) {
|
||||
getButtonCellControlData().selection = isSelected ? Boolean.TRUE : Boolean.FALSE;
|
||||
}//if//
|
||||
}//selectionChanged()//
|
||||
/**
|
||||
* Sets the text.
|
||||
* @param text The text to display.
|
||||
*/
|
||||
protected void controlSetText(String text) {
|
||||
if(getSwtButton() != null) {
|
||||
getSwtButton().setText(text);
|
||||
}//if//
|
||||
}//controlSetText()//
|
||||
/**
|
||||
* Sets the image.
|
||||
* @param image The image to display.
|
||||
*/
|
||||
protected void controlSetImage(JefImage image) {
|
||||
if(swtImage != null) {
|
||||
swtImage.dispose();
|
||||
swtImage = null;
|
||||
}//if//
|
||||
|
||||
if(image != null) {
|
||||
swtImage = SwtUtilities.getImage(getSwtControl().getDisplay(), image);
|
||||
}//if//
|
||||
|
||||
getSwtButton().setImage(swtImage);
|
||||
}//controlSetImage()//
|
||||
/**
|
||||
* Sets the component's selection state.
|
||||
* @param isSelected Whether the button is to be selected.
|
||||
*/
|
||||
protected void controlSetSelection(boolean isSelected) {
|
||||
//Some components may not have controls, such as value holders.//
|
||||
if(getSwtButton() != null) {
|
||||
getSwtButton().setSelection(isSelected);
|
||||
}//if//
|
||||
}//controlSetSelection()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.view.IResourceHolderComponent#resourceHolderChanged(com.foundation.view.AbstractResourceHolder, java.lang.Object, java.lang.Object)
|
||||
*/
|
||||
public void resourceHolderChanged(AbstractResourceHolder resourceHolder, Object oldValue, Object newValue, int flags) {
|
||||
if(resourceHolder == textHolder) {
|
||||
controlSetText((String) resourceHolder.getValue());
|
||||
}//if//
|
||||
else if(resourceHolder == imageHolder) {
|
||||
controlSetImage((JefImage) resourceHolder.getValue());
|
||||
}//else if//
|
||||
else {
|
||||
super.resourceHolderChanged(resourceHolder, oldValue, newValue, flags);
|
||||
}//else//
|
||||
}//resourceHolderChanged()//
|
||||
}//ButtonCellControl//
|
||||
/**
|
||||
* CellButton constructor.
|
||||
*/
|
||||
public CellButton() {
|
||||
}//CellButton()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.cell.CellComponent#supportsControl()
|
||||
*/
|
||||
public boolean supportsControl() {
|
||||
return true;
|
||||
}//supportsControl()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.cell.CellComponent#initializeCellControl(com.foundation.tcv.swt.client.cell.CellComponent.CellControlData)
|
||||
*/
|
||||
protected CellControl initializeCellControl(CellControlData cellControlData) {
|
||||
return new ButtonCellControl(new Button(getCellContainer().getSwtComposite(cellControlData.getRowObject()), style), (ButtonCellControlData) cellControlData);
|
||||
}//initializeCellControl()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.cell.CellComponent#initializeCellControlData(com.foundation.tcv.swt.client.CollectionComponent.RowObject)
|
||||
*/
|
||||
protected CellControlData initializeCellControlData(RowObject rowObject) {
|
||||
return new ButtonCellControlData(rowObject);
|
||||
}//initializeCellControlData()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.cell.CellComponent#releaseCellControlData(com.foundation.tcv.swt.client.cell.CellComponent.CellControlData)
|
||||
*/
|
||||
protected void releaseCellControlData(CellControlData cellControlData) {
|
||||
}//releaseCellControlData()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.cell.CellComponent#paintCell(com.foundation.tcv.swt.client.cell.CellComponent.CellControlData, org.eclipse.swt.graphics.GC)
|
||||
*/
|
||||
protected void paintCell(CellControlData cellControlData, GC graphics) {
|
||||
}//paintCell()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.cell.CellComponent#internalViewRelease()
|
||||
*/
|
||||
protected void internalViewRelease() {
|
||||
if(textHolder != null) {
|
||||
textHolder.release();
|
||||
}//if//
|
||||
|
||||
if(imageHolder != null) {
|
||||
imageHolder.release();
|
||||
}//if//
|
||||
|
||||
if((swtImage != null) && (!swtImage.isDisposed())) {
|
||||
swtImage.dispose();
|
||||
}//if//
|
||||
|
||||
super.internalViewRelease();
|
||||
}//internalViewRelease()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.AbstractComponent#internalProcessMessage(com.foundation.tcv.view.ViewMessage)
|
||||
*/
|
||||
public Object internalProcessMessage(ViewMessage viewMessage) {
|
||||
Object result = null;
|
||||
|
||||
switch(viewMessage.getMessageNumber()) {
|
||||
case MESSAGE_INITIALIZE: {
|
||||
int[] data = (int[]) viewMessage.getMessageData();
|
||||
|
||||
setCellContainer((ICellContainer) getComponent(data[0]));
|
||||
style = data[1];
|
||||
getCellContainer().addCellComponent(this);
|
||||
break;
|
||||
}//case//
|
||||
case MESSAGE_SET_IMAGE: {
|
||||
setImage(viewMessage.getMessageData(), viewMessage.getMessageInteger() != -1 ? (ButtonCellControlData) getCellControlData(getCellContainer().getRowObject(viewMessage.getMessageInteger())) : null);
|
||||
break;
|
||||
}//case//
|
||||
case MESSAGE_SET_TEXT: {
|
||||
setText(viewMessage.getMessageData(), viewMessage.getMessageInteger() != -1 ? (ButtonCellControlData) getCellControlData(getCellContainer().getRowObject(viewMessage.getMessageInteger())) : null);
|
||||
break;
|
||||
}//case//
|
||||
case MESSAGE_SET_AUTO_SYNCHRONIZE_SELECTION: {
|
||||
autoSynchronizeSelection = ((Boolean) viewMessage.getMessageData()).booleanValue();
|
||||
break;
|
||||
}//case//
|
||||
case MESSAGE_SET_AUTO_SYNCHRONIZE_SELECTION_DELAY: {
|
||||
autoSynchronizeSelectionDelay = ((Long) viewMessage.getMessageData()).longValue();
|
||||
break;
|
||||
}//case//
|
||||
case MESSAGE_SET_BLOCK_ON_SELECTIONS: {
|
||||
blockOnSelections = ((Boolean) viewMessage.getMessageData()).booleanValue();
|
||||
break;
|
||||
}//case//
|
||||
case MESSAGE_SET_IS_SELECTED: {
|
||||
setSelection((Boolean) viewMessage.getMessageData(), viewMessage.getMessageInteger() != -1 ? (ButtonCellControlData) getCellControlData(getCellContainer().getRowObject(viewMessage.getMessageInteger())) : null);
|
||||
break;
|
||||
}//case//
|
||||
default: {
|
||||
result = super.internalProcessMessage(viewMessage);
|
||||
}//default//
|
||||
}//switch//
|
||||
|
||||
return result;
|
||||
}//internalProcessMessage()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.cell.CellComponent#internalResourceHolderChanged(com.foundation.tcv.client.view.ResourceHolder, java.lang.Object, java.lang.Object)
|
||||
*/
|
||||
protected void internalResourceHolderChanged(ResourceHolder resourceHolder, Object oldValue, Object newValue, int flags) {
|
||||
if(resourceHolder == textHolder) {
|
||||
IIterator iterator = getCellControlIterator();
|
||||
|
||||
//Update the existing controls.//
|
||||
while(iterator.hasNext()) {
|
||||
ButtonCellControl cellControl = (ButtonCellControl) iterator.next();
|
||||
|
||||
cellControl.refreshText();
|
||||
}//while//
|
||||
}//if//
|
||||
else if(resourceHolder == imageHolder) {
|
||||
IIterator iterator = getCellControlIterator();
|
||||
|
||||
if(swtImage != null) {
|
||||
swtImage.dispose();
|
||||
}//if//
|
||||
|
||||
if(newValue != null) {
|
||||
swtImage = SwtUtilities.getImage(getDisplay(), (JefImage) newValue);
|
||||
}//if//
|
||||
|
||||
//Update the existing controls.//
|
||||
while(iterator.hasNext()) {
|
||||
ButtonCellControl cellControl = (ButtonCellControl) iterator.next();
|
||||
|
||||
cellControl.refreshImage();
|
||||
}//while//
|
||||
}//else if//
|
||||
else {
|
||||
super.internalResourceHolderChanged(resourceHolder, oldValue, newValue, flags);
|
||||
}//else//
|
||||
}//internalResourceHolderChanged()//
|
||||
/**
|
||||
* Sets the image for the cell control(s).
|
||||
* @param value The new value.
|
||||
* @param cellControlData The cell control data if changing a specific cell, otherwise null.
|
||||
*/
|
||||
protected void setImage(Object value, ButtonCellControlData cellControlData) {
|
||||
if(cellControlData == null) {
|
||||
if(imageHolder == null) {
|
||||
imageHolder = new ResourceHolder(this);
|
||||
}//if//
|
||||
|
||||
imageHolder.setValue(value);
|
||||
}//if//
|
||||
else {
|
||||
cellControlData.image = value;
|
||||
|
||||
if(cellControlData.getCellControl() != null) {
|
||||
((ButtonCellControl) cellControlData.getCellControl()).refreshImage();
|
||||
}//if//
|
||||
}//else//
|
||||
}//setImage()//
|
||||
/**
|
||||
* Sets the text for the cell control(s).
|
||||
* @param value The new value.
|
||||
* @param cellControlData The cell control data if changing a specific cell, otherwise null.
|
||||
*/
|
||||
protected void setText(Object value, ButtonCellControlData cellControlData) {
|
||||
if(cellControlData == null) {
|
||||
if(textHolder == null) {
|
||||
textHolder = new ResourceHolder(this);
|
||||
}//if//
|
||||
|
||||
textHolder.setValue(value);
|
||||
}//if//
|
||||
else {
|
||||
cellControlData.text = value;
|
||||
|
||||
if(cellControlData.getCellControl() != null) {
|
||||
((ButtonCellControl) cellControlData.getCellControl()).refreshText();
|
||||
}//if//
|
||||
}//else//
|
||||
}//setText()//
|
||||
/**
|
||||
* Sets the selection for the cell control(s).
|
||||
* @param value The new value.
|
||||
* @param cellControlData The cell control data if changing a specific cell, otherwise null.
|
||||
*/
|
||||
protected void setSelection(Boolean value, ButtonCellControlData cellControlData) {
|
||||
cellControlData.selection = value;
|
||||
|
||||
if(cellControlData.getCellControl() != null) {
|
||||
((ButtonCellControl) cellControlData.getCellControl()).refreshSelection();
|
||||
}//if//
|
||||
}//setSelection()//
|
||||
}//CellButton//
|
||||
@@ -0,0 +1,742 @@
|
||||
/*
|
||||
* Copyright (c) 2007,2008 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.tcv.swt.client.cell;
|
||||
|
||||
import org.eclipse.swt.events.ModifyEvent;
|
||||
import org.eclipse.swt.events.ModifyListener;
|
||||
import org.eclipse.swt.events.SelectionEvent;
|
||||
import org.eclipse.swt.events.SelectionListener;
|
||||
import org.eclipse.swt.graphics.GC;
|
||||
import org.eclipse.swt.widgets.Combo;
|
||||
|
||||
import com.common.thread.IRunnable;
|
||||
import com.common.util.IIterator;
|
||||
import com.common.util.LiteList;
|
||||
import com.common.util.optimized.IntObjectHashMap;
|
||||
import com.foundation.tcv.swt.cell.IComboBox;
|
||||
import com.foundation.tcv.swt.client.ICellContainer;
|
||||
import com.foundation.tcv.swt.client.RowObject;
|
||||
import com.foundation.tcv.view.ViewMessage;
|
||||
|
||||
public class CellComboBox extends CellComponent implements IComboBox {
|
||||
/** Used by the hidden data to identify when the previous value has not yet been assigned a value. */
|
||||
protected static final Object UNSET_VALUE = new Object();
|
||||
|
||||
/** The control style. */
|
||||
private int style = 0;
|
||||
/** Whether the user can type a custom selection. If this is true and the selection attribute is not a String type then the user input must match a list item's text. */
|
||||
private boolean allowUserItems = false;
|
||||
/** Whether the selection should be automatically sent to the model. */
|
||||
private boolean autoSynchronizeSelection = false;
|
||||
/** The number of milliseconds of delay before auto synchronizing the selection. */
|
||||
private long autoSynchronizeSelectionDelay = 500;
|
||||
/** Whether the UI should block until the selection has completed its synchronization. */
|
||||
private boolean blockOnSelections = false;
|
||||
/** Maps the row objects by their unique object identifiers. */
|
||||
private IntObjectHashMap rowObjectByObjectIdMap = new IntObjectHashMap(100, 200);
|
||||
/** Maps the row objects given the index in the control. An object can be represented more than once in the control if the same row object exists in multiple indices. */
|
||||
private LiteList rowObjectByIndexMap = new LiteList(100, 200);
|
||||
/** The text limit to use with the combo box controls. */
|
||||
private int textLimit = -1;
|
||||
|
||||
public static class ComboRowObject extends RowObject {
|
||||
/** The row's text. */
|
||||
private String text = null;
|
||||
|
||||
/**
|
||||
* ComboRowObject constructor.
|
||||
* @param objectId the row object's identifier.
|
||||
*/
|
||||
public ComboRowObject(int objectId) {
|
||||
super(objectId, -1);
|
||||
}//ComboRowObject()//
|
||||
/**
|
||||
* Gets the text for the row.
|
||||
* @return The row's text.
|
||||
*/
|
||||
public String getText() {
|
||||
return text;
|
||||
}//getText()//
|
||||
/**
|
||||
* Sets the text for the row.
|
||||
* @param text The row's text.
|
||||
*/
|
||||
public void setText(String text) {
|
||||
this.text = text;
|
||||
}//setText()//
|
||||
}//ComboRowObject()//
|
||||
/**
|
||||
* Maintains the cell data for the control. A control may only exist if it is visible, but the data must be maintained regardless.
|
||||
*/
|
||||
public class ComboBoxCellControlData extends CellControlData {
|
||||
/** The currently selected index (on the server). A negative one indicates no selection or a custom selection. */
|
||||
private int selectedObjectIdOnServer = -1;
|
||||
/** The custom selection last sent to the server or received by the server. This will be null if there is no custom selection or there is no selection at all. */
|
||||
private String customSelectionOnServer = null;
|
||||
/** The currently selected index. A negative one indicates no selection or a custom selection. */
|
||||
private int selectedObjectId = -1;
|
||||
/** The current custom selection. This will be null if there is no custom selection or there is no selection at all. */
|
||||
private String customSelection = null;
|
||||
|
||||
/**
|
||||
* ComboBoxCellControlData constructor.
|
||||
* @param rowObject The row for the cell.
|
||||
*/
|
||||
public ComboBoxCellControlData(RowObject rowObject) {
|
||||
super(rowObject);
|
||||
}//ComboBoxCellControlData()//
|
||||
/**
|
||||
* Gets the currently selected object identifier on the server.
|
||||
* @return The object identifier for the selection known by the server, or -1 for no selection.
|
||||
*/
|
||||
protected int getSelectedObjectIdOnServer() {
|
||||
return selectedObjectIdOnServer;
|
||||
}//getSelectedObjectIdOnServer()//
|
||||
/**
|
||||
* Sets the currently selected object identifier on the server.
|
||||
* @param objectId The object identifier for the selection known by the server, or -1 for no selection.
|
||||
*/
|
||||
protected void setSelectedObjectIdOnServer(int objectId) {
|
||||
this.selectedObjectIdOnServer = objectId;
|
||||
}//setSelectedObjectIdOnServer()//
|
||||
/**
|
||||
* Gets the current custom selection text on the server.
|
||||
* @return The selection text, or null if there isn't a custom selection.
|
||||
*/
|
||||
protected String getCustomSelectionOnServer() {
|
||||
return customSelectionOnServer;
|
||||
}//getCustomSelectionOnServer()//
|
||||
/**
|
||||
* Sets the current custom selection text on the server.
|
||||
* @param customSelection The selection text, or null if there isn't a custom selection.
|
||||
*/
|
||||
protected void setCustomSelectionOnServer(String customSelection) {
|
||||
this.customSelectionOnServer = customSelection;
|
||||
}//setCustomSelectionOnServer()//
|
||||
/**
|
||||
* Gets the currently selected object identifier.
|
||||
* @return The object identifier for the selection, or -1 for no selection or custom selection.
|
||||
*/
|
||||
protected int getSelectedObjectId() {
|
||||
return selectedObjectId;
|
||||
}//getSelectedObjectId()//
|
||||
/**
|
||||
* Sets the currently selected object identifier.
|
||||
* @param objectId The object identifier for the selection, or -1 for no selection or custom selection.
|
||||
*/
|
||||
protected void setSelectedObjectId(int objectId) {
|
||||
this.selectedObjectId = objectId;
|
||||
}//setSelectedObjectId()//
|
||||
/**
|
||||
* Gets the current custom selection text.
|
||||
* @return The selection text, or null if there isn't a custom selection.
|
||||
*/
|
||||
protected String getCustomSelection() {
|
||||
return customSelection;
|
||||
}//getCustomSelection()//
|
||||
/**
|
||||
* Sets the current custom selection text.
|
||||
* @param customSelection The selection text, or null if there isn't a custom selection.
|
||||
*/
|
||||
protected void setCustomSelection(String customSelection) {
|
||||
this.customSelection = customSelection;
|
||||
}//setCustomSelection()//
|
||||
}//ComboBoxCellControlData//
|
||||
|
||||
/**
|
||||
* Encapsulates a control with related data such as listeners and the data model for the cell.
|
||||
*/
|
||||
public class ComboBoxCellControl extends CellControl implements SelectionListener, ModifyListener {
|
||||
/** The task that auto synchronizes the selection after a short delay. */
|
||||
protected Task autoSynchronizeSelectionTask = null;
|
||||
/** Used to stop selection events from being handled while the items are being changed. */
|
||||
private boolean suspendSelectionEvents = false;
|
||||
|
||||
/**
|
||||
* ComboBoxCellControl constructor.
|
||||
* @param control The control being encapsulated.
|
||||
* @param cellData The cell's data.
|
||||
*/
|
||||
public ComboBoxCellControl(Combo control, ComboBoxCellControlData cellData) {
|
||||
super(control, cellData);
|
||||
getSwtCombo().addSelectionListener(this);
|
||||
getSwtCombo().addModifyListener(this);
|
||||
}//ComboBoxCellControl()//
|
||||
protected void controlRemoveAll() {
|
||||
suspendSelectionEvents = true;
|
||||
getSwtCombo().removeAll();
|
||||
suspendSelectionEvents = false;
|
||||
}//controlRemoveAll()//
|
||||
protected void controlSetItems(Object[] items) {
|
||||
String[] itemTexts = new String[items.length];
|
||||
|
||||
System.arraycopy(items, 0, itemTexts, 0, itemTexts.length);
|
||||
suspendSelectionEvents = true;
|
||||
|
||||
try {
|
||||
getSwtCombo().setItems(itemTexts);
|
||||
}//try//
|
||||
finally {
|
||||
suspendSelectionEvents = false;
|
||||
}//finally//
|
||||
}//controlSetItems()//
|
||||
protected void controlSetItem(int index, Object itemData) {
|
||||
suspendSelectionEvents = true;
|
||||
getSwtCombo().setItem(index, (String) itemData);
|
||||
suspendSelectionEvents = false;
|
||||
}//controlSetItem()//
|
||||
protected void controlAddItem(Object itemData, int index) {
|
||||
suspendSelectionEvents = true;
|
||||
getSwtCombo().add((String) itemData, index);
|
||||
suspendSelectionEvents = false;
|
||||
}//controlAddItem()//
|
||||
protected void controlAddItem(Object itemData) {
|
||||
suspendSelectionEvents = true;
|
||||
getSwtCombo().add((String) itemData);
|
||||
suspendSelectionEvents = false;
|
||||
}//controlAddItem()//
|
||||
protected void controlRemoveItem(int index) {
|
||||
suspendSelectionEvents = true;
|
||||
getSwtCombo().remove(index);
|
||||
suspendSelectionEvents = false;
|
||||
}//controlRemoveItem()//
|
||||
protected int controlGetSelection() {
|
||||
return getSwtCombo().getSelectionIndex();
|
||||
}//controlGetSelection()//
|
||||
protected void controlSetSelection(int index) {
|
||||
suspendSelectionEvents = true;
|
||||
|
||||
if(index == -1) {
|
||||
getSwtCombo().deselectAll();
|
||||
}//if//
|
||||
else {
|
||||
getSwtCombo().select(index);
|
||||
}//else//
|
||||
|
||||
suspendSelectionEvents = false;
|
||||
}//controlSetSelection()//
|
||||
protected void controlSetSelection(String text) {
|
||||
suspendSelectionEvents = true;
|
||||
|
||||
if(text == null) {
|
||||
getSwtCombo().deselectAll();
|
||||
}//if//
|
||||
else {
|
||||
getSwtCombo().setText(text);
|
||||
}//else//
|
||||
|
||||
suspendSelectionEvents = false;
|
||||
}//controlSetSelection()//
|
||||
protected int controlGetSelectionCount() {
|
||||
return getSwtCombo().getText().length() > 0 ? 1 : 0;
|
||||
}//controlGetSelectionCount()//
|
||||
/**
|
||||
* Gets the combo box cell data for the control.
|
||||
* @return The cell data for the combo control.
|
||||
*/
|
||||
public ComboBoxCellControlData getComboBoxCellControlData() {
|
||||
return (ComboBoxCellControlData) getCellControlData();
|
||||
}//getComboBoxCellControlData()//
|
||||
/**
|
||||
* Gets the combo box control.
|
||||
* @return The combo box being encapsulated.
|
||||
*/
|
||||
public Combo getSwtCombo() {
|
||||
return (Combo) getSwtControl();
|
||||
}//getSwtCombo()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.view.swt.cell.CellComponent.CellControl#release()
|
||||
*/
|
||||
public void release() {
|
||||
if((getSwtCombo() != null) && (!getSwtCombo().isDisposed())) {
|
||||
getSwtCombo().removeSelectionListener(this);
|
||||
getSwtCombo().removeModifyListener(this);
|
||||
}//if//
|
||||
|
||||
//Ignore any pending synchronizations.//
|
||||
synchronized(this) {
|
||||
if(autoSynchronizeSelectionTask != null) {
|
||||
removeTask(autoSynchronizeSelectionTask);
|
||||
autoSynchronizeSelectionTask = null;
|
||||
}//if//
|
||||
}//synchronized//
|
||||
|
||||
super.release();
|
||||
}//release()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.cell.CellComponent.CellControl#refresh()
|
||||
*/
|
||||
public void refresh() {
|
||||
refreshCollection();
|
||||
refreshSelection();
|
||||
super.refresh();
|
||||
}//refresh()//
|
||||
/**
|
||||
* Refreshes the selection.
|
||||
*/
|
||||
public void refreshSelection() {
|
||||
controlSetSelection(getComboBoxCellControlData().selectedObjectIdOnServer);
|
||||
}//refreshSelection()//
|
||||
/**
|
||||
* Refreshes the collection.
|
||||
*/
|
||||
public void refreshCollection() {
|
||||
if(getRowObjectByIndexMap().getSize() > 0) {
|
||||
String[] texts = new String[getRowObjectByIndexMap().getSize()];
|
||||
|
||||
for(int index = 0; index < texts.length; index++) {
|
||||
texts[index] = getRowObjectAtIndex(index).text;
|
||||
}//for//
|
||||
|
||||
suspendSelectionEvents = true;
|
||||
getSwtCombo().setItems(texts);
|
||||
suspendSelectionEvents = false;
|
||||
}//if//
|
||||
else {
|
||||
suspendSelectionEvents = true;
|
||||
getSwtCombo().removeAll();
|
||||
suspendSelectionEvents = false;
|
||||
}//else//
|
||||
}//refreshCollection()//
|
||||
/**
|
||||
* Forces any pending synchronizations to complete.
|
||||
*/
|
||||
public void synchronize() {
|
||||
if(!getAutoSynchronizeSelection()) {
|
||||
synchronizeSelection();
|
||||
}//if//
|
||||
else {
|
||||
synchronized(this) {
|
||||
if(autoSynchronizeSelectionTask != null) {
|
||||
removeTask(autoSynchronizeSelectionTask);
|
||||
autoSynchronizeSelectionTask.execute();
|
||||
autoSynchronizeSelectionTask = null;
|
||||
}//if//
|
||||
}//synchronized//
|
||||
}//else//
|
||||
}//synchronize()//
|
||||
/**
|
||||
* Determines whether there is a custom selection.
|
||||
* @return Whether the user has typed a value in the control that is not in the set to select from.
|
||||
*/
|
||||
protected boolean hasCustomSelection() {
|
||||
return getAllowUserItems() && (getSwtCombo().getSelectionIndex() == -1) && (getSwtCombo().getText() != null) && (getSwtCombo().getText().length() > 0);
|
||||
}//hasCustomSelection()//
|
||||
/**
|
||||
* Gets the set of selected object identifiers.
|
||||
* @return The set of selected object identifiers, or null if nothing is selected.
|
||||
*/
|
||||
protected int getSelectedObjectId() {
|
||||
int selectionIndex = getSwtCombo().getSelectionIndex();
|
||||
|
||||
return selectionIndex != -1 ? getRowObjectAtIndex(selectionIndex).objectId : -1;
|
||||
}//getSelectedObjectId()//
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.swt.events.ModifyListener#modifyText(org.eclipse.swt.events.ModifyEvent)
|
||||
*/
|
||||
public void modifyText(ModifyEvent event) {
|
||||
if(!suspendSelectionEvents) {
|
||||
//TODO: Shouldn't this always call widgetSelected(null)?
|
||||
if(getSwtCombo().getSelectionIndex() == -1) {
|
||||
widgetSelected(null);
|
||||
}//if//
|
||||
}//if//
|
||||
}//modifyText()//
|
||||
/* (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) {
|
||||
ComboBoxCellControlData cellData = getComboBoxCellControlData();
|
||||
|
||||
if(getAutoSynchronizeSelection()) {
|
||||
if(getAutoSynchronizeSelectionDelay() > 0) {
|
||||
final int selectedObjectId = !hasCustomSelection() ? getSelectedObjectId() : -1;
|
||||
final String customSelection = hasCustomSelection() ? getSwtCombo().getText() : null;
|
||||
final int externalObjectId = cellData.getRowObject().getObjectId();
|
||||
|
||||
if(((customSelection != null) && (!customSelection.equals(cellData.getCustomSelectionOnServer()))) || (selectedObjectId != cellData.getSelectedObjectIdOnServer())) {
|
||||
//Update the known server state.//
|
||||
cellData.setSelectedObjectIdOnServer(selectedObjectId);
|
||||
cellData.setCustomSelectionOnServer(customSelection);
|
||||
|
||||
//Start a task to send the selection 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(CellComboBox.this) {
|
||||
if(autoSynchronizeSelectionTask == this) {
|
||||
//Cleanup after the task.//
|
||||
autoSynchronizeSelectionTask = null;
|
||||
getEventLoop().executeAsync(new IRunnable() {
|
||||
public Object run() {
|
||||
sendMessage(MESSAGE_VIEW_SYNCHRONIZE_SELECTION, customSelection, null, selectedObjectId, externalObjectId);
|
||||
return null;
|
||||
}//run()//
|
||||
});
|
||||
}//if//
|
||||
}//synchronized//
|
||||
}//run()//
|
||||
};
|
||||
addTask(autoSynchronizeSelectionTask, getAutoSynchronizeSelectionDelay());
|
||||
}//synchronized//
|
||||
}//if//
|
||||
}//if//
|
||||
else {
|
||||
synchronizeSelection();
|
||||
}//else//
|
||||
}//if//
|
||||
}//widgetSelected()//
|
||||
/**
|
||||
* Synchronizes the selection to the model from the view.
|
||||
* <p>This method has no logic to examine the auto synchronization state. It simply synchronizes the selection immediatly.</p>
|
||||
*/
|
||||
protected void synchronizeSelection() {
|
||||
ComboBoxCellControlData cellData = getComboBoxCellControlData();
|
||||
int externalObjectId = cellData.getRowObject().getObjectId();
|
||||
|
||||
if(hasCustomSelection()) {
|
||||
String text = getSwtCombo().getText();
|
||||
|
||||
if(!text.equals(cellData.getCustomSelectionOnServer())) {
|
||||
cellData.setSelectedObjectIdOnServer(-1);
|
||||
cellData.setCustomSelectionOnServer(text);
|
||||
|
||||
if(blockOnSelections) {
|
||||
sendRoundTripMessage(MESSAGE_VIEW_SYNCHRONIZE_SELECTION, text, null, -1, externalObjectId, null);
|
||||
}//if//
|
||||
else {
|
||||
sendMessage(MESSAGE_VIEW_SYNCHRONIZE_SELECTION, text, null, -1, externalObjectId);
|
||||
}//else//
|
||||
}//if//
|
||||
}//if//
|
||||
else {
|
||||
int selectionIndex = getSwtCombo().getSelectionIndex();
|
||||
int objectId = selectionIndex != -1 ? getRowObjectAtIndex(selectionIndex).objectId : -1;
|
||||
|
||||
if(objectId != cellData.getSelectedObjectIdOnServer()) {
|
||||
cellData.setSelectedObjectIdOnServer(objectId);
|
||||
cellData.setCustomSelectionOnServer(null);
|
||||
|
||||
if(blockOnSelections) {
|
||||
sendRoundTripMessage(MESSAGE_VIEW_SYNCHRONIZE_SELECTION, null, null, objectId, externalObjectId, null);
|
||||
}//if//
|
||||
else {
|
||||
sendMessage(MESSAGE_VIEW_SYNCHRONIZE_SELECTION, null, null, objectId, externalObjectId);
|
||||
}//else//
|
||||
}//if//
|
||||
}//else//
|
||||
}//synchronizeSelection()//
|
||||
}//ComboBoxCellControl//
|
||||
/**
|
||||
* ComboBox constructor.
|
||||
*/
|
||||
public CellComboBox() {
|
||||
}//ComboBox()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.cell.CellComponent#internalProcessMessage(com.foundation.tcv.view.ViewMessage)
|
||||
*/
|
||||
public Object internalProcessMessage(ViewMessage viewMessage) {
|
||||
Object retVal = null;
|
||||
|
||||
switch(viewMessage.getMessageNumber()) {
|
||||
case MESSAGE_INITIALIZE: {
|
||||
int[] data = (int[]) viewMessage.getMessageData();
|
||||
|
||||
setCellContainer((ICellContainer) getComponent(data[0]));
|
||||
style = data[1];
|
||||
getCellContainer().addCellComponent(this);
|
||||
break;
|
||||
}//case//
|
||||
case MESSAGE_SET_TEXT_LIMIT: {
|
||||
IIterator iterator = getCellControlIterator();
|
||||
|
||||
textLimit = ((Integer) viewMessage.getMessageData()).intValue();
|
||||
|
||||
//Update existing controls.//
|
||||
while(iterator.hasNext()) {
|
||||
((ComboBoxCellControl) iterator.next()).getSwtCombo().setTextLimit(textLimit);
|
||||
}//while//
|
||||
break;
|
||||
}//case//
|
||||
case MESSAGE_SET_ITEMS: { //A string array and an int array. The int array is the object ID's.//
|
||||
IIterator iterator = getCellControlIterator();
|
||||
String[] texts = (String[]) viewMessage.getMessageData();
|
||||
int[] objectIds = (int[]) viewMessage.getMessageSecondaryData();
|
||||
|
||||
if(texts == null) {
|
||||
getRowObjectByObjectIdMap().removeAll();
|
||||
getRowObjectByIndexMap().removeAll();
|
||||
}//if//
|
||||
else {
|
||||
//Remove all the mappings.//
|
||||
getRowObjectByObjectIdMap().removeAll();
|
||||
getRowObjectByIndexMap().removeAll();
|
||||
|
||||
//Initialize the mappings between indexes and object IDs.//
|
||||
for(int index = 0; index < objectIds.length; index++) {
|
||||
ComboRowObject rowObject = getRowObject(objectIds[index]);
|
||||
|
||||
//Create a row object or increment its reference count.//
|
||||
if(rowObject == null) {
|
||||
rowObject = (ComboRowObject) createRowObject(objectIds[index]);
|
||||
rowObject.text = texts[index];
|
||||
getRowObjectByObjectIdMap().put(rowObject.objectId, rowObject);
|
||||
}//if//
|
||||
else {
|
||||
rowObject.referenceCount++;
|
||||
}//else//
|
||||
|
||||
getRowObjectByIndexMap().add(rowObject);
|
||||
}//for//
|
||||
}//else//
|
||||
|
||||
//Update existing controls.//
|
||||
while(iterator.hasNext()) {
|
||||
((ComboBoxCellControl) iterator.next()).refreshCollection();
|
||||
}//while//
|
||||
break;
|
||||
}//case//
|
||||
case MESSAGE_ADD_ITEM: { //Sends item data and object ID and an optional index.//
|
||||
IIterator iterator = getCellControlIterator();
|
||||
String text = (String) viewMessage.getMessageData();
|
||||
int objectId = viewMessage.getMessageInteger();
|
||||
ComboRowObject rowObject = getRowObject(objectId);
|
||||
int index = viewMessage.getMessageSecondaryInteger();
|
||||
|
||||
//Create a row object or increment its reference count.//
|
||||
if(rowObject == null) {
|
||||
rowObject = (ComboRowObject) createRowObject(objectId);
|
||||
rowObject.text = text;
|
||||
getRowObjectByObjectIdMap().put(rowObject.objectId, rowObject);
|
||||
}//if//
|
||||
else {
|
||||
rowObject.referenceCount++;
|
||||
text = rowObject.text;
|
||||
}//else//
|
||||
|
||||
//If an index was provided then place the item at the requested index.//
|
||||
if(index != -1) {
|
||||
//A little error checking just in case.//
|
||||
if(index > rowObjectByIndexMap.getSize()) {
|
||||
index = rowObjectByIndexMap.getSize();
|
||||
}//if//
|
||||
|
||||
//Update the mappings.//
|
||||
rowObjectByIndexMap.add(index, rowObject);
|
||||
}//if//
|
||||
else {
|
||||
//Update the mappings.//
|
||||
rowObjectByIndexMap.add(rowObject);
|
||||
}//else//
|
||||
|
||||
//Update existing controls.//
|
||||
while(iterator.hasNext()) {
|
||||
//TODO: Do we want to refresh the whole collection, or just add the one item?
|
||||
((ComboBoxCellControl) iterator.next()).refreshCollection();
|
||||
}//while//
|
||||
break;
|
||||
}//case//
|
||||
case MESSAGE_REMOVE_ITEM: { //Note: Since removals are most often of selected items we will first try removing selected objects with the same object id.//
|
||||
IIterator iterator = getCellControlIterator();
|
||||
int objectId = viewMessage.getMessageInteger();
|
||||
RowObject rowObject = getRowObject(objectId);
|
||||
|
||||
//Remove the first instance of the row object from the list.//
|
||||
getRowObjectByIndexMap().remove(rowObject);
|
||||
rowObject.referenceCount--;
|
||||
|
||||
if(rowObject.referenceCount == 0) {
|
||||
getRowObjectByObjectIdMap().remove(objectId);
|
||||
}//if//
|
||||
|
||||
//Update existing controls.//
|
||||
while(iterator.hasNext()) {
|
||||
//TODO: Do we want to refresh the whole collection, or just remove the one item?
|
||||
((ComboBoxCellControl) iterator.next()).refreshCollection();
|
||||
}//while//
|
||||
break;
|
||||
}//case//
|
||||
case MESSAGE_REMOVE_ALL: {
|
||||
IIterator iterator = getCellControlIterator();
|
||||
|
||||
getRowObjectByObjectIdMap().removeAll();
|
||||
getRowObjectByIndexMap().removeAll();
|
||||
|
||||
//Update existing controls.//
|
||||
while(iterator.hasNext()) {
|
||||
((ComboBoxCellControl) iterator.next()).refreshCollection();
|
||||
}//while//
|
||||
break;
|
||||
}//case//
|
||||
case MESSAGE_SET_ITEM_TEXT: {
|
||||
IIterator iterator = getCellControlIterator();
|
||||
String text = (String) viewMessage.getMessageData();
|
||||
int objectId = viewMessage.getMessageInteger();
|
||||
ComboRowObject rowObject = getRowObject(objectId);
|
||||
|
||||
//Set the row object's value.//
|
||||
rowObject.text = text;
|
||||
|
||||
//Update existing controls.//
|
||||
while(iterator.hasNext()) {
|
||||
//TODO: Should we update the one item's text?
|
||||
((ComboBoxCellControl) iterator.next()).refreshCollection();
|
||||
}//while//
|
||||
break;
|
||||
}//case//
|
||||
case MESSAGE_SET_SELECTION: {
|
||||
String text = (String) viewMessage.getMessageData();
|
||||
int collectionObjectId = viewMessage.getMessageInteger();
|
||||
int externalObjectId = viewMessage.getMessageSecondaryInteger();
|
||||
ComboBoxCellControlData controlData = (ComboBoxCellControlData) getCellControlData(getCellContainer().getRowObject(externalObjectId));
|
||||
|
||||
controlData.customSelectionOnServer = text;
|
||||
controlData.selectedObjectIdOnServer = collectionObjectId;
|
||||
|
||||
if(controlData.getCellControl() != null) {
|
||||
((ComboBoxCellControl) controlData.getCellControl()).refreshSelection();
|
||||
}//if//
|
||||
break;
|
||||
}//case//
|
||||
case MESSAGE_SET_AUTO_SYNCHRONIZE_SELECTION: {
|
||||
autoSynchronizeSelection = ((Boolean) viewMessage.getMessageData()).booleanValue();
|
||||
break;
|
||||
}//case//
|
||||
case MESSAGE_SET_AUTO_SYNCHRONIZE_SELECTION_DELAY: {
|
||||
autoSynchronizeSelectionDelay = ((Long) viewMessage.getMessageData()).longValue();
|
||||
break;
|
||||
}//case//
|
||||
default: {
|
||||
retVal = super.internalProcessMessage(viewMessage);
|
||||
}//default//
|
||||
}//switch//
|
||||
|
||||
return retVal;
|
||||
}//internalProcessMessage()//
|
||||
/**
|
||||
* Creates a new row object.
|
||||
* @param objectId The identifier for the combo box collection object that is represented by the row.
|
||||
* @return An empty row object.
|
||||
*/
|
||||
protected RowObject createRowObject(int objectId) {
|
||||
return new ComboRowObject(objectId);
|
||||
}//createRowObject()//
|
||||
/**
|
||||
* Gets the row object containing the data for the object with the given identifier.
|
||||
* @param objectId Identifies the object that the row object represents.
|
||||
* @return The row object that is the avatar for the object identified by the object id.
|
||||
*/
|
||||
public ComboRowObject getRowObject(int objectId) {
|
||||
return (ComboRowObject) rowObjectByObjectIdMap.get(objectId);
|
||||
}//getRowObject()//
|
||||
/**
|
||||
* Gets the row object for the given display collection index.
|
||||
* @param index The zero based index of the row object in the display collection.
|
||||
* @return The row object for the display index.
|
||||
*/
|
||||
protected ComboRowObject getRowObjectAtIndex(int index) {
|
||||
return (ComboRowObject) rowObjectByIndexMap.get(index);
|
||||
}//getRowObjectAtIndex()//
|
||||
/**
|
||||
* Determines whether the control allows the user to type in custom items (combobox).
|
||||
* @return Whether users will be allowed to type in a custom value.
|
||||
*/
|
||||
protected boolean getAllowUserItems() {
|
||||
return allowUserItems;
|
||||
}//getAllowUserItems()//
|
||||
/**
|
||||
* Gets whether the control allows the user to type in custom items (combobox).
|
||||
* @param allowUserItems Whether users will be allowed to type in a custom value.
|
||||
*/
|
||||
protected void setAllowUserItems(boolean allowUserItems) {
|
||||
this.allowUserItems = allowUserItems;
|
||||
}//setAllowUserItems()//
|
||||
/**
|
||||
* Gets whether the control should automatically synchronize all selections.
|
||||
* @return Whether selections should automatically get sent to the server.
|
||||
*/
|
||||
protected boolean getAutoSynchronizeSelection() {
|
||||
return autoSynchronizeSelection;
|
||||
}//getAutoSynchronizeSelection()//
|
||||
/**
|
||||
* Sets whether the control should automatically synchronize all selections.
|
||||
* @param autoSynchronizeSelection Whether selections should automatically get sent to the server.
|
||||
*/
|
||||
protected void setAutoSynchronizeSelection(boolean autoSynchronizeSelection) {
|
||||
this.autoSynchronizeSelection = autoSynchronizeSelection;
|
||||
}//setAutoSynchronizeSelection()//
|
||||
/**
|
||||
* Gets the delay in milliseconds between the selection event and updating the model.
|
||||
* @return The number of milliseconds to wait before updating the model.
|
||||
*/
|
||||
protected long getAutoSynchronizeSelectionDelay() {
|
||||
return autoSynchronizeSelectionDelay;
|
||||
}//getAutoSynchronizeSelectionDelay()//
|
||||
/**
|
||||
* Sets the delay in milliseconds between the selection event and updating the model.
|
||||
* @param autoSynchronizeSelectionDelay The number of milliseconds to wait before updating the model.
|
||||
*/
|
||||
protected void setAutoSynchronizeSelectionDelay(long autoSynchronizeSelectionDelay) {
|
||||
this.autoSynchronizeSelectionDelay = autoSynchronizeSelectionDelay;
|
||||
}//setAutoSynchronizeSelectionDelay()//
|
||||
/**
|
||||
* Gets the map of row objects by their object identifiers.
|
||||
* @return The index of row objects by object identifier.
|
||||
*/
|
||||
protected IntObjectHashMap getRowObjectByObjectIdMap() {
|
||||
return rowObjectByObjectIdMap;
|
||||
}//getRowObjectByObjectIdMap()//
|
||||
/**
|
||||
* Gets the list of row objects indexed in display order.
|
||||
* @return The set of row objects in display order.
|
||||
*/
|
||||
protected LiteList getRowObjectByIndexMap() {
|
||||
return rowObjectByIndexMap;
|
||||
}//getRowObjectByObjectIdMap()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.cell.CellComponent#initializeCellControl(com.foundation.tcv.swt.client.cell.CellComponent.CellControlData)
|
||||
*/
|
||||
protected CellControl initializeCellControl(CellControlData cellControlData) {
|
||||
Combo combo = new Combo(getCellContainer().getSwtComposite(cellControlData.getRowObject()), style);
|
||||
|
||||
return new ComboBoxCellControl(combo, (ComboBoxCellControlData) cellControlData);
|
||||
}//initializeCellControl()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.cell.CellComponent#initializeCellControlData(com.foundation.tcv.swt.client.CollectionComponent.RowObject)
|
||||
*/
|
||||
protected CellControlData initializeCellControlData(RowObject rowObject) {
|
||||
return new ComboBoxCellControlData(rowObject);
|
||||
}//initializeCellControlData()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.cell.CellComponent#releaseCellControlData(com.foundation.tcv.swt.client.cell.CellComponent.CellControlData)
|
||||
*/
|
||||
protected void releaseCellControlData(CellControlData cellControlData) {
|
||||
}//releaseCellControlData()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.cell.CellComponent#supportsControl()
|
||||
*/
|
||||
public boolean supportsControl() {
|
||||
return true;
|
||||
}//supportsControl()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.cell.CellComponent#paintCell(com.foundation.tcv.swt.client.cell.CellComponent.CellControlData, org.eclipse.swt.graphics.GC)
|
||||
*/
|
||||
protected void paintCell(CellControlData cellControlData, GC graphics) {
|
||||
}//paintCell()//
|
||||
}//ComboBox//
|
||||
@@ -0,0 +1,977 @@
|
||||
/*
|
||||
* 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.tcv.swt.client.cell;
|
||||
|
||||
import org.eclipse.swt.graphics.Color;
|
||||
import org.eclipse.swt.graphics.Font;
|
||||
import org.eclipse.swt.graphics.GC;
|
||||
import org.eclipse.swt.widgets.Control;
|
||||
import org.eclipse.swt.widgets.Shell;
|
||||
|
||||
import com.common.debug.Debug;
|
||||
import com.common.util.*;
|
||||
import com.foundation.tcv.client.controller.SessionViewController;
|
||||
import com.foundation.tcv.client.view.IAbstractClientViewComponent;
|
||||
import com.foundation.tcv.client.view.ResourceHolder;
|
||||
import com.foundation.tcv.swt.cell.ICellComponent;
|
||||
import com.foundation.tcv.swt.client.AbstractComponent;
|
||||
import com.foundation.tcv.swt.client.Container;
|
||||
import com.foundation.tcv.swt.client.ICellContainer;
|
||||
import com.foundation.tcv.swt.client.RowObject;
|
||||
import com.foundation.tcv.view.ViewMessage;
|
||||
import com.foundation.view.AbstractMultiResourceHolder;
|
||||
import com.foundation.view.AbstractResourceHolder;
|
||||
import com.foundation.view.JefColor;
|
||||
import com.foundation.view.JefFont;
|
||||
import com.foundation.view.resource.AbstractResourceService;
|
||||
|
||||
/**
|
||||
* <p>Programming Note: Handling VariableAssociations whose values are placed in ResourceHolders.<br>
|
||||
* This class demonstrates how to do this with the foreground and background colors, font, and tool tip text.
|
||||
* The server send the object that is the value for either the row or for all rows.
|
||||
* All rows values are saved in the CellComponent class and the per-row values are saved in the CellControlData.
|
||||
* The CellControl's are all notified upon this change and they re-set their ResourceHolder's value to this object.
|
||||
* The CellControl's also initialize the ResourceHolder's value when the control is setup.
|
||||
* The ResourceHolder's fire change events which cause the actual control to be updated with the correct value.</p>
|
||||
*/
|
||||
public abstract class CellComponent extends AbstractComponent implements ICellComponent {
|
||||
public static final int USE_CONTROL_ALWAYS = 0;
|
||||
public static final int USE_CONTROL_NEVER = 1;
|
||||
public static final int USE_CONTROL_ON_SELECTION = 2;
|
||||
|
||||
/** The container containing this component. */
|
||||
private ICellContainer cellContainer = null;
|
||||
/** The set of CellControlData instances, one for each RowObject. */
|
||||
private IHashMap cellControlDataByRowObject = new LiteHashMap(500);
|
||||
/** The set of all cell controls. Not all cells may have a controls as only those cells that are visible must have one. */
|
||||
private IHashSet cellControls = new LiteHashSet(50);
|
||||
/** The optional decimal scale to be used by the component if it deals with decimal values. */
|
||||
private Integer decimalScale = null;
|
||||
/** The resource holder for the foreground color. */
|
||||
private ResourceHolder foregroundColorHolder = null;
|
||||
/** The resource holder for the background color. */
|
||||
private ResourceHolder backgroundColorHolder = null;
|
||||
/** The resource holder for the font. */
|
||||
private ResourceHolder fontHolder = null;
|
||||
/** The resource holder for the tool tipe text. */
|
||||
private ResourceHolder toolTipTextHolder = null;
|
||||
/** The currently active background color. This is used to ensure that the correct color is destroyed when cleaning up. */
|
||||
private Color currentBackgroundColor = null;
|
||||
/** The currently active foreground color. This is used to ensure that the correct color is destroyed when cleaning up. */
|
||||
private Color currentForegroundColor = null;
|
||||
/** The currently active font. This is used to ensure that the correct font is destroyed when cleaning up. */
|
||||
private Font currentFont = null;
|
||||
/** The optonal layout data used by the cell component if it resides in a cell panel. */
|
||||
private Object layoutData = null;
|
||||
|
||||
/**
|
||||
* Maintains the cell data for the control. A control may only exist if it is visible, but the data must be maintained regardless.
|
||||
*/
|
||||
public abstract class CellControlData {
|
||||
/** The reference to the cell control that is currently displaying the data. This may be null if the cell is not currently displayed. This will also be null if the cell doesn't use a component to render, but instead performs its own rendering. */
|
||||
private CellControl cellControl = null;
|
||||
/** The row object for the row the cell exists in. */
|
||||
private RowObject rowObject = null;
|
||||
/** The control's enabled state. */
|
||||
private Boolean isEnabled = Boolean.TRUE;
|
||||
/** The control's foreground color prior to being placed in the holder. */
|
||||
private Object foregroundColor = null;
|
||||
/** The control's background color prior to being placed in the holder. */
|
||||
private Object backgroundColor = null;
|
||||
/** The control's font prior to being placed in the holder. */
|
||||
private Object font = null;
|
||||
/** The control's tool tip prior to being placed in the holder. */
|
||||
private Object toolTipText = null;
|
||||
|
||||
/**
|
||||
* CellControlData constructor.
|
||||
* @param rowObject The row for the cell.
|
||||
*/
|
||||
public CellControlData(RowObject rowObject) {
|
||||
this.rowObject = rowObject;
|
||||
}//CellControlData()//
|
||||
/**
|
||||
* Gets the cell control associated with the data.
|
||||
* @return The cell control if one exists.
|
||||
*/
|
||||
public CellControl getCellControl() {
|
||||
return cellControl;
|
||||
}//getCellControl()//
|
||||
/**
|
||||
* Gets the object representing the row the cell exists in.
|
||||
* @return The row for the cell.
|
||||
*/
|
||||
public RowObject getRowObject() {
|
||||
return rowObject;
|
||||
}//getRowObject()//
|
||||
}//CellControlData//
|
||||
|
||||
/**
|
||||
* Encapsulates a control with related data such as listeners and the data model for the cell.
|
||||
*/
|
||||
public abstract class CellControl implements IAbstractClientViewComponent {
|
||||
/** The control that handles the display of the cell. */
|
||||
private Control control = null;
|
||||
/** The currently active background color. This is used to ensure that the correct color is destroyed when cleaning up. */
|
||||
private Color currentBackgroundColor = null;
|
||||
/** The currently active foreground color. This is used to ensure that the correct color is destroyed when cleaning up. */
|
||||
private Color currentForegroundColor = null;
|
||||
/** The currently active font. This is used to ensure that the correct font is destroyed when cleaning up. */
|
||||
private Font currentFont = null;
|
||||
/** The resource holder for the foreground color. */
|
||||
private ResourceHolder foregroundColorHolder = null;
|
||||
/** The resource holder for the background color. */
|
||||
private ResourceHolder backgroundColorHolder = null;
|
||||
/** The resource holder for the font. */
|
||||
private ResourceHolder fontHolder = null;
|
||||
/** The resource holder for the tool tipe text. */
|
||||
private ResourceHolder toolTipTextHolder = null;
|
||||
/** The cell data for the control. */
|
||||
private CellControlData cellData = null;
|
||||
|
||||
/**
|
||||
* CellControl constructor.
|
||||
* @param control The control being encapsulated.
|
||||
* @param cellData The cell's data.
|
||||
*/
|
||||
public CellControl(Control control, CellControlData cellData) {
|
||||
this.control = control;
|
||||
this.cellData = cellData;
|
||||
control.setData(this);
|
||||
|
||||
if(cellData.backgroundColor != null) {
|
||||
backgroundColorHolder = new ResourceHolder(this);
|
||||
backgroundColorHolder.setValue(cellData.backgroundColor);
|
||||
}//if//
|
||||
|
||||
if(cellData.foregroundColor != null) {
|
||||
foregroundColorHolder = new ResourceHolder(this);
|
||||
foregroundColorHolder.setValue(cellData.foregroundColor);
|
||||
}//if//
|
||||
|
||||
if(cellData.font != null) {
|
||||
fontHolder = new ResourceHolder(this);
|
||||
fontHolder.setValue(cellData.font);
|
||||
}//if//
|
||||
}//CellControl()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.view.IResourceHolderComponent#getResourceService()
|
||||
*/
|
||||
public AbstractResourceService getResourceService() {
|
||||
return CellComponent.this.getResourceService();
|
||||
}//getResourceService()//
|
||||
/**
|
||||
* Gets the cell component that the control was created by.
|
||||
* @return The control's component.
|
||||
*/
|
||||
public CellComponent getCellComponent() {
|
||||
return CellComponent.this;
|
||||
}//getCellComponent()//
|
||||
/**
|
||||
* Gets the data for the control in the cell.
|
||||
* @return The cell data for the control.
|
||||
*/
|
||||
public CellControlData getCellControlData() {
|
||||
return cellData;
|
||||
}//getCellControlData()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.client.view.IAbstractClientViewComponent#getSessionViewController()
|
||||
*/
|
||||
public SessionViewController getSessionViewController() {
|
||||
return CellComponent.this.getSessionViewController();
|
||||
}//getSessionViewController()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.client.view.IAbstractClientViewComponent#initialize(int, com.foundation.tcv.client.controller.SessionViewController)
|
||||
*/
|
||||
public final void initialize(int number, SessionViewController sessionViewController) {
|
||||
//Never called.//
|
||||
}//initialize()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.view.IAbstractRemoteViewComponent#processMessage(com.foundation.tcv.view.ViewMessage)
|
||||
*/
|
||||
public Object processMessage(ViewMessage viewMessage) {
|
||||
//Never called.//
|
||||
return null;
|
||||
}//processMessage()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.view.IAbstractRemoteViewComponent#processRequest(int, java.lang.Object, java.lang.Object, java.lang.Object, java.lang.Object)
|
||||
*/
|
||||
public Object processRequest(int eventNumber, Object value1, Object value2, Object value3, Object value4) {
|
||||
//Never called.//
|
||||
return null;
|
||||
}//processRequest()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.view.IResourceHolderComponent#resourceHolderChanged(com.foundation.view.AbstractResourceHolder, java.lang.Object, java.lang.Object)
|
||||
*/
|
||||
public void resourceHolderChanged(AbstractResourceHolder resourceHolder, Object oldValue, Object newValue, int flags) {
|
||||
if(resourceHolder == foregroundColorHolder) {
|
||||
destroyColor(getCurrentForegroundColor());
|
||||
setCurrentForegroundColor(createColor((JefColor) resourceHolder.getValue()));
|
||||
controlUpdateForegroundColor();
|
||||
}//if//
|
||||
else if(resourceHolder == backgroundColorHolder) {
|
||||
destroyColor(getCurrentBackgroundColor());
|
||||
setCurrentBackgroundColor(createColor((JefColor) resourceHolder.getValue()));
|
||||
controlUpdateBackgroundColor();
|
||||
}//else if//
|
||||
else if(resourceHolder == fontHolder) {
|
||||
destroyFont(getCurrentFont());
|
||||
setCurrentFont(createFont((JefFont[]) resourceHolder.getValue()));
|
||||
controlUpdateFont();
|
||||
}//else if//
|
||||
else if(resourceHolder == toolTipTextHolder) {
|
||||
controlSetToolTipText((String) resourceHolder.getValue());
|
||||
}//else if//
|
||||
}//resourceHolderChanged()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.view.IResourceHolderComponent#resourceHolderChanged(com.foundation.view.AbstractMultiResourceHolder, com.common.util.IHashSet, java.lang.Object, java.lang.Object)
|
||||
*/
|
||||
public void resourceHolderChanged(AbstractMultiResourceHolder resourceHolder, IHashSet rows, Object oldValue, Object newValue) {
|
||||
}//resourceHolderChanged()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.view.IResourceHolderComponent#resourceHolderChanged(com.foundation.view.AbstractMultiResourceHolder, java.lang.Object, java.lang.Object, java.lang.Object)
|
||||
*/
|
||||
public void resourceHolderChanged(AbstractMultiResourceHolder resourceHolder, Object row, Object oldValue, Object newValue) {
|
||||
}//resourceHolderChanged()//
|
||||
/**
|
||||
* Gets the SWT control for this cell control.
|
||||
* @return The control being encapsulated.
|
||||
*/
|
||||
public Control getSwtControl() {
|
||||
return control;
|
||||
}//getSwtControl()//
|
||||
/**
|
||||
* Initializes the control.
|
||||
*/
|
||||
public void initialize() {
|
||||
getSwtControl().setLayoutData(layoutData);
|
||||
}//initialize()//
|
||||
/**
|
||||
* Refreshes the control.
|
||||
*/
|
||||
public void refresh() {
|
||||
controlUpdateBackgroundColor();
|
||||
controlUpdateFont();
|
||||
controlUpdateForegroundColor();
|
||||
refreshIsEnabled();
|
||||
refreshToolTipText();
|
||||
}//refresh()//
|
||||
/**
|
||||
* Updates the background color being used by the component.
|
||||
*/
|
||||
public void controlUpdateBackgroundColor() {
|
||||
Color newColor = null;
|
||||
|
||||
if(getCurrentFont() != null) {
|
||||
newColor = getCurrentBackgroundColor();
|
||||
}//if//
|
||||
else if(CellComponent.this.getCurrentFont() != null) {
|
||||
newColor = CellComponent.this.getCurrentBackgroundColor();
|
||||
}//else if//
|
||||
|
||||
if(getSwtControl().getBackground() != newColor) {
|
||||
getSwtControl().setBackground(newColor);
|
||||
}//if//
|
||||
}//controlUpdateBackgroundColor()//
|
||||
/**
|
||||
* Updates the foreground color being used by the component.
|
||||
*/
|
||||
public void controlUpdateForegroundColor() {
|
||||
Color newColor = null;
|
||||
|
||||
if(getCurrentFont() != null) {
|
||||
newColor = getCurrentForegroundColor();
|
||||
}//if//
|
||||
else if(CellComponent.this.getCurrentFont() != null) {
|
||||
newColor = CellComponent.this.getCurrentForegroundColor();
|
||||
}//else if//
|
||||
|
||||
if(getSwtControl().getForeground() != newColor) {
|
||||
getSwtControl().setForeground(newColor);
|
||||
}//if//
|
||||
}//controlUpdateForegroundColor()//
|
||||
/**
|
||||
* Updates the font being used by the component.
|
||||
*/
|
||||
public void controlUpdateFont() {
|
||||
Font newFont = null;
|
||||
|
||||
if(getCurrentFont() != null) {
|
||||
newFont = getCurrentFont();
|
||||
}//if//
|
||||
else if(CellComponent.this.getCurrentFont() != null) {
|
||||
newFont = CellComponent.this.getCurrentFont();
|
||||
}//else if//
|
||||
|
||||
if(getSwtControl().getFont() != newFont) {
|
||||
getSwtControl().setFont(newFont);
|
||||
}//if//
|
||||
}//controlUpdateFont()//
|
||||
/**
|
||||
* Refreshes the tool tip value.
|
||||
*/
|
||||
public void refreshToolTipText() {
|
||||
//Check for a common value which will only be set if the value is a single association.//
|
||||
if(CellComponent.this.toolTipTextHolder != null) {
|
||||
getSwtControl().setToolTipText((String) CellComponent.this.toolTipTextHolder.getValue());
|
||||
}//if//
|
||||
else { //Use a value per row.//
|
||||
if(toolTipTextHolder == null) {
|
||||
toolTipTextHolder = new ResourceHolder(this);
|
||||
}//if//
|
||||
|
||||
toolTipTextHolder.setValue(getCellControlData().toolTipText);
|
||||
}//else//
|
||||
}//refreshToolTipText()//
|
||||
/**
|
||||
* Refreshes the control's enabled state.
|
||||
*/
|
||||
public void refreshIsEnabled() {
|
||||
controlSetIsEnabled(getCellControlData().isEnabled == null ? true : getCellControlData().isEnabled.booleanValue());
|
||||
}//refreshIsEnabled()//
|
||||
/**
|
||||
* Releases the control.
|
||||
*/
|
||||
public void release() {
|
||||
if(toolTipTextHolder != null) {
|
||||
toolTipTextHolder.release();
|
||||
}//if//
|
||||
|
||||
if(backgroundColorHolder != null) {
|
||||
backgroundColorHolder.release();
|
||||
}//if//
|
||||
|
||||
if(foregroundColorHolder != null) {
|
||||
foregroundColorHolder.release();
|
||||
}//if//
|
||||
|
||||
if(fontHolder != null) {
|
||||
fontHolder.release();
|
||||
}//if//
|
||||
|
||||
if(getCurrentBackgroundColor() != null) {
|
||||
destroyColor(getCurrentBackgroundColor());
|
||||
}//if//
|
||||
|
||||
if(getCurrentForegroundColor() != null) {
|
||||
destroyColor(getCurrentForegroundColor());
|
||||
}//if//
|
||||
|
||||
if(getCurrentFont() != null) {
|
||||
destroyFont(getCurrentFont());
|
||||
}//if//
|
||||
|
||||
if((control != null) && (!control.isDisposed())) {
|
||||
control.dispose();
|
||||
}//if//
|
||||
}//release()//
|
||||
/**
|
||||
* Forces any pending synchronizations to complete.
|
||||
*/
|
||||
public abstract void synchronize();
|
||||
/**
|
||||
* Gets the current foreground color used by the component.
|
||||
* @return The currently used foreground color, or null if none is provided.
|
||||
*/
|
||||
protected Color getCurrentForegroundColor() {
|
||||
return currentForegroundColor;
|
||||
}//getCurrentForegroundColor()//
|
||||
/**
|
||||
* Sets the current foreground color used by the component.
|
||||
* @param currentForegroundColor The currently used foreground color, or null if none is provided.
|
||||
*/
|
||||
protected void setCurrentForegroundColor(Color currentForegroundColor) {
|
||||
this.currentForegroundColor = currentForegroundColor;
|
||||
}//setCurrentForegroundColor()//
|
||||
/**
|
||||
* Gets the current background color used by the component.
|
||||
* @return The currently used background color, or null if none is provided.
|
||||
*/
|
||||
protected Color getCurrentBackgroundColor() {
|
||||
return currentBackgroundColor;
|
||||
}//getCurrentBackgroundColor()//
|
||||
/**
|
||||
* Sets the current background color used by the component.
|
||||
* @param currentBackgroundColor The currently used background color, or null if none is provided.
|
||||
*/
|
||||
protected void setCurrentBackgroundColor(Color currentBackgroundColor) {
|
||||
this.currentBackgroundColor = currentBackgroundColor;
|
||||
}//setCurrentBackgroundColor()//
|
||||
/**
|
||||
* Gets the current font used by the component.
|
||||
* @return The currently used font, or null if none is provided.
|
||||
*/
|
||||
protected Font getCurrentFont() {
|
||||
return currentFont;
|
||||
}//getCurrentFont()//
|
||||
/**
|
||||
* Sets the current font used by the component.
|
||||
* @param currentFont The currently used font, or null if none is provided.
|
||||
*/
|
||||
protected void setCurrentFont(Font currentFont) {
|
||||
this.currentFont = currentFont;
|
||||
}//setCurrentFont()//
|
||||
/**
|
||||
* Sets the component's enabled state.
|
||||
* @param isEnabled Whether the enabled state should be altered to be enabled, otherwise it is altered to be disabled.
|
||||
*/
|
||||
protected void controlSetIsEnabled(boolean isEnabled) {
|
||||
getSwtControl().setEnabled(isEnabled);
|
||||
}//controlSetEnabledState()//
|
||||
/**
|
||||
* Sets the tool tip.
|
||||
* @param toolTipText The text to display in the default tool tip.
|
||||
*/
|
||||
protected void controlSetToolTipText(String toolTipText) {
|
||||
getSwtControl().setToolTipText(toolTipText);
|
||||
}//controlSetToolTipText()//
|
||||
}//CellControl//
|
||||
/**
|
||||
* CellComponent constructor.
|
||||
*/
|
||||
public CellComponent() {
|
||||
}//CellComponent()//
|
||||
/**
|
||||
* Whether the component will utilize a paint routine to draw the information.
|
||||
* @return Whether a draw capability will be used by this cell component (which may be different from whether the cell component supports a draw routine).
|
||||
*/
|
||||
public boolean usePaint() {
|
||||
return !supportsControl() && supportsPaint();
|
||||
}//usePaint()//
|
||||
/**
|
||||
* Whether the component will utilize a control to draw the information.
|
||||
* @return One of the identifiers indicating whether a control will be used by this cell component (which may be different from whether the cell component supports a creation of a control).
|
||||
*/
|
||||
public int useControl() {
|
||||
return supportsControl() ? USE_CONTROL_ALWAYS : USE_CONTROL_NEVER;
|
||||
}//useControl()//
|
||||
/**
|
||||
* Determines whether the component creates interactive controls and has implemented the initializeCellControl(CellControlData) method.
|
||||
* @return Whether this component builds cell controls.
|
||||
* @see #initializeCellControl(CellControlData)
|
||||
*/
|
||||
public boolean supportsControl() {
|
||||
return false;
|
||||
}//supportsControl()//
|
||||
/**
|
||||
* Determines whether the component is capable of painting a cell in place of a control.
|
||||
* @return Whether this component paints a cell.
|
||||
* @see #paintCell(CellControlData, GC)
|
||||
*/
|
||||
public boolean supportsPaint() {
|
||||
return false;
|
||||
}//supportsPaint()//
|
||||
/**
|
||||
* Gets whether the controls should grab any available horizontal space.
|
||||
* @return Whether the control will use all available horizontal space.
|
||||
*/
|
||||
public boolean grabHorizontalSpace() {
|
||||
return true;
|
||||
}//grabHorizontalSpace()//
|
||||
/**
|
||||
* Gets whether the controls should grab any available vertical space.
|
||||
* @return Whether the control will use all available vertical space.
|
||||
*/
|
||||
public boolean grabVerticalSpace() {
|
||||
return true;
|
||||
}//grabVerticalSpace()//
|
||||
/**
|
||||
* Gets the horizontal alignment for the controls.
|
||||
* @return The control's horizontal alignment.
|
||||
*/
|
||||
public int getHorizontalAlignment() {
|
||||
return HORIZONTAL_ALIGN_LEFT;
|
||||
}//getHorizontalAlignment()//
|
||||
/**
|
||||
* Gets the vertical alignment for the controls.
|
||||
* @return The control's vertical alignment.
|
||||
*/
|
||||
public int getVerticalAlignment() {
|
||||
return VERTICAL_ALIGN_CENTER;
|
||||
}//getVerticalAlignment()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.AbstractComponent#getContainer()
|
||||
*/
|
||||
public Container getContainer() {
|
||||
return cellContainer != null ? cellContainer.getContainer() : null;
|
||||
}//getContainer()//
|
||||
/**
|
||||
* Gets the parent cell container for this component.
|
||||
* @return The view component containing this cell component.
|
||||
*/
|
||||
public ICellContainer getCellContainer() {
|
||||
return cellContainer;
|
||||
}//getCellContainer()//
|
||||
/**
|
||||
* Sets the parent cell container for this component.
|
||||
* @param cellContainer The view component containing this cell component.
|
||||
*/
|
||||
protected void setCellContainer(ICellContainer cellContainer) {
|
||||
this.cellContainer = cellContainer;
|
||||
}//setCellContainer()//
|
||||
/**
|
||||
* Gets the optional decimal scale to be used by the component if it deals with decimal values.
|
||||
* <p>Note: Controls can override this to handle a change in the scale.</p>
|
||||
* @return The optional decimal scale which if negative by default should trim extra zeros (note that BigDecimal does not automatically do this).
|
||||
*/
|
||||
public Integer getDecimalScale() {
|
||||
return decimalScale;
|
||||
}//getDecimalScale()//
|
||||
/**
|
||||
* Sets the optional decimal scale to be used by the component if it deals with decimal values.
|
||||
* @param decimalScale The optional decimal scale which if negative by default should trim extra zeros (note that BigDecimal does not automatically do this).
|
||||
*/
|
||||
public void setDecimalScale(Integer decimalScale) {
|
||||
this.decimalScale = decimalScale;
|
||||
}//setDecimalScale()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.AbstractComponent#getShell()
|
||||
*/
|
||||
public Shell getShell() {
|
||||
return getContainer() != null ? getContainer().getShell() : null;
|
||||
}//getShell()//
|
||||
/**
|
||||
* Creates all controls associated with this component.
|
||||
* @param rowObject The model object representative for the row/cell.
|
||||
* @return The control (or tree of controls) that allows interaction with the cell data.
|
||||
*/
|
||||
public final Control createCellControl(RowObject rowObject) {
|
||||
CellControlData cellControlData = getCellControlData(rowObject);
|
||||
CellControl cellControl = internalCreateCellControl(cellControlData);
|
||||
|
||||
cellControl.initialize();
|
||||
cellControl.refresh();
|
||||
|
||||
return cellControl.getSwtControl();
|
||||
}//createCellControl()//
|
||||
/**
|
||||
* Creates a control associated with this component.
|
||||
* @param cellControlData The model object representative for the row/cell.
|
||||
* @return The cell control that was created.
|
||||
*/
|
||||
protected CellControl internalCreateCellControl(CellControlData cellControlData) {
|
||||
CellControl cellControl = initializeCellControl(cellControlData);
|
||||
|
||||
cellControlData.cellControl = cellControl;
|
||||
cellControls.add(cellControl);
|
||||
|
||||
return cellControl;
|
||||
}//internalCreateCellControl()//
|
||||
/**
|
||||
* Destroys a control associated with this component.
|
||||
* @param control The control no longer required.
|
||||
*/
|
||||
public final void destroyControl(Control control) {
|
||||
CellControl cellControl = (CellControl) control.getData();
|
||||
|
||||
//Force any pending synchronizations to complete.//
|
||||
cellControl.synchronize();
|
||||
//Release the resources.//
|
||||
cellControl.release();
|
||||
//Remove the mapping.//
|
||||
cellControl.getCellControlData().cellControl = null;
|
||||
cellControls.remove(cellControl);
|
||||
}//destroyControl()//
|
||||
/**
|
||||
* Initializes a new CellControl instance complete with a view control which has a back reference to the CellControl.
|
||||
* @param cellControlData The cell data for the control.
|
||||
* @return The control container for the cell.
|
||||
*/
|
||||
protected abstract CellControl initializeCellControl(CellControlData cellControlData);
|
||||
/**
|
||||
* Initializes a new cell control data for the row.
|
||||
* @param rowObject The row data for which a cell control data object will be created.
|
||||
* @return The data container for the cell in the given row.
|
||||
*/
|
||||
protected abstract CellControlData initializeCellControlData(RowObject rowObject);
|
||||
/**
|
||||
* Releases the data for a cell in a row that no longer exists.
|
||||
* @param cellControlData The cell data to be released.
|
||||
*/
|
||||
protected abstract void releaseCellControlData(CellControlData cellControlData);
|
||||
/**
|
||||
* Requests the component paint a cell.
|
||||
* <p>Warning: The graphics context may be reused. All changes must be reset prior to method exit.
|
||||
* @param cellControlData The cell data to be drawn.
|
||||
* @param graphics The graphics context used to affect the cell pixels.
|
||||
*/
|
||||
protected abstract void paintCell(CellControlData cellControlData, GC graphics);
|
||||
/**
|
||||
* Requests the component paint a cell.
|
||||
* @param rowObject The row object supplying the data to be drawn.
|
||||
* @param graphics The graphics context.
|
||||
*/
|
||||
public final void paintCell(RowObject rowObject, GC graphics) {
|
||||
paintCell(getCellControlData(rowObject), graphics);
|
||||
}//paintCell()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.AbstractComponent#internalViewInitialize()
|
||||
*/
|
||||
protected void internalViewInitialize() {
|
||||
super.internalViewInitialize();
|
||||
}//internalViewInitialize()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.AbstractComponent#internalViewInitializeAll()
|
||||
*/
|
||||
protected void internalViewInitializeAll() {
|
||||
super.internalViewInitializeAll();
|
||||
}//internalViewInitializeAll()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.AbstractComponent#internalViewRelease()
|
||||
*/
|
||||
protected void internalViewRelease() {
|
||||
IIterator iterator = getCellControlIterator();
|
||||
|
||||
//Release all controls.//
|
||||
while(iterator.hasNext()) {
|
||||
((CellControl) iterator.next()).release();
|
||||
}//while//
|
||||
|
||||
if(toolTipTextHolder != null) {
|
||||
toolTipTextHolder.release();
|
||||
}//if//
|
||||
|
||||
if(backgroundColorHolder != null) {
|
||||
backgroundColorHolder.release();
|
||||
}//if//
|
||||
|
||||
if(foregroundColorHolder != null) {
|
||||
foregroundColorHolder.release();
|
||||
}//if//
|
||||
|
||||
if(fontHolder != null) {
|
||||
fontHolder.release();
|
||||
}//if//
|
||||
|
||||
if(getCurrentBackgroundColor() != null) {
|
||||
destroyColor(getCurrentBackgroundColor());
|
||||
}//if//
|
||||
|
||||
if(getCurrentForegroundColor() != null) {
|
||||
destroyColor(getCurrentForegroundColor());
|
||||
}//if//
|
||||
|
||||
if(getCurrentFont() != null) {
|
||||
destroyFont(getCurrentFont());
|
||||
}//if//
|
||||
|
||||
super.internalViewRelease();
|
||||
}//internalViewRelease()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.AbstractComponent#internalViewReleaseAll()
|
||||
*/
|
||||
protected void internalViewReleaseAll() {
|
||||
super.internalViewReleaseAll();
|
||||
}//internalViewReleaseAll()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.AbstractComponent#internalViewSynchronize()
|
||||
*/
|
||||
protected final void internalViewSynchronize() {
|
||||
//Never called.//
|
||||
super.internalViewSynchronize();
|
||||
}//internalViewSynchronize()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.AbstractComponent#internalViewSynchronizeAll()
|
||||
*/
|
||||
protected void internalViewSynchronizeAll() {
|
||||
//Never called.//
|
||||
super.internalViewSynchronizeAll();
|
||||
}//internalViewSynchronizeAll()//
|
||||
/**
|
||||
* Registers a row object with the cell component which must create the necessary data structures for the cell data.
|
||||
* @param rowObject The row being registered.
|
||||
*/
|
||||
public void register(RowObject rowObject) {
|
||||
cellControlDataByRowObject.put(rowObject, initializeCellControlData(rowObject));
|
||||
}//register()//
|
||||
/**
|
||||
* Unregisters a row object with the cell component which must release cell resources.
|
||||
* @param rowObject The row being unregistered.
|
||||
*/
|
||||
public void unregister(RowObject rowObject) {
|
||||
CellControlData data = (CellControlData) cellControlDataByRowObject.remove(rowObject);
|
||||
|
||||
releaseCellControlData(data);
|
||||
}//unregister()//
|
||||
/**
|
||||
* Gets the cell data for the given row object.
|
||||
* @param rowObject The row's model object associated with the requested control data.
|
||||
* @return The cell data for the given row object.
|
||||
*/
|
||||
public final CellControlData getCellControlData(RowObject rowObject) {
|
||||
return (CellControlData) cellControlDataByRowObject.get(rowObject);
|
||||
}//getCellControlData()//
|
||||
/**
|
||||
* Gets an iterator over the CellControl instances, one for each control setup for a cell.
|
||||
* @return The iterator over the controls for the cells.
|
||||
*/
|
||||
public final IIterator getCellControlIterator() {
|
||||
return cellControls.iterator();
|
||||
}//getCellControlIterator()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.AbstractComponent#internalProcessMessage(com.foundation.tcv.view.ViewMessage)
|
||||
*/
|
||||
public Object internalProcessMessage(ViewMessage viewMessage) {
|
||||
Object result = null;
|
||||
|
||||
switch(viewMessage.getMessageNumber()) {
|
||||
case MESSAGE_SET_IS_ENABLED: {
|
||||
CellControlData cellControlData = getCellControlData(getCellContainer().getRowObject(viewMessage.getMessageInteger()));
|
||||
Boolean value = (Boolean) viewMessage.getMessageData();
|
||||
|
||||
if(cellControlData == null) {
|
||||
Debug.log("Bad cell control data.");
|
||||
}//if//
|
||||
|
||||
cellControlData.isEnabled = value;
|
||||
|
||||
if(cellControlData.getCellControl() != null) {
|
||||
cellControlData.getCellControl().refreshIsEnabled();
|
||||
}//if//
|
||||
break;
|
||||
}//case//
|
||||
case MESSAGE_SET_BACKGROUND_COLOR: {
|
||||
setBackgroundColor(viewMessage.getMessageData(), viewMessage.getMessageInteger() != -1 ? getCellControlData(getCellContainer().getRowObject(viewMessage.getMessageInteger())) : null);
|
||||
break;
|
||||
}//case//
|
||||
case MESSAGE_SET_FOREGROUND_COLOR: {
|
||||
setForegroundColor(viewMessage.getMessageData(), viewMessage.getMessageInteger() != -1 ? getCellControlData(getCellContainer().getRowObject(viewMessage.getMessageInteger())) : null);
|
||||
break;
|
||||
}//case//
|
||||
case MESSAGE_SET_FONTS: {
|
||||
setFont(viewMessage.getMessageData(), viewMessage.getMessageInteger() != -1 ? getCellControlData(getCellContainer().getRowObject(viewMessage.getMessageInteger())) : null);
|
||||
break;
|
||||
}//case//
|
||||
case MESSAGE_SET_TOOL_TIP_TEXT: {
|
||||
setToolTipText(viewMessage.getMessageData(), viewMessage.getMessageInteger() != -1 ? getCellControlData(getCellContainer().getRowObject(viewMessage.getMessageInteger())) : null);
|
||||
break;
|
||||
}//case//
|
||||
case MESSAGE_SET_DECIMAL_SCALE: {
|
||||
setDecimalScale((Integer) viewMessage.getMessageData());
|
||||
break;
|
||||
}//case//
|
||||
case MESSAGE_SET_LAYOUT_DATA: {
|
||||
setLayoutData(viewMessage.getMessageData());
|
||||
break;
|
||||
}//case//
|
||||
default: {
|
||||
result = super.internalProcessMessage(viewMessage);
|
||||
}//default//
|
||||
}//switch//
|
||||
|
||||
return result;
|
||||
}//internalProcessMessage()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.AbstractComponent#internalResourceHolderChanged(com.foundation.tcv.client.view.ResourceHolder, java.lang.Object, java.lang.Object, int)
|
||||
*/
|
||||
protected void internalResourceHolderChanged(ResourceHolder resourceHolder, Object oldValue, Object newValue, int flags) {
|
||||
if(resourceHolder == backgroundColorHolder) {
|
||||
IIterator iterator = getCellControlIterator();
|
||||
|
||||
destroyColor(getCurrentBackgroundColor());
|
||||
setCurrentBackgroundColor(createColor((JefColor) newValue));
|
||||
|
||||
//Update the existing controls.//
|
||||
while(iterator.hasNext()) {
|
||||
CellControl cellControl = (CellControl) iterator.next();
|
||||
|
||||
cellControl.controlUpdateBackgroundColor();
|
||||
}//while//
|
||||
}//if//
|
||||
else if(resourceHolder == foregroundColorHolder) {
|
||||
IIterator iterator = getCellControlIterator();
|
||||
|
||||
destroyColor(getCurrentForegroundColor());
|
||||
setCurrentForegroundColor(createColor((JefColor) newValue));
|
||||
|
||||
//Update the existing controls.//
|
||||
while(iterator.hasNext()) {
|
||||
CellControl cellControl = (CellControl) iterator.next();
|
||||
|
||||
cellControl.controlUpdateForegroundColor();
|
||||
}//while//
|
||||
}//else if//
|
||||
else if(resourceHolder == fontHolder) {
|
||||
IIterator iterator = getCellControlIterator();
|
||||
|
||||
destroyFont(getCurrentFont());
|
||||
setCurrentFont(createFont((JefFont[]) newValue));
|
||||
|
||||
//Update the existing controls.//
|
||||
while(iterator.hasNext()) {
|
||||
CellControl cellControl = (CellControl) iterator.next();
|
||||
|
||||
cellControl.controlUpdateFont();
|
||||
}//while//
|
||||
}//else if//
|
||||
else if(resourceHolder == toolTipTextHolder) {
|
||||
IIterator iterator = getCellControlIterator();
|
||||
|
||||
//Update the existing controls.//
|
||||
while(iterator.hasNext()) {
|
||||
CellControl cellControl = (CellControl) iterator.next();
|
||||
|
||||
cellControl.refreshToolTipText();
|
||||
}//while//
|
||||
}//else if//
|
||||
else {
|
||||
super.internalResourceHolderChanged(resourceHolder, oldValue, newValue, flags);
|
||||
}//else//
|
||||
}//internalResourceHolderChanged()//
|
||||
/**
|
||||
* Sets the background color for the cell control(s).
|
||||
* @param value The new value.
|
||||
* @param cellControlData The cell control data if changing a specific cell, otherwise null.
|
||||
*/
|
||||
protected void setBackgroundColor(Object value, CellControlData cellControlData) {
|
||||
if(cellControlData == null) {
|
||||
if(backgroundColorHolder == null) {
|
||||
backgroundColorHolder = new ResourceHolder(this);
|
||||
}//if//
|
||||
|
||||
backgroundColorHolder.setValue(value);
|
||||
}//if//
|
||||
else {
|
||||
cellControlData.backgroundColor = value;
|
||||
|
||||
if(cellControlData.getCellControl() != null) {
|
||||
CellControl cellControl = cellControlData.getCellControl();
|
||||
|
||||
if(cellControl.backgroundColorHolder == null) {
|
||||
cellControl.backgroundColorHolder = new ResourceHolder(cellControl);
|
||||
}//if//
|
||||
|
||||
cellControl.backgroundColorHolder.setValue(value);
|
||||
}//if//
|
||||
}//else//
|
||||
}//setBackgroundColor()//
|
||||
/**
|
||||
* Sets the foreground color for the cell control(s).
|
||||
* @param value The new value.
|
||||
* @param cellControlData The cell control data if changing a specific cell, otherwise null.
|
||||
*/
|
||||
protected void setForegroundColor(Object value, CellControlData cellControlData) {
|
||||
if(cellControlData == null) {
|
||||
if(foregroundColorHolder == null) {
|
||||
foregroundColorHolder = new ResourceHolder(this);
|
||||
}//if//
|
||||
|
||||
foregroundColorHolder.setValue(value);
|
||||
}//if//
|
||||
else {
|
||||
cellControlData.foregroundColor = value;
|
||||
|
||||
if(cellControlData.getCellControl() != null) {
|
||||
CellControl cellControl = cellControlData.getCellControl();
|
||||
|
||||
if(cellControl.foregroundColorHolder == null) {
|
||||
cellControl.foregroundColorHolder = new ResourceHolder(cellControl);
|
||||
}//if//
|
||||
|
||||
cellControl.foregroundColorHolder.setValue(value);
|
||||
}//if//
|
||||
}//else//
|
||||
}//setForegroundColor()//
|
||||
/**
|
||||
* Sets the font for the cell control(s).
|
||||
* @param value The new value.
|
||||
* @param cellControlData The cell control data if changing a specific cell, otherwise null.
|
||||
*/
|
||||
protected void setFont(Object value, CellControlData cellControlData) {
|
||||
if(cellControlData == null) {
|
||||
if(fontHolder == null) {
|
||||
fontHolder = new ResourceHolder(this);
|
||||
}//if//
|
||||
|
||||
fontHolder.setValue(value);
|
||||
}//if//
|
||||
else {
|
||||
cellControlData.font = value;
|
||||
|
||||
if(cellControlData.getCellControl() != null) {
|
||||
CellControl cellControl = cellControlData.getCellControl();
|
||||
|
||||
if(cellControl.fontHolder == null) {
|
||||
cellControl.fontHolder = new ResourceHolder(cellControl);
|
||||
}//if//
|
||||
|
||||
cellControl.fontHolder.setValue(value);
|
||||
}//if//
|
||||
}//else//
|
||||
}//setFont()//
|
||||
/**
|
||||
* Sets the tool tip text for the cell control(s).
|
||||
* @param value The new value.
|
||||
* @param cellControlData The cell control data if changing a specific cell, otherwise null.
|
||||
*/
|
||||
protected void setToolTipText(Object value, CellControlData cellControlData) {
|
||||
if(cellControlData == null) {
|
||||
if(toolTipTextHolder == null) {
|
||||
toolTipTextHolder = new ResourceHolder(this);
|
||||
}//if//
|
||||
|
||||
toolTipTextHolder.setValue(value);
|
||||
}//if//
|
||||
else {
|
||||
cellControlData.toolTipText = value;
|
||||
|
||||
if(cellControlData.getCellControl() != null) {
|
||||
cellControlData.getCellControl().refreshToolTipText();
|
||||
}//if//
|
||||
}//else//
|
||||
}//setToolTipText()//
|
||||
/**
|
||||
* Sets the layout data for the component.
|
||||
* @param layoutData The data that describes how the component is to be layed out within its parent.
|
||||
*/
|
||||
public void setLayoutData(Object layoutData) {
|
||||
this.layoutData = layoutData;
|
||||
}//setLayoutData()//
|
||||
/**
|
||||
* Gets the current foreground color used by the component.
|
||||
* @return The currently used foreground color, or null if none is provided.
|
||||
*/
|
||||
protected Color getCurrentForegroundColor() {
|
||||
return currentForegroundColor;
|
||||
}//getCurrentForegroundColor()//
|
||||
/**
|
||||
* Sets the current foreground color used by the component.
|
||||
* @param currentForegroundColor The currently used foreground color, or null if none is provided.
|
||||
*/
|
||||
protected void setCurrentForegroundColor(Color currentForegroundColor) {
|
||||
this.currentForegroundColor = currentForegroundColor;
|
||||
}//setCurrentForegroundColor()//
|
||||
/**
|
||||
* Gets the current background color used by the component.
|
||||
* @return The currently used background color, or null if none is provided.
|
||||
*/
|
||||
protected Color getCurrentBackgroundColor() {
|
||||
return currentBackgroundColor;
|
||||
}//getCurrentBackgroundColor()//
|
||||
/**
|
||||
* Sets the current background color used by the component.
|
||||
* @param currentBackgroundColor The currently used background color, or null if none is provided.
|
||||
*/
|
||||
protected void setCurrentBackgroundColor(Color currentBackgroundColor) {
|
||||
this.currentBackgroundColor = currentBackgroundColor;
|
||||
}//setCurrentBackgroundColor()//
|
||||
/**
|
||||
* Gets the current font used by the component.
|
||||
* @return The currently used font, or null if none is provided.
|
||||
*/
|
||||
protected Font getCurrentFont() {
|
||||
return currentFont;
|
||||
}//getCurrentFont()//
|
||||
/**
|
||||
* Sets the current font used by the component.
|
||||
* @param currentFont The currently used font, or null if none is provided.
|
||||
*/
|
||||
protected void setCurrentFont(Font currentFont) {
|
||||
this.currentFont = currentFont;
|
||||
}//setCurrentFont()//
|
||||
}//CellComponent//
|
||||
@@ -0,0 +1,362 @@
|
||||
/*
|
||||
* Copyright (c) 2007,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.tcv.swt.client.cell;
|
||||
|
||||
import org.eclipse.swt.SWT;
|
||||
import org.eclipse.swt.graphics.GC;
|
||||
import org.eclipse.swt.widgets.Composite;
|
||||
import org.eclipse.swt.widgets.Control;
|
||||
|
||||
import com.common.util.IIterator;
|
||||
import com.common.util.IList;
|
||||
import com.common.util.LiteList;
|
||||
import com.foundation.tcv.swt.client.Container;
|
||||
import com.foundation.tcv.swt.client.ICellContainer;
|
||||
import com.foundation.tcv.swt.client.Layout;
|
||||
import com.foundation.tcv.swt.client.RowObject;
|
||||
import com.foundation.tcv.view.ViewMessage;
|
||||
import com.foundation.view.swt.cell.CellContainer.ContainerControl;
|
||||
|
||||
public abstract class CellContainer extends CellComponent implements ICellContainer, com.foundation.tcv.swt.cell.ICellContainer {
|
||||
/** A collection of components contained by this container. */
|
||||
private IList cellComponents = null;
|
||||
/** The layout used by the container. */
|
||||
private Layout layout = null;
|
||||
/** The ordering of the contained cell components for tabbing. */
|
||||
private CellComponent[] tabOrder = null;
|
||||
/** The inheritance of the background for this container. */
|
||||
private int inheritType = 0;
|
||||
|
||||
public class ContainerCellControlData extends CellControlData {
|
||||
/**
|
||||
* ContainerCellControlData constructor.
|
||||
* @param rowObject The row for the cell.
|
||||
*/
|
||||
public ContainerCellControlData(RowObject rowObject) {
|
||||
super(rowObject);
|
||||
}//ContainerCellControlData()//
|
||||
}//ContainerCellControlData//
|
||||
|
||||
public class ContainerCellControl extends CellControl {
|
||||
/**
|
||||
* ContainerCellControl constructor.
|
||||
* @param control The control being encapsulated.
|
||||
* @param cellData The cell's data.
|
||||
*/
|
||||
public ContainerCellControl(Composite control, ContainerCellControlData cellData) {
|
||||
super(control, cellData);
|
||||
}//ContainerCellControl()//
|
||||
/**
|
||||
* Gets the button cell data for the control.
|
||||
* @return The cell data for the button control.
|
||||
*/
|
||||
public ContainerCellControlData getContainerCellControlData() {
|
||||
return (ContainerCellControlData) getCellControlData();
|
||||
}//getContainerCellControlData()//
|
||||
/**
|
||||
* Gets the button control.
|
||||
* @return The button being encapsulated.
|
||||
*/
|
||||
public Composite getSwtComposite() {
|
||||
return (Composite) getSwtControl();
|
||||
}//getSwtButton()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.cell.CellComponent.CellControl#initialize()
|
||||
*/
|
||||
public void initialize() {
|
||||
if(CellContainer.this.getLayout() != null) {
|
||||
getSwtComposite().setLayout(CellContainer.this.getLayout().createLayout(getContainerCellControlData().getRowObject()));
|
||||
}//if//
|
||||
|
||||
super.initialize();
|
||||
|
||||
setInheritBackground(CellContainer.this.inheritType);
|
||||
|
||||
//Initialize the child cell components.//
|
||||
for(int index = 0; index < getCellComponents().getSize(); index++) {
|
||||
((CellComponent) getCellComponents().get(index)).getCellControlData(getCellControlData().getRowObject()).getCellControl().initialize();
|
||||
}//for//
|
||||
|
||||
if((getTabOrder() != null) && (getTabOrder().length > 0)) {
|
||||
Control[] tabList = new Control[getTabOrder().length];
|
||||
|
||||
for(int index = 0; index < getTabOrder().length; index++) {
|
||||
tabList[index] = getTabOrder()[index].getCellControlData(getCellControlData().getRowObject()).getCellControl().getSwtControl();
|
||||
}//for//
|
||||
|
||||
getSwtComposite().setTabList(tabList);
|
||||
}//if//
|
||||
}//initialize()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.cell.CellComponent.CellControl#refresh()
|
||||
*/
|
||||
public void refresh() {
|
||||
super.refresh();
|
||||
|
||||
//Refresh the child cell components.//
|
||||
for(int index = 0; index < getCellComponents().getSize(); index++) {
|
||||
((CellComponent) getCellComponents().get(index)).getCellControlData(getCellControlData().getRowObject()).getCellControl().refresh();
|
||||
}//for//
|
||||
}//refresh()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.view.swt.cell.CellComponent.CellControl#release()
|
||||
*/
|
||||
public void release() {
|
||||
super.release();
|
||||
|
||||
//Release the child cell components.//
|
||||
for(int index = 0; index < getCellComponents().getSize(); index++) {
|
||||
((CellComponent) getCellComponents().get(index)).getCellControlData(getCellControlData().getRowObject()).getCellControl().release();
|
||||
}//for//
|
||||
}//release()//
|
||||
/**
|
||||
* Forces any pending synchronizations to complete.
|
||||
*/
|
||||
public void synchronize() {
|
||||
//Synchronize the child cell components.//
|
||||
for(int index = 0; index < getCellComponents().getSize(); index++) {
|
||||
((CellComponent) getCellComponents().get(index)).getCellControlData(getCellControlData().getRowObject()).getCellControl().synchronize();
|
||||
}//for//
|
||||
}//synchronize()//
|
||||
/**
|
||||
* Sets the background inheritance for all children.
|
||||
* @param inherit Whether the background of this composite should be inherited by all child controls. The default value will cause children that don't specify otherwise to inherit the background.
|
||||
* @see #INHERIT_NONE
|
||||
* @see #INHERIT_DEFAULT
|
||||
* @see #INHERIT_FORCE
|
||||
*/
|
||||
public void setInheritBackground(int inheritType) {
|
||||
int mode = inheritType == INHERIT_FORCE ? SWT.INHERIT_FORCE : inheritType == INHERIT_DEFAULT ? SWT.INHERIT_DEFAULT : SWT.INHERIT_NONE;
|
||||
|
||||
getSwtComposite().setBackgroundMode(mode);
|
||||
}//setInheritBackground()//
|
||||
}//ContainerCellControl//
|
||||
/**
|
||||
* CellContainer constructor.
|
||||
*/
|
||||
public CellContainer() {
|
||||
}//CellContainer()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.cell.CellComponent#register(com.foundation.tcv.swt.client.RowObject)
|
||||
*/
|
||||
public void register(RowObject rowObject) {
|
||||
super.register(rowObject);
|
||||
|
||||
if(cellComponents != null) {
|
||||
for(int index = 0; index < cellComponents.getSize(); index++) {
|
||||
CellComponent next = (CellComponent) cellComponents.get(index);
|
||||
|
||||
next.register(rowObject);
|
||||
}//for//
|
||||
}//if//
|
||||
}//register()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.cell.CellComponent#unregister(com.foundation.tcv.swt.client.RowObject)
|
||||
*/
|
||||
public void unregister(RowObject rowObject) {
|
||||
super.unregister(rowObject);
|
||||
|
||||
if(cellComponents != null) {
|
||||
for(int index = 0; index < cellComponents.getSize(); index++) {
|
||||
CellComponent next = (CellComponent) cellComponents.get(index);
|
||||
|
||||
next.unregister(rowObject);
|
||||
}//for//
|
||||
}//if//
|
||||
}//unregister()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.cell.CellComponent#paintCell(com.foundation.tcv.swt.client.cell.CellComponent.CellControlData, org.eclipse.swt.graphics.GC)
|
||||
*/
|
||||
protected void paintCell(CellControlData cellControlData, GC graphics) {
|
||||
//Does nothing. TODO: Should some components of a cell container be paintable and others are not?
|
||||
}//paintCell()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.ICellContainer#addCellComponent(com.foundation.tcv.swt.client.cell.CellComponent)
|
||||
*/
|
||||
public void addCellComponent(CellComponent component) {
|
||||
if(cellComponents == null) {
|
||||
cellComponents = new LiteList(10, 20);
|
||||
}//if//
|
||||
|
||||
cellComponents.add(component);
|
||||
|
||||
if(isInitialized()) {
|
||||
component.internalViewInitializeAll();
|
||||
}//if//
|
||||
}//addCellComponent()//
|
||||
/**
|
||||
* Removes a cell component that was child of this container.
|
||||
* @param component The cell component to no longer be contained by this container.
|
||||
*/
|
||||
public void removeCellComponent(CellComponent component) {
|
||||
cellComponents.remove(component);
|
||||
}//removeCellComponent()//
|
||||
/**
|
||||
* Gets the collection of cell components for this container.
|
||||
* @return The cell components contained within this container.
|
||||
*/
|
||||
public IList getCellComponents() {
|
||||
return cellComponents == null ? LiteList.EMPTY_LIST : cellComponents;
|
||||
}//getCellComponents()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.ICellContainer#getRowObject(int)
|
||||
*/
|
||||
public RowObject getRowObject(int objectId) {
|
||||
return getCellContainer().getRowObject(objectId);
|
||||
}//getRowObject()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.ICellContainer#getRowObjects()
|
||||
*/
|
||||
public IIterator getRowObjects() {
|
||||
return getCellContainer().getRowObjects();
|
||||
}//getRowObjects()//
|
||||
/**
|
||||
* Gets the layout for this container.
|
||||
* @return The container's layout.
|
||||
*/
|
||||
public Layout getLayout() {
|
||||
return layout;
|
||||
}//getLayout()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.ICellContainer#setLayout(com.foundation.tcv.swt.client.Layout)
|
||||
*/
|
||||
public void setLayout(Layout layout) {
|
||||
this.layout = layout;
|
||||
}//setLayout()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.ICellContainer#getSwtComposite(com.foundation.tcv.swt.client.RowObject)
|
||||
*/
|
||||
public Composite getSwtComposite(RowObject rowObject) {
|
||||
return ((ContainerCellControl) ((ContainerCellControlData) getCellControlData(rowObject)).getCellControl()).getSwtComposite();
|
||||
}//getSwtComposite()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.ICellContainer#getSwtComposites()
|
||||
*/
|
||||
public IIterator getSwtComposites() {
|
||||
final IIterator cellControlIterator = getCellControlIterator();
|
||||
|
||||
return new IIterator() {
|
||||
public void resetToFront() {
|
||||
cellControlIterator.resetToFront();
|
||||
}//resetToFont()//
|
||||
public boolean remove() {
|
||||
return false;
|
||||
}//remove()//
|
||||
public Object next() {
|
||||
return ((ContainerControl) cellControlIterator.next()).getSwtComposite();
|
||||
}//next()//
|
||||
public boolean hasNext() {
|
||||
return cellControlIterator.hasNext();
|
||||
}//hasNext()//
|
||||
};
|
||||
}//getSwtComposite()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.cell.CellComponent#getContainer()
|
||||
*/
|
||||
public Container getContainer() {
|
||||
return getCellContainer() == null ? null : getCellContainer().getContainer();
|
||||
}//getContainer()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.view.swt.cell.CellComponent#internalViewInitializeAll()
|
||||
*/
|
||||
protected void internalViewInitializeAll() {
|
||||
super.internalViewInitializeAll();
|
||||
|
||||
if(cellComponents != null) {
|
||||
for(int index = 0; index < cellComponents.getSize(); index++) {
|
||||
((CellComponent) cellComponents.get(index)).internalViewInitializeAll();
|
||||
}//for//
|
||||
}//if//
|
||||
}//internalViewInitializeAll()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.view.swt.cell.CellComponent#internalViewReleaseAll()
|
||||
*/
|
||||
protected void internalViewReleaseAll() {
|
||||
super.internalViewReleaseAll();
|
||||
|
||||
if(cellComponents != null) {
|
||||
for(int index = 0; index < cellComponents.getSize(); index++) {
|
||||
((CellComponent) cellComponents.get(index)).internalViewReleaseAll();
|
||||
}//for//
|
||||
}//if//
|
||||
}//internalViewReleaseAll()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.view.swt.cell.CellComponent#internalViewSynchronizeAll()
|
||||
*/
|
||||
protected void internalViewSynchronizeAll() {
|
||||
super.internalViewSynchronizeAll();
|
||||
|
||||
if(cellComponents != null) {
|
||||
for(int index = 0; index < cellComponents.getSize(); index++) {
|
||||
((CellComponent) cellComponents.get(index)).internalViewSynchronizeAll();
|
||||
}//for//
|
||||
}//if//
|
||||
}//internalViewSynchronizeAll()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.AbstractComponent#internalProcessMessage(com.foundation.tcv.view.ViewMessage)
|
||||
*/
|
||||
public Object internalProcessMessage(ViewMessage viewMessage) {
|
||||
Object result = null;
|
||||
|
||||
switch(viewMessage.getMessageNumber()) {
|
||||
case MESSAGE_SET_TAB_ORDER: {
|
||||
int[] componentNumbers = (int[]) viewMessage.getMessageData();
|
||||
CellComponent[] array = new CellComponent[componentNumbers.length];
|
||||
|
||||
for(int index = 0; index < componentNumbers.length; index++) {
|
||||
array[index] = (CellComponent) getComponent(componentNumbers[index]);
|
||||
}//for//
|
||||
|
||||
setTabOrder(array);
|
||||
break;
|
||||
}//case//
|
||||
case MESSAGE_SET_INHERIT_BACKGROUND: {
|
||||
setInheritBackground(viewMessage.getMessageInteger());
|
||||
break;
|
||||
}//case//
|
||||
default: {
|
||||
result = super.internalProcessMessage(viewMessage);
|
||||
}//default//
|
||||
}//switch//
|
||||
|
||||
return result;
|
||||
}//internalProcessMessage()//
|
||||
/**
|
||||
* Gets the tab ordering for the cell components contained within the panel.
|
||||
* @return The panel's component tab ordering.
|
||||
*/
|
||||
protected CellComponent[] getTabOrder() {
|
||||
return tabOrder;
|
||||
}//getTabOrder()//
|
||||
/**
|
||||
* Sets the tab ordering for the cell components contained within the panel.
|
||||
* @param tabOrder The panel's component tab ordering.
|
||||
*/
|
||||
protected void setTabOrder(CellComponent[] tabOrder) {
|
||||
this.tabOrder = tabOrder;
|
||||
}//setTabOrder()//
|
||||
/**
|
||||
* Sets the background inheritance for all children.
|
||||
* @param inherit Whether the background of this composite should be inherited by all child controls. The default value will cause children that don't specify otherwise to inherit the background.
|
||||
* @see #INHERIT_NONE
|
||||
* @see #INHERIT_DEFAULT
|
||||
* @see #INHERIT_FORCE
|
||||
*/
|
||||
public void setInheritBackground(int inheritType) {
|
||||
IIterator iterator = getCellControlIterator();
|
||||
|
||||
//Update the existing controls.//
|
||||
while(iterator.hasNext()) {
|
||||
ContainerControl containerControl = (ContainerControl) iterator.next();
|
||||
|
||||
containerControl.setInheritBackground(inheritType);
|
||||
}//while//
|
||||
|
||||
this.inheritType = inheritType;
|
||||
}//setInheritBackground()//
|
||||
}//CellContainer//
|
||||
@@ -0,0 +1,340 @@
|
||||
/*
|
||||
* Copyright (c) 2006,2008 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.tcv.swt.client.cell;
|
||||
|
||||
import java.util.Calendar;
|
||||
import java.util.Date;
|
||||
import java.util.GregorianCalendar;
|
||||
|
||||
import org.eclipse.swt.events.SelectionEvent;
|
||||
import org.eclipse.swt.events.SelectionListener;
|
||||
import org.eclipse.swt.graphics.GC;
|
||||
import org.eclipse.swt.widgets.DateTime;
|
||||
|
||||
import com.common.thread.IRunnable;
|
||||
import com.foundation.tcv.swt.cell.ICellDateTime;
|
||||
import com.foundation.tcv.swt.client.ICellContainer;
|
||||
import com.foundation.tcv.swt.client.RowObject;
|
||||
import com.foundation.tcv.view.ViewMessage;
|
||||
|
||||
public class CellDateTime extends CellComponent implements ICellDateTime {
|
||||
/** The control style. */
|
||||
private int style = 0;
|
||||
/** Whether the selection state should be auto-synchronized. */
|
||||
private boolean autoSynchronizeSelection = true;
|
||||
/** The delay to be used when auto synchronizing changes. */
|
||||
private long autoSynchronizeSelectionDelay = 500;
|
||||
/** Whether the year should be transfered to/from the view/model. */
|
||||
private boolean includeYear = false;
|
||||
/** Whether the month should be transfered to/from the view/model. */
|
||||
private boolean includeMonth = false;
|
||||
/** Whether the day should be transfered to/from the view/model. */
|
||||
private boolean includeDay = false;
|
||||
/** Whether the hour should be transfered to/from the view/model. */
|
||||
private boolean includeHour = false;
|
||||
/** Whether the minutes should be transfered to/from the view/model. */
|
||||
private boolean includeMinute = false;
|
||||
/** Whether the seconds should be transfered to/from the view/model. */
|
||||
private boolean includeSecond = false;
|
||||
|
||||
/**
|
||||
* Maintains the cell data for the control. A control may only exist if it is visible, but the data must be maintained regardless.
|
||||
*/
|
||||
public class DateTimeCellControlData extends CellControlData {
|
||||
/** The control's selection state. */
|
||||
private Date selection = null;
|
||||
|
||||
/**
|
||||
* DateTimeCellControlData constructor.
|
||||
* @param rowObject The row for the cell.
|
||||
*/
|
||||
public DateTimeCellControlData(RowObject rowObject) {
|
||||
super(rowObject);
|
||||
}//DateTimeCellControlData()//
|
||||
}//DateTimeCellControlData//
|
||||
|
||||
/**
|
||||
* Encapsulates a control with related data such as listeners and the data model for the cell.
|
||||
*/
|
||||
public class DateTimeCellControl extends CellControl implements SelectionListener {
|
||||
/** The task that auto synchronizes the selection state after a short delay. */
|
||||
private Task autoSynchronizeSelectionTask = null;
|
||||
/** The calendar used to transfer the date/time data to/from the model. */
|
||||
private Calendar calendar = GregorianCalendar.getInstance();
|
||||
|
||||
/**
|
||||
* DateTimeCellControl constructor.
|
||||
* @param control The control being encapsulated.
|
||||
* @param cellData The cell's data.
|
||||
*/
|
||||
public DateTimeCellControl(DateTime control, DateTimeCellControlData cellData) {
|
||||
super(control, cellData);
|
||||
getSwtDateTime().addSelectionListener(this);
|
||||
}//DateTimeCellControl()//
|
||||
/**
|
||||
* Gets the button cell data for the control.
|
||||
* @return The cell data for the button control.
|
||||
*/
|
||||
public DateTimeCellControlData getDateTimeCellControlData() {
|
||||
return (DateTimeCellControlData) getCellControlData();
|
||||
}//getDateTimeCellControlData()//
|
||||
/**
|
||||
* Gets the button control.
|
||||
* @return The button being encapsulated.
|
||||
*/
|
||||
public org.eclipse.swt.widgets.DateTime getSwtDateTime() {
|
||||
return (org.eclipse.swt.widgets.DateTime) getSwtControl();
|
||||
}//getSwtDateTime()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.cell.CellComponent.CellControl#initialize()
|
||||
*/
|
||||
public void initialize() {
|
||||
super.initialize();
|
||||
}//initialize()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.cell.CellComponent.CellControl#refresh()
|
||||
*/
|
||||
public void refresh() {
|
||||
super.refresh();
|
||||
refreshSelection();
|
||||
}//refresh()//
|
||||
/**
|
||||
* Refreshes the selection value.
|
||||
*/
|
||||
public void refreshSelection() {
|
||||
controlSetSelection(getDateTimeCellControlData().selection != null ? getDateTimeCellControlData().selection : new Date());
|
||||
}//refreshSelection()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.view.swt.cell.CellComponent.CellControl#release()
|
||||
*/
|
||||
public void release() {
|
||||
if(!getSwtDateTime().isDisposed()) {
|
||||
getSwtDateTime().removeSelectionListener(this);
|
||||
}//if//
|
||||
|
||||
//Ignore any pending synchronizations.//
|
||||
synchronized(this) {
|
||||
if(autoSynchronizeSelectionTask != null) {
|
||||
removeTask(autoSynchronizeSelectionTask);
|
||||
autoSynchronizeSelectionTask = null;
|
||||
}//if//
|
||||
}//synchronized//
|
||||
|
||||
super.release();
|
||||
}//release()//
|
||||
/**
|
||||
* Forces any pending synchronizations to complete.
|
||||
*/
|
||||
public void synchronize() {
|
||||
if(autoSynchronizeSelectionTask != null) {
|
||||
removeTask(autoSynchronizeSelectionTask);
|
||||
autoSynchronizeSelectionTask.execute();
|
||||
autoSynchronizeSelectionTask = null;
|
||||
}//if//
|
||||
}//synchronize()//
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.swt.events.SelectionListener#widgetDefaultSelected(org.eclipse.swt.events.SelectionEvent)
|
||||
*/
|
||||
public void widgetDefaultSelected(SelectionEvent event) {
|
||||
}//widgetDefaultSelected()//
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.swt.events.SelectionListener#widgetSelected(org.eclipse.swt.events.SelectionEvent)
|
||||
*/
|
||||
public void widgetSelected(SelectionEvent event) {
|
||||
if(includeYear) {
|
||||
calendar.set(Calendar.YEAR, getSwtDateTime().getYear());
|
||||
}//if//
|
||||
|
||||
if(includeMonth) {
|
||||
calendar.set(Calendar.MONTH, getSwtDateTime().getMonth());
|
||||
}//if//
|
||||
|
||||
if(includeDay) {
|
||||
calendar.set(Calendar.DAY_OF_MONTH, getSwtDateTime().getDay());
|
||||
}//if//
|
||||
|
||||
if(includeHour) {
|
||||
calendar.set(Calendar.HOUR_OF_DAY, getSwtDateTime().getHours());
|
||||
}//if//
|
||||
|
||||
if(includeMinute) {
|
||||
calendar.set(Calendar.MINUTE, getSwtDateTime().getMinutes());
|
||||
}//if//
|
||||
|
||||
if(includeSecond) {
|
||||
calendar.set(Calendar.SECOND, getSwtDateTime().getSeconds());
|
||||
}//if//
|
||||
|
||||
selectionChanged(calendar.getTime());
|
||||
}//widgetSelected()//
|
||||
/**
|
||||
* Called when the selection is changed in the view control.
|
||||
* This method updates all bindings and
|
||||
* @param date The current selection.
|
||||
*/
|
||||
protected void selectionChanged(final Date date) {
|
||||
if(autoSynchronizeSelection) {
|
||||
if(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(DateTimeCellControl.this) {
|
||||
if(autoSynchronizeSelectionTask == this) {
|
||||
//Cleanup after the task.//
|
||||
autoSynchronizeSelectionTask = null;
|
||||
getEventLoop().executeAsync(new IRunnable() {
|
||||
public Object run() {
|
||||
sendMessage(MESSAGE_VIEW_SYNCHRONIZE_SELECTION, date, null, getDateTimeCellControlData().getRowObject().getObjectId(), 0);
|
||||
return null;
|
||||
}//run()//
|
||||
});
|
||||
}//if//
|
||||
}//synchronized//
|
||||
}//run()//
|
||||
};
|
||||
addTask(autoSynchronizeSelectionTask, autoSynchronizeSelectionDelay);
|
||||
}//synchronized//
|
||||
}//if//
|
||||
else {
|
||||
sendMessage(MESSAGE_VIEW_SYNCHRONIZE_SELECTION, date, null, getDateTimeCellControlData().getRowObject().getObjectId(), 0);
|
||||
}//else//
|
||||
}//if//
|
||||
|
||||
getDateTimeCellControlData().selection = date;
|
||||
}//selectionChanged()//
|
||||
/**
|
||||
* Sets the component's selection state.
|
||||
* @param isSelected Whether the button is to be selected.
|
||||
*/
|
||||
protected void controlSetSelection(Date date) {
|
||||
if(getSwtDateTime() != null) {
|
||||
date = date == null ? new Date() : date;
|
||||
calendar.setTime(date);
|
||||
|
||||
if(includeYear) {
|
||||
getSwtDateTime().setYear(calendar.get(Calendar.YEAR));
|
||||
}//if//
|
||||
|
||||
if(includeMonth) {
|
||||
getSwtDateTime().setMonth(calendar.get(Calendar.MONTH));
|
||||
}//if//
|
||||
|
||||
if(includeDay) {
|
||||
getSwtDateTime().setDay(calendar.get(Calendar.DAY_OF_MONTH));
|
||||
}//if//
|
||||
|
||||
if(includeHour) {
|
||||
getSwtDateTime().setHours(calendar.get(Calendar.HOUR_OF_DAY));
|
||||
}//if//
|
||||
|
||||
if(includeMinute) {
|
||||
getSwtDateTime().setMinutes(calendar.get(Calendar.MINUTE));
|
||||
}//if//
|
||||
|
||||
if(includeSecond) {
|
||||
getSwtDateTime().setSeconds(calendar.get(Calendar.SECOND));
|
||||
}//if//
|
||||
}//if//
|
||||
}//controlSetSelection()//
|
||||
}//DateTimeCellControl//
|
||||
/**
|
||||
* CellDateTime constructor.
|
||||
*/
|
||||
public CellDateTime() {
|
||||
}//CellDateTime()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.cell.CellComponent#supportsControl()
|
||||
*/
|
||||
public boolean supportsControl() {
|
||||
return true;
|
||||
}//supportsControl()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.cell.CellComponent#initializeCellControl(com.foundation.tcv.swt.client.cell.CellComponent.CellControlData)
|
||||
*/
|
||||
protected CellControl initializeCellControl(CellControlData cellControlData) {
|
||||
return new DateTimeCellControl(new DateTime(getCellContainer().getSwtComposite(cellControlData.getRowObject()), style), (DateTimeCellControlData) cellControlData);
|
||||
}//initializeCellControl()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.cell.CellComponent#initializeCellControlData(com.foundation.tcv.swt.client.CollectionComponent.RowObject)
|
||||
*/
|
||||
protected CellControlData initializeCellControlData(RowObject rowObject) {
|
||||
return new DateTimeCellControlData(rowObject);
|
||||
}//initializeCellControlData()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.cell.CellComponent#releaseCellControlData(com.foundation.tcv.swt.client.cell.CellComponent.CellControlData)
|
||||
*/
|
||||
protected void releaseCellControlData(CellControlData cellControlData) {
|
||||
}//releaseCellControlData()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.cell.CellComponent#paintCell(com.foundation.tcv.swt.client.cell.CellComponent.CellControlData, org.eclipse.swt.graphics.GC)
|
||||
*/
|
||||
protected void paintCell(CellControlData cellControlData, GC graphics) {
|
||||
}//paintCell()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.cell.CellComponent#internalViewRelease()
|
||||
*/
|
||||
protected void internalViewRelease() {
|
||||
super.internalViewRelease();
|
||||
}//internalViewRelease()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.AbstractComponent#internalProcessMessage(com.foundation.tcv.view.ViewMessage)
|
||||
*/
|
||||
public Object internalProcessMessage(ViewMessage viewMessage) {
|
||||
Object result = null;
|
||||
|
||||
switch(viewMessage.getMessageNumber()) {
|
||||
case MESSAGE_INITIALIZE: {
|
||||
setCellContainer((ICellContainer) getComponent(viewMessage.getMessageInteger()));
|
||||
style = viewMessage.getMessageSecondaryInteger();
|
||||
getCellContainer().addCellComponent(this);
|
||||
includeYear = (((style & STYLE_DATE) > 0) || ((style & STYLE_CALENDAR) > 0));
|
||||
includeMonth = (((style & STYLE_DATE) > 0) || ((style & STYLE_CALENDAR) > 0));
|
||||
includeDay = ((((style & STYLE_DATE) > 0) && ((style & STYLE_SHORT) == 0)) || ((style & STYLE_CALENDAR) > 0));
|
||||
includeHour = ((style & STYLE_TIME) > 0);
|
||||
includeMinute = ((style & STYLE_TIME) > 0);
|
||||
includeSecond = (((style & STYLE_TIME) > 0) && ((style & STYLE_SHORT) == 0));
|
||||
break;
|
||||
}//case//
|
||||
case MESSAGE_SET_AUTO_SYNCHRONIZE_SELECTION: {
|
||||
autoSynchronizeSelection = ((Boolean) viewMessage.getMessageData()).booleanValue();
|
||||
break;
|
||||
}//case//
|
||||
case MESSAGE_SET_AUTO_SYNCHRONIZE_SELECTION_DELAY: {
|
||||
autoSynchronizeSelectionDelay = ((Long) viewMessage.getMessageData()).longValue();
|
||||
break;
|
||||
}//case//
|
||||
case MESSAGE_VIEW_REFRESH_SELECTION: {
|
||||
setSelection((Date) viewMessage.getMessageData(), viewMessage.getMessageInteger() != -1 ? (DateTimeCellControlData) getCellControlData(getCellContainer().getRowObject(viewMessage.getMessageInteger())) : null);
|
||||
break;
|
||||
}//case//
|
||||
default: {
|
||||
result = super.internalProcessMessage(viewMessage);
|
||||
}//default//
|
||||
}//switch//
|
||||
|
||||
return result;
|
||||
}//internalProcessMessage()//
|
||||
/**
|
||||
* Sets the selection for the cell control(s).
|
||||
* @param value The new value.
|
||||
* @param cellControlData The cell control data if changing a specific cell, otherwise null.
|
||||
*/
|
||||
protected void setSelection(Date value, DateTimeCellControlData cellControlData) {
|
||||
cellControlData.selection = value;
|
||||
|
||||
if(cellControlData.getCellControl() != null) {
|
||||
((DateTimeCellControl) cellControlData.getCellControl()).refreshSelection();
|
||||
}//if//
|
||||
}//setSelection()//
|
||||
}//CellDateTime//
|
||||
@@ -0,0 +1,136 @@
|
||||
/*
|
||||
* Copyright (c) 2007,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.tcv.swt.client.cell;
|
||||
|
||||
import org.eclipse.swt.widgets.Composite;
|
||||
|
||||
import com.foundation.tcv.swt.cell.ICellPanel;
|
||||
import com.foundation.tcv.swt.client.ICellContainer;
|
||||
import com.foundation.tcv.swt.client.RowObject;
|
||||
import com.foundation.tcv.view.ViewMessage;
|
||||
|
||||
public class CellPanel extends CellContainer implements ICellPanel {
|
||||
/** The control style. */
|
||||
private int style = 0;
|
||||
|
||||
public class PanelCellControlData extends ContainerCellControlData {
|
||||
/**
|
||||
* PanelCellControlData constructor.
|
||||
* @param rowObject The row for the cell.
|
||||
*/
|
||||
public PanelCellControlData(RowObject rowObject) {
|
||||
super(rowObject);
|
||||
}//PanelCellControlData()//
|
||||
}//PanelCellControlData//
|
||||
|
||||
public class PanelCellControl extends ContainerCellControl {
|
||||
/**
|
||||
* PanelCellControl constructor.
|
||||
* @param control The control being encapsulated.
|
||||
* @param cellData The cell's data.
|
||||
*/
|
||||
public PanelCellControl(Composite control, PanelCellControlData cellData) {
|
||||
super(control, cellData);
|
||||
}//PanelCellControl()//
|
||||
/**
|
||||
* Gets the cell data for the control.
|
||||
* @return The cell data for the control.
|
||||
*/
|
||||
public PanelCellControlData getPanelCellControlData() {
|
||||
return (PanelCellControlData) getCellControlData();
|
||||
}//getPanelCellControlData()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.cell.CellComponent.CellControl#initialize()
|
||||
*/
|
||||
public void initialize() {
|
||||
super.initialize();
|
||||
}//initialize()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.cell.CellComponent.CellControl#refresh()
|
||||
*/
|
||||
public void refresh() {
|
||||
super.refresh();
|
||||
}//refresh()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.view.swt.cell.CellComponent.CellControl#release()
|
||||
*/
|
||||
public void release() {
|
||||
super.release();
|
||||
}//release()//
|
||||
/**
|
||||
* Forces any pending synchronizations to complete.
|
||||
*/
|
||||
public void synchronize() {
|
||||
super.synchronize();
|
||||
}//synchronize()//
|
||||
}//PanelCellControl//
|
||||
/**
|
||||
* CellPanel constructor.
|
||||
*/
|
||||
public CellPanel() {
|
||||
super();
|
||||
}//CellPanel()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.cell.CellComponent#initializeCellControl(com.foundation.tcv.swt.client.cell.CellComponent.CellControlData)
|
||||
*/
|
||||
protected CellControl initializeCellControl(CellControlData cellControlData) {
|
||||
return new PanelCellControl(new Composite(getCellContainer().getSwtComposite(cellControlData.getRowObject()), style), (PanelCellControlData) cellControlData);
|
||||
}//initializeCellControl()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.cell.CellComponent#internalCreateCellControl(com.foundation.tcv.swt.client.cell.CellComponent.CellControlData)
|
||||
*/
|
||||
protected CellControl internalCreateCellControl(CellControlData cellControlData) {
|
||||
CellControl result = super.internalCreateCellControl(cellControlData);
|
||||
|
||||
//Initialize the child cell components.//
|
||||
for(int index = 0; index < getCellComponents().getSize(); index++) {
|
||||
((CellComponent) getCellComponents().get(index)).createCellControl(cellControlData.getRowObject());
|
||||
}//for//
|
||||
|
||||
return result;
|
||||
}//internalCreateCellControl()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.cell.CellComponent#initializeCellControlData(com.foundation.tcv.swt.client.RowObject)
|
||||
*/
|
||||
protected CellControlData initializeCellControlData(RowObject rowObject) {
|
||||
return new PanelCellControlData(rowObject);
|
||||
}//initializeCellControlData()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.cell.CellComponent#releaseCellControlData(com.foundation.tcv.swt.client.cell.CellComponent.CellControlData)
|
||||
*/
|
||||
protected void releaseCellControlData(CellControlData cellControlData) {
|
||||
}//releaseCellControlData()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.cell.CellComponent#supportsControl()
|
||||
*/
|
||||
public boolean supportsControl() {
|
||||
return true;
|
||||
}//supportsControl()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.AbstractComponent#internalProcessMessage(com.foundation.tcv.view.ViewMessage)
|
||||
*/
|
||||
public Object internalProcessMessage(ViewMessage viewMessage) {
|
||||
Object result = null;
|
||||
|
||||
switch(viewMessage.getMessageNumber()) {
|
||||
case MESSAGE_INITIALIZE: {
|
||||
int[] data = (int[]) viewMessage.getMessageData();
|
||||
|
||||
setCellContainer((ICellContainer) getComponent(data[0]));
|
||||
style = data[1];
|
||||
getCellContainer().addCellComponent(this);
|
||||
break;
|
||||
}//case//
|
||||
default: {
|
||||
result = super.internalProcessMessage(viewMessage);
|
||||
}//default//
|
||||
}//switch//
|
||||
|
||||
return result;
|
||||
}//internalProcessMessage()//
|
||||
}//CellPanel//
|
||||
@@ -0,0 +1,192 @@
|
||||
/*
|
||||
* Copyright (c) 2007,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.tcv.swt.client.cell;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
|
||||
import org.eclipse.swt.graphics.Color;
|
||||
import org.eclipse.swt.graphics.GC;
|
||||
import org.eclipse.swt.graphics.Rectangle;
|
||||
|
||||
import com.foundation.tcv.swt.cell.IProgress;
|
||||
import com.foundation.tcv.swt.client.ICellContainer;
|
||||
import com.foundation.tcv.swt.client.RowObject;
|
||||
import com.foundation.tcv.view.ViewMessage;
|
||||
import com.foundation.view.JefColor;
|
||||
import com.foundation.view.swt.util.SwtUtilities;
|
||||
|
||||
public class CellProgress extends CellComponent implements IProgress {
|
||||
/** The multiplier used to generate an integer from the current progress value. */
|
||||
private BigDecimal multiplier = null;
|
||||
/** The progress color. */
|
||||
private JefColor foreground = new JefColor("blue");
|
||||
/** The progress style. */
|
||||
private int style = 0;
|
||||
/** The control's default maximum. */
|
||||
private int maximum = 0;
|
||||
/** The control's default minimum. */
|
||||
private int minimum = 0;
|
||||
|
||||
/**
|
||||
* Maintains the cell data for the control. A control may only exist if it is visible, but the data must be maintained regardless.
|
||||
*/
|
||||
public class ProgressCellControlData extends CellControlData {
|
||||
/** The current progress in its original form. */
|
||||
private BigDecimal currentProgress = null;
|
||||
|
||||
/**
|
||||
* ProgressCellControlData constructor.
|
||||
* @param rowObject The row for the cell.
|
||||
*/
|
||||
public ProgressCellControlData(RowObject rowObject) {
|
||||
super(rowObject);
|
||||
}//ProgressCellControlData()//
|
||||
/**
|
||||
* Gets the current progress.
|
||||
* @return The current progress in its original form.
|
||||
*/
|
||||
public BigDecimal getCurrentProgress() {
|
||||
return currentProgress;
|
||||
}//getCurrentProgress()//
|
||||
/**
|
||||
* Sets the current progress.
|
||||
* @param currentProgress The current progress in its original form.
|
||||
*/
|
||||
public void setCurrentProgress(BigDecimal currentProgress) {
|
||||
this.currentProgress = currentProgress;
|
||||
}//setCurrentProgress()//
|
||||
}//ProgressCellControlData//
|
||||
/**
|
||||
* Progress constructor.
|
||||
*/
|
||||
public CellProgress() {
|
||||
}//Progress()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.cell.CellComponent#supportsPaint()
|
||||
*/
|
||||
public boolean supportsPaint() {
|
||||
return true;
|
||||
}//supportsPaint()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.AbstractComponent#internalProcessMessage(com.foundation.tcv.view.ViewMessage)
|
||||
*/
|
||||
public Object internalProcessMessage(ViewMessage viewMessage) {
|
||||
Object result = null;
|
||||
|
||||
switch(viewMessage.getMessageNumber()) {
|
||||
case MESSAGE_INITIALIZE: {
|
||||
int[] data = (int[]) viewMessage.getMessageData();
|
||||
|
||||
setCellContainer((ICellContainer) getComponent(data[0]));
|
||||
style = data[1];
|
||||
getCellContainer().addCellComponent(this);
|
||||
break;
|
||||
}//case//
|
||||
case MESSAGE_SET_MAXIMUM: {
|
||||
maximum = viewMessage.getMessageData() != null ? ((Integer) viewMessage.getMessageData()).intValue() : 1;
|
||||
break;
|
||||
}//case//
|
||||
case MESSAGE_SET_MINIMUM: {
|
||||
minimum = viewMessage.getMessageData() != null ? ((Integer) viewMessage.getMessageData()).intValue() : 0;
|
||||
break;
|
||||
}//case//
|
||||
case MESSAGE_SET_PROGRESS: {
|
||||
ProgressCellControlData controlData = (ProgressCellControlData) getCellControlData(getCellContainer().getRowObject(viewMessage.getMessageInteger()));
|
||||
|
||||
controlData.setCurrentProgress(viewMessage.getMessageData() != null ? (BigDecimal) viewMessage.getMessageData() : new BigDecimal(minimum));
|
||||
//TODO: Narrow this to the affected cell.
|
||||
getContainer().getSwtComposite().redraw();
|
||||
break;
|
||||
}//case//
|
||||
case MESSAGE_SET_MULTIPLIER: {
|
||||
setMultiplier((BigDecimal) viewMessage.getMessageData());
|
||||
//TODO: Narrow this to the affected cell.
|
||||
getContainer().getSwtComposite().redraw();
|
||||
break;
|
||||
}//case//
|
||||
default: {
|
||||
result = super.internalProcessMessage(viewMessage);
|
||||
}//default//
|
||||
}//switch//
|
||||
|
||||
return result;
|
||||
}//internalProcessMessage()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.cell.CellComponent#initializeCellControl(com.foundation.tcv.swt.client.cell.CellComponent.CellControlData)
|
||||
*/
|
||||
protected CellControl initializeCellControl(CellControlData cellControlData) {
|
||||
return null;
|
||||
}//initializeCellControl()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.cell.CellComponent#initializeCellControlData(com.foundation.tcv.swt.client.CollectionComponent.RowObject)
|
||||
*/
|
||||
protected CellControlData initializeCellControlData(RowObject rowObject) {
|
||||
return new ProgressCellControlData(rowObject);
|
||||
}//initializeCellControlData()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.cell.CellComponent#releaseCellControlData(com.foundation.tcv.swt.client.cell.CellComponent.CellControlData)
|
||||
*/
|
||||
protected void releaseCellControlData(CellControlData cellControlData) {
|
||||
}//releaseCellControlData()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.client.cell.CellComponent#paintCell(com.foundation.tcv.swt.client.cell.CellComponent.CellControlData, org.eclipse.swt.graphics.GC)
|
||||
*/
|
||||
protected void paintCell(CellControlData cellControlData, GC graphics) {
|
||||
ProgressCellControlData progressData = ((ProgressCellControlData) cellControlData);
|
||||
BigDecimal currentProgress = progressData.getCurrentProgress();
|
||||
double progress;
|
||||
|
||||
if(currentProgress != null) {
|
||||
if(multiplier != null) {
|
||||
currentProgress = currentProgress.multiply(multiplier);
|
||||
}//if//
|
||||
|
||||
progress = currentProgress.doubleValue();
|
||||
|
||||
if(progress != minimum) {
|
||||
Rectangle rectangle = graphics.getClipping();
|
||||
double width = rectangle.width;
|
||||
Color foreground = SwtUtilities.getColor(graphics.getDevice(), this.foreground);
|
||||
Color oldForeground = graphics.getForeground();
|
||||
Color oldBackground = graphics.getBackground();
|
||||
|
||||
//Set the graphics context's initial settings.//
|
||||
graphics.setForeground(foreground);
|
||||
graphics.setBackground(foreground);
|
||||
|
||||
//Draw the progress bar.//
|
||||
rectangle.height -= 2;
|
||||
rectangle.y--;
|
||||
rectangle.width = (int) Math.ceil(width / ((maximum - minimum) / progress));
|
||||
graphics.fillRectangle(rectangle);
|
||||
|
||||
//Reset the graphics context settings.//
|
||||
graphics.setForeground(oldForeground);
|
||||
graphics.setBackground(oldBackground);
|
||||
|
||||
if(!this.foreground.isColorConstant()) {
|
||||
foreground.dispose();
|
||||
}//if//
|
||||
}//if//
|
||||
}//if//
|
||||
}//paintCell()//
|
||||
/**
|
||||
* Gets the multiplier used to construct an integer from the progress value.
|
||||
* @return The progress multiplier.
|
||||
*/
|
||||
public BigDecimal getMultiplier() {
|
||||
return multiplier;
|
||||
}//getMultiplier()//
|
||||
/**
|
||||
* Sets the multiplier used to construct an integer from the progress value.
|
||||
* @param multiplier The progress multiplier.
|
||||
*/
|
||||
public void setMultiplier(BigDecimal multiplier) {
|
||||
this.multiplier = multiplier;
|
||||
}//setMultiplier()//
|
||||
}//Progress//
|
||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user