[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.
|
Before Width: | Height: | Size: 3.2 KiB |
|
Before Width: | Height: | Size: 3.3 KiB |
|
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 3.2 KiB |
|
After Width: | Height: | Size: 6.3 KiB |
|
After Width: | Height: | Size: 6.4 KiB |
|
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);
|
||||
|
||||