diff --git a/platform/dvcs-impl/resources/icons/Loading@2x.gif b/platform/dvcs-impl/resources/icons/Loading@2x.gif deleted file mode 100644 index 77c756d99cb1..000000000000 Binary files a/platform/dvcs-impl/resources/icons/Loading@2x.gif and /dev/null differ diff --git a/platform/dvcs-impl/resources/icons/Loading@2x_dark.gif b/platform/dvcs-impl/resources/icons/Loading@2x_dark.gif deleted file mode 100644 index f95c9287108f..000000000000 Binary files a/platform/dvcs-impl/resources/icons/Loading@2x_dark.gif and /dev/null differ diff --git a/platform/dvcs-impl/resources/icons/loading.gif b/platform/dvcs-impl/resources/icons/loading.gif index bfd4da223753..de907980d8eb 100644 Binary files a/platform/dvcs-impl/resources/icons/loading.gif and b/platform/dvcs-impl/resources/icons/loading.gif differ diff --git a/platform/dvcs-impl/resources/icons/loading@2x.gif b/platform/dvcs-impl/resources/icons/loading@2x.gif new file mode 100644 index 000000000000..7e6d0c3899eb Binary files /dev/null and b/platform/dvcs-impl/resources/icons/loading@2x.gif differ diff --git a/platform/dvcs-impl/resources/icons/loading@2x_dark.gif b/platform/dvcs-impl/resources/icons/loading@2x_dark.gif new file mode 100644 index 000000000000..f76af050bb9d Binary files /dev/null and b/platform/dvcs-impl/resources/icons/loading@2x_dark.gif differ diff --git a/platform/dvcs-impl/resources/icons/loading_dark.gif b/platform/dvcs-impl/resources/icons/loading_dark.gif index e41778b2c6e7..5d4800a0f98b 100644 Binary files a/platform/dvcs-impl/resources/icons/loading_dark.gif and b/platform/dvcs-impl/resources/icons/loading_dark.gif differ diff --git a/platform/dvcs-impl/src/com/intellij/dvcs/push/ui/LoadingIconProvider.java b/platform/dvcs-impl/src/com/intellij/dvcs/push/ui/LoadingIcon.java similarity index 57% rename from platform/dvcs-impl/src/com/intellij/dvcs/push/ui/LoadingIconProvider.java rename to platform/dvcs-impl/src/com/intellij/dvcs/push/ui/LoadingIcon.java index a1179e933514..69c43cc4467e 100644 --- a/platform/dvcs-impl/src/com/intellij/dvcs/push/ui/LoadingIconProvider.java +++ b/platform/dvcs-impl/src/com/intellij/dvcs/push/ui/LoadingIcon.java @@ -15,6 +15,7 @@ */ package com.intellij.dvcs.push.ui; +import com.intellij.openapi.diagnostic.Logger; import com.intellij.util.ImageLoader; import com.intellij.util.ui.JBImageIcon; import com.intellij.util.ui.UIUtil; @@ -25,23 +26,60 @@ import javax.swing.tree.DefaultTreeModel; import javax.swing.tree.TreeNode; import javax.swing.tree.TreePath; import java.awt.*; -import java.awt.image.BufferedImage; import java.awt.image.ImageObserver; -class LoadingIconProvider { +class LoadingIcon extends JBImageIcon { private static final String LOADING_ICON = "/icons/loading.gif"; - private static final JBImageIcon EMPTY_ICON = new JBImageIcon(UIUtil.createImage(18, 18, BufferedImage.TYPE_3BYTE_BGR)); + private static final Logger LOG = Logger.getInstance(LoadingIcon.class); - @NotNull - public static JBImageIcon getLoadingIcon() { - Image image = ImageLoader.loadFromResource(LOADING_ICON); - return image == null ? EMPTY_ICON : new JBImageIcon(image); + private final int myWidth; + private final int myHeight; + private final int myDeltaX; + private final int myDeltaY; + + LoadingIcon(@NotNull Image image, int width, int height) { + super(image); + int myOriginalWidth = image.getWidth(null); + int myOriginalHeight = image.getHeight(null); + myWidth = Math.max(width, myOriginalWidth); + myHeight = Math.max(height, myOriginalHeight); + myDeltaX = (myWidth - myOriginalWidth) / 2 - 2; + myDeltaY = (myHeight - myOriginalHeight) / 2 + 2; } @NotNull - public static ImageObserver createObserver(@NotNull JTree tree, @NotNull TreeNode treeNode) { - return new NodeImageObserver(tree, treeNode); + static LoadingIcon create(int width, int height) { + Image image = ImageLoader.loadFromResource(LOADING_ICON); + if (image == null) { + LOG.error("Couldn't load image: " + LOADING_ICON); + return createEmpty(width, height); + } + return new LoadingIcon(image, width, height); + } + + @NotNull + static LoadingIcon createEmpty(int width, int height) { + return new LoadingIcon(UIUtil.createImage(width, height, Transparency.TRANSLUCENT), width, height); + } + + void setObserver(@NotNull JTree tree, @NotNull TreeNode treeNode) { + setImageObserver(new NodeImageObserver(tree, treeNode)); + } + + @Override + public final synchronized void paintIcon(final Component c, final Graphics g, final int x, final int y) { + super.paintIcon(c, g, x + myDeltaX, y + myDeltaY); + } + + @Override + public int getIconHeight() { + return myHeight; + } + + @Override + public int getIconWidth() { + return myWidth; } private static class NodeImageObserver implements ImageObserver { diff --git a/platform/dvcs-impl/src/com/intellij/dvcs/push/ui/RepositoryNode.java b/platform/dvcs-impl/src/com/intellij/dvcs/push/ui/RepositoryNode.java index 3f1582afeb04..b75ce5079558 100644 --- a/platform/dvcs-impl/src/com/intellij/dvcs/push/ui/RepositoryNode.java +++ b/platform/dvcs-impl/src/com/intellij/dvcs/push/ui/RepositoryNode.java @@ -34,20 +34,22 @@ import java.util.concurrent.atomic.AtomicReference; public class RepositoryNode extends CheckedTreeNode implements EditableTreeNode, Comparable { - private static final int CHECKBOX_WIDTH = new JCheckBox().getPreferredSize().width; - - @NotNull protected final ImageIcon myLoadingIcon; + @NotNull protected final LoadingIcon myLoadingIcon; @NotNull protected final AtomicBoolean myLoading = new AtomicBoolean(true); @NotNull private final RepositoryWithBranchPanel myRepositoryPanel; @Nullable private Future> myFuture; + protected final int myLoadingIconWidth; public RepositoryNode(@NotNull RepositoryWithBranchPanel repositoryPanel, boolean enabled) { super(repositoryPanel); setChecked(false); setEnabled(enabled); myRepositoryPanel = repositoryPanel; - myLoadingIcon = LoadingIconProvider.getLoadingIcon(); + + Dimension size = new JCheckBox().getPreferredSize(); + myLoadingIconWidth = size.width; + myLoadingIcon = LoadingIcon.create(myLoadingIconWidth, size.height); } public boolean isCheckboxVisible() { @@ -60,8 +62,7 @@ public class RepositoryNode extends CheckedTreeNode implements EditableTreeNode, if (myLoading.get()) { renderer.setIcon(myLoadingIcon); renderer.setIconOnTheRight(false); - renderer.setIconTextGap(CHECKBOX_WIDTH - myLoadingIcon.getIconWidth()); - repoFixedWidth += CHECKBOX_WIDTH; + repoFixedWidth += myLoadingIconWidth; } renderer.append(getRepoName(renderer, repoFixedWidth), SimpleTextAttributes.GRAY_ATTRIBUTES); renderer.appendFixedTextFragmentWidth(repoFixedWidth); @@ -110,7 +111,7 @@ public class RepositoryNode extends CheckedTreeNode implements EditableTreeNode, public void startLoading(@NotNull JTree tree, @NotNull Future> future) { myFuture = future; myLoading.set(true); - myLoadingIcon.setImageObserver(LoadingIconProvider.createObserver(tree, this)); + myLoadingIcon.setObserver(tree, this); } public int compareTo(@NotNull RepositoryNode repositoryNode) { diff --git a/platform/dvcs-impl/src/com/intellij/dvcs/push/ui/SingleRepositoryNode.java b/platform/dvcs-impl/src/com/intellij/dvcs/push/ui/SingleRepositoryNode.java index 65fecd19e010..3cf9a5290d2f 100644 --- a/platform/dvcs-impl/src/com/intellij/dvcs/push/ui/SingleRepositoryNode.java +++ b/platform/dvcs-impl/src/com/intellij/dvcs/push/ui/SingleRepositoryNode.java @@ -23,10 +23,12 @@ import org.jetbrains.annotations.NotNull; public class SingleRepositoryNode extends RepositoryNode { @NotNull private final RepositoryWithBranchPanel myRepositoryPanel; + private final LoadingIcon myEmptyIcon; public SingleRepositoryNode(@NotNull RepositoryWithBranchPanel repositoryPanel) { super(repositoryPanel, true); myRepositoryPanel = repositoryPanel; + myEmptyIcon = LoadingIcon.createEmpty(myLoadingIcon.getIconWidth(), myLoadingIcon.getIconHeight()); } @Override @@ -36,11 +38,11 @@ public class SingleRepositoryNode extends RepositoryNode { @Override public void render(@NotNull ColoredTreeCellRenderer renderer) { - if (myLoading.get()) { - renderer.setIcon(myLoadingIcon); - renderer.setIconOnTheRight(false); - } + renderer.setIcon(myLoading.get() ? myLoadingIcon : myEmptyIcon); + renderer.setIconOnTheRight(false); + renderer.append(""); + renderer.appendFixedTextFragmentWidth(myLoadingIconWidth); renderer.append(myRepositoryPanel.getSourceName(), SimpleTextAttributes.REGULAR_ATTRIBUTES); renderer.append(myRepositoryPanel.getArrow(), SimpleTextAttributes.REGULAR_ATTRIBUTES); PushTargetPanel pushTargetPanel = myRepositoryPanel.getTargetPanel(); diff --git a/platform/util/src/com/intellij/util/ui/JBImageIcon.java b/platform/util/src/com/intellij/util/ui/JBImageIcon.java index a955de287cbf..d3990cf18396 100644 --- a/platform/util/src/com/intellij/util/ui/JBImageIcon.java +++ b/platform/util/src/com/intellij/util/ui/JBImageIcon.java @@ -32,7 +32,7 @@ public class JBImageIcon extends ImageIcon { } @Override - public final synchronized void paintIcon(final Component c, final Graphics g, final int x, final int y) { + public synchronized void paintIcon(final Component c, final Graphics g, final int x, final int y) { final ImageObserver observer = getImageObserver(); UIUtil.drawImage(g, getImage(), x, y, observer == null ? c : observer);