/* * Copyright (C) Azureus Software, Inc, All Rights Reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program 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 General Public License for more details ( see the LICENSE file ). * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package com.aelitis.azureus.ui.swt.skin; import org.eclipse.swt.SWT; import org.eclipse.swt.events.*; import org.eclipse.swt.graphics.*; import org.eclipse.swt.layout.FormData; import org.eclipse.swt.widgets.*; import org.gudy.azureus2.core3.util.*; import org.gudy.azureus2.ui.swt.Utils; import com.aelitis.azureus.ui.swt.imageloader.ImageLoader; import com.aelitis.azureus.ui.swt.imageloader.ImageLoader.ImageDownloaderListener; /** * @author TuxPaper * @created Jun 12, 2006 * */ public class SWTSkinObjectImage2 extends SWTSkinObjectBasic { protected static final Long DRAW_SCALE = new Long(1); protected static final Long DRAW_SCALEDOWN_OR_CENTER = new Long(8); protected static final Long DRAW_STRETCH = new Long(2); protected static final Long DRAW_NORMAL = new Long(0); protected static final Long DRAW_LEFT = new Long(7); protected static final Long DRAW_TILE = new Long(3); protected static final Long DRAW_CENTER = new Long(4); protected static final Long DRAW_HCENTER = new Long(5); protected static final Long DRAW_ANIMATE = new Long(6); private Canvas canvas; private boolean customImage; private String customImageID; private String currentImageID; private static PaintListener paintListener; private int h_align; private int drawAlpha = 255; static { paintListener = new PaintListener() { public void paintControl(PaintEvent e) { //SWTSkinObject so = (SWTSkinObject) e.widget.getData("SkinObject"); try { e.gc.setAdvanced(true); e.gc.setInterpolation(SWT.HIGH); } catch (Exception ex) { } final Canvas control = (Canvas) e.widget; Image imgSrc = (Image) control.getData("image"); Integer drawAlpha = (Integer) control.getData("drawAlpha"); if (drawAlpha != null) { e.gc.setAlpha(drawAlpha); } //Long hpadding_obj = (Long) control.getData("hpadding"); //int hpadding = hpadding_obj == null ? 0 : hpadding_obj.intValue(); Long drawMode = (Long) control.getData("drawmode"); if (drawMode == DRAW_ANIMATE) { Image[] images = (Image[]) control.getData("images"); if (images != null) { int idx = ((Number) control.getData("ImageIndex")).intValue(); imgSrc = images[idx]; } } Image imgRight = null; Image imgLeft = null; String idToRelease = null; ImageLoader imageLoader = null; if (imgSrc == null || imgSrc.isDisposed()) { SWTSkinObjectImage2 soImage = (SWTSkinObjectImage2) control.getData("SkinObject"); imageLoader = soImage.getSkin().getImageLoader( soImage.getProperties()); String imageID = (String) control.getData("ImageID"); if (imageLoader.imageExists(imageID)) { idToRelease = imageID; Image[] images = imageLoader.getImages(imageID); if (images.length == 3) { imgLeft = images[0]; imgSrc = images[1]; imgRight = images[2]; } else { imgSrc = images[0]; } } else { return; } } Rectangle imgSrcBounds = imgSrc.getBounds(); Rectangle imgSrcBoundsAdj = Utils.adjustPXForDPI(imgSrcBounds); Point size = control.getSize(); if (drawMode == DRAW_SCALEDOWN_OR_CENTER) { if (size.x < imgSrcBounds.width || size.y < imgSrcBounds.height) { drawMode = DRAW_SCALE; } else { drawMode = DRAW_CENTER; } } if (drawMode == DRAW_STRETCH) { e.gc.drawImage(imgSrc, 0, 0, imgSrcBounds.width, imgSrcBounds.height, 0, 0, size.x, size.y); } else if (drawMode == DRAW_LEFT) { e.gc.drawImage(imgSrc, 0, 0, imgSrcBounds.width, imgSrcBounds.height, 0, 0, imgSrcBoundsAdj.width, imgSrcBoundsAdj.height); //e.gc.drawImage(imgSrc, 0, 0); } else if (drawMode == DRAW_NORMAL || drawMode == DRAW_CENTER || drawMode == DRAW_ANIMATE) { int x; int y; if ((control.getStyle() & SWT.RIGHT) != 0) { x = size.x - imgSrcBoundsAdj.width; y = (size.y - imgSrcBoundsAdj.height) / 2; } else { x = (size.x - imgSrcBoundsAdj.width) / 2; y = (size.y - imgSrcBoundsAdj.height) / 2; } e.gc.drawImage(imgSrc, 0, 0, imgSrcBounds.width, imgSrcBounds.height, x, y, imgSrcBoundsAdj.width, imgSrcBoundsAdj.height); //e.gc.drawImage(imgSrc, x, y); } else if (drawMode == DRAW_HCENTER) { int x = (size.x - imgSrcBounds.width) / 2; int y = 0; e.gc.drawImage(imgSrc, 0, 0, imgSrcBounds.width, imgSrcBounds.height, x, y, imgSrcBoundsAdj.width, imgSrcBoundsAdj.height); //e.gc.drawImage(imgSrc, x, y); } else if (drawMode == DRAW_SCALE) { float dx = (float) size.x / imgSrcBounds.width; float dy = (float) size.y / imgSrcBounds.height ; float d = Math.min(dx, dy); int newX = (int) (imgSrcBounds.width * d); int newY = (int) (imgSrcBounds.height * d); e.gc.drawImage(imgSrc, 0, 0, imgSrcBounds.width, imgSrcBounds.height, (size.x - newX) / 2, (size.y - newY) / 2, newX, newY); } else { int x0 = 0; int y0 = 0; int x1 = size.x; int y1 = size.y; if (imgRight == null) { imgRight = (Image) control.getData("image-right"); } if (imgRight != null) { int width = Utils.adjustPXForDPI(imgRight.getBounds().width); x1 -= width; } if (imgLeft == null) { imgLeft = (Image) control.getData("image-left"); } if (imgLeft != null) { // TODO: Tile down e.gc.drawImage(imgLeft, 0, 0); x0 += Utils.adjustPXForDPI(imgLeft.getBounds().width); } for (int y = y0; y < y1; y += imgSrcBoundsAdj.height) { for (int x = x0; x < x1; x += imgSrcBoundsAdj.width) { //e.gc.drawImage(imgSrc, x, y); e.gc.drawImage(imgSrc, 0, 0, imgSrcBounds.width, imgSrcBounds.height, x, y, imgSrcBoundsAdj.width, imgSrcBoundsAdj.height); } } if (imgRight != null) { // TODO: Tile down Rectangle imgRightBounds = imgRight.getBounds(); Rectangle imgRightBoundsAdj = Utils.adjustPXForDPI(imgRightBounds); e.gc.drawImage(imgRight, 0, 0, imgRightBounds.width, imgRightBounds.height, x1, 0, imgRightBoundsAdj.width, imgRightBoundsAdj.height); //e.gc.drawImage(imgRight, x1, 0); } } if (idToRelease != null && imageLoader != null) { imageLoader.releaseImage(idToRelease); } } }; } /** * @param skin * */ public SWTSkinObjectImage2(SWTSkin skin, SWTSkinProperties skinProperties, String sID, String sConfigID, SWTSkinObject parent) { super(skin, skinProperties, sID, sConfigID, "image", parent); customImage = false; customImageID = null; setControl(createImageWidget(sConfigID)); } private Canvas createImageWidget(String sConfigID) { String propImageID = properties.getStringValue(sConfigID + ".imageid"); if (propImageID != null) { currentImageID = customImageID = propImageID; } else { currentImageID = sConfigID; } int style = SWT.WRAP | SWT.DOUBLE_BUFFERED; String sAlign = properties.getStringValue(sConfigID + ".align"); if (sAlign != null && !Constants.isUnix) { h_align = SWTSkinUtils.getAlignment(sAlign, SWT.NONE); if (h_align != SWT.NONE) { style |= h_align; } } if (properties.getIntValue(sConfigID + ".border", 0) == 1) { style |= SWT.BORDER; } Composite createOn; if (parent == null) { createOn = skin.getShell(); } else { createOn = (Composite) parent.getControl(); } canvas = new Canvas(createOn, style); canvas.setData("SkinObject", this); // { // public Point computeSize(int wHint, int hHint) { // Object image = canvas.getData("image"); // Object imageID = canvas.getData("ImageID"); // if (image == null // && (imageID == null || ((String) imageID).length() == 0)) { // return new Point(0, 0); // } // return super.computeSize(wHint, hHint); // }; // // public Point computeSize(int wHint, int hHint, boolean changed) { // Object image = canvas.getData("image"); // Object imageID = canvas.getData("ImageID"); // if (image == null // && (imageID == null || ((String) imageID).length() == 0)) { // return new Point(0, 0); // } // return super.computeSize(wHint, hHint, changed); // }; // }; Color color = properties.getColor(sConfigID + ".color"); if (color != null) { canvas.setBackground(color); } final String sURL = properties.getStringValue(sConfigID + ".url"); if (sURL != null && sURL.length() > 0) { canvas.setToolTipText(sURL); canvas.addListener(SWT.MouseUp, new Listener() { public void handleEvent(Event arg0) { Utils.launch(UrlUtils.encode(sURL)); } }); } String sCursor = properties.getStringValue(sConfigID + ".cursor"); if (sCursor != null && sCursor.length() > 0) { if (sCursor.equalsIgnoreCase("hand")) { canvas.addListener(SWT.MouseEnter, skin.getHandCursorListener(canvas.getDisplay())); canvas.addListener(SWT.MouseExit, skin.getHandCursorListener(canvas.getDisplay())); } } // SWTBGImagePainter painter = (SWTBGImagePainter) parent.getData("BGPainter"); // if (painter != null) { // canvas.addListener(SWT.Paint, painter); // } canvas.addDisposeListener(new DisposeListener() { public void widgetDisposed(DisposeEvent e) { String oldImageID = (String) canvas.getData("ImageID"); if (oldImageID != null && canvas.getData("image") != null) { ImageLoader imageLoader = skin.getImageLoader(properties); imageLoader.releaseImage(oldImageID); } } }); // needed to set paint listener and canvas size swt_reallySetImage(); return canvas; } public void setVisible(boolean visible) { super.setVisible(visible); if (visible) { Utils.execSWTThread(new AERunnable() { public void runSupport() { swt_reallySetImage(); } }); } } //protected void setCanvasImage(String sConfigID, AECallback callback) { protected void setCanvasImage(String sImageID, AECallback callback) { setCanvasImage(sConfigID, sImageID, callback); } //private void setCanvasImage(final String sConfigID, final String sImageID, AECallback callback) { private void setCanvasImage(final String sConfigID, final String sImageID, AECallback callback) { Utils.execSWTThread(new AERunnableWithCallback(callback) { public Object runSupport() { if (canvas == null || canvas.isDisposed()) { return null; } canvas.setData("drawAlpha", drawAlpha); String oldImageID = (String) canvas.getData("ImageID"); if (sImageID != null && sImageID.equals(oldImageID)) { return null; } ImageLoader imageLoader = skin.getImageLoader(properties); if (oldImageID != null && canvas.getData("image") != null) { imageLoader.releaseImage(oldImageID); } int hpadding = properties.getIntValue(sConfigID + ".h-padding", 0); canvas.setData("hpadding", new Long(hpadding)); Image[] images = sImageID == null || sImageID.length() == 0 ? null : imageLoader.getImages(sImageID); String sDrawMode = properties.getStringValue(sConfigID + ".drawmode"); if (sDrawMode == null) { sDrawMode = properties.getStringValue( SWTSkinObjectImage2.this.sConfigID + ".drawmode", ""); } Long drawMode; if (sDrawMode.equals("scale")) { drawMode = DRAW_SCALE; } else if (sDrawMode.equals("scaledown")) { drawMode = DRAW_SCALEDOWN_OR_CENTER; } else if (sDrawMode.equals("stretch")) { drawMode = DRAW_STRETCH; } else if (sDrawMode.equals("center")) { drawMode = DRAW_CENTER; } else if (sDrawMode.equals("h-center")) { drawMode = DRAW_HCENTER; } else if (sDrawMode.equalsIgnoreCase("tile")) { drawMode = DRAW_TILE; } else if (sDrawMode.equalsIgnoreCase("animate") || (sDrawMode.length() == 0 && images != null && images.length > 3)) { drawMode = DRAW_ANIMATE; } else if (sDrawMode.equalsIgnoreCase("left")) { drawMode = DRAW_LEFT; } else { drawMode = DRAW_NORMAL; } canvas.setData("drawmode", drawMode); Image image = null; boolean hasExistingDelay = canvas.getData("delay") != null; canvas.setData("delay", null); if (images == null) { canvas.setData("images", null); image = null; } else if (drawMode == DRAW_ANIMATE) { int animationDelay = ImageLoader.getInstance().getAnimationDelay(sImageID); canvas.setData("images", images); canvas.setData("ImageIndex", Long.valueOf(0)); canvas.setData("delay", new Long(animationDelay)); image = images[0]; if (!hasExistingDelay) { setupAnimationTrigger(animationDelay); } } else if (images.length == 3) { Image imageLeft = images[0]; if (ImageLoader.isRealImage(imageLeft)) { canvas.setData("image-left", imageLeft); } image = images[1]; Image imageRight = images[2]; if (ImageLoader.isRealImage(imageRight)) { canvas.setData("image-right", imageRight); } } else if (images.length > 0) { image = images[0]; } if (image == null || image.isDisposed()) { image = ImageLoader.noImage; } //allowImageDimming = sDrawMode.equalsIgnoreCase("dim"); Rectangle imgBounds = image.getBounds(); //imgBounds = Utils.adjustPXForDPI(canvas.getDisplay(), imgBounds); if (drawMode != DRAW_CENTER && drawMode != DRAW_HCENTER && drawMode != DRAW_STRETCH && drawMode != DRAW_SCALEDOWN_OR_CENTER) { canvas.setSize(imgBounds.width + hpadding, imgBounds.height); canvas.setData("oldSize", canvas.getSize()); } //canvas.setData("image", image); if (drawMode == DRAW_TILE || drawMode == DRAW_NORMAL || drawMode == DRAW_LEFT || drawMode == DRAW_ANIMATE) { // XXX Huh? A tile of one? :) FormData fd = (FormData) canvas.getLayoutData(); if (fd == null) { fd = new FormData(imgBounds.width + hpadding, imgBounds.height); } else { fd.width = imgBounds.width + hpadding; fd.height = imgBounds.height; } canvas.setData("oldSize", new Point(fd.width, fd.height)); canvas.setLayoutData(fd); Utils.relayout(canvas); } // remove in case already added canvas.removePaintListener(paintListener); canvas.addPaintListener(paintListener); canvas.setData("ImageID", sImageID); canvas.redraw(); SWTSkinUtils.addMouseImageChangeListeners(canvas); if (drawMode != DRAW_ANIMATE) { imageLoader.releaseImage(sImageID); } return null; } }); } protected void setupAnimationTrigger(int animationDelay) { Utils.execSWTThreadLater(animationDelay, new AERunnable() { public void runSupport() { if (!control.isDisposed()) { Object data = control.getData("delay"); if (data == null) { return; } Image[] images = (Image[]) control.getData("images"); int idx = ((Number) control.getData("ImageIndex")).intValue(); idx++; if (idx >= images.length) { idx = 0; } control.setData("ImageIndex", new Long(idx)); control.redraw(); int delay = ((Number) control.getData("delay")).intValue(); setupAnimationTrigger(delay); } } }); } // @see com.aelitis.azureus.ui.swt.skin.SWTSkinObject#setBackground(java.lang.String, java.lang.String) public void setBackground(String sConfigID, String sSuffix) { // No background for images? } // @see com.aelitis.azureus.ui.swt.skin.SWTSkinObject#switchSuffix(java.lang.String) public String switchSuffix(String suffix, int level, boolean walkUp, boolean walkDown) { suffix = super.switchSuffix(suffix, level, walkUp, walkDown); if (customImage) { return suffix; } if (suffix == null) { return null; } final String fSuffix = suffix; Utils.execSWTThread(new AERunnable() { public void runSupport() { currentImageID = (customImageID == null ? (sConfigID + ".image") : customImageID) + fSuffix; if (isVisible()) { swt_reallySetImage(); } } }); return suffix; } protected void swt_reallySetImage() { if (currentImageID == null || customImage) { drawAlpha = 255; return; } boolean removedDisabled = false; ImageLoader imageLoader = skin.getImageLoader(properties); boolean imageExists = imageLoader.imageExists(currentImageID); if (!imageExists && imageLoader.imageExists(currentImageID + ".image")) { currentImageID = sConfigID + ".image"; imageExists = true; } if (!imageExists && suffixes != null) { for (int i = suffixes.length - 1; i >= 0; i--) { String suffixToRemove = suffixes[i]; if (suffixToRemove != null) { if (suffixToRemove.equals("-disabled")) { removedDisabled = true; } currentImageID = currentImageID.substring(0, currentImageID.length() - suffixToRemove.length()); if (imageLoader.imageExists(currentImageID)) { imageExists = true; break; } } } } if (imageExists) { drawAlpha = removedDisabled ? 64 : 255; setCanvasImage(currentImageID, null); } else { drawAlpha = 255; Utils.execSWTThread(new AERunnable() { public void runSupport() { FormData fd = (FormData) canvas.getLayoutData(); if (fd == null) { fd = new FormData(0, 0); } else { fd.width = 0; fd.height = 0; } canvas.setLayoutData(fd); if (initialized) { Utils.relayout(canvas); } } }); } } public void setImage(final Image image) { Utils.execSWTThread(new AERunnable() { public void runSupport() { customImage = true; customImageID = null; drawAlpha = 255; canvas.setData("image", image); canvas.setData("ImageID", null); canvas.setData("image-left", null); canvas.setData("image-right", null); canvas.setData("drawAlpha", null); canvas.removePaintListener(paintListener); canvas.addPaintListener(paintListener); Utils.relayout(canvas); canvas.redraw(); } }); } public void setImageByID(final String imageID, final AECallback callback) { if (!customImage && customImageID != null && customImageID.equals(imageID)) { if (callback != null) { callback.callbackFailure(null); } return; } customImage = false; customImageID = imageID; if (imageID == null) { setCanvasImage(this.sConfigID, null, null); return; } Utils.execSWTThread(new AERunnable() { public void runSupport() { String fullImageID = imageID + getSuffix(); ImageLoader imageLoader = skin.getImageLoader(properties); Image image = imageLoader.getImage(fullImageID); if (ImageLoader.isRealImage(image)) { setCanvasImage(sConfigID, fullImageID, callback); } else { setCanvasImage(sConfigID, imageID, callback); } imageLoader.releaseImage(fullImageID); } }); } public void setImageUrl(final String url) { if (!customImage && customImageID != null && customImageID.equals(url)) { return; } customImage = false; customImageID = url; Utils.execSWTThread(new AERunnable() { public void runSupport() { final ImageLoader imageLoader = skin.getImageLoader(properties); imageLoader.getUrlImage(url, new ImageDownloaderListener() { public void imageDownloaded(Image image, boolean returnedImmediately) { setCanvasImage(url, null); imageLoader.releaseImage(url); } }); } }); } }