/* * 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.view.swt; import javax.management.RuntimeErrorException; import org.eclipse.swt.SWT; import org.eclipse.swt.custom.ScrolledComposite; import org.eclipse.swt.graphics.Point; import org.eclipse.swt.graphics.Rectangle; import org.eclipse.swt.widgets.Canvas; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.Event; import org.eclipse.swt.widgets.Listener; import org.eclipse.swt.widgets.ScrollBar; import com.common.util.*; import com.common.debug.*; import com.foundation.view.*; import com.foundation.view.swt.layout.Layout; import com.foundation.view.swt.layout.LayoutData; import com.foundation.util.*; import com.foundation.controller.*; import com.foundation.event.*; public class Panel extends Container { /** The attribute that provides the collection of internal view controllers. */ private IAttributeAssociation internalViewsAssociation = null; /** A support for receiving collection change events. */ private EventSupport eventSupport = new EventSupport(null); /** The collection of internal view controllers. */ private ICollection internalViewControllers = null; /** The collection of internal view controllers currently open. Maintaining this collection is necessary in the event that all view controllers are removed from the collection. */ private LiteList openViewControllers = null; /** The next location ? */ private int nextLocation = 0; /** The location increment ? */ private int locationIncrement = 20; /** The composite used to slide the contents around if the user has requested vertical and/or horizontal scrolling. */ private ScrolledComposite scrolledComposite; /** The composite used to slide the contents around if the user has requested vertical and/or horizontal scrolling. */ private Composite composite; /** * Panel default constructor. *
Warning: This is only for use by the framework. This should never be called to create a useable instance.
*/ public Panel() { }//Panel()// /** * Panel 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_EMBEDDED * @see #STYLE_DOUBLE_BUFFERED * @see #STYLE_H_SCROLL * @see #STYLE_V_SCROLL * @see #STYLE_BORDER * @see #STYLE_LEFT_TO_RIGHT * @see #STYLE_RIGHT_TO_LEFT */ public Panel(IAbstractContainer parent, String name, int style) { super(parent, name, style); }//Panel()// /* (non-Javadoc) * @see com.foundation.view.swt.AbstractComponent#initializeControl(int) */ protected void initializeControl(int style, Object data) { boolean hScroll = ((style & SWT.H_SCROLL) != 0); boolean vScroll = ((style & SWT.V_SCROLL) != 0); if(hScroll || vScroll) { scrolledComposite = new ScrolledComposite(((IAbstractSwtContainer) getContainer()).getSwtParent(), style); scrolledComposite.setData(this); composite = new Composite(scrolledComposite, 0); composite.setData(this); scrolledComposite.setTabList(new Control[] {composite}); scrolledComposite.setContent(composite); setSwtWidget(scrolledComposite); scrolledComposite.setAlwaysShowScrollBars(false); scrolledComposite.setExpandHorizontal(true); scrolledComposite.setExpandVertical(true); scrolledComposite.setMinSize(0, 0); if(hScroll) { getSwtComposite().getHorizontalBar().setVisible(false); getSwtComposite().getHorizontalBar().setIncrement(20); }//if// if(vScroll) { getSwtComposite().getVerticalBar().setVisible(false); getSwtComposite().getVerticalBar().setIncrement(20); }//if// }//if// else { setSwtWidget(new org.eclipse.swt.widgets.Composite(((IAbstractSwtContainer) getContainer()).getSwtParent(), style)); getSwtWidget().setData(this); }//else// }//initializeControl()// /* (non-Javadoc) * @see com.foundation.view.swt.Container#internalLayout() */ protected void internalLayout() { if(scrolledComposite != null) { composite.setSize(composite.computeSize(-1, -1, true)); }//if// super.internalLayout(); }//internalLayout()// /* (non-Javadoc) * @see com.foundation.view.swt.Container#postResize() */ public void postResize() { super.postResize(); if(scrolledComposite != null) { Rectangle interior = scrolledComposite.getClientArea(); Rectangle interior2 = null; scrolledComposite.setMinSize(0, 0); while(!interior.equals(interior2)) { Point size = null; composite.computeSize(0, 0, true); if(composite.getLayout() instanceof com.foundation.view.swt.layout.Layout) { size = ((com.foundation.view.swt.layout.Layout) composite.getLayout()).computeCurrentSize(composite); }//if// else { Debug.log(new RuntimeException("Only Brainstorm based layouts may be used. The layout must extend " + Layout.class.getName())); }//else// if(getSwtComposite().getHorizontalBar() != null) { scrolledComposite.setMinWidth(size.x); }//if// if(getSwtComposite().getVerticalBar() != null) { scrolledComposite.setMinHeight(size.y); }//if// interior2 = interior; interior = scrolledComposite.getClientArea(); }//while// }//if// }//postResize()// /* (non-Javadoc) * @see com.foundation.view.swt.Container#getSwtParent() */ public org.eclipse.swt.widgets.Composite getSwtParent() { return scrolledComposite != null ? composite : getSwtComposite(); }//getSwtParent()// /** * Sets the internal view controller collection. * @param internalViewsAssociation The association containing the collection of view controllers representing views that exist within this panel. */ public void setInternalViewsAssociation(IAttributeAssociation internalViewsAssociation) { this.internalViewsAssociation = internalViewsAssociation; }//setInternalViewsAssociation()// /* (non-Javadoc) * @see com.foundation.view.swt.AbstractComponent#internalViewInitialize() */ protected void internalViewInitialize() { if(internalViewsAssociation != null) { openViewControllers = new LiteList(10, 50); internalViewsAssociation.register(); }//if// super.internalViewInitialize(); }//internalViewInitialize()// /* (non-Javadoc) * @see com.foundation.view.swt.AbstractComponent#internalViewRelease() */ protected void internalViewRelease() { super.internalViewRelease(); if(internalViewsAssociation != null) { internalViewsAssociation.unregister(); eventSupport.unregisterAll(); closeAllViews(); }//if// }//internalViewRelease()// /* (non-Javadoc) * @see com.foundation.view.swt.AbstractComponent#internalViewRefresh() */ protected void internalViewRefresh() { super.internalViewRefresh(); if(internalViewsAssociation != null) { ICollection internalViewControllers = (ICollection) internalViewsAssociation.getAttributeValue(); ICollection copy = null; if(this.internalViewControllers != internalViewControllers) { //Unregister the old event hooks.// if(this.internalViewControllers instanceof IEventEmitter) { eventSupport.unregisterAll((IEventEmitter) this.internalViewControllers); }//if// closeAllViews(); //Save a reference to the current collection in the model.// this.internalViewControllers = internalViewControllers; if(internalViewControllers instanceof IManagedCollection) { //Register the new event hooks.// synchronized(internalViewControllers) { eventSupport.register(((IManagedCollection) internalViewControllers), IManagedCollection.EVENT.getNumber(), this, true); copy = new LiteList(internalViewControllers); }//synchronized// }//if// }//if// if(copy != null) { IIterator iterator = copy.iterator(); while(iterator.hasNext()) { Object next = iterator.next(); if(next instanceof ViewController) { closeView((ViewController) next); openViewControllers.add(next); }//if// else { Debug.log("Error: Only view controllers may populate the collection of internal frames attached to the panel."); }//else// }//while// }//if// }//if// }//internalViewRefresh()// /* (non-Javadoc) * @see com.foundation.view.swt.AbstractComponent#internalViewSynchronize() */ protected void internalViewSynchronize() { super.internalViewSynchronize(); }//internalViewSynchronize()// /* (non-Javadoc) * @see com.foundation.view.swt.AbstractComponent#internalEvaluate(com.common.event.IEventEmitter, int, java.lang.Object[]) */ protected void internalEvaluate(IEventEmitter eventEmitter, int eventNumber, Object[] arguments) { //Add, remove, or replace items from the list.// if(eventEmitter == internalViewControllers) { if(eventNumber == IManagedCollection.EVENT.getNumber()) { CollectionChangeEvent event = (CollectionChangeEvent) arguments[0]; if(event.hasAdds()) { if(event.getAddedObjects() != null) { IIterator iterator = event.getAddedObjects().iterator(); while(iterator.hasNext()) { Object next = iterator.next(); openView((ViewController) next); }//while// }//if// else { openView((ViewController) event.getAddedObject()); }//else// }//if// if(event.hasRemoves()) { if(event.getRemovedObjects() != null) { IIterator iterator = event.getRemovedObjects().iterator(); while(iterator.hasNext()) { Object next = iterator.next(); openViewControllers.remove(next); closeView((ViewController) next); }//while// }//if// else { openViewControllers.remove(event.getRemovedObject()); closeView((ViewController) event.getRemovedObject()); }//else// }//if// }//if// }//if// else { super.internalEvaluate(eventEmitter, eventNumber, arguments); }//else// }//internalEvaluate()// /* (non-Javadoc) * @see com.foundation.view.swt.Component#onValueChanged(com.foundation.view.swt.IAttributeAssociation) */ protected void internalOnValueChanged(IAttributeAssociation attributeAssociation) { if(attributeAssociation == internalViewsAssociation) { internalViewRefresh(); }//if// else { super.internalOnValueChanged(attributeAssociation); }//else// }//internalOnValueChanged()// /** * Opens the view for the associated view controller. * @param viewController The view controller that will provide the view. */ private void openView(ViewController viewController) { IView view = viewController.openPartial(this, null); if(view instanceof Frame) { int location = nextLocation; if(location + ((Frame) view).getSwtControl().getSize().x > getSwtControl().getSize().x) { location = 0; }//if// else if(location + ((Frame) view).getSwtControl().getSize().y > getSwtControl().getSize().y) { location = 0; }//else if// nextLocation = location + locationIncrement; ((Frame) view).setLocation(location, location); }//if// else { //I could at some point wrapper the view component with a frame.// Debug.log("Error: The view must be a frame for it to be a valid internal view."); }//else// }//openView()// /** * Closes the view for the associated view controller. * @param viewController The view controller that provided the view. */ private void closeView(ViewController viewController) { viewController.close(); }//closeView()// /** * Closes all the internal views. */ private void closeAllViews() { IIterator iterator = openViewControllers.iterator(); while(iterator.hasNext()) { closeView((ViewController) iterator.next()); }//while// openViewControllers.removeAll(); }//closeAllViews()// }//Panel//