Package org.eclipse.sapphire.ui.forms.swt.internal

Source Code of org.eclipse.sapphire.ui.forms.swt.internal.WithPresentation

/******************************************************************************
* 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.swt.internal;

import static org.eclipse.sapphire.ui.forms.swt.GridLayoutUtil.gd;
import static org.eclipse.sapphire.ui.forms.swt.GridLayoutUtil.gdfill;
import static org.eclipse.sapphire.ui.forms.swt.GridLayoutUtil.gdhfill;
import static org.eclipse.sapphire.ui.forms.swt.GridLayoutUtil.gdhindent;
import static org.eclipse.sapphire.ui.forms.swt.GridLayoutUtil.gdhspan;
import static org.eclipse.sapphire.ui.forms.swt.GridLayoutUtil.gdvalign;
import static org.eclipse.sapphire.ui.forms.swt.GridLayoutUtil.glayout;
import static org.eclipse.sapphire.ui.forms.swt.GridLayoutUtil.glspacing;

import java.util.HashMap;
import java.util.Map;
import java.util.SortedSet;

import org.eclipse.sapphire.Element;
import org.eclipse.sapphire.ElementHandle;
import org.eclipse.sapphire.ElementType;
import org.eclipse.sapphire.Event;
import org.eclipse.sapphire.FilteredListener;
import org.eclipse.sapphire.Listener;
import org.eclipse.sapphire.LocalizableText;
import org.eclipse.sapphire.LoggingService;
import org.eclipse.sapphire.PropertyEvent;
import org.eclipse.sapphire.Sapphire;
import org.eclipse.sapphire.Text;
import org.eclipse.sapphire.modeling.CapitalizationType;
import org.eclipse.sapphire.modeling.EditFailedException;
import org.eclipse.sapphire.services.PossibleTypesService;
import org.eclipse.sapphire.ui.SapphireActionGroup;
import org.eclipse.sapphire.ui.SapphirePart.LabelChangedEvent;
import org.eclipse.sapphire.ui.assist.internal.PropertyEditorAssistDecorator;
import org.eclipse.sapphire.ui.forms.FormComponentPart;
import org.eclipse.sapphire.ui.forms.WithDef;
import org.eclipse.sapphire.ui.forms.WithPart;
import org.eclipse.sapphire.ui.forms.WithPart.Style;
import org.eclipse.sapphire.ui.forms.swt.RadioButtonsGroup;
import org.eclipse.sapphire.ui.forms.swt.SapphireActionPresentationManager;
import org.eclipse.sapphire.ui.forms.swt.SapphireKeyboardActionPresentation;
import org.eclipse.sapphire.ui.forms.swt.SwtPresentation;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.DisposeEvent;
import org.eclipse.swt.events.DisposeListener;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Label;

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

public final class WithPresentation extends PageBookPresentation
{
    @Text( "None" )
    private static LocalizableText noneSelection;
   
    @Text( "Enable {0}" )
    private static LocalizableText enableElementLabel;
   
    static
    {
        LocalizableText.init( WithPresentation.class );
    }

    public WithPresentation( final FormComponentPart part, final SwtPresentation parent, final Composite composite )
    {
        super( part, parent, composite );
    }

    @Override
    public WithPart part()
    {
        return (WithPart) super.part();
    }
   
    @Override
    public void render()
    {
        final WithPart part = part();
        final WithDef def = part.definition();
        final ElementHandle<?> property = part.property();
       
        final Composite composite = new Composite( composite(), SWT.NONE );
        composite.setLayoutData( gdhspan( ( part.getScaleVertically() ? gdfill() : gdhfill() ), 2 ) );
        composite.setLayout( glayout( 1, 0, 0 ) );
       
        register( composite );
       
        final PossibleTypesService possibleTypesService = property.service( PossibleTypesService.class );

        final Composite typeSelectorComposite = new Composite( composite, SWT.NONE );
        typeSelectorComposite.setLayoutData( gdhfill() );
       
        final Runnable renderTypeSelectorOp = new Runnable()
        {
            public void run()
            {
                for( Control control : typeSelectorComposite.getChildren() )
                {
                    control.dispose();
                }
               
                final SortedSet<ElementType> allPossibleTypes = possibleTypesService.types();
                final int allPossibleTypesCount = allPossibleTypes.size();
                final Runnable updateUserInterfaceOp;
               
                final Style defaultStyle;
               
                if( allPossibleTypesCount == 1 )
                {
                    defaultStyle = Style.CHECKBOX;
                }
                else if( allPossibleTypesCount <= 3 )
                {
                    defaultStyle = Style.RADIO_BUTTONS;
                }
                else
                {
                    defaultStyle = Style.DROP_DOWN_LIST;
                }
               
                Style style = Style.decode( def.getHint( WithDef.HINT_STYLE ) );
               
                if( style == null || ( style == Style.CHECKBOX && allPossibleTypesCount != 1 ) )
                {
                    style = defaultStyle;
                }
               
                final SapphireActionGroup actions = part.getActions();
                final SapphireActionPresentationManager actionPresentationManager = new SapphireActionPresentationManager( WithPresentation.this, actions );
                final SapphireKeyboardActionPresentation actionPresentationKeyboard = new SapphireKeyboardActionPresentation( actionPresentationManager );
               
                final boolean showLabel = ( part.label() != null );

                if( style == Style.CHECKBOX )
                {
                    typeSelectorComposite.setLayout( glspacing( glayout( 2, 0, 0 ), 2 ) );
                   
                    final PropertyEditorAssistDecorator decorator = new PropertyEditorAssistDecorator( part, property, typeSelectorComposite );
                    decorator.control().setLayoutData( gd() );
                   
                    final Button masterCheckBox = new Button( typeSelectorComposite, SWT.CHECK );
                    masterCheckBox.setLayoutData( gd() );
                    decorator.addEditorControl( masterCheckBox );
                    actionPresentationKeyboard.attach( masterCheckBox );
                    attachHelp( masterCheckBox, property );
                   
                    if( showLabel )
                    {
                        masterCheckBox.setText( part.label( CapitalizationType.FIRST_WORD_ONLY, true ) );
                       
                        attachPartListener
                        (
                            new FilteredListener<LabelChangedEvent>()
                            {
                                @Override
                                protected void handleTypedEvent( final LabelChangedEvent event )
                                {
                                    masterCheckBox.setText( part.label( CapitalizationType.FIRST_WORD_ONLY, true ) );
                                    layout();
                                }
                            }
                        );
                    }
                   
                    updateUserInterfaceOp = new Runnable()
                    {
                        public void run()
                        {
                            if( Display.getCurrent() == null )
                            {
                                masterCheckBox.getDisplay().asyncExec( this );
                                return;
                            }
                           
                            final Element subModelElement = ( (ElementHandle<?>) property ).content();
                           
                            masterCheckBox.setSelection( subModelElement != null );
                            masterCheckBox.setEnabled( property.enabled() );
                        }
                    };
                           
                    masterCheckBox.addSelectionListener
                    (
                        new SelectionAdapter()
                        {
                            @Override
                            public void widgetSelected( final SelectionEvent event )
                            {
                                try
                                {
                                    final ElementHandle<?> handle = (ElementHandle<?>) property;
                                   
                                    if( masterCheckBox.getSelection() == true )
                                    {
                                        handle.content( true );
                                    }
                                    else
                                    {
                                        handle.clear();
                                    }
                                }
                                catch( Exception e )
                                {
                                    // Note that the EditFailedException is ignored here because the user has already
                                    // been notified and likely has taken action that led to the exception (such as
                                    // declining to make a file writable).
                                   
                                    final EditFailedException editFailedException = EditFailedException.findAsCause( e );
                                   
                                    if( editFailedException == null )
                                    {
                                        Sapphire.service( LoggingService.class ).log( e );
                                    }
                                }
                            }
                        }
                    );
                }
                else
                {
                    typeSelectorComposite.setLayout( glspacing( glayout( 3, 0, 0 ), 2 ) );
                   
                    if( showLabel )
                    {
                        final Label label = new Label( typeSelectorComposite, SWT.NONE );
                        label.setLayoutData( gdhindent( gd(), 9 ) );
                        label.setText( part.label( CapitalizationType.FIRST_WORD_ONLY, true ) + ":" );
                       
                        attachPartListener
                        (
                            new FilteredListener<LabelChangedEvent>()
                            {
                                @Override
                                protected void handleTypedEvent( final LabelChangedEvent event )
                                {
                                    label.setText( part.label( CapitalizationType.FIRST_WORD_ONLY, true ) + ":" );
                                    layout();
                                }
                            }
                        );
                    }
                   
                    final PropertyEditorAssistDecorator decorator = new PropertyEditorAssistDecorator( part, property, typeSelectorComposite );
                    decorator.control().setLayoutData( gdhindent( gdvalign( gd(), ( style == Style.DROP_DOWN_LIST ? SWT.TOP : SWT.CENTER ) ), ( showLabel ? 3 : 0 ) ) );
                   
                    if( style == Style.RADIO_BUTTONS )
                    {
                        final RadioButtonsGroup radioButtonsGroup = new RadioButtonsGroup( typeSelectorComposite, false );
                        radioButtonsGroup.setLayoutData( gdhfill() );
                       
                        final Map<ElementType,Button> typeToButton = new HashMap<ElementType,Button>();
                        final Map<Button,ElementType> buttonToType = new HashMap<Button,ElementType>();
                       
                        for( final ElementType type : allPossibleTypes )
                        {
                            final String label = type.getLabel( true, CapitalizationType.FIRST_WORD_ONLY, false );
                            final Button button = radioButtonsGroup.addRadioButton( label );
                            typeToButton.put( type, button );
                            buttonToType.put( button, type );
                            decorator.addEditorControl( button );
                            actionPresentationKeyboard.attach( button );
                            attachHelp( button, property );
                        }
                       
                        final Button noneButton = radioButtonsGroup.addRadioButton( noneSelection.text() );
                        noneButton.setVisible( false );
                        decorator.addEditorControl( noneButton );
                        actionPresentationKeyboard.attach( noneButton );
                        attachHelp( noneButton, property );
                       
                        updateUserInterfaceOp = new Runnable()
                        {
                            public void run()
                            {
                                if( Display.getCurrent() == null )
                                {
                                    radioButtonsGroup.getDisplay().asyncExec( this );
                                    return;
                                }
                               
                                final Element subModelElement = ( (ElementHandle<?>) property ).content();
                                final Button button;
                               
                                if( subModelElement == null )
                                {
                                    button = noneButton;
                                    noneButton.setVisible( true );
                                }
                                else
                                {
                                    button = typeToButton.get( subModelElement.type() );
                                    noneButton.setVisible( false );
                                }
                               
                                if( radioButtonsGroup.getSelection() != button )
                                {
                                    radioButtonsGroup.setSelection( button );
                                }
                               
                                radioButtonsGroup.setEnabled( property.enabled() );
                            }
                        };
                               
                        radioButtonsGroup.addSelectionListener
                        (
                            new SelectionAdapter()
                            {
                                @Override
                                public void widgetSelected( final SelectionEvent event )
                                {
                                    try
                                    {
                                        final ElementHandle<?> handle = (ElementHandle<?>) property;
                                        final Button button = radioButtonsGroup.getSelection();
                                       
                                        if( button == noneButton )
                                        {
                                            handle.clear();
                                        }
                                        else
                                        {
                                            final ElementType type = buttonToType.get( button );
                                            handle.content( true, type );
                                        }
                                    }
                                    catch( Exception e )
                                    {
                                        // Note that the EditFailedException is ignored here because the user has already
                                        // been notified and likely has taken action that led to the exception (such as
                                        // declining to make a file writable).
                                       
                                        final EditFailedException editFailedException = EditFailedException.findAsCause( e );
                                       
                                        if( editFailedException == null )
                                        {
                                            Sapphire.service( LoggingService.class ).log( e );
                                        }
                                    }
                                }
                            }
                        );
                    }
                    else if( style == Style.DROP_DOWN_LIST )
                    {
                        final Combo combo = new Combo( typeSelectorComposite, SWT.SINGLE | SWT.BORDER | SWT.READ_ONLY );
                        combo.setLayoutData( gdhfill() );
                        decorator.addEditorControl( combo );
                        actionPresentationKeyboard.attach( combo );
                        attachHelp( combo, property );
                       
                        final Map<ElementType,Integer> typeToIndex = new HashMap<ElementType,Integer>();
                        final Map<Integer,ElementType> indexToType = new HashMap<Integer,ElementType>();
                       
                        int index = 0;
                       
                        for( ElementType type : allPossibleTypes )
                        {
                            final String label = type.getLabel( true, CapitalizationType.FIRST_WORD_ONLY, false );
                            combo.add( label );
                            typeToIndex.put( type, index );
                            indexToType.put( index, type );
                           
                            index++;
                        }
                       
                        updateUserInterfaceOp = new Runnable()
                        {
                            public void run()
                            {
                                if( Display.getCurrent() == null )
                                {
                                    combo.getDisplay().asyncExec( this );
                                    return;
                                }
                               
                                final Element subModelElement = ( (ElementHandle<?>) property ).content();
                                final int index;
                               
                                if( subModelElement == null )
                                {
                                    index = -1;
                                }
                                else
                                {
                                    index = typeToIndex.get( subModelElement.type() );
                                }
                               
                                if( combo.getSelectionIndex() != index )
                                {
                                    if( index == -1 )
                                    {
                                        combo.deselectAll();
                                    }
                                    else
                                    {
                                        combo.select( index );
                                    }
                                }
                               
                                combo.setEnabled( property.enabled() );
                            }
                        };
   
                        combo.addSelectionListener
                        (
                            new SelectionAdapter()
                            {
                                @Override
                                public void widgetSelected( final SelectionEvent event )
                                {
                                    try
                                    {
                                        final ElementHandle<?> handle = (ElementHandle<?>) property;
                                        final int index = combo.getSelectionIndex();
                                       
                                        if( index == -1 )
                                        {
                                            handle.clear();
                                        }
                                        else
                                        {
                                            final ElementType type = indexToType.get( index );
                                            handle.content( true, type );
                                        }
                                    }
                                    catch( Exception e )
                                    {
                                        // Note that the EditFailedException is ignored here because the user has already
                                        // been notified and likely has taken action that led to the exception (such as
                                        // declining to make a file writable).
                                       
                                        final EditFailedException editFailedException = EditFailedException.findAsCause( e );
                                       
                                        if( editFailedException == null )
                                        {
                                            Sapphire.service( LoggingService.class ).log( e );
                                        }
                                    }
                                }
                            }
                        );
                    }
                    else
                    {
                        throw new IllegalStateException();
                    }
                }
               
                actionPresentationKeyboard.render();
               
                updateUserInterfaceOp.run();
               
                final Listener modelPropertyListener = new FilteredListener<PropertyEvent>()
                {
                    @Override
                    protected void handleTypedEvent( final PropertyEvent event )
                    {
                        updateUserInterfaceOp.run();
                    }
                };
               
                property.attach( modelPropertyListener );
               
                typeSelectorComposite.layout( true, true );
               
                typeSelectorComposite.getChildren()[ 0 ].addDisposeListener
                (
                    new DisposeListener()
                    {
                        public void widgetDisposed( final DisposeEvent event )
                        {
                            property.detach( modelPropertyListener );
                            actionPresentationManager.dispose();
                            actionPresentationKeyboard.dispose();
                        }
                    }
                );
            }
        };
       
        renderTypeSelectorOp.run();
       
        final Listener possibleTypesServiceListener = new Listener()
        {
            @Override
            public void handle( final Event event )
            {
                renderTypeSelectorOp.run();
            }
        };
       
        possibleTypesService.attach( possibleTypesServiceListener );
       
        typeSelectorComposite.addDisposeListener
        (
            new DisposeListener()
            {
                public void widgetDisposed( final DisposeEvent event )
                {
                    possibleTypesService.detach( possibleTypesServiceListener );
                }
            }
        );
   
        final Composite separatorComposite = new Composite( composite, SWT.NONE );
        separatorComposite.setLayoutData( gdhindent( gdhspan( gdhfill(), 2 ), 9 ) );
        separatorComposite.setLayout( glayout( 1, 0, 5 ) );
       
        final Label separator = new Label( separatorComposite, SWT.SEPARATOR | SWT.HORIZONTAL );
        separator.setLayoutData( gdhfill() );
       
        super.render( composite );
    }

}
TOP

Related Classes of org.eclipse.sapphire.ui.forms.swt.internal.WithPresentation

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.