summaryrefslogtreecommitdiff
path: root/platform/platform-impl/src/com/intellij/openapi/options/newEditor/OptionsTree.java
diff options
context:
space:
mode:
Diffstat (limited to 'platform/platform-impl/src/com/intellij/openapi/options/newEditor/OptionsTree.java')
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/options/newEditor/OptionsTree.java129
1 files changed, 120 insertions, 9 deletions
diff --git a/platform/platform-impl/src/com/intellij/openapi/options/newEditor/OptionsTree.java b/platform/platform-impl/src/com/intellij/openapi/options/newEditor/OptionsTree.java
index e0ab24815ece..175b994122ef 100644
--- a/platform/platform-impl/src/com/intellij/openapi/options/newEditor/OptionsTree.java
+++ b/platform/platform-impl/src/com/intellij/openapi/options/newEditor/OptionsTree.java
@@ -23,6 +23,7 @@ import com.intellij.openapi.options.ConfigurableGroup;
import com.intellij.openapi.options.OptionsBundle;
import com.intellij.openapi.options.SearchableConfigurable;
import com.intellij.openapi.options.ex.ConfigurableWrapper;
+import com.intellij.openapi.options.ex.NodeConfigurable;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.ActionCallback;
import com.intellij.openapi.util.Disposer;
@@ -116,10 +117,7 @@ public class OptionsTree extends JPanel implements Disposable, OptionsEditorColl
}
});
- final JScrollPane scrolls = ScrollPaneFactory.createScrollPane(myTree);
- scrolls.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
-
- add(scrolls, BorderLayout.CENTER);
+ add(new StickySeparator(myTree), BorderLayout.CENTER);
mySelection = new MergingUpdateQueue("OptionsTree", 150, false, this, this, this).setRestartTimerOnAdd(true);
myTree.getSelectionModel().addTreeSelectionListener(new TreeSelectionListener() {
@@ -290,7 +288,7 @@ public class OptionsTree extends JPanel implements Disposable, OptionsEditorColl
}
class Renderer extends GroupedElementsRenderer.Tree {
-
+ private GroupSeparator mySeparator;
private JLabel myProjectIcon;
private JLabel myHandle;
@@ -298,7 +296,8 @@ public class OptionsTree extends JPanel implements Disposable, OptionsEditorColl
protected void layout() {
myRendererComponent.setOpaqueActive(false);
- myRendererComponent.add(mySeparatorComponent, BorderLayout.NORTH);
+ mySeparator = new GroupSeparator();
+ myRendererComponent.add(Registry.is("ide.file.settings.order.new") ? mySeparator : mySeparatorComponent, BorderLayout.NORTH);
final NonOpaquePanel content = new NonOpaquePanel(new BorderLayout());
myHandle = new JLabel("", SwingConstants.CENTER);
@@ -325,7 +324,7 @@ public class OptionsTree extends JPanel implements Disposable, OptionsEditorColl
JComponent result;
Color fg = UIUtil.getTreeTextForeground();
-
+ mySeparator.configure(null, false);
final Base base = extractNode(value);
if (base instanceof EditorNode) {
@@ -335,6 +334,7 @@ public class OptionsTree extends JPanel implements Disposable, OptionsEditorColl
final DefaultMutableTreeNode prevValue = ((DefaultMutableTreeNode)value).getPreviousSibling();
if (prevValue == null || prevValue instanceof LoadingNode) {
group = editor.getGroup();
+ mySeparator.configure(group, false);
}
else {
final Base prevBase = extractNode(prevValue);
@@ -342,6 +342,7 @@ public class OptionsTree extends JPanel implements Disposable, OptionsEditorColl
final EditorNode prevEditor = (EditorNode)prevBase;
if (prevEditor.getGroup() != editor.getGroup()) {
group = editor.getGroup();
+ mySeparator.configure(group, true);
}
}
}
@@ -404,8 +405,25 @@ public class OptionsTree extends JPanel implements Disposable, OptionsEditorColl
myTextLabel.setBorder(new EmptyBorder(1,2,1,0));
}
- Project project = getConfigurableProject(base);
- if (project != null && Registry.is("ide.file.settings.order.new")) {
+ Project project = null;
+ if (base != null && Registry.is("ide.file.settings.order.new")) {
+ SimpleNode parent = base.getParent();
+ if (parent == myRoot) {
+ project = getConfigurableProject(base); // show icon for top-level nodes
+ if (base.getConfigurable() instanceof NodeConfigurable) { // special case for custom subgroups (build.tools)
+ Configurable[] configurables = ((NodeConfigurable)base.getConfigurable()).getConfigurables();
+ if (configurables != null) { // assume that all configurables have the same project
+ project = getConfigurableProject(configurables[0]);
+ }
+ }
+ }
+ else if (parent instanceof Base && ((Base)parent).getConfigurable() instanceof NodeConfigurable) {
+ if (((Base)base.getParent()).getConfigurable() instanceof NodeConfigurable) {
+ project = getConfigurableProject(base); // special case for custom subgroups
+ }
+ }
+ }
+ if (project != null) {
myProjectIcon.setBackground(selected ? getSelectionBackground() : getBackground());
myProjectIcon.setIcon(selected ? AllIcons.General.ProjectConfigurableSelected : AllIcons.General.ProjectConfigurable);
myProjectIcon.setVisible(true);
@@ -903,4 +921,97 @@ public class OptionsTree extends JPanel implements Disposable, OptionsEditorColl
}
return getConfigurableProject(node.getParent());
}
+
+ private static final class GroupSeparator extends JLabel {
+ public static final int SPACE = 10;
+
+ public GroupSeparator() {
+ setFont(UIUtil.getLabelFont());
+ setFont(getFont().deriveFont(Font.BOLD));
+ }
+
+ public void configure(ConfigurableGroup group, boolean isSpaceNeeded) {
+ if (group == null) {
+ setVisible(false);
+ }
+ else {
+ setVisible(true);
+ int bottom = UIUtil.isUnderNativeMacLookAndFeel() ? 1 : 3;
+ int top = isSpaceNeeded
+ ? bottom + SPACE
+ : bottom;
+ setBorder(BorderFactory.createEmptyBorder(top, 3, bottom, 3));
+ setText(group.getDisplayName());
+ }
+ }
+ }
+
+ private static final class StickySeparator extends JComponent {
+ private final SimpleTree myTree;
+ private final JScrollPane myScroller;
+ private final GroupSeparator mySeparator;
+
+ public StickySeparator(SimpleTree tree) {
+ myTree = tree;
+ myScroller = ScrollPaneFactory.createScrollPane(myTree);
+ myScroller.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
+ mySeparator = new GroupSeparator();
+ add(myScroller);
+ }
+
+ @Override
+ public void doLayout() {
+ myScroller.setBounds(0, 0, getWidth(), getHeight());
+ }
+
+ @Override
+ public void paint(Graphics g) {
+ super.paint(g);
+
+ if (Registry.is("ide.file.settings.order.new")) {
+ ConfigurableGroup group = getGroup(GroupSeparator.SPACE + mySeparator.getFont().getSize());
+ if (group != null && group == getGroup(-GroupSeparator.SPACE)) {
+ mySeparator.configure(group, false);
+
+ Rectangle bounds = myScroller.getViewport().getBounds();
+ int height = mySeparator.getPreferredSize().height;
+ if (bounds.height > height) {
+ bounds.height = height;
+ }
+ g.setColor(myTree.getBackground());
+ if (g instanceof Graphics2D) {
+ int h = bounds.height / 3;
+ int y = bounds.y + bounds.height - h;
+ g.fillRect(bounds.x, bounds.y, bounds.width, bounds.height - h);
+ ((Graphics2D)g).setPaint(UIUtil.getGradientPaint(
+ 0, y, g.getColor(),
+ 0, y + h, ColorUtil.toAlpha(g.getColor(), 0)));
+ g.fillRect(bounds.x, y, bounds.width, h);
+ }
+ else {
+ g.fillRect(bounds.x, bounds.y, bounds.width, bounds.height);
+ }
+ mySeparator.setSize(bounds.width - 1, bounds.height);
+ mySeparator.paint(g.create(bounds.x + 1, bounds.y, bounds.width - 1, bounds.height));
+ }
+ }
+ }
+
+ private ConfigurableGroup getGroup(int offset) {
+ TreePath path = myTree.getClosestPathForLocation(-myTree.getX(), -myTree.getY() + offset);
+ SimpleNode node = myTree.getNodeFor(path);
+ if (node instanceof FilteringTreeStructure.FilteringNode) {
+ Object delegate = ((FilteringTreeStructure.FilteringNode)node).getDelegate();
+ while (delegate instanceof EditorNode) {
+ EditorNode editor = (EditorNode)delegate;
+ ConfigurableGroup group = editor.getGroup();
+ if (group != null) {
+ return group;
+ }
+ delegate = editor.getParent();
+ }
+ }
+ return null;
+ }
+ }
}