import com.intellij.util.SmartList;
import com.intellij.util.concurrency.Semaphore;
import com.intellij.util.containers.ContainerUtil;
+import com.intellij.util.ui.IconAnimator;
import gnu.trove.THashMap;
import gnu.trove.THashSet;
import org.jetbrains.annotations.NotNull;
private final Map<RunContentListener, Disposable> myListeners = new THashMap<RunContentListener, Disposable>();
private final LinkedList<String> myToolwindowIdZBuffer = new LinkedList<String>();
+ private final Map<String, IconAnimator> myIconAnimators = new THashMap<String, IconAnimator>();
public RunContentManagerImpl(@NotNull Project project, @NotNull DockManager dockManager) {
myProject = project;
return;
}
- ToolWindow toolWindow = toolWindowManager.registerToolWindow(toolWindowId, true, ToolWindowAnchor.BOTTOM, this, true);
+ final ToolWindow toolWindow = toolWindowManager.registerToolWindow(toolWindowId, true, ToolWindowAnchor.BOTTOM, this, true);
final ContentManager contentManager = toolWindow.getContentManager();
contentManager.addDataProvider(new DataProvider() {
private int myInsideGetData = 0;
}
});
myToolwindowIdToContentManagerMap.put(toolWindowId, contentManager);
+ final IconAnimator iconAnimator = new IconAnimator(contentManager, executor.getToolWindowIcon(), new IconAnimator.PaintCallback() {
+ @Override
+ public void paintNow(Icon icon) {
+ if (toolWindow.isDisposed()) return;
+ toolWindow.setIcon(null);
+ toolWindow.setIcon(icon);
+ }
+ });
+ myIconAnimators.put(toolWindowId, iconAnimator);
Disposer.register(contentManager, new Disposable() {
@Override
public void dispose() {
myToolwindowIdToContentManagerMap.remove(toolWindowId).removeAllContents(true);
myToolwindowIdZBuffer.remove(toolWindowId);
+ myIconAnimators.remove(toolWindowId);
}
});
myToolwindowIdZBuffer.addLast(toolWindowId);
showRunContent(executor, descriptor, descriptor.getExecutionId());
}
- public void showRunContent(@NotNull final Executor executor, @NotNull final RunContentDescriptor descriptor, long executionId) {
+ public void showRunContent(@NotNull final Executor executor, @NotNull final RunContentDescriptor descriptor, final long executionId) {
if (ApplicationManager.getApplication().isUnitTestMode()) {
return;
}
final ProcessAdapter processAdapter = new ProcessAdapter() {
@Override
public void startNotified(final ProcessEvent event) {
- ApplicationManager.getApplication().invokeLater(new Runnable() {
- @Override
- public void run() {
- final Icon icon = descriptor.getIcon();
- content.setIcon(icon == null ? executor.getToolWindowIcon() : icon);
- }
- });
+ IconAnimator animator = myIconAnimators.get(executor.getToolWindowId());
+ if (animator != null) {
+ animator.setActive(true);
+ }
}
@Override
@Override
public void run() {
final Icon icon = descriptor.getIcon();
+
+ boolean alive = false;
+ String toolWindowId = executor.getToolWindowId();
+ ContentManager manager = myToolwindowIdToContentManagerMap.get(toolWindowId);
+ for (Content content : manager.getContents()) {
+ RunContentDescriptor descriptor = getRunContentDescriptorByContent(content);
+ if (descriptor != null) {
+ ProcessHandler handler = descriptor.getProcessHandler();
+ if (handler != null && !handler.isProcessTerminated()) {
+ alive = true;
+ break;
+ }
+ }
+ }
+
+ IconAnimator animator = myIconAnimators.get(toolWindowId);
+ if (animator != null) {
+ animator.setActive(alive);
+ }
content.setIcon(icon == null ? executor.getDisabledIcon() : IconLoader.getTransparentIcon(icon));
}
});
--- /dev/null
+/*
+ * Copyright 2000-2015 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.util.ui;
+
+import com.intellij.openapi.Disposable;
+import com.intellij.openapi.util.Disposer;
+import org.jetbrains.annotations.NotNull;
+
+import javax.swing.*;
+import java.awt.*;
+
+public class IconAnimator extends Animator implements Icon {
+ private final Icon myBase;
+ @NotNull private final PaintCallback myCallback;
+ private final Color[] myAlphas;
+ private int myFrame;
+ private boolean myActive;
+
+ public IconAnimator(@NotNull Disposable parent, @NotNull Icon base, @NotNull PaintCallback callback) {
+ super("IconAnimator{" + System.currentTimeMillis()+"}", base.getIconWidth(), 2000, true);
+ Disposer.register(parent, this);
+ myBase = base;
+ myCallback = callback;
+ myAlphas = initAlphas();
+ }
+
+ private Color[] initAlphas() {
+ Color[] colors = new Color[myBase.getIconWidth()];
+ for (int i = 0; i < colors.length; i++) {
+ double a = 2 * Math.PI * i / colors.length;
+ float v = (1 - (float)Math.sin(a)) / 2;
+ //noinspection UseJBColor
+ colors[i] = new Color(v, v, v, v * v * v / 16 + .05F);
+ }
+ return colors;
+ }
+
+ public void setActive(boolean active) {
+ if (myActive == active) return;
+
+ myActive = active;
+
+ if (isRunning() ^ myActive) {
+ if (myActive) {
+ resume();
+ } else {
+ suspend();
+ }
+ myCallback.paintNow(this);
+ }
+ }
+
+ @Override
+ public void paintNow(int frame, int totalFrames, int cycle) {
+ myFrame = frame;
+ myCallback.paintNow(this);
+ }
+
+ @Override
+ public void paintIcon(Component component, Graphics graphics, int x, int y) {
+ myBase.paintIcon(component, graphics, x, y);
+ if (!myActive) return;
+
+ for (int i = 0; i < myAlphas.length; i++) {
+ Color alpha = myAlphas[(i + myFrame) % myAlphas.length];
+ graphics.setColor(alpha);
+ graphics.drawRect(x + i, y, 1, getIconHeight());
+ }
+ }
+
+ @Override
+ public int getIconWidth() {
+ return myBase.getIconWidth();
+ }
+
+ @Override
+ public int getIconHeight() {
+ return myBase.getIconHeight();
+ }
+
+ public interface PaintCallback {
+ void paintNow(Icon icon);
+ }
+}
public final void setIcon(final Icon icon) {
ApplicationManager.getApplication().assertIsDispatchThread();
final Icon oldIcon = getIcon();
- if (oldIcon != icon && !(icon instanceof LayeredIcon) && (icon.getIconHeight() != JBUI.scale(13) || icon.getIconWidth() != JBUI.scale(13))) {
+ if (oldIcon != icon && icon != null && !(icon instanceof LayeredIcon) && (icon.getIconHeight() != JBUI.scale(13) || icon.getIconWidth() != JBUI.scale(13))) {
LOG.warn("ToolWindow icons should be 13x13. Please fix ToolWindow (ID: " + getId() + ") or icon " + icon);
}
- getSelectedContent().setIcon(icon);
+ //getSelectedContent().setIcon(icon);
myIcon = icon;
myChangeSupport.firePropertyChange(PROP_ICON, oldIcon, icon);
}