/******************************************************************************* * Copyright (c) 2000-present Liferay, Inc. All rights reserved. * * This library is free software; you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License as published by the Free * Software Foundation; either version 2.1 of the License, or (at your option) * any later version. * * This library is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more * details. * *******************************************************************************/ package com.liferay.ide.project.ui.upgrade.animated; import com.liferay.ide.project.ui.ProjectUI; import java.net.URL; import java.util.ArrayList; import java.util.List; import org.eclipse.jface.resource.ImageDescriptor; import org.eclipse.swt.SWT; import org.eclipse.swt.events.DisposeEvent; import org.eclipse.swt.events.DisposeListener; import org.eclipse.swt.events.FocusEvent; import org.eclipse.swt.events.FocusListener; import org.eclipse.swt.events.MouseAdapter; import org.eclipse.swt.events.MouseEvent; import org.eclipse.swt.events.MouseMoveListener; import org.eclipse.swt.events.MouseTrackAdapter; import org.eclipse.swt.events.PaintEvent; import org.eclipse.swt.events.PaintListener; import org.eclipse.swt.graphics.Color; import org.eclipse.swt.graphics.Font; import org.eclipse.swt.graphics.FontData; import org.eclipse.swt.graphics.GC; import org.eclipse.swt.graphics.Image; import org.eclipse.swt.graphics.Point; import org.eclipse.swt.graphics.Rectangle; import org.eclipse.swt.graphics.Resource; import org.eclipse.swt.widgets.Canvas; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Display; /** * @author Simon Jiang * @author Andy Wu */ public abstract class AbstractCanvas extends Canvas { private static final int DEFAULT_TIMER_INTERVAL = 10; public static final int NONE = -1; protected long currentTime = 0L; public static Rectangle drawText( GC gc, double cX, double cY, String text ) { return drawText( gc, cX, cY, text, 0 ); } public static Rectangle drawText( GC gc, double cX, double cY, String text, int box ) { Point extent = gc.stringExtent( text ); int x = (int) ( cX - extent.x / 2 ); int y = (int) ( cY - extent.y / 2 ); if( x < box ) { x = box; } Rectangle rectangle = new Rectangle( x, y, extent.x, extent.y ); if( box > 0 ) { rectangle.x -= box; rectangle.y -= box; rectangle.width += 2 * box; rectangle.height += 2 * box; gc.fillRectangle( rectangle ); } gc.drawText( text, x, y, true ); return rectangle; } public static Rectangle drawTextNotCenter( GC gc, int cX, int cY, String text, int box ) { Point extent = gc.stringExtent( text ); int x = (int) ( cX - extent.x / 2 ); if( x < box ) { x = box; } Rectangle rectangle = new Rectangle( cX, cY, extent.x, extent.y ); if( box > 0 ) { rectangle.x -= box; rectangle.y -= box; rectangle.width += 2 * box; rectangle.height += 2 * box; gc.fillRectangle( rectangle ); } // System.out.println( x+" "+y+" "+extent.x+" "+extent.y +" "+rectangle.x+" "+rectangle.y+" "+rectangle.width+" // "+rectangle.height); gc.drawText( text, cX, cY, true ); return rectangle; } protected Font baseFont; private final List<Resource> resources = new ArrayList<Resource>(); private final Runnable runnable = new Runnable() { public void run() { doRun(); } }; public AbstractCanvas( Composite parent, int style ) { super( parent, style | SWT.DOUBLE_BUFFERED ); addFocusListener( new FocusListener() { public void focusGained( FocusEvent e ) { redraw(); } public void focusLost( FocusEvent e ) { redraw(); } } ); addDisposeListener( new DisposeListener() { @Override public void widgetDisposed( DisposeEvent e ) { dispose(); } } ); addMouseTrackListener( new MouseTrackAdapter() { @Override public void mouseExit( MouseEvent e ) { onMouseMove( Integer.MIN_VALUE, Integer.MIN_VALUE ); } } ); addMouseMoveListener( new MouseMoveListener() { public void mouseMove( MouseEvent e ) { onMouseMove( e.x, e.y ); } } ); addMouseListener( new MouseAdapter() { @Override public void mouseDown( MouseEvent e ) { // left button if( e.button == 1 ) { onMouseDown( e.x, e.y ); } } } ); addPaintListener( new PaintListener() { @Override public void paintControl( PaintEvent e ) { Image buffer = new Image( getDisplay(), getBounds() ); GC canvasGc = e.gc; GC bufferGC = new GC( buffer ); bufferGC.setAdvanced( true ); bufferGC.setBackground( canvasGc.getBackground() ); bufferGC.fillRectangle( buffer.getBounds() ); paint( bufferGC ); canvasGc.drawImage( buffer, 0, 0 ); bufferGC.dispose(); buffer.dispose(); scheduleRun(); } } ); } protected final Color createColor( int r, int g, int b ) { Display display = getDisplay(); Color color = new Color( display, r, g, b ); resources.add( color ); return color; } protected final Font createFont( int pixelHeight ) { return createFont( pixelHeight, 0 ); } protected final Font createFont( int pixelHeight, int pixelWidth, String... testStrings ) { if( testStrings.length == 0 ) { pixelWidth = Integer.MAX_VALUE; testStrings = new String[] { "Ag" }; } Display display = getDisplay(); GC fontGC = new GC( display ); try { FontData[] fontData = baseFont.getFontData(); int fontSize = 40; while( fontSize > 0 ) { for( int i = 0; i < fontData.length; i++ ) { fontData[i].setHeight( fontSize ); fontData[i].setStyle( SWT.BOLD ); } Font font = new Font( display, fontData ); fontGC.setFont( font ); if( isFontSmallEnough( pixelHeight, pixelWidth, fontGC, testStrings ) ) { resources.add( font ); return font; } font.dispose(); --fontSize; } throw new RuntimeException( "Could not create font: " + pixelHeight ); } finally { fontGC.dispose(); } } @Override public void dispose() { for( Resource resource : resources ) { if( resource != null && !resource.isDisposed() ) { resource.dispose(); } } } protected synchronized void doRun() { if( isDisposed() ) { return; } currentTime += 20; boolean needsRedraw = needRedraw(); if( needsRedraw ) { redraw(); } else { scheduleRun(); } } public Rectangle drawImage( GC gc, Image image, int cX, int cY ) { Rectangle bounds = image.getBounds(); cX -= bounds.width / 2; cY -= bounds.height / 2; gc.drawImage( image, cX, cY ); return new Rectangle( cX, cY, bounds.width, bounds.height ); } protected final Font getBaseFont() { return baseFont; } protected void init() { Display display = getDisplay(); Font initialFont = getFont(); FontData[] fontData = initialFont.getFontData(); for( int i = 0; i < fontData.length; i++ ) { fontData[i].setHeight( 16 ); fontData[i].setStyle( SWT.BOLD ); } baseFont = new Font( display, fontData ); } private boolean isFontSmallEnough( int pixelHeight, int pixelWidth, GC fontGC, String[] testStrings ) { for( String testString : testStrings ) { Point extent = fontGC.stringExtent( testString ); if( extent.y > pixelHeight || extent.x > pixelWidth ) { return false; } } return true; } protected final Image loadImage( String name ) { URL url = null; try { url = ProjectUI.getDefault().getBundle().getEntry( "images/" + name ); } catch( Exception e ) { } ImageDescriptor imagedesc = ImageDescriptor.createFromURL( url ); Image image = imagedesc.createImage(); resources.add( image ); return image; } protected abstract boolean needRedraw(); protected abstract void onMouseDown( int x, int y ); protected abstract void onMouseMove( int x, int y ); protected abstract void paint( GC bufferGC ); protected void scheduleRun() { getDisplay().timerExec( DEFAULT_TIMER_INTERVAL, runnable ); } }