tree wide selection

This commit is contained in:
Konstantin Bulenkov
2012-07-23 17:50:51 +02:00
parent b7c624162c
commit 9e39717c36
11 changed files with 76 additions and 47 deletions
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2009 JetBrains s.r.o.
* Copyright 2000-2012 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.
@@ -17,7 +17,7 @@ package com.intellij.ui;
import com.intellij.util.ui.EmptyIcon;
import com.intellij.util.ui.UIUtil;
import com.intellij.util.ui.tree.MacTreeUI;
import com.intellij.util.ui.tree.WideSelectionTreeUI;
import org.jetbrains.annotations.Nls;
import org.jetbrains.annotations.NotNull;
@@ -64,7 +64,7 @@ public abstract class ColoredTreeCellRenderer extends SimpleColoredComponent imp
if (UIUtil.isFullRowSelectionLAF()) {
setBackground(selected ? UIUtil.getTreeSelectionBackground() : null);
}
else if (UIUtil.isUnderAquaBasedLookAndFeel() && tree.getUI() instanceof MacTreeUI && ((MacTreeUI)tree.getUI()).isWideSelection()) {
else if (/*UIUtil.isUnderAquaBasedLookAndFeel() && */tree.getUI() instanceof WideSelectionTreeUI && ((WideSelectionTreeUI)tree.getUI()).isWideSelection()) {
setPaintFocusBorder(false);
//setBackground(selected ? UIUtil.getTreeSelectionBackground() : null);
}
@@ -100,7 +100,7 @@ public abstract class ColoredTreeCellRenderer extends SimpleColoredComponent imp
super.setOpaque(false); // avoid erasing Nimbus focus frame
super.setIconOpaque(false);
}
else if (UIUtil.isUnderAquaBasedLookAndFeel() && tree.getUI() instanceof MacTreeUI && ((MacTreeUI)tree.getUI()).isWideSelection()) {
else if (tree.getUI() instanceof WideSelectionTreeUI && ((WideSelectionTreeUI)tree.getUI()).isWideSelection()) {
super.setOpaque(false); // avoid erasing Nimbus focus frame
super.setIconOpaque(false);
}
@@ -108,7 +108,7 @@ public abstract class ColoredTreeCellRenderer extends SimpleColoredComponent imp
super.setOpaque(myOpaque || selected && hasFocus || selected && isFocused()); // draw selection background even for non-opaque tree
}
if (tree.getUI() instanceof MacTreeUI) {
if (tree.getUI() instanceof WideSelectionTreeUI && UIUtil.isUnderAquaBasedLookAndFeel()) {
setMyBorder(null);
setIpad(new Insets(0, 2, 0, 2));
}
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2009 JetBrains s.r.o.
* Copyright 2000-2012 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.
@@ -16,7 +16,7 @@
package com.intellij.ui;
import com.intellij.util.ui.UIUtil;
import com.intellij.util.ui.tree.MacTreeUI;
import com.intellij.util.ui.tree.WideSelectionTreeUI;
import javax.swing.*;
import javax.swing.tree.TreeCellRenderer;
@@ -36,7 +36,7 @@ public class HighlightableCellRenderer extends HighlightableComponent implements
setFont(UIUtil.getTreeFont());
setIcon(null);
if (tree.getUI() instanceof MacTreeUI && ((MacTreeUI)tree.getUI()).isWideSelection()) {
if (tree.getUI() instanceof WideSelectionTreeUI && ((WideSelectionTreeUI)tree.getUI()).isWideSelection()) {
setOpaque(false);
myIsSelected = false;
myHasFocus = false;
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2010 JetBrains s.r.o.
* Copyright 2000-2012 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.
@@ -17,7 +17,7 @@ package com.intellij.ui;
import com.intellij.util.ui.MacUIUtil;
import com.intellij.util.ui.UIUtil;
import com.intellij.util.ui.tree.MacTreeUI;
import com.intellij.util.ui.tree.WideSelectionTreeUI;
import org.jetbrains.annotations.NotNull;
import javax.swing.*;
@@ -33,7 +33,7 @@ public class JBDefaultTreeCellRenderer extends DefaultTreeCellRenderer {
public JBDefaultTreeCellRenderer(@NotNull final JTree tree) {
MacUIUtil.doNotFillBackground(tree, this);
myMacTreeUI = tree.getUI() instanceof MacTreeUI && ((MacTreeUI)tree.getUI()).isWideSelection();
myMacTreeUI = tree.getUI() instanceof WideSelectionTreeUI && ((WideSelectionTreeUI)tree.getUI()).isWideSelection();
}
@Override
@@ -27,7 +27,7 @@ import com.intellij.util.ui.AsyncProcessIcon;
import com.intellij.util.ui.ComponentWithEmptyText;
import com.intellij.util.ui.StatusText;
import com.intellij.util.ui.UIUtil;
import com.intellij.util.ui.tree.MacTreeUI;
import com.intellij.util.ui.tree.WideSelectionTreeUI;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -96,8 +96,8 @@ public class Tree extends JTree implements ComponentWithEmptyText, ComponentWith
public void setUI(final TreeUI ui) {
TreeUI actualUI = ui;
if (!isCustomUI()) {
if (!(ui instanceof MacTreeUI) && UIUtil.isUnderAquaBasedLookAndFeel()) {
actualUI = new MacTreeUI(isMacWideSelection(), !isFileColorsEnabled());
if (!(ui instanceof WideSelectionTreeUI) /*&& UIUtil.isUnderAquaBasedLookAndFeel()*/) {
actualUI = new WideSelectionTreeUI(isMacWideSelection(), !isFileColorsEnabled());
}
}
super.setUI(actualUI);
@@ -23,7 +23,7 @@ import com.intellij.openapi.application.ModalityState;
import com.intellij.openapi.project.Project;
import com.intellij.ui.DoubleClickListener;
import com.intellij.ui.treeStructure.treetable.TreeTable;
import com.intellij.util.ui.tree.MacTreeUI;
import com.intellij.util.ui.tree.WideSelectionTreeUI;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
@@ -106,7 +106,7 @@ public class EditSourceOnDoubleClickHandler {
@Override
public boolean onDoubleClick(MouseEvent e) {
final TreePath path = myTree.getUI() instanceof MacTreeUI ? myTree.getClosestPathForLocation(e.getX(), e.getY())
final TreePath path = myTree.getUI() instanceof WideSelectionTreeUI ? myTree.getClosestPathForLocation(e.getX(), e.getY())
: myTree.getPathForLocation(e.getX(), e.getY());
if (path == null) return false;
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2009 JetBrains s.r.o.
* Copyright 2000-2012 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.
@@ -19,7 +19,7 @@ import com.intellij.ide.dnd.DnDAware;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.util.SystemInfo;
import com.intellij.ui.treeStructure.Tree;
import com.intellij.util.ui.tree.MacTreeUI;
import com.intellij.util.ui.tree.WideSelectionTreeUI;
import com.intellij.util.ui.tree.TreeUtil;
import org.jetbrains.annotations.NotNull;
@@ -58,7 +58,7 @@ public class DnDAwareTree extends Tree implements DnDAware {
public final boolean isOverSelection(final Point point) {
final TreeUI ui = getUI();
final TreePath path = ui instanceof MacTreeUI && ((MacTreeUI)ui).isWideSelection()
final TreePath path = ui instanceof WideSelectionTreeUI && ((WideSelectionTreeUI)ui).isWideSelection()
? getClosestPathForLocation(point.x, point.y) : getPathForLocation(point.x, point.y);
if (path == null) return false;
return isPathSelected(path);
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2009 JetBrains s.r.o.
* Copyright 2000-2012 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.
@@ -37,7 +37,7 @@ import com.intellij.ui.treeStructure.Tree;
import com.intellij.ui.treeStructure.treetable.TreeTableModel;
import com.intellij.util.ui.EmptyIcon;
import com.intellij.util.ui.UIUtil;
import com.intellij.util.ui.tree.MacTreeUI;
import com.intellij.util.ui.tree.WideSelectionTreeUI;
import com.intellij.util.ui.tree.TreeUtil;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.Nullable;
@@ -97,7 +97,7 @@ public class ActionsTree {
myTree.setRootVisible(false);
myTree.setShowsRootHandles(true);
myTree.putClientProperty(MacTreeUI.STRIPED_CLIENT_PROPERTY, Boolean.TRUE);
myTree.putClientProperty(WideSelectionTreeUI.STRIPED_CLIENT_PROPERTY, Boolean.TRUE);
myTree.setCellRenderer(new KeymapsRenderer());
myTree.getSelectionModel().setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION);
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2009 JetBrains s.r.o.
* Copyright 2000-2012 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.
@@ -19,7 +19,7 @@ import com.intellij.openapi.util.text.StringUtil;
import com.intellij.ui.components.JBScrollPane;
import com.intellij.util.ArrayUtil;
import com.intellij.util.ui.UIUtil;
import com.intellij.util.ui.tree.MacTreeUI;
import com.intellij.util.ui.tree.WideSelectionTreeUI;
import org.jetbrains.annotations.NonNls;
import javax.swing.*;
@@ -131,7 +131,7 @@ public abstract class MultilineTreeCellRenderer extends JComponent implements Tr
}
// fill background
if (!(myTree.getUI() instanceof MacTreeUI) || !((MacTreeUI)myTree.getUI()).isWideSelection()) {
if (!(myTree.getUI() instanceof WideSelectionTreeUI) || !((WideSelectionTreeUI)myTree.getUI()).isWideSelection()) {
g.setColor(bgColor);
g.fillRect(borderX, borderY, borderW, borderH);
@@ -18,7 +18,7 @@ package com.intellij.ui;
import com.intellij.openapi.util.Pair;
import com.intellij.ui.treeStructure.Tree;
import com.intellij.util.ui.UIUtil;
import com.intellij.util.ui.tree.MacTreeUI;
import com.intellij.util.ui.tree.WideSelectionTreeUI;
import javax.swing.*;
import javax.swing.event.TreeModelEvent;
@@ -133,13 +133,13 @@ public class TreeExpandableItemsHandler extends AbstractExpandableItemsHandler<I
@Override
protected Dimension getImageSize(int width, int height) {
final TreeUI ui = myComponent.getUI();
return new Dimension(width, ui instanceof MacTreeUI && ((MacTreeUI)ui).isWideSelection() ? height - 1 : height);
return new Dimension(width, ui instanceof WideSelectionTreeUI && ((WideSelectionTreeUI)ui).isWideSelection() ? height - 1 : height);
}
@Override
protected void doFillBackground(final int height, final int width, final Graphics2D g) {
final TreeUI ui = myComponent.getUI();
super.doFillBackground(ui instanceof MacTreeUI && ((MacTreeUI)ui).isWideSelection() ? height - 1 : height, width, g);
super.doFillBackground(ui instanceof WideSelectionTreeUI && ((WideSelectionTreeUI)ui).isWideSelection() ? height - 1 : height, width, g);
}
@Override
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2010 JetBrains s.r.o.
* Copyright 2000-2012 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.
@@ -20,7 +20,7 @@ import com.intellij.openapi.util.registry.Registry;
import com.intellij.ui.ColorUtil;
import com.intellij.ui.Gray;
import com.intellij.ui.mac.foundation.Foundation;
import com.intellij.util.ui.tree.MacTreeUI;
import com.intellij.util.ui.tree.WideSelectionTreeUI;
import org.jetbrains.annotations.NotNull;
import javax.swing.*;
@@ -251,8 +251,8 @@ public class MacUIUtil {
public static void doNotFillBackground(@NotNull final JTree tree, @NotNull final DefaultTreeCellRenderer renderer) {
TreeUI ui = tree.getUI();
if (ui instanceof MacTreeUI) {
if (((MacTreeUI)ui).isWideSelection()) {
if (ui instanceof WideSelectionTreeUI) {
if (((WideSelectionTreeUI)ui).isWideSelection()) {
renderer.setOpaque(false);
try {
final Field fillBackground = DefaultTreeCellRenderer.class.getDeclaredField("fillBackground");
@@ -35,15 +35,16 @@ import java.awt.event.MouseListener;
/**
* @author Konstantin Bulenkov
*/
public class MacTreeUI extends BasicTreeUI {
private static final Color DECORATED_ROW_BG_COLOR = new Color(242, 245, 249);
public class WideSelectionTreeUI extends BasicTreeUI {
@NonNls public static final String SOURCE_LIST_CLIENT_PROPERTY = "mac.ui.source.list";
@NonNls public static final String STRIPED_CLIENT_PROPERTY = "mac.ui.striped";
private static final Icon TREE_COLLAPSED_ICON = UIUtil.getTreeCollapsedIcon();
private static final Icon TREE_EXPANDED_ICON = UIUtil.getTreeExpandedIcon();
private static final Icon TREE_SELECTED_COLLAPSED_ICON = AllIcons.Mac.Tree_white_right_arrow;
private static final Icon TREE_SELECTED_EXPANDED_ICON = AllIcons.Mac.Tree_white_down_arrow;
private static final Icon TREE_SELECTED_COLLAPSED_ICON = UIUtil.isUnderAquaBasedLookAndFeel() ? AllIcons.Mac.Tree_white_right_arrow
: TREE_COLLAPSED_ICON;
private static final Icon TREE_SELECTED_EXPANDED_ICON = UIUtil.isUnderAquaBasedLookAndFeel() ? AllIcons.Mac.Tree_white_down_arrow
: TREE_EXPANDED_ICON;
private static final Border LIST_BACKGROUND_PAINTER = (Border)UIManager.get("List.sourceListBackgroundPainter");
private static final Border LIST_SELECTION_BACKGROUND_PAINTER = (Border)UIManager.get("List.sourceListSelectionBackgroundPainter");
@@ -54,11 +55,11 @@ public class MacTreeUI extends BasicTreeUI {
private boolean myAlwaysPaintRowBackground;
private boolean myOldRepaintAllRowValue;
public MacTreeUI() {
public WideSelectionTreeUI() {
this(true, true);
}
public MacTreeUI(final boolean wideSelection, boolean alwaysPaintRowBackground) {
public WideSelectionTreeUI(final boolean wideSelection, boolean alwaysPaintRowBackground) {
myWideSelection = wideSelection;
myAlwaysPaintRowBackground = alwaysPaintRowBackground;
}
@@ -214,7 +215,9 @@ public class MacTreeUI extends BasicTreeUI {
final boolean isExpanded,
final boolean hasBeenExpanded,
final boolean isLeaf) {
if (!UIUtil.isUnderAquaBasedLookAndFeel()) {
super.paintHorizontalPartOfLeg(g, clipBounds, insets, bounds, path, row, isExpanded, hasBeenExpanded, isLeaf);
}
}
@Override
@@ -224,10 +227,16 @@ public class MacTreeUI extends BasicTreeUI {
@Override
protected void paintVerticalPartOfLeg(final Graphics g, final Rectangle clipBounds, final Insets insets, final TreePath path) {
if (!UIUtil.isUnderAquaBasedLookAndFeel()) {
super.paintVerticalPartOfLeg(g, clipBounds, insets, path);
}
}
@Override
protected void paintHorizontalLine(Graphics g, JComponent c, int y, int left, int right) {
if (!UIUtil.isUnderAquaBasedLookAndFeel()) {
super.paintHorizontalLine(g, c, y, left, right);
}
}
public boolean isWideSelection() {
@@ -274,15 +283,15 @@ public class MacTreeUI extends BasicTreeUI {
}
}
else {
Color bg = tree.hasFocus() ? UIUtil.getTreeSelectionBackground() : UIUtil.getTreeUnfocusedSelectionBackground();
if (!selected) {
bg = background;
}
//Color bg = tree.hasFocus() ? UIUtil.getTreeSelectionBackground() : UIUtil.getTreeUnfocusedSelectionBackground();
//if (!selected) {
// bg = background;
//}
if (myAlwaysPaintRowBackground || selected) {
rowGraphics.setColor(bg);
rowGraphics.fillRect(xOffset, bounds.y, containerWidth, bounds.height - 1);
}
//if (/*myAlwaysPaintRowBackground || */selected) {
// rowGraphics.setColor(bg);
// rowGraphics.fillRect(xOffset, bounds.y, containerWidth, bounds.height - 1);
//}
}
if (shouldPaintExpandControl(path, row, isExpanded, hasBeenExpanded, isLeaf)) {
@@ -299,6 +308,9 @@ public class MacTreeUI extends BasicTreeUI {
@Override
public void paint(Graphics g, JComponent c) {
if (myAlwaysPaintRowBackground && myWideSelection) {
paintSelectedRows(g, ((JTree)c));
}
if (myWideSelection) {
final int containerWidth = tree.getParent() instanceof JViewport ? tree.getParent().getWidth() : tree.getWidth();
final int xOffset = tree.getParent() instanceof JViewport ? ((JViewport)tree.getParent()).getViewPosition().x : 0;
@@ -317,6 +329,23 @@ public class MacTreeUI extends BasicTreeUI {
super.paint(g, c);
}
protected void paintSelectedRows(Graphics g, JTree tr) {
final Rectangle rect = tr.getVisibleRect();
final int firstVisibleRow = tr.getClosestRowForLocation(rect.x, rect.y);
final int lastVisibleRow = tr.getClosestRowForLocation(rect.x, rect.y + rect.height);
for (int row = firstVisibleRow; row <= lastVisibleRow; row++) {
if (tr.getSelectionModel().isRowSelected(row)) {
final Rectangle bounds = tr.getRowBounds(row);
Color color = tr.hasFocus() ? UIUtil.getTreeSelectionBackground() : UIUtil.getTreeUnfocusedSelectionBackground();
if (color != null) {
g.setColor(color);
g.fillRect(0, bounds.y, tr.getWidth(), bounds.height);
}
}
}
}
@Override
protected CellRendererPane createCellRendererPane() {
return new CellRendererPane() {