Files
Brainstorm/Foundation SWT/src/com/foundation/view/swt/StackViewer.java
2014-05-30 10:31:51 -07:00

314 lines
11 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.custom.StackLayout;
import org.eclipse.swt.widgets.Layout;
import com.common.util.ICollection;
import com.common.util.IIterator;
import com.common.util.IList;
import com.common.util.LiteList;
import com.foundation.controller.ViewController;
import com.foundation.util.IInlineCollectionObservable;
import com.foundation.util.IInlineCollectionObserver;
import com.foundation.util.IInlineIndexedCollectionObservable;
import com.foundation.util.IInlineIndexedCollectionObserver;
import com.foundation.view.IEventAssociation;
import com.foundation.view.SingleAssociationContainer;
import com.foundation.view.SingleResourceAssociation;
import com.foundation.view.swt.util.SwtUtilities;
/*
* Displays components in a stack such that only one component is visible at a time.
*/
public class StackViewer extends Container implements IInlineIndexedCollectionObserver, IInlineCollectionObserver {
/** The association that results in a collection of view controllers. */
private SingleResourceAssociation views = null;
/** The association that tracks which view is being displayed. */
private SingleResourceAssociation visibleView = null;
/** The previous collection of view controllers. */
private IList viewControllers = new LiteList(1, 15);
/** Temporarily suspends processing of events fired by registered collections. */
private boolean suspendCollectionEvents = false;
/**
* StackViewer 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
*/
public StackViewer(Container parent, String name, int style) {
super(parent, name, style);
this.views = new SingleResourceAssociation(this, this, getViewContext(), SingleResourceAssociation.TYPE_OBJECT, false, null);
this.visibleView = new SingleResourceAssociation(this, this, getViewContext(), SingleResourceAssociation.TYPE_OBJECT, false, null);
}//StackViewer()//
/* (non-Javadoc)
* @see com.foundation.view.swt.AbstractComponent#initializeControl(int)
*/
protected void initializeControl(int style, Object data) {
setSwtWidget(new org.eclipse.swt.widgets.Composite(((Container) getContainer()).getSwtParent(), style));
getSwtWidget().setData(this);
getSwtComposite().setLayout(new StackLayout());
}//initializeControl()//
/**
* Gets the stack layout used with the wizard.
* @return The wizard's stack layout.
*/
protected StackLayout getLayout() {
return (StackLayout) getSwtComposite().getLayout();
}//getLayout()//
/* (non-Javadoc)
* @see com.foundation.view.swt.Container#setLayout(org.eclipse.swt.widgets.Layout)
*/
public void setLayout(Layout layout) {
//Does nothing. Layouts are not allowed here.//
}//setLayout()//
/**
* 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) getSwtControl();
}//getSwtComposite()//
/**
* Sets the association container used to access the views in the stack.
* @param container The views association metadata.
*/
public void setViewsAssociation(SingleAssociationContainer container) {
verifyThread();
this.views.setAssociations(container);
}//setViewsAssociation()//
/**
* Sets the association container used to access the visible view.
* @param container The visible view association metadata.
*/
public void setVisibleViewAssociation(SingleAssociationContainer container) {
verifyThread();
this.visibleView.setAssociations(container);
}//setVisibleViewAssociation()//
/* (non-Javadoc)
* @see com.foundation.view.swt.AbstractComponent#internalOnEventFired(com.foundation.view.swt.IEventAssociation, java.lang.Object[])
*/
protected void internalOnEventFired(IEventAssociation eventAssociation, Object[] eventArguments) {
}//internalOnEventFired()//
/* (non-Javadoc)
* @see com.foundation.view.swt.AbstractComponent#internalViewInitialize()
*/
protected void internalViewInitialize() {
views.initialize();
visibleView.initialize();
super.internalViewInitialize();
}//internalViewInitialize()//
/* (non-Javadoc)
* @see com.foundation.view.swt.AbstractComponent#internalViewRelease()
*/
protected void internalViewRelease() {
super.internalViewRelease();
views.release();
visibleView.release();
for(int index = 0; index < viewControllers.getSize(); index++) {
((ViewController) viewControllers.get(index)).close();
}//for//
}//internalViewRelease()//
/* (non-Javadoc)
* @see com.foundation.view.swt.AbstractComponent#internalViewRefresh()
*/
protected void internalViewRefresh() {
super.internalViewRefresh();
internalRefreshViews();
internalRefreshVisibleView();
}//internalViewRefresh()//
/**
* Refreshes the currently visible component.
*/
protected void internalRefreshViews() {
Object oldValue = views.getValue();
if(views.refresh()) {
stopRendering();
try {
Object newValue = views.getValue();
//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//
//Close the old view controllers.//
for(int index = 0; index < viewControllers.getSize(); index++) {
((ViewController) viewControllers.get(index)).close();
}//for//
viewControllers.removeAll();
//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();
//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;
controller.openPartial(this, getViewContext());
}//if//
else {
throw new RuntimeException("Expecting a view controller.");
}//else//
}//while//
//Add the controllers to the list of view controllers.//
viewControllers.addAll((ICollection) newValue);
//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;
controller.openPartial(this, getViewContext());
//Add the one controller to the list of view controllers.//
viewControllers.add(controller);
}//else if//
}//try//
finally {
startRendering();
}//finally//
}//if//
}//internalRefreshViews()//
/**
* Refreshes the currently visible component.
*/
protected void internalRefreshVisibleView() {
if(visibleView.refresh()) {
Object view = (Object) visibleView.getValue();
int index = viewControllers.getIndexOf(view);
if(index >= 0) {
((StackLayout) getSwtComposite().getLayout()).topControl = getSwtComposite().getChildren()[index];
getSwtComposite().layout(true, false);
}//if//
}//if//
}//internalRefreshVisibleView()//
/* (non-Javadoc)
* @see com.foundation.view.swt.AbstractComponent#internalViewSynchronize()
*/
protected void internalViewSynchronize() {
//Since the page can only be set manually, this method should do nothing.//
super.internalViewSynchronize();
}//internalViewSynchronize()//
/* (non-Javadoc)
* @see com.foundation.view.swt.Component#internalOnValueChanged(com.foundation.view.SingleResourceAssociation, int)
*/
protected void internalOnValueChanged(SingleResourceAssociation association, int flags) {
if(association == visibleView) {
internalRefreshVisibleView();
}//if//
else if(association == views) {
internalRefreshViews();
}//else if//
else {
super.internalOnValueChanged(association, flags);
}//else//
}//internalOnValueChanged()//
/* (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)) {
viewControllers.add(value);
((ViewController) value).openPartial(this, getViewContext());
}//if//
}//valueAdded()//
/* (non-Javadoc)
* @see com.foundation.util.IInlineIndexedCollectionObserver#valueAdded(java.lang.Object, int)
*/
public void valueAdded(Object value, int index) {
valueAdded(value);
}//valueAdded()//
/* (non-Javadoc)
* @see com.foundation.util.IInlineCollectionObserver#valueRemoved(java.lang.Object)
*/
public void valueRemoved(Object value) {
if((!suspendCollectionEvents) && (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) {
//Does nothing.//
}//valuesSorted()//
}//StackViewer//