Merge remote-tracking branch 'origin/master'
[idea/community.git] / platform / platform-api / src / com / intellij / util / ui / IconAnimator.java
1 /*
2  * Copyright 2000-2015 JetBrains s.r.o.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 package com.intellij.util.ui;
17
18 import com.intellij.openapi.Disposable;
19 import com.intellij.openapi.util.Disposer;
20 import org.jetbrains.annotations.NotNull;
21
22 import javax.swing.*;
23 import java.awt.*;
24
25 public class IconAnimator extends Animator implements Icon {
26   private final Icon myBase;
27   @NotNull private final PaintCallback myCallback;
28   private final Color[] myAlphas;
29   private int myFrame;
30   private boolean myActive;
31
32   public IconAnimator(@NotNull Disposable parent, @NotNull Icon base, @NotNull PaintCallback callback) {
33     super("IconAnimator{" + System.currentTimeMillis()+"}", base.getIconWidth(), 2000, true);
34     Disposer.register(parent, this);
35     myBase = base;
36     myCallback = callback;
37     myAlphas = initAlphas();
38   }
39
40   private Color[] initAlphas() {
41     Color[] colors = new Color[myBase.getIconWidth()];
42     for (int i = 0; i < colors.length; i++) {
43       double a = 2 * Math.PI * i / colors.length;
44       float v = (1 - (float)Math.sin(a)) / 2;
45       //noinspection UseJBColor
46       colors[i] = new Color(v, v, v, v * v * v / 16 + .05F);
47     }
48     return colors;
49   }
50
51   public void setActive(boolean active) {
52     if (myActive == active) return;
53
54     myActive = active;
55
56     if (isRunning() ^ myActive) {
57       if (myActive) {
58         resume();
59       } else {
60         suspend();
61       }
62       myCallback.paintNow(this);
63     }
64   }
65
66   @Override
67   public void paintNow(int frame, int totalFrames, int cycle) {
68     myFrame = frame;
69     myCallback.paintNow(this);
70   }
71
72   @Override
73   public void paintIcon(Component component, Graphics graphics, int x, int y) {
74     myBase.paintIcon(component, graphics, x, y);
75     if (!myActive) return;
76
77     for (int i = 0; i < myAlphas.length; i++) {
78       Color alpha = myAlphas[(i + myFrame) % myAlphas.length];
79       graphics.setColor(alpha);
80       graphics.drawRect(x + i, y, 1, getIconHeight());
81     }
82   }
83
84   @Override
85   public int getIconWidth() {
86     return myBase.getIconWidth();
87   }
88
89   @Override
90   public int getIconHeight() {
91     return myBase.getIconHeight();
92   }
93
94   public interface PaintCallback {
95     void paintNow(Icon icon);
96   }
97 }