/*** * * Copyright (C) 2008 Alessandro La Rosa * * 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 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. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * Contact: alessandro.larosa@gmail.com * * Author: Alessandro La Rosa */ import javax.microedition.lcdui.Canvas; import javax.microedition.lcdui.Graphics; import javax.microedition.lcdui.Image; public class SlidingImage { // constants defining the 2 types of sliding public static final int SLIDE_IN = 0; public static final int SLIDE_OUT = 1; // image type of sliding public int slideType = SLIDE_OUT; // pieces of the sliding image public int pieces = 4; // direction of sliding (up, right, down or left) public int direction = Canvas.LEFT; // image object and properties Image image = null; int imageWidth = 0; int imageHeight = 0; // transition time properties int duration = 0; long startTime = 0; // transition state public boolean sliding = false; public boolean ended = false; /** * Class constructor * * @param image image to be slided * @param pieces number of pieces of the sliding image * @param slideType type of slide, can be SLIDE_IN or SLIDE_OUT */ public SlidingImage(Image image, int pieces, int slideType) { this.image = image; this.imageWidth = image.getWidth(); this.imageHeight = image.getHeight(); this.slideType = slideType; this.pieces = pieces; } /** * Resets the image to its starting state * */ public void reset() { ended = false; sliding = false; } /** * Resets the image to its starting state, specifying new pieces and slideType values * * @param pieces number of pieces of the sliding image * @param slideType type of slide, can be SLIDE_IN or SLIDE_OUT */ public void reset(int pieces, int slideType) { reset(); this.pieces = pieces; this.slideType = slideType; } /** * Starts the sliding effect * * @param direction direction of sliding (Canvas.UP, RIGHT, DOWN or LEFT) * @param duration duration of sliding in milliseconds */ public void slide(int direction, int duration) { this.direction = direction; this.duration = duration; this.startTime = System.currentTimeMillis(); ended = false; sliding = true; } /** * Draws the sliding image by using the anchor point * * @param g Graphics object to paint the image * @param x the x coordinate of the anchor point * @param y the y coordinate of the anchor point * @param anchor the anchor point for positioning the image */ public void paint(Graphics g, int x, int y, int anchor) { if(!sliding && ((ended && slideType == SLIDE_IN) || (!ended && slideType == SLIDE_OUT))) { g.drawImage(image, x, y, anchor); } else if(sliding) { // we translate accordingly to coordinates and anchor point int translateX = (anchor & Graphics.RIGHT) > 0 ? x - imageWidth : ((anchor & Graphics.HCENTER) > 0 ? x - imageWidth / 2 : x); int translateY = (anchor & Graphics.BOTTOM) > 0 ? y - imageHeight : ((anchor & Graphics.VCENTER) > 0 ? y - imageHeight / 2 : y); g.translate(translateX, translateY); // now we get current clipping properties int cx, cy, cw, ch; cx = g.getClipX(); cy = g.getClipY(); cw = g.getClipWidth(); ch = g.getClipHeight(); // let's get current duration and check if effect has ended int timeDiff = (int)(System.currentTimeMillis() - startTime); if(timeDiff > duration) { timeDiff = duration; ended = true; sliding = false; } // if it's a SLIDE_IN effect, we reverse the current time if(slideType == SLIDE_IN) { timeDiff = duration - timeDiff; } // now, let's pre-calculate some coords/properties int pieceEnd = 0; int pieceCoord = 0; int pieceSize = (direction == Canvas.LEFT || direction == Canvas.RIGHT) ? imageHeight / pieces : imageWidth / pieces; int singleSlideDuration = (int)duration / pieces; switch(direction) { case Canvas.LEFT: pieceEnd = cx - imageWidth;break; case Canvas.RIGHT: pieceEnd = cx + cw;break; case Canvas.UP: pieceEnd = cy - imageHeight;break; case Canvas.DOWN: pieceEnd = cy + ch;break; } // finally, we can paint single slide pieces for(int i = 0; i < pieces; i++) { // check if this piece has not to be painted (is out of clipping region) if(timeDiff > (i + 1) * singleSlideDuration) { continue; } else { pieceCoord = (timeDiff < i * singleSlideDuration) ? 0 : pieceEnd * (timeDiff - i * singleSlideDuration) / singleSlideDuration; if(direction == Canvas.LEFT || direction == Canvas.RIGHT) { g.setClip(pieceCoord, i * pieceSize, imageWidth, pieceSize); g.drawImage(image, pieceCoord, 0, Graphics.TOP | Graphics.LEFT); } else { g.setClip(i * pieceSize, pieceCoord, pieceSize, imageHeight); g.drawImage(image, 0, pieceCoord, Graphics.TOP | Graphics.LEFT); } } } //restore clipping properties and translate back g.setClip(cx, cy, cw, ch); g.translate(- translateX, - translateY); } } }