Package com.eclipsesource.tabris.widgets

Source Code of com.eclipsesource.tabris.widgets.ScrollingComposite

/*******************************************************************************
* Copyright (c) 2013 EclipseSource and others.
* 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:
*    EclipseSource - initial API and implementation
******************************************************************************/
package com.eclipsesource.tabris.widgets;

import static com.eclipsesource.tabris.internal.Clauses.when;
import static com.eclipsesource.tabris.internal.Clauses.whenNull;

import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.ScrolledComposite;
import org.eclipse.swt.events.ControlAdapter;
import org.eclipse.swt.events.ControlEvent;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Shell;


/**
* <p>
* A {@link ScrollingComposite} can be used the same way as a simple {@link Composite}. The difference between
* a {@link Composite} and a {@link ScrollingComposite} is that a {@link ScrollingComposite} shows scrollbars
* automatically when it's content becomes to big.
* </p>
* <p>
* You may noticed that there is a {@link ScrolledComposite}. A {@link ScrolledComposite} is not an easy widget. In
* most cases it's enough to have just a scrollable container for some content that grows dynamically.
* This task can not be accomplished easily with the {@link ScrolledComposite}. Thus the {@link ScrollingComposite}
* was created to make just the described task easy and nothing more.
* </p>
*
* <p>
* Please note: A {@link ScrollingComposite} uses a {@link ScrolledComposite} as it's parent. So, if you need to get the
* {@link ScrolledComposite} use the {@link ScrollingComposite#getParent()} method.
* </p>
*
* <p>
* <b>Styles:</b> H_SCROLL, V_SCROLL
* </p>
*
* @see Composite
* @see ScrolledComposite
*
* @since 1.0
*/
public class ScrollingComposite extends Composite {

  private ScrolledComposite scrolledComposite;

  /**
   * <p>
   * Constructs a new {@link ScrollingComposite}. See {@link Composite#Composite(Composite, int)} for a more detailed
   * description.
   * </p>
   *
   * @see Composite#Composite(Composite, int)
   */
  public ScrollingComposite( Composite parent, int style ) {
    super( createScrolledComposite( parent, checkStyle( style ) ), checkStyle( style ) );
    scrolledComposite = ( ScrolledComposite )this.getParent();
    initializeScrolledComposite();
  }

  private static int checkStyle( int style ) {
    int mask = SWT.H_SCROLL | SWT.V_SCROLL | SWT.BORDER | SWT.LEFT_TO_RIGHT;
    return style & mask;
  }

  private static ScrolledComposite createScrolledComposite( Composite parent, int style ) {
    ScrolledComposite scrolledComposite = new ScrolledComposite( parent, style ) {
      @Override
      public void layout( boolean changed, boolean all ) {
        super.layout( changed, all );
        Control content = getContent();
        if( content != null && !content.isDisposed() ) {
          ( ( ScrollingComposite )content ).layout( changed, all );
        }
      }
    };
    scrolledComposite.setExpandVertical( true );
    scrolledComposite.setExpandHorizontal( true );
    return scrolledComposite;
  }

  private void initializeScrolledComposite() {
    scrolledComposite.setContent( this );
    handleScrollbars();
    scrolledComposite.addControlListener( new ControlAdapter() {
      @Override
      public void controlResized( ControlEvent event ) {
        handleScrollbars();
        scrolledComposite.layout( true, true );
      }
    } );
  }

  @Override
  public void layout( boolean changed, boolean all ) {
    handleScrollbars();
    super.layout( changed, all );
  }

  private void handleScrollbars() {
    computeSize( SWT.DEFAULT, SWT.DEFAULT );
  }

  @Override
  public Point computeSize( int wHint, int hHint, boolean changed ) {
    Point size = super.computeSize( wHint, hHint, changed );
    scrolledComposite.setMinSize( size );
    return size;
  }

  @Override
  public void setLayoutData( Object layoutData ) {
    checkWidget();
    scrolledComposite.setLayoutData( layoutData );
  }

  /**
   * <p>
   * Scrolls to the defined control until it's visible.
   * </p>
   *
   * @param control the control to scroll to. Must not be <code>null</code>.
   *
   * @exception IllegalArgumentException when the defined control is <code>null</code> or not a children of
   *                                     this Composite.
   */
  public void reveal( Control control ) {
    checkRevealState( control );
    scrolledComposite.showControl( control );
  }

  /**
   * <p>
   * Checks if a control is visible within the visible area. The control needs to be completely visible for a
   * <code>true</code> result.
   * </p>
   *
   * @param control the control to check the visibility. Must not be <code>null</code>.
   *
   * @exception IllegalArgumentException when the defined control is <code>null</code> or not a children of
   *                                     this Composite.
   */
  public boolean isRevealed( Control control ) {
    checkRevealState( control );
    Point origin = scrolledComposite.getOrigin();
    Rectangle clientArea = scrolledComposite.getClientArea();
    Rectangle controlBounds = control.getBounds();
    boolean verticalVisible = ( clientArea.height + origin.y - controlBounds.y - controlBounds.height ) >= 0
                              && clientArea.height + origin.y <= controlBounds.y + clientArea.height;
    boolean horizontalVisible = ( clientArea.width + origin.x - control.getLocation().x - controlBounds.width ) >= 0
                                && ( clientArea.width + origin.x ) <= ( control.getLocation().x  + clientArea.width );
    return horizontalVisible && verticalVisible;
  }

  private void checkRevealState( Control control ) {
    whenNull( control ).throwIllegalArgument( "Child to reveal must not be null" );
    when( !containsControl( control ) ).throwIllegalArgument( "Control is not a child" );
    checkWidget();
  }

  private boolean containsControl( Control control ) {
    boolean contains = false;
    if( control != null && !control.isDisposed() ) {
      Composite parent = control.getParent();
      while( parent != null && !( parent instanceof Shell ) && !contains ) {
        if( this == parent ) {
          contains = true;
        }
        parent = parent.getParent();
      }
    }
    return contains;
  }

  @Override
  public void dispose() {
    if( scrolledComposite != null ) {
      scrolledComposite = null;
      getParent().dispose();
    }
    super.dispose();
  }

}
TOP

Related Classes of com.eclipsesource.tabris.widgets.ScrollingComposite

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.