[push] Change loading icons to the standard ones, fix widths

Let the LoadingIcon occupy the same area as the JCheckbox does
to avoid flickering when loading icon is changed to the checkbox.

Keep an empty icon to occupy the same place for the single repo case.
This commit is contained in:
Kirill Likhodedov
2014-09-28 17:33:40 +04:00
parent 72e39d16c2
commit b833599f0c
10 changed files with 62 additions and 21 deletions
Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 3.1 KiB

@@ -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 {
@@ -34,20 +34,22 @@ import java.util.concurrent.atomic.AtomicReference;
public class RepositoryNode extends CheckedTreeNode implements EditableTreeNode, Comparable<RepositoryNode> {
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<AtomicReference<OutgoingResult>> 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<AtomicReference<OutgoingResult>> future) {
myFuture = future;
myLoading.set(true);
myLoadingIcon.setImageObserver(LoadingIconProvider.createObserver(tree, this));
myLoadingIcon.setObserver(tree, this);
}
public int compareTo(@NotNull RepositoryNode repositoryNode) {
@@ -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();
@@ -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);