Source code file content

Revision: 3

Using Timeline.abort and Timeline.setCycleDelay in the relevant animations
» Project Revision History

» Checkout URL

granite / src / org / pushingpixels / granite / content / Stage1LoadingProgress.java

Size: 10665 bytes, 1 line
/*
 * Copyright (c) 2009 Granite Kirill Grouchnikov. All Rights Reserved.
 *
 * Redistribution and use in source and binary forms, with or without 
 * modification, are permitted provided that the following conditions are met:
 * 
 *  o Redistributions of source code must retain the above copyright notice, 
 *    this list of conditions and the following disclaimer. 
 *     
 *  o Redistributions in binary form must reproduce the above copyright notice, 
 *    this list of conditions and the following disclaimer in the documentation 
 *    and/or other materials provided with the distribution. 
 *     
 *  o Neither the name of Granite Kirill Grouchnikov nor the names of 
 *    its contributors may be used to endorse or promote products derived 
 *    from this software without specific prior written permission. 
 *     
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 
 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 
 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
 */
package org.pushingpixels.granite.content;

import org.eclipse.swt.SWT;
import org.eclipse.swt.events.PaintEvent;
import org.eclipse.swt.events.PaintListener;
import org.eclipse.swt.graphics.*;
import org.eclipse.swt.widgets.*;
import org.pushingpixels.trident.Timeline;
import org.pushingpixels.trident.Timeline.RepeatBehavior;
import org.pushingpixels.trident.Timeline.TimelineState;
import org.pushingpixels.trident.callback.UIThreadTimelineCallbackAdapter;
import org.pushingpixels.trident.swt.SWTRepaintCallback;

/**
 * Adds the following functionality to the album scroller container:
 * 
 * <ul>
 * <li>Overlaying an indefinite load progress indicator on top of the container
 * children</li>
 * <li>Changes in load progress indicator visibility are animated to fade in and
 * fade out</li>
 * </ul>
 * 
 * @author Kirill Grouchnikov
 */
public class Stage1LoadingProgress extends Stage0Base {
	/**
	 * The looping timeline to animate the indefinite load progress. When
	 * {@link #setLoading(boolean)} is called with <code>true</code>, this
	 * timeline is started. When {@link #setLoading(boolean)} is called with
	 * <code>false</code>, this timeline is cancelled at the end of the
	 * {@link #loadingBarFadeTimeline}.
	 */
	Timeline loadingBarLoopTimeline;

	/**
	 * The timeline for showing and hiding the loading progress bar. When
	 * {@link #setLoading(boolean)} is called with <code>true</code>, this
	 * timeline is started. When {@link #setLoading(boolean)} is called with
	 * <code>false</code>, this timeline is started in reverse.
	 */
	Timeline loadingBarFadeTimeline;

	/**
	 * The pixel width of the load progress visuals.
	 */
	static final int PROGRESS_WIDTH = 300;

	/**
	 * The pixel height of the load progress visuals.
	 */
	static final int PROGRESS_HEIGHT = 32;

	protected ProgressBarIndicator progressIndicator;

	protected static class ProgressBarIndicator extends Canvas {
		/**
		 * The current position of the {@link #loadingBarLoopTimeline}.
		 */
		float loadingBarLoopPosition;

		/**
		 * The current alpha value of the loading progress bar. Is updated by
		 * the {@link #loadingBarFadeTimeline}.
		 */
		int loadingBarAlpha;

		public ProgressBarIndicator(Composite composite) {
			super(composite, SWT.TRANSPARENT | SWT.DOUBLE_BUFFERED
					| SWT.NO_BACKGROUND);
			this.loadingBarAlpha = 0;

			this.addPaintListener(new PaintListener() {
				@Override
				public void paintControl(PaintEvent e) {
					if (loadingBarAlpha > 0) {
						int width = getBounds().width;
						int height = getBounds().height;

						GC gc = e.gc;
						gc.setAntialias(SWT.ON);
						gc.setAlpha(loadingBarAlpha);

						Color fill1 = new Color(e.display, 156, 208, 221);
						Color fill2 = new Color(e.display, 101, 183, 243);
						Pattern pFill1 = new Pattern(e.display, 0, 0, 0,
								height / 2.0f, fill1, loadingBarAlpha, fill2,
								loadingBarAlpha);
						gc.setBackgroundPattern(pFill1);
						gc.fillRectangle(0, 0, width, height / 2);
						fill1.dispose();
						fill2.dispose();
						pFill1.dispose();

						Color fill3 = new Color(e.display, 67, 169, 241);
						Color fill4 = new Color(e.display, 138, 201, 247);
						Pattern pFill2 = new Pattern(e.display, 0,
								height / 2.0f, 0, height, fill3,
								loadingBarAlpha, fill4, loadingBarAlpha);
						gc.setBackgroundPattern(pFill2);
						gc.fillRectangle(0, height / 2, width, height / 2);
						fill3.dispose();
						fill4.dispose();
						pFill2.dispose();

						int stripeCellWidth = 25;
						Color stripe1 = new Color(e.display, 36, 155, 239);
						Color stripe2 = new Color(e.display, 17, 145, 238);
						Pattern pStripe1 = new Pattern(e.display, 0, 0, 0,
								height / 2.0f, stripe1, loadingBarAlpha,
								stripe2, loadingBarAlpha);
						Color stripe3 = new Color(e.display, 15, 56, 200);
						Color stripe4 = new Color(e.display, 3, 133, 219);
						Pattern pStripe2 = new Pattern(e.display, 0, 0, 0,
								height / 2.0f, stripe3, loadingBarAlpha,
								stripe4, loadingBarAlpha);

						int stripeWidth = 10;
						gc.setLineAttributes(new LineAttributes(9.0f));
						for (int stripeX = (int) (loadingBarLoopPosition * stripeCellWidth); stripeX < width
								+ height; stripeX += stripeCellWidth) {
							gc.setBackgroundPattern(pStripe1);
							gc.fillPolygon(new int[] {
									stripeX - stripeWidth / 2,
									0,
									stripeX + stripeWidth / 2,
									0,
									stripeX - stripeCellWidth / 2 + stripeWidth
											/ 2,
									height / 2,
									stripeX - stripeCellWidth / 2 - stripeWidth
											/ 2, height / 2 });
							gc.setBackgroundPattern(pStripe2);
							gc
									.fillPolygon(new int[] {
											stripeX - stripeCellWidth / 2
													- stripeWidth / 2,
											height / 2,
											stripeX - stripeCellWidth / 2
													+ stripeWidth / 2,
											height / 2,
											stripeX - stripeCellWidth
													+ stripeWidth / 2,
											height,
											stripeX - stripeCellWidth
													- stripeWidth / 2, height });
						}
						stripe1.dispose();
						stripe2.dispose();
						stripe3.dispose();
						stripe4.dispose();
						pStripe1.dispose();
						pStripe2.dispose();

						gc.setForeground(e.display
								.getSystemColor(SWT.COLOR_GRAY));
						float lineWeight = 1.3f;
						gc.setLineAttributes(new LineAttributes(lineWeight));
						Path outline = new Path(e.display);
						outline.moveTo(0, 0);
						outline.lineTo(width - lineWeight, 0);
						outline.lineTo(width - lineWeight, height - lineWeight);
						outline.lineTo(0, height - lineWeight);
						outline.close();
						gc.drawPath(outline);
						outline.dispose();
					}
				}
			});
		}

