From 841cf9ff10bceca70683190a92ac24aa616e9403 Mon Sep 17 00:00:00 2001 From: "Egor.Ushakov" Date: Mon, 20 Feb 2017 17:39:02 +0300 Subject: [PATCH] IDEA-167963 Animation for breakpoint removal --- .../impl/EditorGutterComponentImpl.java | 12 ++-- .../openapi/editor/impl/EditorImpl.java | 62 ++++++++----------- 2 files changed, 35 insertions(+), 39 deletions(-) diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorGutterComponentImpl.java b/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorGutterComponentImpl.java index d77db43cfa4c..94ec4c898a31 100644 --- a/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorGutterComponentImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorGutterComponentImpl.java @@ -226,16 +226,20 @@ class EditorGutterComponentImpl extends EditorGutterComponentEx implements Mouse return true; }) .setImageProvider((NullableFunction)info -> { - Image image = IconUtil.toImage(scaleIcon(getGutterRenderer(info.getPoint()).getIcon())); - // [tav] temp workaround for JRE-224 - boolean inUserScale = SystemInfo.isWindows ? !UIUtil.isJreHiDPI(myEditor.getComponent()) : true; - image = ImageUtil.toBufferedImage(image, inUserScale); + Image image = getDragImage(getGutterRenderer(info.getPoint())); return new DnDImage(image, new Point(image.getWidth(null) / 2, image.getHeight(null) / 2)); }) .enableAsNativeTarget() // required to accept dragging from editor (as editor component doesn't use DnDSupport to implement drag'n'drop) .install(); } + Image getDragImage(GutterMark renderer) { + Image image = IconUtil.toImage(scaleIcon(renderer.getIcon())); + // [tav] temp workaround for JRE-224 + boolean inUserScale = SystemInfo.isWindows ? !UIUtil.isJreHiDPI(myEditor.getComponent()) : true; + return ImageUtil.toBufferedImage(image, inUserScale); + } + private void fireResized() { processComponentEvent(new ComponentEvent(this, ComponentEvent.COMPONENT_RESIZED)); } diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorImpl.java b/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorImpl.java index 6be46e58096d..fde8307a76dd 100644 --- a/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorImpl.java @@ -4135,59 +4135,51 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi private static class ExplosionPainter extends AbstractPainter { private final Point myExplosionLocation; - private static final long TIME_PER_FRAME = 50; + private final Image myImage; + + private static final long TIME_PER_FRAME = 30; + private final int myWidth; + private final int myHeight; private long lastRepaintTime = System.currentTimeMillis(); - private int spriteIndex; - private static final int SPRITE_SIZE = 64; - private static final int SPRITES_IN_ROW = 4; + private int frameIndex; + private static final int TOTAL_FRAMES = 8; - private final Image [] sprites = new Image [16]; private final AtomicBoolean nrp = new AtomicBoolean(true); - ExplosionPainter(final Point explosionLocation) { + ExplosionPainter(final Point explosionLocation, Image image) { myExplosionLocation = new Point(explosionLocation.x, explosionLocation.y); - Image explosionImage = ImageLoader.loadFromResource("/debugger/explosion.png"); - - for (int i = 0; i < sprites.length; i ++) { - sprites[i] = initSprites(i, explosionImage); - } - } - - private static BufferedImage initSprites(int index, Image explosionImage) { - BufferedImage spriteImage = UIUtil.createImage(SPRITE_SIZE, SPRITE_SIZE, BufferedImage.TYPE_INT_ARGB); - Graphics2D spriteGraphics = (Graphics2D)spriteImage.getGraphics(); - int sourceX = SPRITE_SIZE * (index % SPRITES_IN_ROW); - int sourceY = SPRITE_SIZE * (index / SPRITES_IN_ROW); - spriteGraphics.drawImage(explosionImage, - 0, 0, SPRITE_SIZE, SPRITE_SIZE, - sourceX, sourceY, sourceX + 64, sourceY + 64, - null); - return spriteImage; + myImage = image; + myWidth = myImage.getWidth(null); + myHeight = myImage.getHeight(null); } @Override public void executePaint(Component component, Graphics2D g) { - if (!nrp.get()) return; - int x = myExplosionLocation.x - 32; - int y = myExplosionLocation.y - 32; - long currentTimeMillis = System.currentTimeMillis(); + + float alpha = 1 - (float)frameIndex / TOTAL_FRAMES; + g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, alpha)); + Image scaledImage = ImageUtil.scaleImage(myImage, alpha); + + int x = myExplosionLocation.x - scaledImage.getWidth(null) / 2; + int y = myExplosionLocation.y - scaledImage.getHeight(null) / 2; + if (currentTimeMillis - lastRepaintTime < TIME_PER_FRAME) { - UIUtil.drawImage(g, sprites[spriteIndex], x, y, null); - JobScheduler.getScheduler().schedule(() -> component.repaint(x, y, 12, 64), TIME_PER_FRAME, TimeUnit.MILLISECONDS); + UIUtil.drawImage(g, scaledImage, x, y, null); + JobScheduler.getScheduler().schedule(() -> component.repaint(x, y, myWidth, myHeight), TIME_PER_FRAME, TimeUnit.MILLISECONDS); return; } lastRepaintTime = currentTimeMillis; - - UIUtil.drawImage(g, sprites[spriteIndex++], x, y, null); - if (spriteIndex == sprites.length) { + frameIndex++; + UIUtil.drawImage(g, scaledImage, x, y, null); + if (frameIndex == TOTAL_FRAMES) { nrp.set(false); ApplicationManager.getApplication().invokeLater(() -> IdeGlassPaneUtil.find(component).removePainter(this)); - component.repaint(x, y, SPRITE_SIZE, SPRITE_SIZE); + component.repaint(x, y, myWidth, myHeight); } - component.repaint(x, y, SPRITE_SIZE, SPRITE_SIZE); + component.repaint(x, y, myWidth, myHeight); } @Override @@ -4217,7 +4209,7 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi new Point( mouseLocationOnScreen.x - editorComponentLocationOnScreen.x, mouseLocationOnScreen.y - editorComponentLocationOnScreen.y - ) + ), editor.getGutterComponentEx().getDragImage((GutterIconRenderer)attachedObject) ), editor.getDisposable() );