844 lines
32 KiB
Java
844 lines
32 KiB
Java
/*
|
|
* 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.view.swt;
|
|
|
|
import org.eclipse.swt.SWT;
|
|
import org.eclipse.swt.graphics.Image;
|
|
import org.eclipse.swt.widgets.TabItem;
|
|
import com.common.util.*;
|
|
import com.common.debug.*;
|
|
import com.foundation.controller.*;
|
|
import com.foundation.util.IInlineCollectionObservable;
|
|
import com.foundation.util.IInlineCollectionObserver;
|
|
import com.foundation.util.IInlineIndexedCollectionObservable;
|
|
import com.foundation.util.IInlineIndexedCollectionObserver;
|
|
import com.foundation.view.*;
|
|
import com.foundation.view.resource.AbstractResourceService;
|
|
import com.foundation.view.swt.util.SwtUtilities;
|
|
|
|
/*
|
|
* This tab panel allows for static pages and dynamic pages where dynamic pages are tied to the model which supplies the view controller's for each dynamic page.
|
|
* The panel was designed such that any ordering of static and dynamic pages can be given. The dynamic page is created by calling the addPages() method which allows associations to be added.
|
|
* The PagesHolder (returned by addPages()) then manages the page or collection of page view controllers.
|
|
* <p>TODO: Add some way of sending the selected page to the view controller, and some way for the view controller to programatically select a page.</p>
|
|
*/
|
|
public class TabPanel extends Container implements Component.IComponentListener {
|
|
public static final int STYLE_TOP = SWT.TOP;
|
|
public static final int STYLE_BOTTOM = SWT.BOTTOM;
|
|
|
|
/** A collection of Component and PagesHolder instances which define the tabs in this tab folder. */
|
|
private IList pages = new LiteList(10, 50);
|
|
/** A mapping of TabItem's indexed by the related component. */
|
|
private LiteHashMap tabItemsByComponentMap = new LiteHashMap(15);
|
|
/** A flag to suspend the customized behavior when adding a control. This lets the page holder add and remove tabs without the tab panel attempting to add and remove tabs also. */
|
|
private boolean suspendCustomComponentBehavior = false;
|
|
|
|
/**
|
|
* The public interface for interacting with the pages holder.
|
|
*/
|
|
public interface IPagesHolder {
|
|
/**
|
|
* Sets the association container used to access the tab pages.
|
|
* @param container The tab pages association metadata.
|
|
*/
|
|
public void setPagesAssociation(SingleAssociationContainer container);
|
|
}//IPagesHolder//
|
|
|
|
/**
|
|
* A place holder for zero or more pages which are set based on a resource association which can return a view controller or a list of view controllers, one for each page.
|
|
*/
|
|
private class PagesHolder implements IPagesHolder, ISingleResourceAssociationChangeListener, IInlineIndexedCollectionObserver, IInlineCollectionObserver, Component.IComponentListener {
|
|
/** Allows one association to return either a collection of controllers, or one controller which will be turned into a tab page. */
|
|
private SingleResourceAssociation pages = new SingleResourceAssociation(TabPanel.this, this, getViewContext(), SingleResourceAssociation.TYPE_OBJECT, false, null);
|
|
/** The PagesHolder or Component which the pages in this PagesHolder follow in the tab order. */
|
|
private Object followsComponent = null;
|
|
/** The previous collection of view controllers. */
|
|
private IList viewControllers = new LiteList(1, 15);
|
|
/** TabItem instances mapped by their corresponding view controllers. */
|
|
private LiteHashMap tabItemsByViewControllerMap = new LiteHashMap(15);
|
|
/** A two way (one to one) mapping between the Component instances and their ViewController instances. */
|
|
private LiteHashMap componentControllerMapping = new LiteHashMap(30);
|
|
/** Temporarily suspends processing of events fired by registered collections. */
|
|
private boolean suspendCollectionEvents = false;
|
|
|
|
public PagesHolder(Object followsComponent) {
|
|
this.followsComponent = followsComponent;
|
|
}//PagesHolder()//
|
|
/* (non-Javadoc)
|
|
* @see com.foundation.view.swt.TabPanel.IPagesHolder#setPagesAssociation(com.foundation.view.SingleAssociationContainer)
|
|
*/
|
|
public void setPagesAssociation(SingleAssociationContainer container) {
|
|
verifyThread();
|
|
this.pages.setAssociations(container);
|
|
}//setPagesAssociation()//
|
|
/**
|
|
* Initializes the pages.
|
|
*/
|
|
public void initialize() {
|
|
pages.initialize();
|
|
}//initialize()//
|
|
/**
|
|
* Releases the pages.
|
|
*/
|
|
public void release() {
|
|
IIterator iterator = new LiteList(viewControllers).iterator();
|
|
|
|
pages.release();
|
|
|
|
//Release the tab resources and cleanup the mappings and listeners.//
|
|
while(iterator.hasNext()) {
|
|
ViewController next = (ViewController) iterator.next();
|
|
|
|
internalRemoveTab(next);
|
|
next.close();
|
|
}//while//
|
|
|
|
componentControllerMapping.removeAll();
|
|
componentControllerMapping = null;
|
|
tabItemsByViewControllerMap.removeAll();
|
|
tabItemsByViewControllerMap = null;
|
|
viewControllers.removeAll();
|
|
viewControllers = null;
|
|
followsComponent = null;
|
|
pages = null;
|
|
}//release()//
|
|
/**
|
|
* Refreshes the pages.
|
|
*/
|
|
public void refresh() {
|
|
//Not necessary since it is handled by the Container base class.//
|
|
//for(int index = 0; index < viewControllers.getSize(); index++) {
|
|
// ((AbstractComponent) ((ViewController) viewControllers.get(index)).getView()).internalViewRefreshAll();
|
|
//}//for//
|
|
|
|
refreshPages();
|
|
}//initialize()//
|
|
/**
|
|
* Synchronizes the pages.
|
|
*/
|
|
public void synchronize() {
|
|
//Not necessary since it is handled by the Container base class.//
|
|
//for(int index = 0; index < viewControllers.getSize(); index++) {
|
|
// ((AbstractComponent) ((ViewController) viewControllers.get(index)).getView()).internalViewSynchronizeAll();
|
|
//}//for//
|
|
}//initialize()//
|
|
/**
|
|
* Gets the TabItem that the pages of this holder follow.
|
|
* @return The tab item that the tab items related to this holder follow in the tab item ordering.
|
|
*/
|
|
public TabItem getPreviousTabItem() {
|
|
TabItem result = null;
|
|
|
|
if(followsComponent instanceof PagesHolder) {
|
|
result = ((PagesHolder) followsComponent).getLastTabItem();
|
|
}//if//
|
|
else if(followsComponent instanceof Component) {
|
|
result = (TabItem) tabItemsByComponentMap.get(followsComponent);
|
|
}//else if//
|
|
|
|
return result;
|
|
}//getPreviousTabItem()//
|
|
/**
|
|
* Gets the last tab item for this holder.
|
|
* @return The last TabItem instance which can be used as the previous TabItem for the component that follows this holder. This will only be null if there are no pages in this holder and there are no pages in front of this holder.
|
|
*/
|
|
public TabItem getLastTabItem() {
|
|
TabItem result = null;
|
|
|
|
if(viewControllers.getSize() > 0) {
|
|
result = (TabItem) tabItemsByViewControllerMap.get(viewControllers.getLast());
|
|
}//if//
|
|
else {
|
|
result = getPreviousTabItem();
|
|
}//else//
|
|
|
|
return result;
|
|
}//getLastTabItem()//
|
|
/**
|
|
* Refreshes the pages represented by this holder.
|
|
*/
|
|
protected void refreshPages() {
|
|
Object oldValue = pages.getValue();
|
|
|
|
if(pages.refresh()) {
|
|
startChanges(0);
|
|
|
|
try {
|
|
Object newValue = pages.getValue();
|
|
TabItem previous = getPreviousTabItem();
|
|
int previousIndex = previous != null ? getSwtTabFolder().indexOf(previous) + 1 : 0;
|
|
|
|
//Remove listeners from the old value.//
|
|
if(oldValue instanceof IInlineIndexedCollectionObservable) {
|
|
((IInlineIndexedCollectionObservable) oldValue).removeCollectionObserver(this);
|
|
}//if//
|
|
else if(oldValue instanceof IInlineCollectionObservable) {
|
|
((IInlineCollectionObservable) oldValue).removeCollectionObserver(this);
|
|
}//else if//
|
|
|
|
//If the new value is a collection or object then add and remove pages as required, and add listeners as required.//
|
|
if(newValue instanceof ICollection) {
|
|
IIterator iterator = ((ICollection) newValue).iterator();
|
|
LiteList newViewControllers = new LiteList(((ICollection) newValue).getSize());
|
|
|
|
//Add tabs for all the view controllers.//
|
|
while(iterator.hasNext()) {
|
|
Object next = iterator.next();
|
|
|
|
//Ignore non-view controller objects.//
|
|
if(next instanceof ViewController) {
|
|
ViewController controller = (ViewController) next;
|
|
int index = viewControllers != null ? viewControllers.getIndexOf(controller) : -1;
|
|
|
|
if(index != -1) {
|
|
TabItem newTabItem = internalRecreateTab(controller, previousIndex);
|
|
|
|
viewControllers.remove(index);
|
|
|
|
//Note we don't just increment the index since they could get moved by the changes made by updating the tabs.//
|
|
if(newTabItem != null) {
|
|
previousIndex = getSwtTabFolder().indexOf(newTabItem) + 1;
|
|
}//if//
|
|
}//if//
|
|
else {
|
|
TabItem newTabItem = internalAddTab(controller, previousIndex);
|
|
|
|
//Note we don't just increment the index since they could get moved by the changes made by updating the tabs.//
|
|
if(newTabItem != null) {
|
|
previousIndex = getSwtTabFolder().indexOf(newTabItem) + 1;
|
|
}//if//
|
|
}//else//
|
|
|
|
newViewControllers.add(controller);
|
|
}//if//
|
|
else {
|
|
//Don't allow non-view controller objects since it will mess up the valuesSorted(..) method.//
|
|
throw new RuntimeException("Expecting a view controller.");
|
|
}//else//
|
|
}//while//
|
|
|
|
//Remove the previous view controller(s).//
|
|
removeOldPages(viewControllers);
|
|
//Add the controllers to the list of view controllers.//
|
|
viewControllers.addAll(newViewControllers);
|
|
//Prevent collection events from notifying us of existing items in the collection.//
|
|
suspendCollectionEvents = true;
|
|
|
|
//Add a listener to the collection so we get change events.//
|
|
if(newValue instanceof IInlineIndexedCollectionObservable) {
|
|
((IInlineIndexedCollectionObservable) newValue).addCollectionObserver(this);
|
|
}//if//
|
|
else if(newValue instanceof IInlineCollectionObservable) {
|
|
((IInlineCollectionObservable) newValue).addCollectionObserver(this);
|
|
}//else if//
|
|
|
|
//Re-enable the collection events.//
|
|
suspendCollectionEvents = false;
|
|
}//if//
|
|
else if(newValue instanceof ViewController) {
|
|
ViewController controller = (ViewController) newValue;
|
|
int index = viewControllers != null ? viewControllers.getIndexOf(controller) : -1;
|
|
|
|
if(index != -1) {
|
|
internalRecreateTab(controller, previousIndex);
|
|
viewControllers.remove(index);
|
|
}//if//
|
|
else {
|
|
internalAddTab(controller, previousIndex);
|
|
}//else//
|
|
|
|
//Remove the previous view controller(s).//
|
|
removeOldPages(viewControllers);
|
|
//Add the one controller to the list of view controllers.//
|
|
viewControllers.add(controller);
|
|
}//else if//
|
|
else {
|
|
removeOldPages(viewControllers);
|
|
}//else//
|
|
}//try//
|
|
finally {
|
|
stopChanges();
|
|
}//finally//
|
|
}//if//
|
|
}//refreshPages()//
|
|
/**
|
|
* Removes the old pages from the tab panel.
|
|
* @param viewControllers The collection of view controllers no longer in the tab panel.
|
|
* @param oldValue The previous value
|
|
*/
|
|
private void removeOldPages(IList viewControllers) {
|
|
while(viewControllers.getSize() > 0) {
|
|
ViewController controller = (ViewController) viewControllers.remove(viewControllers.getSize() - 1);
|
|
|
|
//Remove each controller's page and close the controller.//
|
|
internalRemoveTab(controller);
|
|
controller.close();
|
|
}//while//
|
|
}//removeOldPages()//
|
|
/**
|
|
* Adds a tab to the panel for the given view controller.
|
|
* @param viewController The view controller whose view component will be displayed in the tab.
|
|
* @param index The index of this tab item, which will be used to set the tab item ordering.
|
|
* @return The new tab item.
|
|
*/
|
|
protected TabItem internalAddTab(ViewController viewController, int index) {
|
|
TabItem tabItem = null;
|
|
|
|
suspendCustomComponentBehavior = true;
|
|
|
|
try {
|
|
if(viewController != null) {
|
|
Component component;
|
|
|
|
viewController.openPartial(TabPanel.this, getViewContext());
|
|
component = (Component) viewController.getView();
|
|
tabItem = new org.eclipse.swt.widgets.TabItem(getSwtTabFolder(), 0, index);
|
|
|
|
if(component instanceof Container) {
|
|
Image image = component.getContainerImage();
|
|
|
|
tabItem.setText(component.getContainerTitle() == null ? "" : component.getContainerTitle());
|
|
tabItem.setImage(image);
|
|
}//if//
|
|
else {
|
|
tabItem.setText("");
|
|
}//else//
|
|
|
|
tabItem.setToolTipText(component.getToolTipText());
|
|
tabItem.setControl(component.getSwtControl());
|
|
tabItem.setData(component);
|
|
component.registerListener(this);
|
|
tabItemsByViewControllerMap.put(viewController, tabItem);
|
|
componentControllerMapping.put(viewController, component);
|
|
componentControllerMapping.put(component, viewController);
|
|
}//if//
|
|
else {
|
|
Debug.log("Error: Invalid component. Unable to add the component as a tab in the tab panel.");
|
|
}//else//
|
|
}//try//
|
|
finally {
|
|
suspendCustomComponentBehavior = false;
|
|
}//finally//
|
|
|
|
return tabItem;
|
|
}//internalAddTab()//
|
|
/**
|
|
* Removes a tab from the panel for the given related view component.
|
|
* @param viewController The view controller whose view component's tab will be removed.
|
|
*/
|
|
protected void internalRemoveTab(ViewController viewController) {
|
|
suspendCustomComponentBehavior = true;
|
|
|
|
try {
|
|
TabItem tabItem = (TabItem) tabItemsByViewControllerMap.remove(viewController);
|
|
Component component = (Component) viewController.getView();
|
|
|
|
if(component == null) {
|
|
component = (Component) componentControllerMapping.get(viewController);
|
|
}//if//
|
|
|
|
//Unregister the component data listener.//
|
|
if(component != null) {
|
|
component.unregisterListener(this);
|
|
componentControllerMapping.remove(component);
|
|
}//if//
|
|
|
|
//Dispose of the old tab item.//
|
|
if(tabItem != null) {
|
|
//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//
|
|
|
|
componentControllerMapping.remove(viewController);
|
|
}//try//
|
|
finally {
|
|
suspendCustomComponentBehavior = false;
|
|
}//finally//
|
|
}//internalRemoveTab()//
|
|
/**
|
|
* Recreates the view controller's tab by removing the old tab and adding a new one at the given index.
|
|
* @param viewController The view controller whose view component's tab will be removed and re-added.
|
|
* @param index The index of the recreated tab item.
|
|
* @return The new tab item.
|
|
*/
|
|
protected TabItem internalRecreateTab(ViewController viewController, int index) {
|
|
TabItem oldTabItem = (TabItem) tabItemsByViewControllerMap.remove(viewController);
|
|
TabItem tabItem = null;
|
|
|
|
if((oldTabItem != null) && (viewController != null) && (((Component) viewController.getView()).getSwtControl() != null)) {
|
|
tabItem = new org.eclipse.swt.widgets.TabItem(getSwtTabFolder(), 0, index);
|
|
tabItem.setText(oldTabItem.getText());
|
|
tabItem.setImage(oldTabItem.getImage());
|
|
tabItem.setToolTipText(oldTabItem.getToolTipText());
|
|
tabItem.setControl(oldTabItem.getControl());
|
|
tabItem.setData(oldTabItem.getData());
|
|
//Replace the tab item in the mapping by view controller.//
|
|
tabItemsByViewControllerMap.put(viewController, tabItem);
|
|
}//if//
|
|
else {
|
|
Debug.log("Error: Invalid component. Unable to recreate the component as a tab in the tab panel.");
|
|
|
|
//Attempt to cleanup after the controller.//
|
|
if(oldTabItem != null) {
|
|
internalRemoveTab(viewController);
|
|
}//if//
|
|
}//else//
|
|
|
|
//Dispose of the old tab item.//
|
|
oldTabItem.dispose();
|
|
|
|
return tabItem;
|
|
}//internalRecreateTab()//
|
|
/* (non-Javadoc)
|
|
* @see com.foundation.view.ISingleResourceAssociationChangeListener#onValueChanged(com.foundation.view.ResourceAssociation, int)
|
|
*/
|
|
public void onValueChanged(ResourceAssociation resourceAssociation, int flags) {
|
|
if(resourceAssociation == pages) {
|
|
refreshPages();
|
|
}//if//
|
|
}//onValueChanged()//
|
|
/* (non-Javadoc)
|
|
* @see com.foundation.view.ISingleResourceAssociationChangeListener#onModelExternallyChanged(com.foundation.view.ResourceAssociation, boolean, java.lang.Object)
|
|
*/
|
|
public void onModelExternallyChanged(ResourceAssociation resourceAssociation, boolean isCleared, Object originalValue) {
|
|
}//onModelExternallyChanged()//
|
|
/* (non-Javadoc)
|
|
* @see com.foundation.view.ISingleResourceAssociationChangeListener#addMessageHold()
|
|
*/
|
|
public void addMessageHold() {
|
|
}//addMessageHold()//
|
|
/* (non-Javadoc)
|
|
* @see com.foundation.view.ISingleResourceAssociationChangeListener#removeMessageHold()
|
|
*/
|
|
public void removeMessageHold() {
|
|
}//removeMessageHold()//
|
|
/* (non-Javadoc)
|
|
* @see com.foundation.util.IInlineIndexedCollectionObserver#startChanges(int)
|
|
*/
|
|
public void startChanges(int changeCount) {
|
|
startRendering();
|
|
}//startChanges()//
|
|
/* (non-Javadoc)
|
|
* @see com.foundation.util.IInlineIndexedCollectionObserver#stopChanges()
|
|
*/
|
|
public void stopChanges() {
|
|
stopRendering();
|
|
}//stopChanges()//
|
|
/* (non-Javadoc)
|
|
* @see com.foundation.util.IInlineCollectionObserver#valueAdded(java.lang.Object)
|
|
*/
|
|
public void valueAdded(Object value) {
|
|
if((!suspendCollectionEvents) && (value instanceof ViewController)) {
|
|
TabItem last = getLastTabItem();
|
|
int tabIndex = last == null ? 0 : getSwtTabFolder().indexOf(last) + 1;
|
|
|
|
internalAddTab((ViewController) value, tabIndex);
|
|
viewControllers.add(tabIndex, value);
|
|
}//if//
|
|
}//valueAdded()//
|
|
/* (non-Javadoc)
|
|
* @see com.foundation.util.IInlineIndexedCollectionObserver#valueAdded(java.lang.Object, int)
|
|
*/
|
|
public void valueAdded(Object value, int index) {
|
|
if((!suspendCollectionEvents) && (value instanceof ViewController)) {
|
|
TabItem previous = getPreviousTabItem();
|
|
int tabIndex = (previous == null ? 0 : getSwtTabFolder().indexOf(previous) + 1) + index;
|
|
|
|
internalAddTab((ViewController) value, tabIndex);
|
|
viewControllers.add(tabIndex, value);
|
|
}//if//
|
|
}//valueAdded()//
|
|
/* (non-Javadoc)
|
|
* @see com.foundation.util.IInlineCollectionObserver#valueRemoved(java.lang.Object)
|
|
*/
|
|
public void valueRemoved(Object value) {
|
|
if((!suspendCollectionEvents) && (value instanceof ViewController)) {
|
|
internalRemoveTab((ViewController) value);
|
|
viewControllers.remove(value);
|
|
((ViewController) value).close();
|
|
}//if//
|
|
}//valueRemoved()//
|
|
/* (non-Javadoc)
|
|
* @see com.foundation.util.IInlineIndexedCollectionObserver#valueRemoved(java.lang.Object, int)
|
|
*/
|
|
public void valueRemoved(Object value, int index) {
|
|
valueRemoved(value);
|
|
}//valueRemoved()//
|
|
/* (non-Javadoc)
|
|
* @see com.foundation.util.IInlineIndexedCollectionObserver#removingAll()
|
|
*/
|
|
public void removingAll() {
|
|
if(!suspendCollectionEvents) {
|
|
IIterator iterator = viewControllers.iterator();
|
|
|
|
startChanges(viewControllers.getSize());
|
|
|
|
try {
|
|
while(iterator.hasNext()) {
|
|
valueRemoved(iterator.next());
|
|
}//while//
|
|
}//try//
|
|
finally {
|
|
stopChanges();
|
|
}//finally//
|
|
}//if//
|
|
}//removingAll()//
|
|
/* (non-Javadoc)
|
|
* @see com.foundation.util.IInlineIndexedCollectionObserver#valuesSorted(int[])
|
|
*/
|
|
public void valuesSorted(int[] mapping) {
|
|
if(!suspendCollectionEvents) {
|
|
TabItem previousTabItem = getPreviousTabItem();
|
|
int nextIndex = previousTabItem == null ? 0 : getSwtTabFolder().indexOf(previousTabItem) + 1;
|
|
TabItem[] oldTabItems = new TabItem[mapping.length];
|
|
LiteList newViewControllers = new LiteList(viewControllers.getSize());
|
|
|
|
startChanges(0);
|
|
|
|
//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, nextIndex);
|
|
ViewController controller = (ViewController) componentControllerMapping.get(oldTabItem.getData());
|
|
|
|
newViewControllers.add(viewControllers.get(mapping[index]));
|
|
tabItem.setText(oldTabItem.getText());
|
|
tabItem.setImage(oldTabItem.getImage());
|
|
tabItem.setToolTipText(oldTabItem.getToolTipText());
|
|
tabItem.setControl(oldTabItem.getControl());
|
|
tabItem.setData(oldTabItem.getData());
|
|
nextIndex++;
|
|
oldTabItems[index] = oldTabItem;
|
|
//Replace the tab item in the mapping by view controller.//
|
|
tabItemsByViewControllerMap.put(controller, tabItem);
|
|
}//for//
|
|
|
|
//Remove the old tab items.//
|
|
for(int index = 0; index < oldTabItems.length; index++) {
|
|
oldTabItems[index].dispose();
|
|
}//for//
|
|
|
|
viewControllers.replaceAll(newViewControllers);
|
|
stopChanges();
|
|
}//if//
|
|
}//valuesSorted()//
|
|
/* (non-Javadoc)
|
|
* @see com.foundation.view.swt.Component.IComponentListener#imageChanged(com.foundation.view.swt.Component, org.eclipse.swt.graphics.Image)
|
|
*/
|
|
public void imageChanged(Component component, Image newImage) {
|
|
ViewController controller = (ViewController) componentControllerMapping.get(component);
|
|
|
|
if(controller != null) {
|
|
TabItem tabItem = (TabItem) tabItemsByViewControllerMap.get(controller);
|
|
|
|
if(tabItem != null) {
|
|
tabItem.setImage(newImage);
|
|
}//if//
|
|
}//if//
|
|
}//imageChanged()//
|
|
/* (non-Javadoc)
|
|
* @see com.foundation.view.swt.Component.IComponentListener#titleChanged(com.foundation.view.swt.Component, java.lang.String)
|
|
*/
|
|
public void titleChanged(Component component, String newTitle) {
|
|
ViewController controller = (ViewController) componentControllerMapping.get(component);
|
|
|
|
if(controller != null) {
|
|
TabItem tabItem = (TabItem) tabItemsByViewControllerMap.get(controller);
|
|
|
|
if(tabItem != null) {
|
|
tabItem.setText(newTitle == null ? "" : newTitle);
|
|
}//if//
|
|
}//if//
|
|
}//titleChanged()//
|
|
/* (non-Javadoc)
|
|
* @see com.foundation.view.swt.Component.IComponentListener#toolTipTextChanged(com.foundation.view.swt.Component, java.lang.String)
|
|
*/
|
|
public void toolTipTextChanged(Component component, String newToolTipText) {
|
|
ViewController controller = (ViewController) componentControllerMapping.get(component);
|
|
|
|
if(controller != null) {
|
|
TabItem tabItem = (TabItem) tabItemsByViewControllerMap.get(controller);
|
|
|
|
if(tabItem != null) {
|
|
tabItem.setToolTipText(newToolTipText);
|
|
}//if//
|
|
}//if//
|
|
}//toolTipTextChanged()//
|
|
/* (non-Javadoc)
|
|
* @see com.foundation.view.ISingleResourceAssociationChangeListener#getResourceService()
|
|
*/
|
|
public AbstractResourceService getResourceService() {
|
|
return TabPanel.this.getResourceService();
|
|
}//getResourceService()//
|
|
/* (non-Javadoc)
|
|
* @see com.foundation.view.ISingleResourceAssociationChangeListener#getDecorationManager()
|
|
*/
|
|
public DecorationManager getDecorationManager() {
|
|
return TabPanel.this.getDecorationManager();
|
|
}//getDecorationManager()//
|
|
/* (non-Javadoc)
|
|
* @see com.foundation.view.ISingleResourceAssociationChangeListener#addDecoration(com.foundation.view.AbstractDecoration)
|
|
*/
|
|
public void addDecoration(AbstractDecoration decoration) {
|
|
//Never used.//
|
|
}//addDecoration()//
|
|
/* (non-Javadoc)
|
|
* @see com.foundation.view.ISingleResourceAssociationChangeListener#removeDecoration(com.foundation.view.AbstractDecoration)
|
|
*/
|
|
public void removeDecoration(AbstractDecoration decoration) {
|
|
//Never used.//
|
|
}//removeDecoration()//
|
|
}//PagesHolder//
|
|
/**
|
|
* TabPanel constructor.
|
|
* @param parent A composite control which will be the parent of the new instance (cannot be null).
|
|
* @param name The unique component name.
|
|
* @param style The style of control to construct.
|
|
* @see #STYLE_NO_BACKGROUND
|
|
* @see #STYLE_NO_FOCUS
|
|
* @see #STYLE_NO_MERGE_PAINTS
|
|
* @see #STYLE_NO_REDRAW_RESIZE
|
|
* @see #STYLE_NO_RADIO_GROUP
|
|
* @see #STYLE_H_SCROLL
|
|
* @see #STYLE_V_SCROLL
|
|
* @see #STYLE_BORDER
|
|
* @see #STYLE_LEFT_TO_RIGHT
|
|
* @see #STYLE_RIGHT_TO_LEFT
|
|
* @see #STYLE_TOP
|
|
* @see #STYLE_BOTTOM
|
|
*/
|
|
public TabPanel(Container parent, String name, int style) {
|
|
super(parent, name, style);
|
|
}//TabPanel()//
|
|
/* (non-Javadoc)
|
|
* @see com.foundation.view.swt.AbstractComponent#initializeControl(int)
|
|
*/
|
|
protected void initializeControl(int style, Object data) {
|
|
setSwtWidget(new org.eclipse.swt.widgets.TabFolder(((Container) getContainer()).getSwtParent(), style));
|
|
getSwtWidget().setData(this);
|
|
}//initializeControl()//
|
|
/**
|
|
* 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) getSwtControl();
|
|
}//getSwtTabFolder()//
|
|
/**
|
|
* Adds N pages to the tab panel, where the pages come from an association with the model.
|
|
* @return The page holder which can be used to add associations.
|
|
*/
|
|
public IPagesHolder addPages() {
|
|
PagesHolder holder = new PagesHolder(pages.getSize() > 0 ? pages.getLast() : null);
|
|
|
|
pages.add(holder);
|
|
|
|
return holder;
|
|
}//addPages()//
|
|
/* (non-Javadoc)
|
|
* @see com.foundation.view.swt.Container#addComponent(com.foundation.view.IAbstractComponent)
|
|
*/
|
|
public void addComponent(IAbstractComponent component) {
|
|
super.addComponent(component);
|
|
|
|
if(component instanceof Component && !suspendCustomComponentBehavior) {
|
|
pages.add(component);
|
|
|
|
if(isInitialized()) {
|
|
internalAddTab((Component) component);
|
|
}//if//
|
|
}//if//
|
|
}//addComponent()//
|
|
/* (non-Javadoc)
|
|
* @see com.foundation.view.swt.Container#removeComponent(com.foundation.view.IAbstractComponent)
|
|
*/
|
|
public void removeComponent(IAbstractComponent component) {
|
|
if(component instanceof Component && !suspendCustomComponentBehavior) {
|
|
internalRemoveTab((Component) component);
|
|
pages.remove(component);
|
|
}//if//
|
|
|
|
super.removeComponent(component);
|
|
}//removeComponent()//
|
|
/**
|
|
* Adds a tab to the panel for the given view component.
|
|
* <p>Tabs displaying a view controller's view should set the tab item's data to be the view controller instead of the view component.</p>
|
|
* @param component The view component that will be displayed in the tab.
|
|
*/
|
|
protected void internalAddTab(Component component) {
|
|
if((component != null) && (component.getSwtControl() != null)) {
|
|
TabItem tabItem = new org.eclipse.swt.widgets.TabItem(getSwtTabFolder(), 0);
|
|
|
|
if(component instanceof Container) {
|
|
Image image = component.getContainerImage();
|
|
|
|
tabItem.setText(component.getContainerTitle() == null ? "" : component.getContainerTitle());
|
|
tabItem.setImage(image);
|
|
}//if//
|
|
else {
|
|
tabItem.setText("");
|
|
}//else//
|
|
|
|
tabItem.setToolTipText(component.getToolTipText());
|
|
tabItem.setControl(component.getSwtControl());
|
|
tabItem.setData(component);
|
|
tabItemsByComponentMap.put(component, tabItem);
|
|
component.registerListener(this);
|
|
}//if//
|
|
else {
|
|
Debug.log("Error: Invalid component. Unable to add the component as a tab in the tab panel.");
|
|
}//else//
|
|
}//internalAddTab()//
|
|
/**
|
|
* Removes a tab from the panel for the given related view component.
|
|
* @param component The view component associated with the tab to be removed.
|
|
*/
|
|
protected void internalRemoveTab(Component component) {
|
|
TabItem tabItem = (TabItem) tabItemsByComponentMap.remove(component);
|
|
|
|
//Dispose of the old tab item.//
|
|
if(tabItem != null) {
|
|
tabItem.dispose();
|
|
}//if//
|
|
|
|
component.unregisterListener(this);
|
|
}//internalRemoveTab()//
|
|
/* (non-Javadoc)
|
|
* @see com.foundation.view.swt.AbstractComponent#internalViewInitializeAll()
|
|
*/
|
|
public void internalViewInitializeAll() {
|
|
IIterator iterator = null;
|
|
|
|
//Note: We are using the initialize all to setup the tabs so that they can be released before releasing the children.//
|
|
super.internalViewInitializeAll();
|
|
iterator = pages.iterator();
|
|
|
|
//Initialize the tabs.//
|
|
while(iterator.hasNext()) {
|
|
Object page = iterator.next();
|
|
|
|
if(page instanceof PagesHolder) {
|
|
((PagesHolder) page).initialize();
|
|
}//if//
|
|
else {
|
|
//Not necessary since it is handled by the Container base class.//
|
|
//((Component) page).internalViewInitializeAll();
|
|
internalAddTab((Component) page);
|
|
}//else//
|
|
}//for//
|
|
}//internalViewInitializeAll()//
|
|
/* (non-Javadoc)
|
|
* @see com.foundation.view.IView#viewReleaseAll()
|
|
*/
|
|
public void internalViewReleaseAll() {
|
|
IIterator iterator = pages.iterator();
|
|
|
|
//Note: We are using the release all to release the tabs so that they can be released before releasing the children.//
|
|
while(iterator.hasNext()) {
|
|
Object page = iterator.next();
|
|
|
|
if(page instanceof Component) {
|
|
//Not necessary since it is handled by the Container base class.//
|
|
//((Component) page).internalViewReleaseAll();
|
|
internalRemoveTab((Component) page);
|
|
}//if//
|
|
else {
|
|
((PagesHolder) page).release();
|
|
}//else//
|
|
}//for//
|
|
|
|
super.internalViewReleaseAll();
|
|
}//internalViewReleaseAll()//
|
|
/* (non-Javadoc)
|
|
* @see com.foundation.view.swt.Container#internalViewRefreshAll()
|
|
*/
|
|
public void internalViewRefreshAll() {
|
|
for(int index = 0; index < pages.getSize(); index++) {
|
|
Object page = pages.get(index);
|
|
|
|
if(page instanceof PagesHolder) {
|
|
((PagesHolder) page).refresh();
|
|
}//if//
|
|
else if(page instanceof Component) {
|
|
//Not necessary since it is handled by the Container base class.//
|
|
//((Component) page).internalViewRefreshAll();
|
|
}//else//
|
|
}//for//
|
|
|
|
super.internalViewRefreshAll();
|
|
}//internalViewRefreshAll()//
|
|
/* (non-Javadoc)
|
|
* @see com.foundation.view.swt.Container#internalViewSynchronizeAll()
|
|
*/
|
|
public void internalViewSynchronizeAll() {
|
|
for(int index = 0; index < pages.getSize(); index++) {
|
|
Object page = pages.get(index);
|
|
|
|
if(page instanceof PagesHolder) {
|
|
((PagesHolder) page).synchronize();
|
|
}//if//
|
|
else if(page instanceof Component) {
|
|
//Not necessary since it is handled by the Container base class.//
|
|
//((Component) page).internalViewSynchronizeAll();
|
|
}//else//
|
|
}//for//
|
|
|
|
super.internalViewSynchronizeAll();
|
|
}//internalViewSynchronizeAll()//
|
|
/* (non-Javadoc)
|
|
* @see #onEventFired()
|
|
*/
|
|
protected void internalOnEventFired(IEventAssociation eventAssociation, Object[] eventArguments) {
|
|
}//internalOnEventFired()//
|
|
/* (non-Javadoc)
|
|
* @see com.foundation.view.swt.Component#onValueChanged(com.foundation.view.swt.IAttributeAssociation)
|
|
*/
|
|
protected void internalOnValueChanged(IAttributeAssociation attributeAssociation) {
|
|
super.internalOnValueChanged(attributeAssociation);
|
|
}//internalOnValueChanged()//
|
|
/* (non-Javadoc)
|
|
* @see com.foundation.view.swt.Component.IComponentListener#imageChanged(com.foundation.view.swt.Component, org.eclipse.swt.graphics.Image)
|
|
*/
|
|
public void imageChanged(Component component, Image newImage) {
|
|
TabItem tabItem = (TabItem) tabItemsByComponentMap.get(component);
|
|
|
|
if(tabItem != null) {
|
|
tabItem.setImage(newImage);
|
|
}//if//
|
|
else {
|
|
component.unregisterListener(this);
|
|
}//else//
|
|
}//imageChanged()//
|
|
/* (non-Javadoc)
|
|
* @see com.foundation.view.swt.Component.IComponentListener#titleChanged(com.foundation.view.swt.Component, java.lang.String)
|
|
*/
|
|
public void titleChanged(Component component, String newTitle) {
|
|
TabItem tabItem = (TabItem) tabItemsByComponentMap.get(component);
|
|
|
|
if(tabItem != null) {
|
|
tabItem.setText(newTitle);
|
|
}//if//
|
|
else {
|
|
component.unregisterListener(this);
|
|
}//else//
|
|
}//titleChanged()//
|
|
/* (non-Javadoc)
|
|
* @see com.foundation.view.swt.Component.IComponentListener#toolTipTextChanged(com.foundation.view.swt.Component, java.lang.String)
|
|
*/
|
|
public void toolTipTextChanged(Component component, String newToolTipText) {
|
|
TabItem tabItem = (TabItem) tabItemsByComponentMap.get(component);
|
|
|
|
if(tabItem != null) {
|
|
tabItem.setToolTipText(newToolTipText);
|
|
}//if//
|
|
else {
|
|
component.unregisterListener(this);
|
|
}//else//
|
|
}//toolTipTextChanged()//
|
|
}//TabPanel// |