		/**
		 * Sets the new alpha value of the loading progress bar. Is called by
		 * the {@link #loadingBarFadeTimeline}.
		 * 
		 * @param loadingBarAlpha
		 *            The new alpha value of the loading progress bar.
		 */
		public void setLoadingBarAlpha(int loadingBarAlpha) {
			this.loadingBarAlpha = loadingBarAlpha;
		}

		/**
		 * Sets the new loop position of the loading progress bar. Is called by
		 * the {@link #loadingBarLoopTimeline}.
		 * 
		 * @param loadingBarLoopPosition
		 *            The new loop position of the loading progress bar.
		 */
		public void setLoadingBarLoopPosition(float loadingBarLoopPosition) {
			this.loadingBarLoopPosition = loadingBarLoopPosition;
		}
	}

	/**
	 * Creates a container with support for showing load progress.
	 */
	public Stage1LoadingProgress(Composite composite) {
		super(composite);

		this.progressIndicator = new ProgressBarIndicator(this);
		this.setLayout(new Layout() {
			@Override
			protected void layout(Composite composite, boolean flushCache) {
				int w = composite.getBounds().width;
				int h = composite.getBounds().height;
				// put the progress indication in the center
				progressIndicator.setBounds((w - PROGRESS_WIDTH) / 2,
						(h - PROGRESS_HEIGHT) / 2, PROGRESS_WIDTH,
						PROGRESS_HEIGHT);
			}

			@Override
			protected Point computeSize(Composite composite, int wHint,
					int hHint, boolean flushCache) {
				return new Point(wHint, hHint);
			}
		});

		this.loadingBarLoopTimeline = new Timeline(this.progressIndicator);
		this.loadingBarLoopTimeline.addPropertyToInterpolate(
				"loadingBarLoopPosition", 0.0f, 1.0f);
		this.loadingBarLoopTimeline.addCallback(new SWTRepaintCallback(this));
		this.loadingBarLoopTimeline.setDuration(750);

		// create the fade timeline
		this.loadingBarFadeTimeline = new Timeline(this.progressIndicator);
		this.loadingBarFadeTimeline.addPropertyToInterpolate("loadingBarAlpha",
				0, 255);
		this.loadingBarFadeTimeline
				.addCallback(new UIThreadTimelineCallbackAdapter() {
					@Override
					public void onTimelineStateChanged(TimelineState oldState,
							TimelineState newState, float durationFraction,
							float timelinePosition) {
						if (oldState == TimelineState.PLAYING_REVERSE
								&& newState == TimelineState.DONE) {
							// after the loading progress is faded out, stop the
							// loading
							// animation
							loadingBarLoopTimeline.cancel();
							progressIndicator.setVisible(false);
						}
					}
				});
		this.loadingBarFadeTimeline.setDuration(500);
	}

	/**
	 * Starts or stops the loading progress animation.
	 * 
	 * @param isLoading
	 *            if <code>true</code>, this container will display a loading
	 *            progress animation, if <code>false</code>, the loading
	 *            progress animation will be stopped.
	 */
	public void setLoading(boolean isLoading) {
		if (isLoading) {
			this.loadingBarFadeTimeline.play();
			this.loadingBarLoopTimeline.playLoop(RepeatBehavior.LOOP);
		} else {
			this.loadingBarFadeTimeline.playReverse();
		}
	}
}
  • Mysql
  • Glassfish
  • Jruby
  • Rails
  • Nblogo
Terms of Use; Privacy Policy;
© 2010, Oracle Corporation and/or its affiliates
(revision 20100521.d19488a)
 
 
loading
Please Confirm