1160 lines
43 KiB
Java
1160 lines
43 KiB
Java
|
|
/*
|
||
|
|
* 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.KeyEvent;
|
||
|
|
import org.eclipse.swt.events.KeyListener;
|
||
|
|
import org.eclipse.swt.events.MouseEvent;
|
||
|
|
import org.eclipse.swt.events.MouseListener;
|
||
|
|
import org.eclipse.swt.graphics.Color;
|
||
|
|
import org.eclipse.swt.graphics.Font;
|
||
|
|
import org.eclipse.swt.graphics.GC;
|
||
|
|
import org.eclipse.swt.graphics.Image;
|
||
|
|
import org.eclipse.swt.graphics.Pattern;
|
||
|
|
import org.eclipse.swt.graphics.Rectangle;
|
||
|
|
import org.eclipse.swt.widgets.Composite;
|
||
|
|
import org.eclipse.swt.widgets.Control;
|
||
|
|
import org.eclipse.swt.widgets.Display;
|
||
|
|
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.thread.Scheduler;
|
||
|
|
import com.common.util.IIterator;
|
||
|
|
import com.common.util.IList;
|
||
|
|
import com.common.util.LiteList;
|
||
|
|
import com.common.comparison.Comparator;
|
||
|
|
import com.foundation.view.*;
|
||
|
|
import com.foundation.view.swt.util.SwtUtilities;
|
||
|
|
import com.foundation.tcv.client.view.ResourceHolder;
|
||
|
|
import com.foundation.tcv.swt.*;
|
||
|
|
import com.foundation.tcv.view.*;
|
||
|
|
|
||
|
|
/*
|
||
|
|
* The component is the base class for all standard view components.
|
||
|
|
*/
|
||
|
|
public abstract class Component extends AbstractComponent implements IComponent, IControlLocator, KeyListener {
|
||
|
|
/** DEBUG ONLY - See server component class for the DEBUG flag. */
|
||
|
|
private String name = null;
|
||
|
|
/** The container containing this component. */
|
||
|
|
private Container container = null;
|
||
|
|
/** The reference to the popup menu. Not all components must allow a popup menu. */
|
||
|
|
private Menu menu = null;
|
||
|
|
/** Whether the parent container has been disabled. The active enabled state for this component is: isParentEnabled && isLocallyEnabled. */
|
||
|
|
protected boolean isParentEnabled = true;
|
||
|
|
/** Whether this component has been disabled. The active enabled state for this component is: isParentEnabled && isLocallyEnabled. */
|
||
|
|
protected boolean isLocallyEnabled = true;
|
||
|
|
/** Whether the component was given a specific size and thus should not be packed. */
|
||
|
|
private boolean hasSpecificSize = false;
|
||
|
|
/** The optional decimal scale to be used by the component if it deals with decimal values. */
|
||
|
|
private Integer decimalScale = null;
|
||
|
|
/** A holder for the value of the tool tip text. */
|
||
|
|
private ResourceHolder toolTipTextHolder = new ResourceHolder(this);
|
||
|
|
/** A holder for the value of the foreground color. */
|
||
|
|
private ResourceHolder foregroundColorHolder = new ResourceHolder(this);
|
||
|
|
/** A holder for the value of the background color. */
|
||
|
|
private ResourceHolder backgroundColorHolder = new ResourceHolder(this);
|
||
|
|
/** A holder for the value of the font. */
|
||
|
|
private ResourceHolder fontHolder = 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);
|
||
|
|
/** A holder for the value of the container title. */
|
||
|
|
private ResourceHolder containerTitleHolder = new ResourceHolder(this);
|
||
|
|
/** A holder for the value of the container image. */
|
||
|
|
private ResourceHolder containerImageHolder = new ResourceHolder(this);
|
||
|
|
/** A holder for the value of the background image. */
|
||
|
|
private ResourceHolder backgroundImageHolder = new ResourceHolder(this);
|
||
|
|
/** A holder for the value of the change notification image. */
|
||
|
|
private Object changeImage = null;
|
||
|
|
/** A holder for the value of the change notification text. */
|
||
|
|
private Object changeText = null;
|
||
|
|
/** A holder for the value of the update notification image. */
|
||
|
|
private Object updateImage = null;
|
||
|
|
/** A holder for the value of the update notification text. */
|
||
|
|
private Object updateText = null;
|
||
|
|
/** A holder for the value of the update notification timeout. */
|
||
|
|
private Integer updateTimeout = null;
|
||
|
|
/** The task used to remove the update decoration. */
|
||
|
|
private UpdateControlDecorationRemovalTask updateControlDecorationRemovalTask = null;
|
||
|
|
/** The currently displayed control decoration notifying the user that the value in the control has been updated. */
|
||
|
|
private ControlDecoration updateControlDecoration = null;
|
||
|
|
/** The swt image used by the container of this component to represent the component. */
|
||
|
|
private Image swtContainerImage = null;
|
||
|
|
/** The set of key bindings in search order. */
|
||
|
|
private IList keyBindings = null;
|
||
|
|
/** The swt image used by the component as the background. This overrides the background gradient. */
|
||
|
|
private Image currentBackgroundImage = null;
|
||
|
|
/** The gradient to be used for the background gradient, or null if none is to be used. */
|
||
|
|
private JefGradient currentBackgroundGradient = null;
|
||
|
|
/** The gradient to be used for the background gradient image, or null if none is to be used. */
|
||
|
|
private Image currentBackgroundGradientImage = null;
|
||
|
|
/** The currently active background color (if using a solid color - versus a gradient. 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;
|
||
|
|
/** Whether the initialization routine has completed. */
|
||
|
|
//private boolean isInitializationComplete = false;
|
||
|
|
/** The listener for the resize event that refreshes the background image. */
|
||
|
|
private Listener backgroundImageResizeListener = null;
|
||
|
|
/** Whether the control should render a custom background. */
|
||
|
|
private boolean useCustomBackground = false;
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Encapsulates the images used by the overlay rendering (utilized when the component is a composite and has no background but does have a background color).
|
||
|
|
*/
|
||
|
|
private static class OverlayBufferSet {
|
||
|
|
public Image originalImage = null;
|
||
|
|
public Image bufferImage = null;
|
||
|
|
}//OverlayBufferSet//
|
||
|
|
|
||
|
|
/**
|
||
|
|
* The task used to remove stale updated decorations on controls.
|
||
|
|
*/
|
||
|
|
private class UpdateControlDecorationRemovalTask implements Runnable {
|
||
|
|
public UpdateControlDecorationRemovalTask() {
|
||
|
|
Integer timeout = getUpdateDecorationTimeout();
|
||
|
|
|
||
|
|
getSwtControl().getDisplay().timerExec(timeout == null || timeout.intValue() <= 0 ? 10000 : timeout.intValue(), this);
|
||
|
|
}//UpdateControlDecorationRemovalTask()//
|
||
|
|
public void reset() {
|
||
|
|
Integer timeout = getUpdateDecorationTimeout();
|
||
|
|
|
||
|
|
getSwtControl().getDisplay().timerExec(timeout == null || timeout.intValue() <= 0 ? 10000 : timeout.intValue(), this);
|
||
|
|
}//reset()//
|
||
|
|
public void run() {
|
||
|
|
if(updateControlDecoration != null && updateControlDecorationRemovalTask == UpdateControlDecorationRemovalTask.this && !getSwtControl().isDisposed()) {
|
||
|
|
removeDecoration(updateControlDecoration);
|
||
|
|
updateControlDecoration = null;
|
||
|
|
updateControlDecorationRemovalTask = null;
|
||
|
|
}//if//
|
||
|
|
}//evaluate()//
|
||
|
|
}//UpdateControlDecorationRemovalTask//
|
||
|
|
|
||
|
|
/**
|
||
|
|
* A listener interface so that other interested components can get notification when the tool tip text is altered.
|
||
|
|
*/
|
||
|
|
public interface IComponentListener {
|
||
|
|
/**
|
||
|
|
* Notifies the listener when the component's tool tip has been altered.
|
||
|
|
* @param component The component whose tool tip was modified.
|
||
|
|
* @param newToolTipText The new tool tip.
|
||
|
|
*/
|
||
|
|
public void toolTipTextChanged(Component component, String newToolTipText);
|
||
|
|
/**
|
||
|
|
* Notifies the listener when the container's title is altered.
|
||
|
|
* @param component The component whose title was modified.
|
||
|
|
* @param newTitle The new title.
|
||
|
|
*/
|
||
|
|
public void titleChanged(Component component, String newTitle);
|
||
|
|
/**
|
||
|
|
* Notifies the listener when the container's image is altered.
|
||
|
|
* @param component The component whose image was modified.
|
||
|
|
* @param newImage The new image.
|
||
|
|
*/
|
||
|
|
public void imageChanged(Component component, Image newImage);
|
||
|
|
}//IComponentListener//
|
||
|
|
/**
|
||
|
|
* Component constructor.
|
||
|
|
*/
|
||
|
|
public Component() {
|
||
|
|
}//Component()//
|
||
|
|
/**
|
||
|
|
* Gets the change decoration text by recursively navigating the component hierarchy searching for text that was set by the view.
|
||
|
|
* @return The change decoration's text resource reference or actual text.
|
||
|
|
*/
|
||
|
|
public Object getChangeDecorationText() {
|
||
|
|
return changeText != null ? changeText : getContainer() instanceof Component ? ((Component) getContainer()).getChangeDecorationText() : null;
|
||
|
|
}//getChangeDecorationText()//
|
||
|
|
/**
|
||
|
|
* Gets the change decoration image by recursively navigating the component hierarchy searching for an image that was set by the view.
|
||
|
|
* @return The change decoration's resource reference.
|
||
|
|
*/
|
||
|
|
public Object getChangeDecorationImage() {
|
||
|
|
return changeImage != null ? changeImage : getContainer() instanceof Component ? ((Component) getContainer()).getChangeDecorationImage() : null;
|
||
|
|
}//getChangeDecorationImage()//
|
||
|
|
/**
|
||
|
|
* Gets the ControlDecoration for displaying a change in the data.
|
||
|
|
* @return The decoration used to display a data change or null if not enough data was provided.
|
||
|
|
*/
|
||
|
|
public ControlDecoration getChangeControlDecoration() {
|
||
|
|
Object text = getChangeDecorationText();
|
||
|
|
Object image = getChangeDecorationImage();
|
||
|
|
|
||
|
|
return image != null ? new ControlDecoration(image, text) : null;
|
||
|
|
}//getChangeControlDecoration()//
|
||
|
|
/**
|
||
|
|
* Gets the update decoration text by recursively navigating the component hierarchy searching for text that was set by the view.
|
||
|
|
* @return The update decoration's text resource reference or actual text.
|
||
|
|
*/
|
||
|
|
public Object getUpdateDecorationText() {
|
||
|
|
return updateText != null ? updateText : getContainer() instanceof Component ? ((Component) getContainer()).getUpdateDecorationText() : null;
|
||
|
|
}//getUpdateDecorationText()//
|
||
|
|
/**
|
||
|
|
* Gets the update decoration image by recursively navigating the component hierarchy searching for an image that was set by the view.
|
||
|
|
* @return The update decoration's resource reference.
|
||
|
|
*/
|
||
|
|
public Object getUpdateDecorationImage() {
|
||
|
|
return updateImage != null ? updateImage : getContainer() instanceof Component ? ((Component) getContainer()).getUpdateDecorationImage() : null;
|
||
|
|
}//getUpdateDecorationImage()//
|
||
|
|
/**
|
||
|
|
* Gets the update decoration timeout by recursively navigating the component hierarchy searching for timeout that was set by the view.
|
||
|
|
* @return The update decoration's timeout resource reference or actual timeout.
|
||
|
|
*/
|
||
|
|
public Integer getUpdateDecorationTimeout() {
|
||
|
|
return updateTimeout != null ? updateTimeout : getContainer() instanceof Component ? ((Component) getContainer()).getUpdateDecorationTimeout() : null;
|
||
|
|
}//getUpdateDecorationTimeout()//
|
||
|
|
/**
|
||
|
|
* Gets the ControlDecoration for displaying an update of the data.
|
||
|
|
* <p>Note: This differs from the change control decoration in that the user has not made any local changes.</p>
|
||
|
|
* @return The decoration used to display a data update or null if not enough data was provided.
|
||
|
|
*/
|
||
|
|
public ControlDecoration getUpdateControlDecoration() {
|
||
|
|
Object text = getUpdateDecorationText();
|
||
|
|
Object image = getUpdateDecorationImage();
|
||
|
|
|
||
|
|
return image != null ? new ControlDecoration(image, text) : null;
|
||
|
|
}//getUpdateControlDecoration()//
|
||
|
|
/**
|
||
|
|
* Displays the update control decoration.
|
||
|
|
*/
|
||
|
|
public void displayUpdateControlDecoration() {
|
||
|
|
if(updateControlDecoration != null) {
|
||
|
|
updateControlDecorationRemovalTask.reset();
|
||
|
|
}//if//
|
||
|
|
else {
|
||
|
|
updateControlDecoration = getUpdateControlDecoration();
|
||
|
|
updateControlDecorationRemovalTask = new UpdateControlDecorationRemovalTask();
|
||
|
|
|
||
|
|
if(updateControlDecoration != null) {
|
||
|
|
Control control = addDecoration(updateControlDecoration);
|
||
|
|
|
||
|
|
if(control != null) {
|
||
|
|
control.addMouseListener(new MouseListener() {
|
||
|
|
public void mouseUp(MouseEvent e) {
|
||
|
|
}//mouseUp()//
|
||
|
|
public void mouseDown(MouseEvent e) {
|
||
|
|
removeDecoration(updateControlDecoration);
|
||
|
|
updateControlDecoration = null;
|
||
|
|
Scheduler.removeTask(updateControlDecorationRemovalTask);
|
||
|
|
updateControlDecorationRemovalTask = null;
|
||
|
|
}//mouseDown()//
|
||
|
|
public void mouseDoubleClick(MouseEvent e) {
|
||
|
|
}//mouseDoubleClick()//
|
||
|
|
});
|
||
|
|
}//if//
|
||
|
|
}//if//
|
||
|
|
}//else//
|
||
|
|
}//displayUpdateControlDecoration()//
|
||
|
|
/* (non-Javadoc)
|
||
|
|
* @see AbstractComponent#destroy()
|
||
|
|
*/
|
||
|
|
protected void destroy() {
|
||
|
|
if(getSwtControl() != null) {
|
||
|
|
if(!getSwtControl().isDisposed()) {
|
||
|
|
getSwtControl().setVisible(false);
|
||
|
|
}//if//
|
||
|
|
|
||
|
|
super.destroy();
|
||
|
|
}//if//
|
||
|
|
}//destroy()//
|
||
|
|
/**
|
||
|
|
* Gets the component's given name (from the VML).
|
||
|
|
* <p>DEBUG ONLY - See server component class's DEBUG flag.</p>
|
||
|
|
* @return The name for the component or null if unknown.
|
||
|
|
*/
|
||
|
|
public String getName() {
|
||
|
|
return name;
|
||
|
|
}//getName()//
|
||
|
|
/* (non-Javadoc)
|
||
|
|
* @see com.foundation.tcv.swt.client.AbstractComponent#getContainer()
|
||
|
|
*/
|
||
|
|
public Container getContainer() {
|
||
|
|
return container;
|
||
|
|
}//getContainer()//
|
||
|
|
/**
|
||
|
|
* Sets the parent container for this component.
|
||
|
|
* @param container The view component containing this component.
|
||
|
|
*/
|
||
|
|
protected void setContainer(Container container) {
|
||
|
|
this.container = container;
|
||
|
|
}//setContainer()//
|
||
|
|
/* (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;
|
||
|
|
getSwtControl().setMenu(menu != null ? menu.getSwtMenu() : null);
|
||
|
|
}//setMenu()//
|
||
|
|
/**
|
||
|
|
* Gets the widget encapsulated by this component.
|
||
|
|
* @return The encapsulated widget, or null if this component does not have a viewable element.
|
||
|
|
*/
|
||
|
|
public Control getSwtControl() {
|
||
|
|
return (Control) getSwtWidget();
|
||
|
|
}//getSwtControl()//
|
||
|
|
/* (non-Javadoc)
|
||
|
|
* @see com.foundation.tcv.swt.client.AbstractComponent#getShell()
|
||
|
|
*/
|
||
|
|
public Shell getShell() {
|
||
|
|
return getSwtControl() != null && !getSwtControl().isDisposed() ? getSwtControl().getShell() : null;
|
||
|
|
}//getShell()//
|
||
|
|
/**
|
||
|
|
* 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()//
|
||
|
|
/**
|
||
|
|
* Searches this component and all child components for the control with the focus.
|
||
|
|
* @return The control with the focus, or null if no control has the focus.
|
||
|
|
*/
|
||
|
|
protected Control getFocusControl() {
|
||
|
|
return getSwtControl().isFocusControl() ? getSwtControl() : null;
|
||
|
|
}//getFocusControl()//
|
||
|
|
/* (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#internalViewInitialize()
|
||
|
|
*/
|
||
|
|
protected void internalViewInitialize() {
|
||
|
|
if(keyBindings != null && keyBindings.getSize() > 0) {
|
||
|
|
getSwtControl().addKeyListener(this);
|
||
|
|
}//if//
|
||
|
|
|
||
|
|
if(useCustomBackground) {
|
||
|
|
registerCustomBackgroundRenderer();
|
||
|
|
}//if//
|
||
|
|
|
||
|
|
super.internalViewInitialize();
|
||
|
|
}//internalViewInitialize()//
|
||
|
|
/* (non-Javadoc)
|
||
|
|
* @see com.foundation.tcv.swt.client.AbstractComponent#internalViewRelease()
|
||
|
|
*/
|
||
|
|
protected void internalViewRelease() {
|
||
|
|
if(getContainer() != null) {
|
||
|
|
getContainer().getComponents().remove(this);
|
||
|
|
}//if//
|
||
|
|
|
||
|
|
toolTipTextHolder.release();
|
||
|
|
foregroundColorHolder.release();
|
||
|
|
backgroundColorHolder.release();
|
||
|
|
fontHolder.release();
|
||
|
|
isVisibleHolder.release();
|
||
|
|
isEnabledHolder.release();
|
||
|
|
containerImageHolder.release();
|
||
|
|
containerTitleHolder.release();
|
||
|
|
backgroundImageHolder.release();
|
||
|
|
|
||
|
|
if(getCurrentBackgroundImage() != null) {
|
||
|
|
destroyImage(getCurrentBackgroundImage());
|
||
|
|
setCurrentBackgroundImage(null);
|
||
|
|
}//if//
|
||
|
|
|
||
|
|
if(getCurrentBackgroundGradientImage() != null) {
|
||
|
|
getCurrentBackgroundGradientImage().dispose();
|
||
|
|
setCurrentBackgroundGradientImage(null);
|
||
|
|
}//if//
|
||
|
|
|
||
|
|
if(getCurrentForegroundColor() != null) {
|
||
|
|
destroyColor(getCurrentForegroundColor());
|
||
|
|
setCurrentForegroundColor(null);
|
||
|
|
}//if//
|
||
|
|
|
||
|
|
if(getCurrentBackgroundColor() != null) {
|
||
|
|
destroyColor(getCurrentBackgroundColor());
|
||
|
|
setCurrentBackgroundColor(null);
|
||
|
|
}//if//
|
||
|
|
|
||
|
|
if(getCurrentFont() != null) {
|
||
|
|
destroyFont(getCurrentFont());
|
||
|
|
setCurrentFont(null);
|
||
|
|
}//if//
|
||
|
|
|
||
|
|
if(swtContainerImage != null) {
|
||
|
|
destroyImage(swtContainerImage);
|
||
|
|
swtContainerImage = null;
|
||
|
|
}//if//
|
||
|
|
|
||
|
|
super.internalViewRelease();
|
||
|
|
}//internalViewRelease()//
|
||
|
|
/* (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#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) {
|
||
|
|
String value = newValue != null ? newValue.toString() : null;
|
||
|
|
|
||
|
|
setToolTipText(value);
|
||
|
|
}//if//
|
||
|
|
else if(resourceHolder == containerTitleHolder) {
|
||
|
|
IIterator listeners = getListeners(IComponentListener.class);
|
||
|
|
|
||
|
|
//Notify all the listeners.//
|
||
|
|
while(listeners.hasNext()) {
|
||
|
|
((IComponentListener) listeners.next()).titleChanged(this, (String) newValue);
|
||
|
|
}//while//
|
||
|
|
}//else if//
|
||
|
|
else if(resourceHolder == containerImageHolder) {
|
||
|
|
IIterator listeners = getListeners(IComponentListener.class);
|
||
|
|
|
||
|
|
destroyImage(swtContainerImage);
|
||
|
|
swtContainerImage = createImage((JefImage) containerImageHolder.getValue());
|
||
|
|
|
||
|
|
//Notify all the listeners.//
|
||
|
|
while(listeners.hasNext()) {
|
||
|
|
((IComponentListener) listeners.next()).imageChanged(this, swtContainerImage);
|
||
|
|
}//while//
|
||
|
|
}//else if//
|
||
|
|
else if(resourceHolder == backgroundColorHolder) {
|
||
|
|
internalSetBackgroundColor(newValue instanceof JefColor ? new JefGradient((JefColor) newValue, null, JefGradient.DIAGONAL) : (JefGradient) newValue);
|
||
|
|
}//else if//
|
||
|
|
else if(resourceHolder == foregroundColorHolder) {
|
||
|
|
internalSetForegroundColor((JefColor) newValue);
|
||
|
|
}//else if//
|
||
|
|
else if(resourceHolder == fontHolder) {
|
||
|
|
internalSetFont(newValue == null || newValue instanceof JefFont[] ? (JefFont[]) newValue : new JefFont[] {(JefFont) newValue});
|
||
|
|
resize();
|
||
|
|
}//else if//
|
||
|
|
else if(resourceHolder == isVisibleHolder) {
|
||
|
|
if(!getSwtControl().isDisposed()) {
|
||
|
|
getSwtControl().setVisible(((Boolean) newValue).booleanValue());
|
||
|
|
|
||
|
|
//Never resize shells when changing visibility since nothing about the size should have changed from when the shell was first created.//
|
||
|
|
if(!(getSwtControl() instanceof Shell)) {
|
||
|
|
resize();
|
||
|
|
}//if//
|
||
|
|
}//if//
|
||
|
|
}//else if//
|
||
|
|
else if(resourceHolder == isEnabledHolder) {
|
||
|
|
internalSetEnabledState(((Boolean) newValue).booleanValue(), true);
|
||
|
|
|
||
|
|
//Never resize shells when changing visibility since nothing about the size should have changed from when the shell was first created.//
|
||
|
|
if(!(getSwtControl() instanceof Shell)) {
|
||
|
|
resize();
|
||
|
|
}//if//
|
||
|
|
}//else if//
|
||
|
|
else if(resourceHolder == backgroundImageHolder) {
|
||
|
|
internalSetBackgroundImage((JefImage) backgroundImageHolder.getValue());
|
||
|
|
}//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: {
|
||
|
|
boolean isVisible = data != null && data instanceof Boolean ? ((Boolean) data).booleanValue() : false;
|
||
|
|
|
||
|
|
if(getSwtControl().getVisible() != isVisible) {
|
||
|
|
getSwtControl().setVisible(isVisible);
|
||
|
|
|
||
|
|
//Never resize shells when changing visibility since nothing about the size should have changed from when the shell was first created.//
|
||
|
|
if(!(getSwtControl() instanceof Shell)) {
|
||
|
|
resize();
|
||
|
|
}//if//
|
||
|
|
}//if//
|
||
|
|
break;
|
||
|
|
}//case//
|
||
|
|
case LINK_TARGET_IS_ENABLED: {
|
||
|
|
internalSetEnabledState(data != null && data instanceof Boolean ? ((Boolean) data).booleanValue() : false, true);
|
||
|
|
break;
|
||
|
|
}//case//
|
||
|
|
case LINK_TARGET_GAIN_FOCUS: {
|
||
|
|
getSwtControl().setFocus();
|
||
|
|
break;
|
||
|
|
}//case//
|
||
|
|
case LINK_TARGET_TOOL_TIP_TEXT: {
|
||
|
|
getSwtControl().setToolTipText(data instanceof String ? (String) data : "");
|
||
|
|
break;
|
||
|
|
}//case//
|
||
|
|
case LINK_TARGET_BACKGROUND_COLOR: {
|
||
|
|
internalSetBackgroundColor(data instanceof JefGradient ? (JefGradient) data : data instanceof JefColor ? new JefGradient((JefColor) data) : null);
|
||
|
|
break;
|
||
|
|
}//case//
|
||
|
|
case LINK_TARGET_FOREGROUND_COLOR: {
|
||
|
|
internalSetForegroundColor(data instanceof JefColor ? (JefColor) data : null);
|
||
|
|
break;
|
||
|
|
}//case//
|
||
|
|
case LINK_TARGET_FONT: {
|
||
|
|
internalSetFont(data instanceof JefFont ? new JefFont[] {(JefFont) data} : data instanceof JefFont[] ? (JefFont[]) data : null);
|
||
|
|
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_GET_BOUNDS: {
|
||
|
|
retVal = getSwtControl().getBounds();
|
||
|
|
break;
|
||
|
|
}//case//
|
||
|
|
case MESSAGE_GET_LOCATION: {
|
||
|
|
retVal = getSwtControl().getLocation();
|
||
|
|
break;
|
||
|
|
}//case//
|
||
|
|
case MESSAGE_GET_SIZE: {
|
||
|
|
retVal = getSwtControl().getSize();
|
||
|
|
break;
|
||
|
|
}//case//
|
||
|
|
case MESSAGE_GET_IS_FOCUS_CONTROL: {
|
||
|
|
retVal = getSwtControl().isFocusControl() ? Boolean.TRUE : Boolean.FALSE;
|
||
|
|
break;
|
||
|
|
}//case//
|
||
|
|
case MESSAGE_SET_BOUNDS: {
|
||
|
|
getSwtControl().setBounds(((int[]) viewMessage.getMessageData())[0], ((int[]) viewMessage.getMessageData())[1], ((int[]) viewMessage.getMessageData())[2], ((int[]) viewMessage.getMessageData())[3]);
|
||
|
|
break;
|
||
|
|
}//case//
|
||
|
|
case MESSAGE_SET_LOCATION: {
|
||
|
|
getSwtControl().setLocation(((int[]) viewMessage.getMessageData())[0], ((int[]) viewMessage.getMessageData())[1]);
|
||
|
|
break;
|
||
|
|
}//case//
|
||
|
|
case MESSAGE_SET_SIZE: {
|
||
|
|
hasSpecificSize = true;
|
||
|
|
getSwtControl().setSize(((int[]) viewMessage.getMessageData())[0], ((int[]) viewMessage.getMessageData())[1]);
|
||
|
|
break;
|
||
|
|
}//case//
|
||
|
|
case MESSAGE_SET_FOCUS: {
|
||
|
|
getSwtControl().setFocus();
|
||
|
|
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_LAYOUT_DATA: {
|
||
|
|
getSwtControl().setLayoutData(((LayoutData) viewMessage.getMessageData()).createSwtLayoutData(this));
|
||
|
|
resize();
|
||
|
|
break;
|
||
|
|
}//case//
|
||
|
|
case MESSAGE_SET_TOOL_TIP_TEXT: {
|
||
|
|
toolTipTextHolder.setValue(viewMessage.getMessageData());
|
||
|
|
break;
|
||
|
|
}//case//
|
||
|
|
case MESSAGE_SET_BACKGROUND_COLOR: {
|
||
|
|
backgroundColorHolder.setValue(viewMessage.getMessageData());
|
||
|
|
break;
|
||
|
|
}//case//
|
||
|
|
case MESSAGE_SET_FOREGROUND_COLOR: {
|
||
|
|
foregroundColorHolder.setValue(viewMessage.getMessageData());
|
||
|
|
break;
|
||
|
|
}//case//
|
||
|
|
case MESSAGE_SET_FONTS: {
|
||
|
|
fontHolder.setValue(viewMessage.getMessageData());
|
||
|
|
break;
|
||
|
|
}//case//
|
||
|
|
case MESSAGE_PACK: {
|
||
|
|
if(!isSuspendingLayouts()) {
|
||
|
|
if(viewMessage.getMessageData() instanceof Boolean) {
|
||
|
|
getSwtControl().pack(((Boolean) viewMessage.getMessageData()).booleanValue());
|
||
|
|
}//if//
|
||
|
|
else {
|
||
|
|
getSwtControl().pack();
|
||
|
|
}//else//
|
||
|
|
}//if//
|
||
|
|
break;
|
||
|
|
}//case//
|
||
|
|
case MESSAGE_SET_DECIMAL_SCALE: {
|
||
|
|
setDecimalScale((Integer) viewMessage.getMessageData());
|
||
|
|
break;
|
||
|
|
}//case//
|
||
|
|
case MESSAGE_SET_CONTAINER_TITLE: {
|
||
|
|
containerTitleHolder.setValue(viewMessage.getMessageData());
|
||
|
|
break;
|
||
|
|
}//case//
|
||
|
|
case MESSAGE_SET_CONTAINER_IMAGE: {
|
||
|
|
containerImageHolder.setValue(viewMessage.getMessageData());
|
||
|
|
break;
|
||
|
|
}//case//
|
||
|
|
case MESSAGE_ADD_KEY_BINDING: {
|
||
|
|
if(keyBindings == null) {
|
||
|
|
keyBindings = new LiteList(10, 40);
|
||
|
|
}//if//
|
||
|
|
|
||
|
|
keyBindings.add((KeyBindingData) viewMessage.getMessageData());
|
||
|
|
|
||
|
|
if(isInitialized()) {
|
||
|
|
if(keyBindings.getSize() == 1) {
|
||
|
|
getSwtControl().addKeyListener(this);
|
||
|
|
}//if//
|
||
|
|
}//if//
|
||
|
|
break;
|
||
|
|
}//case//
|
||
|
|
case MESSAGE_SET_BACKGROUND_IMAGE: {
|
||
|
|
backgroundImageHolder.setValue(viewMessage.getMessageData());
|
||
|
|
break;
|
||
|
|
}//case//
|
||
|
|
case MESSAGE_SET_CHANGE_IMAGE: {
|
||
|
|
changeImage = viewMessage.getMessageData();
|
||
|
|
break;
|
||
|
|
}//case//
|
||
|
|
case MESSAGE_SET_CHANGE_TEXT: {
|
||
|
|
changeText = viewMessage.getMessageData();
|
||
|
|
break;
|
||
|
|
}//case//
|
||
|
|
case MESSAGE_SET_UPDATE_IMAGE: {
|
||
|
|
updateImage = viewMessage.getMessageData();
|
||
|
|
break;
|
||
|
|
}//case//
|
||
|
|
case MESSAGE_SET_UPDATE_TEXT: {
|
||
|
|
updateText = viewMessage.getMessageData();
|
||
|
|
break;
|
||
|
|
}//case//
|
||
|
|
case MESSAGE_SET_UPDATE_TIMEOUT: {
|
||
|
|
updateTimeout = (Integer) viewMessage.getMessageData();
|
||
|
|
break;
|
||
|
|
}//case//
|
||
|
|
case MESSAGE_DISPLAY_UPDATE_CONTROL_DECORATION: {
|
||
|
|
//Notify the user that the value has changed from the model.//
|
||
|
|
displayUpdateControlDecoration();
|
||
|
|
break;
|
||
|
|
}//case//
|
||
|
|
case MESSAGE_SET_NAME: {
|
||
|
|
this.name = (String) viewMessage.getMessageData();
|
||
|
|
break;
|
||
|
|
}//case//
|
||
|
|
case MESSAGE_USE_CUSTOM_BACKGROUND: {
|
||
|
|
useCustomBackground = true;
|
||
|
|
break;
|
||
|
|
}//case//
|
||
|
|
default: {
|
||
|
|
retVal = super.internalProcessMessage(viewMessage);
|
||
|
|
}//case//
|
||
|
|
}//switch//
|
||
|
|
|
||
|
|
return retVal;
|
||
|
|
}//internalProcessMessage()//
|
||
|
|
/**
|
||
|
|
* Updates the background image for the control.
|
||
|
|
* The subclass can override this method if there is more than one potential source for the background image.
|
||
|
|
*/
|
||
|
|
protected void controlUpdateBackgroundImage() {
|
||
|
|
if(getCurrentBackgroundImage() != null) {
|
||
|
|
getSwtControl().setBackgroundImage(getCurrentBackgroundImage());
|
||
|
|
}//if//
|
||
|
|
else {
|
||
|
|
getSwtControl().setBackgroundImage(getCurrentBackgroundGradientImage());
|
||
|
|
}//else//
|
||
|
|
}//controlUpdateBackgroundImage()//
|
||
|
|
/**
|
||
|
|
* Updates the background color for the control.
|
||
|
|
* The subclass can override this method if there is more than one potential source for the background color.
|
||
|
|
*/
|
||
|
|
protected void controlUpdateBackgroundColor() {
|
||
|
|
getSwtControl().setBackground(getCurrentBackgroundColor());
|
||
|
|
}//controlUpdateBackgroundColor()//
|
||
|
|
/**
|
||
|
|
* Updates the foreground color for the control.
|
||
|
|
* The subclass can override this method if there is more than one potential source for the foreground color.
|
||
|
|
*/
|
||
|
|
protected void controlUpdateForegroundColor() {
|
||
|
|
getSwtControl().setForeground(getCurrentForegroundColor());
|
||
|
|
}//controlUpdateForegroundColor()//
|
||
|
|
/**
|
||
|
|
* Updates the font for the control.
|
||
|
|
* The subclass can override this method if there is more than one potential source for the font.
|
||
|
|
*/
|
||
|
|
protected void controlUpdateFont() {
|
||
|
|
getSwtControl().setFont(getCurrentFont());
|
||
|
|
}//controlUpdateFont()//
|
||
|
|
/**
|
||
|
|
* Sets the background image using the gradient data.
|
||
|
|
* Note that any previous background image will be disposed.
|
||
|
|
* <p>Warning: Don't call this method if there is a background image set since the gradient shouldn't over write it and won't properly dispose of the resources.</p>
|
||
|
|
* @param gradient The gradient to be used.
|
||
|
|
*/
|
||
|
|
protected void internalSetBackgroundImage(JefGradient gradient) {
|
||
|
|
Image image = null;
|
||
|
|
|
||
|
|
//Dispose of the old gradient background image.//
|
||
|
|
if(getCurrentBackgroundGradientImage() != null) {
|
||
|
|
getCurrentBackgroundGradientImage().dispose();
|
||
|
|
}//if//
|
||
|
|
|
||
|
|
setCurrentBackgroundColor(gradient != null ? createColor(gradient.getStartColor()) : null);
|
||
|
|
|
||
|
|
if(gradient != null) {
|
||
|
|
Rectangle clientArea = getSwtControl() instanceof Composite ? ((Composite) getSwtControl()).getClientArea() : getSwtControl().getBounds();
|
||
|
|
|
||
|
|
if(clientArea.width != 0 && clientArea.height != 0) {
|
||
|
|
Display display = getSwtControl().getDisplay();
|
||
|
|
Color c1 = createColor(gradient.getStartColor());
|
||
|
|
Color c2 = createColor(gradient.getEndColor());
|
||
|
|
Pattern pattern = new Pattern(display, (gradient.getDirection() == JefGradient.REVERSE_DIAGONAL ? clientArea.width : 0), 0, (gradient.getDirection() == JefGradient.VERTICAL ? 1 : gradient.getDirection() == JefGradient.REVERSE_DIAGONAL ? 0 : clientArea.width), (gradient.getDirection() == JefGradient.HORIZONTAL ? 1 : clientArea.height), c1, gradient.getStartColor().getAlpha(), c2, gradient.getEndColor().getAlpha());
|
||
|
|
GC gc;
|
||
|
|
|
||
|
|
image = new Image(display, Math.max(1, clientArea.width), Math.max(1, clientArea.height));
|
||
|
|
gc = new GC(image);
|
||
|
|
|
||
|
|
//Force the x/y values to zero since getBounds uses them to provide the upper left point of the control.//
|
||
|
|
clientArea.x = 0;
|
||
|
|
clientArea.y = 0;
|
||
|
|
clientArea.width = Math.max(1, clientArea.width);
|
||
|
|
clientArea.height = Math.max(1, clientArea.height);
|
||
|
|
gc.setBackgroundPattern(pattern);
|
||
|
|
gc.fillRectangle(clientArea);
|
||
|
|
|
||
|
|
gc.dispose();
|
||
|
|
destroyColor(c1);
|
||
|
|
destroyColor(c2);
|
||
|
|
pattern.dispose();
|
||
|
|
}//if//
|
||
|
|
}//if//
|
||
|
|
|
||
|
|
setCurrentBackgroundGradient(gradient);
|
||
|
|
setCurrentBackgroundGradientImage(image);
|
||
|
|
controlUpdateBackgroundColor();
|
||
|
|
controlUpdateBackgroundImage();
|
||
|
|
}//controlSetBackgroundImage()//
|
||
|
|
/**
|
||
|
|
* Sets the control's background image.
|
||
|
|
* @param image The image to use for the background.
|
||
|
|
*/
|
||
|
|
protected void internalSetBackgroundImage(JefImage image) {
|
||
|
|
if(getCurrentBackgroundImage() != null) {
|
||
|
|
destroyImage(getCurrentBackgroundImage());
|
||
|
|
}//if//
|
||
|
|
|
||
|
|
setCurrentBackgroundImage(createImage(image));
|
||
|
|
controlUpdateBackgroundImage();
|
||
|
|
}//internalSetBackgroundImage()//
|
||
|
|
/**
|
||
|
|
* Sets the control's background color.
|
||
|
|
* @param color The background color.
|
||
|
|
*/
|
||
|
|
protected void internalSetBackgroundColor(JefGradient color) {
|
||
|
|
if(useCustomBackground) {
|
||
|
|
setCurrentBackgroundGradient(color);
|
||
|
|
}//if//
|
||
|
|
else if((color == null) || (color != null && color.getEndColor() == null)) {
|
||
|
|
//Dispose of the old background color.//
|
||
|
|
if(getCurrentBackgroundColor() != null) {
|
||
|
|
destroyColor(getCurrentBackgroundColor());
|
||
|
|
}//if//
|
||
|
|
|
||
|
|
//Dispose of the old background gradient since you can't have both a color and a gradient.//
|
||
|
|
if(getCurrentBackgroundGradientImage() != null) {
|
||
|
|
getCurrentBackgroundGradientImage().dispose();
|
||
|
|
setCurrentBackgroundGradientImage(null);
|
||
|
|
controlUpdateBackgroundImage();
|
||
|
|
unregisterBackgroundImageResizeListener();
|
||
|
|
}//if//
|
||
|
|
|
||
|
|
setCurrentBackgroundColor(createColor(color == null ? null : color.getStartColor()));
|
||
|
|
controlUpdateBackgroundColor();
|
||
|
|
}//else if//
|
||
|
|
else {
|
||
|
|
//Dispose of the old background color since you can't have both a color and a gradient.//
|
||
|
|
if(getCurrentBackgroundColor() != null) {
|
||
|
|
destroyColor(getCurrentBackgroundColor());
|
||
|
|
}//if//
|
||
|
|
|
||
|
|
setCurrentBackgroundGradient(color);
|
||
|
|
registerBackgroundImageResizeListener();
|
||
|
|
internalSetBackgroundImage(color);
|
||
|
|
}//else//
|
||
|
|
}//controlSetBackgroundColor()//
|
||
|
|
/**
|
||
|
|
* Sets up the listener to render a custom background.
|
||
|
|
*/
|
||
|
|
protected void registerCustomBackgroundRenderer() {
|
||
|
|
if(!getSwtControl().isDisposed()) {
|
||
|
|
getSwtControl().addListener(SWT.Paint, new Listener() {
|
||
|
|
private OverlayBufferSet overlayBufferSet = new OverlayBufferSet();
|
||
|
|
|
||
|
|
public void handleEvent(Event event) {
|
||
|
|
renderCustomBackground(event.gc, overlayBufferSet);
|
||
|
|
}//handleEvent()//
|
||
|
|
});
|
||
|
|
}//if//
|
||
|
|
}//registerCustomBackgroundRenderer()//
|
||
|
|
/**
|
||
|
|
* Renders a custom overlay background.
|
||
|
|
*/
|
||
|
|
protected void renderCustomBackground(GC gc, OverlayBufferSet overlayBufferSet) {
|
||
|
|
JefGradient gradient = getCurrentBackgroundGradient();
|
||
|
|
|
||
|
|
if(gradient != null && gradient.getStartColor() != null) {
|
||
|
|
Rectangle bounds = getSwtControl().getBounds();
|
||
|
|
|
||
|
|
if(overlayBufferSet.originalImage == null) {
|
||
|
|
overlayBufferSet.originalImage = new Image(getDisplay(), bounds.width, bounds.height);
|
||
|
|
gc.copyArea(overlayBufferSet.originalImage, 0, 0);
|
||
|
|
}//if//
|
||
|
|
|
||
|
|
if(overlayBufferSet.bufferImage == null || bounds.width != overlayBufferSet.bufferImage.getImageData().width || bounds.height != overlayBufferSet.bufferImage.getImageData().height) {
|
||
|
|
JefColor jefColor = gradient.getStartColor();
|
||
|
|
Color color = createColor(jefColor);
|
||
|
|
GC bufferGc = null;
|
||
|
|
|
||
|
|
if(overlayBufferSet.bufferImage != null) {
|
||
|
|
overlayBufferSet.bufferImage.dispose();
|
||
|
|
}//if//
|
||
|
|
|
||
|
|
overlayBufferSet.bufferImage = new Image(getDisplay(), bounds.width, bounds.height);
|
||
|
|
bufferGc = new GC(overlayBufferSet.bufferImage);
|
||
|
|
bufferGc.setAdvanced(true);
|
||
|
|
bufferGc.drawImage(overlayBufferSet.originalImage, 0, 0);
|
||
|
|
bufferGc.setAlpha(jefColor.getAlpha());
|
||
|
|
bufferGc.setBackground(color);
|
||
|
|
bufferGc.fillRectangle(bounds);
|
||
|
|
bufferGc.dispose();
|
||
|
|
destroyColor(color);
|
||
|
|
}//if//
|
||
|
|
|
||
|
|
gc.drawImage(overlayBufferSet.bufferImage, 0, 0);
|
||
|
|
}//if//
|
||
|
|
}//renderCustomBackground()//
|
||
|
|
/**
|
||
|
|
* Unregisters the resize listener that updates the background image.
|
||
|
|
*/
|
||
|
|
protected void unregisterBackgroundImageResizeListener() {
|
||
|
|
if(!getSwtControl().isDisposed() && backgroundImageResizeListener != null) {
|
||
|
|
getSwtControl().removeListener(SWT.Resize, backgroundImageResizeListener);
|
||
|
|
backgroundImageResizeListener = null;
|
||
|
|
}//if//
|
||
|
|
}//unregisterBackgroundImageResizeListener()//
|
||
|
|
/**
|
||
|
|
* Registers the resize listener that updates the background image.
|
||
|
|
*/
|
||
|
|
protected void registerBackgroundImageResizeListener() {
|
||
|
|
if(!getSwtControl().isDisposed() && backgroundImageResizeListener == null) {
|
||
|
|
getSwtControl().addListener(SWT.Resize, backgroundImageResizeListener = new Listener() {
|
||
|
|
public void handleEvent(Event event) {
|
||
|
|
internalSetBackgroundImage(getCurrentBackgroundGradient());
|
||
|
|
}//handleEvent()//
|
||
|
|
});
|
||
|
|
}//if//
|
||
|
|
}//registerBackgroundImageResizeListener()//
|
||
|
|
/**
|
||
|
|
* Sets the control's foreground color.
|
||
|
|
* @param color The foreground color.
|
||
|
|
*/
|
||
|
|
protected void internalSetForegroundColor(JefColor color) {
|
||
|
|
if(currentForegroundColor != null) {
|
||
|
|
destroyColor(currentForegroundColor);
|
||
|
|
}//if//
|
||
|
|
|
||
|
|
setCurrentForegroundColor(createColor(color));
|
||
|
|
controlUpdateForegroundColor();
|
||
|
|
}//controlSetForegroundColor()//
|
||
|
|
/**
|
||
|
|
* Sets the control's font.
|
||
|
|
* @param color The font.
|
||
|
|
*/
|
||
|
|
protected void internalSetFont(JefFont[] font) {
|
||
|
|
if(currentFont != null) {
|
||
|
|
destroyFont(currentFont);
|
||
|
|
}//if//
|
||
|
|
|
||
|
|
setCurrentFont(createFont(font));
|
||
|
|
controlUpdateFont();
|
||
|
|
}//controlSetFont()//
|
||
|
|
/**
|
||
|
|
* Gets the current background image used by the component.
|
||
|
|
* @return The currently used background image, or null if none is provided.
|
||
|
|
*/
|
||
|
|
protected Image getCurrentBackgroundImage() {
|
||
|
|
return currentBackgroundImage;
|
||
|
|
}//getCurrentBackgroundImage()//
|
||
|
|
/**
|
||
|
|
* Sets the current background image used by the component.
|
||
|
|
* @param currentBackgroundImage The currently used background image, or null if none is provided.
|
||
|
|
*/
|
||
|
|
protected void setCurrentBackgroundImage(Image currentBackgroundImage) {
|
||
|
|
this.currentBackgroundImage = currentBackgroundImage;
|
||
|
|
}//setCurrentBackgroundImage()//
|
||
|
|
/**
|
||
|
|
* Gets the current background gradient used by the component.
|
||
|
|
* @return The currently used background gradient, or null if none is provided.
|
||
|
|
*/
|
||
|
|
protected JefGradient getCurrentBackgroundGradient() {
|
||
|
|
return currentBackgroundGradient;
|
||
|
|
}//getCurrentBackgroundGradient()//
|
||
|
|
/**
|
||
|
|
* Sets the current background gradient used by the component.
|
||
|
|
* @param currentBackgroundGradient The currently used background gradient, or null if none is provided.
|
||
|
|
*/
|
||
|
|
protected void setCurrentBackgroundGradient(JefGradient currentBackgroundGradient) {
|
||
|
|
this.currentBackgroundGradient = currentBackgroundGradient;
|
||
|
|
}//setCurrentBackgroundGradient()//
|
||
|
|
/**
|
||
|
|
* Gets the current background gradient image used by the component.
|
||
|
|
* @return The currently used background gradient image, or null if none is provided.
|
||
|
|
*/
|
||
|
|
protected Image getCurrentBackgroundGradientImage() {
|
||
|
|
return currentBackgroundGradientImage;
|
||
|
|
}//getCurrentBackgroundGradientImage()//
|
||
|
|
/**
|
||
|
|
* Sets the current background gradient image used by the component.
|
||
|
|
* @param currentBackgroundGradientImage The currently used background gradient image, or null if none is provided.
|
||
|
|
*/
|
||
|
|
protected void setCurrentBackgroundGradientImage(Image currentBackgroundGradientImage) {
|
||
|
|
this.currentBackgroundGradientImage = currentBackgroundGradientImage;
|
||
|
|
}//setCurrentBackgroundGradientImage()//
|
||
|
|
/**
|
||
|
|
* 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()//
|
||
|
|
/**
|
||
|
|
* 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.
|
||
|
|
* @param isLocal Whether this change in state is locally generated, or from the parent container.
|
||
|
|
*/
|
||
|
|
protected void internalSetEnabledState(boolean isEnabled, boolean isLocal) {
|
||
|
|
//Some components may not have controls, such as value holders.//
|
||
|
|
if(getSwtControl() != null && !getSwtControl().isDisposed()) {
|
||
|
|
if(isLocal) {
|
||
|
|
isLocallyEnabled = isEnabled;
|
||
|
|
}//if//
|
||
|
|
else {
|
||
|
|
isParentEnabled = isEnabled;
|
||
|
|
}//else//
|
||
|
|
|
||
|
|
getSwtControl().setEnabled(isLocallyEnabled && isParentEnabled);
|
||
|
|
}//if//
|
||
|
|
}//internalSetEnabledState()//
|
||
|
|
/**
|
||
|
|
* Gets the container's title.
|
||
|
|
* <p>Note: Also see IComponentListener and addListener(..) to receive notification when the title changes.</p>
|
||
|
|
* @return The container's title to be used when needed (example: a tab in a tab panel, or title bar of the window).
|
||
|
|
*/
|
||
|
|
public String getContainerTitle() {
|
||
|
|
return (String) this.containerTitleHolder.getValue();
|
||
|
|
}//setContainerTitle()//
|
||
|
|
/**
|
||
|
|
* Gets the container's image.
|
||
|
|
* <p>Note: Also see IComponentListener and addListener(..) to receive notification when the title changes.</p>
|
||
|
|
* @return The image data that will be displayed by the container when an image is needed to represent it (example: a tab in a tab panel).
|
||
|
|
*/
|
||
|
|
public Image getContainerImage() {
|
||
|
|
return swtContainerImage;
|
||
|
|
}//getContainerImage()//
|
||
|
|
/**
|
||
|
|
* 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, getSwtControl().getToolTipText())) {
|
||
|
|
IIterator listeners = getListeners(IComponentListener.class);
|
||
|
|
|
||
|
|
//Notify all the listeners.//
|
||
|
|
while(listeners.hasNext()) {
|
||
|
|
((IComponentListener) listeners.next()).toolTipTextChanged(this, toolTipText);
|
||
|
|
}//while//
|
||
|
|
|
||
|
|
//Update the control.//
|
||
|
|
getSwtControl().setToolTipText(toolTipText);
|
||
|
|
}//if//
|
||
|
|
}//setToolTipText()//
|
||
|
|
/* (non-Javadoc)
|
||
|
|
* @see com.foundation.tcv.swt.IControlLocator#getControl(int)
|
||
|
|
*/
|
||
|
|
public Control getControl(int componentNumber) {
|
||
|
|
return ((Component) getSessionViewController().getComponent(componentNumber)).getSwtControl();
|
||
|
|
}//getControl()//
|
||
|
|
/* (non-Javadoc)
|
||
|
|
* @see com.foundation.tcv.swt.client.AbstractComponent#internalInitializationComplete()
|
||
|
|
*/
|
||
|
|
protected void internalInitializationComplete() {
|
||
|
|
/* This doesn't work at this time because it doesn't make the startup of complex views faster and doesn't fix odd rendering in the table/tree cell components.
|
||
|
|
if(getSwtControl() instanceof Composite) {
|
||
|
|
if(!hasSpecificSize) {
|
||
|
|
getSwtControl().pack(true);
|
||
|
|
}//if//
|
||
|
|
|
||
|
|
((Composite) getSwtControl()).layout();
|
||
|
|
}//if//
|
||
|
|
else {
|
||
|
|
if(!hasSpecificSize) {
|
||
|
|
getSwtControl().pack(true);
|
||
|
|
}//if//
|
||
|
|
}//else//
|
||
|
|
|
||
|
|
isInitializationComplete = true;
|
||
|
|
*/
|
||
|
|
}//internalInitializationComplete()//
|
||
|
|
/**
|
||
|
|
* Forces the component to resize and requests that the window layout.
|
||
|
|
*/
|
||
|
|
public void resize() {
|
||
|
|
if(getSwtControl() != null && !getSwtControl().isDisposed()) {
|
||
|
|
flushLayoutCache();
|
||
|
|
}//if//
|
||
|
|
|
||
|
|
if(isInitialized() && !isSuspendingLayouts()) {
|
||
|
|
if(!hasSpecificSize) {
|
||
|
|
getSwtControl().pack(true);
|
||
|
|
}//if//
|
||
|
|
|
||
|
|
if(getSwtControl() instanceof Shell) {
|
||
|
|
((Shell) getSwtControl()).layout();
|
||
|
|
}//if//
|
||
|
|
else if(getSwtControl().getParent() != null) {
|
||
|
|
getSwtControl().getParent().layout();
|
||
|
|
}//else if//
|
||
|
|
|
||
|
|
//Allow the parents of this component to adjust to the children resizing.//
|
||
|
|
if(!hasSpecificSize && getContainer() != null) {
|
||
|
|
getContainer().postResize();
|
||
|
|
}//if//
|
||
|
|
}//if//
|
||
|
|
}//resize()//
|
||
|
|
/**
|
||
|
|
* Clears any cached data in the component's layout due to a change in the component's state that would invalidate any cached layout information.
|
||
|
|
*/
|
||
|
|
public void flushLayoutCache() {
|
||
|
|
Control control = getSwtControl();
|
||
|
|
|
||
|
|
if(control.getLayoutData() instanceof com.foundation.view.swt.layout.LayoutData) {
|
||
|
|
((com.foundation.view.swt.layout.LayoutData) control.getLayoutData()).flushCache();
|
||
|
|
}//if//
|
||
|
|
|
||
|
|
if(getContainer() != null) {
|
||
|
|
getContainer().flushLayoutCache();
|
||
|
|
}//if//
|
||
|
|
}//flushLayoutCache()//
|
||
|
|
/* (non-Javadoc)
|
||
|
|
* @see org.eclipse.swt.events.KeyListener#keyPressed(org.eclipse.swt.events.KeyEvent)
|
||
|
|
*/
|
||
|
|
public void keyPressed(KeyEvent event) {
|
||
|
|
int modifiers = SwtUtilities.convertKeyModifiers(event.stateMask);
|
||
|
|
int character = event.keyCode;
|
||
|
|
|
||
|
|
if(keyBindings != null) {
|
||
|
|
for(int index = 0; (event.doit) && (index < keyBindings.getSize()); index++) {
|
||
|
|
KeyBindingData keyBinding = (KeyBindingData) keyBindings.get(index);
|
||
|
|
|
||
|
|
if(keyBinding.getModifiers() == modifiers) {
|
||
|
|
if(keyBinding.getKeyCode() != null) {
|
||
|
|
if(keyBinding.getKeyCode().intValue() == character) {
|
||
|
|
sendRoundTripMessage(MESSAGE_INVOKE_KEY_BINDING, null, null, modifiers, character, null);
|
||
|
|
event.doit = false;
|
||
|
|
}//if//
|
||
|
|
}//if//
|
||
|
|
else {
|
||
|
|
//TODO: Can we detect a modifier key being pressed without a non-modifier key?
|
||
|
|
}//else//
|
||
|
|
}//if//
|
||
|
|
}//for//
|
||
|
|
}//if//
|
||
|
|
}//keyPressed()//
|
||
|
|
/* (non-Javadoc)
|
||
|
|
* @see org.eclipse.swt.events.KeyListener#keyReleased(org.eclipse.swt.events.KeyEvent)
|
||
|
|
*/
|
||
|
|
public void keyReleased(KeyEvent event) {
|
||
|
|
}//keyReleased()//
|
||
|
|
}//Component//
|