Package org.eclipse.sapphire.ui.forms

Source Code of org.eclipse.sapphire.ui.forms.ContainerPart$Children

/******************************************************************************
* Copyright (c) 2014 Oracle
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
*    Konstantin Komissarchik - initial implementation and ongoing maintenance
******************************************************************************/

package org.eclipse.sapphire.ui.forms;

import static org.eclipse.sapphire.util.CollectionsUtil.equalsBasedOnEntryIdentity;

import java.util.List;

import org.eclipse.sapphire.Event;
import org.eclipse.sapphire.FilteredListener;
import org.eclipse.sapphire.Listener;
import org.eclipse.sapphire.modeling.ModelPath;
import org.eclipse.sapphire.modeling.Status;
import org.eclipse.sapphire.modeling.el.AndFunction;
import org.eclipse.sapphire.modeling.el.Function;
import org.eclipse.sapphire.modeling.el.FunctionContext;
import org.eclipse.sapphire.modeling.el.FunctionResult;
import org.eclipse.sapphire.ui.PartValidationEvent;
import org.eclipse.sapphire.ui.PartVisibilityEvent;
import org.eclipse.sapphire.ui.SapphirePart;
import org.eclipse.sapphire.util.ListFactory;

/**
* @author <a href="mailto:konstantin.komissarchik@oracle.com">Konstantin Komissarchik</a>
*/

public abstract class ContainerPart<T extends FormComponentPart> extends FormComponentPart
{
    private Children children;
   
    @Override
    protected Function initVisibleWhenFunction()
    {
        return AndFunction.create
        (
            super.initVisibleWhenFunction(),
            new Function()
            {
                @Override
                public String name()
                {
                    return "VisibleIfChildrenVisible";
                }
   
                @Override
                public FunctionResult evaluate( final FunctionContext context )
                {
                    return new FunctionResult( this, context )
                    {
                        @Override
                        protected void init()
                        {
                            ContainerPart.this.attach
                            (
                                new FilteredListener<VisibleChildrenEvent>()
                                {
                                    @Override
                                    protected void handleTypedEvent( final VisibleChildrenEvent event )
                                    {
                                        refresh();
                                    }
                                }
                            );
                        }
   
                        @Override
                        protected Object evaluate()
                        {
                            return ! children().visible().isEmpty();
                        }
                    };
                }
            }
        );
    }
   
    protected abstract Children initChildren();
   
    public final Children children()
    {
        if( this.children == null )
        {
            this.children = initChildren();
        }
       
        return this.children;
    }

    @Override
    protected Status computeValidation()
    {
        final Status.CompositeStatusFactory factory = Status.factoryForComposite();

        for( SapphirePart child : children().visible() )
        {
            factory.merge( child.validation() );
        }
       
        return factory.create();
    }
   
    @Override
    public boolean setFocus()
    {
        broadcast( new FocusReceivedEvent( this ) );
       
        for( SapphirePart child : children().visible() )
        {
            if( child.setFocus() == true )
            {
                return true;
            }
        }
       
        return false;
    }

    @Override
    public boolean setFocus( final ModelPath path )
    {
        broadcast( new FocusReceivedEvent( this ) );
       
        for( SapphirePart child : children().visible() )
        {
            if( child.setFocus( path ) == true )
            {
                return true;
            }
        }
       
        return false;
    }

    @Override
    public void dispose()
    {
        if( this.children != null )
        {
            this.children.dispose();
            this.children = null;
        }
       
        super.dispose();
    }
   
    public abstract class Children
    {
        private List<T> all;
        private List<T> visible;
        private boolean initializingVisibleChildren;
       
        protected abstract void init( ListFactory<T> childPartsListFactory );
       
        public List<T> all()
        {
            if( this.all == null )
            {
                final ListFactory<T> factory = ListFactory.start();
               
                init( factory );
               
                this.all = factory.result();
               
                final Listener listener = new Listener()
                {
                    @Override
                    public void handle( final Event event )
                    {
                        if( event instanceof PartValidationEvent )
                        {
                            refreshValidation();
                        }
                        else if( event instanceof PartVisibilityEvent )
                        {
                            refreshVisibleChildren();
                        }
                    }
                };
               
                for( final SapphirePart part : this.all )
                {
                    part.initialize();
                    part.attach( listener );
                }
            }
           
            return all;
        }
       
        public List<T> visible()
        {
            if( this.visible == null )
            {
                if( this.initializingVisibleChildren )
                {
                    this.visible = ListFactory.empty();
                }
                else
                {
                    this.initializingVisibleChildren = true;
                   
                    try
                    {
                        refreshVisibleChildren();
                    }
                    finally
                    {
                        this.initializingVisibleChildren = false;
                    }
                }
            }
           
            return this.visible;
        }
       
        private void refreshVisibleChildren()
        {
            final ListFactory<T> factory = ListFactory.start();
           
            for( final T child : all() )
            {
                if( child.visible() )
                {
                    factory.add( child );
                }
            }
           
            final List<T> fresh = factory.result();
           
            if( this.visible == null )
            {
                this.visible = fresh;
            }
            else if( ! equalsBasedOnEntryIdentity( this.visible, fresh ) )
            {
                this.visible = fresh;
                broadcast( new VisibleChildrenEvent( ContainerPart.this ) );
                refreshValidation();
            }
        }
       
        private void dispose()
        {
            if( this.all != null )
            {
                for( final FormComponentPart child : this.all )
                {
                    child.dispose();
                }
               
                this.all = null;
                this.visible = null;
            }
        }
    }

    public static final class VisibleChildrenEvent extends PartEvent
    {
        public VisibleChildrenEvent( final ContainerPart<?> part )
        {
            super( part );
        }

        @Override
        public ContainerPart<?> part()
        {
            return (ContainerPart<?>) super.part();
        }
    }

}
TOP

Related Classes of org.eclipse.sapphire.ui.forms.ContainerPart$Children

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.