Show gradient for scroll pane without border in the Settings dialog

This commit is contained in:
Sergey Malenkov
2014-10-28 13:10:56 +03:00
parent 357093ebb8
commit 8a39e28b81
4 changed files with 159 additions and 45 deletions

View File

@@ -34,6 +34,7 @@ import com.intellij.openapi.util.ActionCallback;
import com.intellij.ui.JBColor;
import com.intellij.ui.RelativeFont;
import com.intellij.ui.ScrollPaneFactory;
import com.intellij.ui.components.GradientViewport;
import com.intellij.ui.components.labels.LinkLabel;
import com.intellij.util.ui.update.MergingUpdateQueue;
import com.intellij.util.ui.update.Update;
@@ -269,7 +270,8 @@ class ConfigurableEditor extends AbstractEditor implements AnActionListener, AWT
content.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
}
if (ConfigurableWrapper.cast(Configurable.NoScroll.class, configurable) == null) {
JScrollPane scroll = ScrollPaneFactory.createScrollPane(content, true);
JScrollPane scroll = ScrollPaneFactory.createScrollPane(null, true);
scroll.setViewport(new GradientViewport(content, 5, 0, 0, 0, true));
scroll.getVerticalScrollBar().setUnitIncrement(10);
content = scroll;
}

View File

@@ -39,6 +39,7 @@ import com.intellij.openapi.util.registry.Registry;
import com.intellij.ui.LightColors;
import com.intellij.ui.OnePixelSplitter;
import com.intellij.ui.ScrollPaneFactory;
import com.intellij.ui.components.GradientViewport;
import com.intellij.ui.components.labels.LinkLabel;
import com.intellij.ui.components.panels.NonOpaquePanel;
import com.intellij.ui.components.panels.Wrapper;
@@ -712,11 +713,9 @@ public class OptionsEditor extends JPanel implements DataProvider, Place.Navigat
if (c != null) {
if (scrollable) {
JScrollPane scroll = ScrollPaneFactory.createScrollPane(c);
scroll.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED);
scroll.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED);
JScrollPane scroll = ScrollPaneFactory.createScrollPane(null, true);
scroll.setViewport(new GradientViewport(c, 5, 5, 5, 5, false));
scroll.getVerticalScrollBar().setUnitIncrement(10);
scroll.setBorder(null);
add(scroll, BorderLayout.CENTER);
}
else {

View File

@@ -25,6 +25,7 @@ import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.ActionCallback;
import com.intellij.openapi.util.Disposer;
import com.intellij.ui.*;
import com.intellij.ui.components.GradientViewport;
import com.intellij.ui.treeStructure.CachingSimpleNode;
import com.intellij.ui.treeStructure.SimpleNode;
import com.intellij.ui.treeStructure.SimpleTree;
@@ -79,7 +80,6 @@ final class SettingsTreeView extends JComponent implements Disposable, OptionsEd
private final SettingsFilter myFilter;
private final MyRoot myRoot;
private final JScrollPane myScroller;
private JLabel mySeparator;
private final IdentityHashMap<Configurable, MyNode> myConfigurableToNodeMap = new IdentityHashMap<Configurable, MyNode>();
private final IdentityHashMap<UnnamedConfigurable, ConfigurableWrapper> myConfigurableToWrapperMap
= new IdentityHashMap<UnnamedConfigurable, ConfigurableWrapper>();
@@ -107,18 +107,38 @@ final class SettingsTreeView extends JComponent implements Disposable, OptionsEd
myTree.setExpandableItemsEnabled(false);
RelativeFont.BOLD.install(myTree);
myScroller = ScrollPaneFactory.createScrollPane(myTree, true);
myScroller = ScrollPaneFactory.createScrollPane(null, true);
myScroller.setViewport(new GradientViewport(myTree, 5, 0, 0, 0, true) {
private JLabel myHeader;
@Override
protected Component getHeader() {
if (0 == myTree.getY()) {
return null; // separator is not needed without scrolling
}
if (myHeader == null) {
myHeader = new JLabel();
myHeader.setForeground(FOREGROUND);
myHeader.setIconTextGap(ICON_GAP);
myHeader.setBorder(BorderFactory.createEmptyBorder(1, 10 + getLeftMargin(0), 0, 0));
}
myHeader.setFont(myTree.getFont());
myHeader.setIcon(myTree.getEmptyHandle());
int height = myHeader.getPreferredSize().height;
String group = findGroupNameAt(0, height + 3);
if (group == null || !group.equals(findGroupNameAt(0, 0))) {
return null; // do not show separator over another group
}
myHeader.setText(group);
return myHeader;
}
});
myScroller.getVerticalScrollBar().setUI(ButtonlessScrollBarUI.createTransparent());
myScroller.setBackground(BACKGROUND);
myScroller.getViewport().setBackground(BACKGROUND);
myScroller.getVerticalScrollBar().setBackground(BACKGROUND);
add(myScroller);
mySeparator = new JLabel();
mySeparator.setForeground(FOREGROUND);
mySeparator.setIconTextGap(ICON_GAP);
mySeparator.setBorder(BorderFactory.createEmptyBorder(1, 10 + getLeftMargin(0), 0, 0));
myTree.addComponentListener(new ComponentAdapter() {
@Override
public void componentResized(ComponentEvent e) {
@@ -271,39 +291,6 @@ final class SettingsTreeView extends JComponent implements Disposable, OptionsEd
myScroller.setBounds(0, 0, getWidth(), getHeight());
}
@Override
public void paint(Graphics g) {
super.paint(g);
if (0 == myTree.getY()) {
return; // separator is not needed without scrolling
}
mySeparator.setFont(myTree.getFont());
mySeparator.setIcon(myTree.getEmptyHandle());
int height = mySeparator.getPreferredSize().height;
String group = findGroupNameAt(0, height + 3);
if (group != null && group.equals(findGroupNameAt(0, 0))) {
mySeparator.setText(group);
Rectangle bounds = myScroller.getViewport().getBounds();
if (bounds.height > height) {
bounds.height = height;
}
g.setColor(myTree.getBackground());
g.fillRect(bounds.x, bounds.y, bounds.width, bounds.height);
if (g instanceof Graphics2D) {
int h = 6; // gradient height
int y = bounds.y + bounds.height;
((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);
}
mySeparator.setBounds(bounds);
mySeparator.paint(g);
}
}
void selectFirst() {
for (ConfigurableGroup eachGroup : myRoot.myGroups) {
Configurable[] kids = eachGroup.getConfigurables();

View File

@@ -0,0 +1,126 @@
/*
* Copyright 2000-2014 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.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.ui.components;
import com.intellij.openapi.util.registry.Registry;
import com.intellij.ui.ColorUtil;
import javax.swing.*;
import java.awt.*;
/**
* @author Sergey.Malenkov
*/
public class GradientViewport extends JViewport {
private final Insets myInsets;
private final boolean myAlways;
public GradientViewport(Component view, int top, int left, int bottom, int right, boolean forScrollBars) {
myInsets = new Insets(top, left, bottom, right);
myAlways = forScrollBars;
setView(view);
}
protected Component getHeader() {
return null;
}
@Override
public void paint(Graphics g) {
super.paint(g);
g = g.create();
try {
Color background = getBackground();
Component header = getHeader();
if (header != null) {
header.setBounds(0, 0, getWidth(), header.getPreferredSize().height);
if (background != null) {
g.setColor(background);
g.fillRect(header.getX(), header.getY(), header.getWidth(), header.getHeight());
}
}
if (g instanceof Graphics2D && background != null && !Registry.is("ui.no.bangs.and.whistles")) {
paintGradient((Graphics2D)g, background, 0, header == null ? 0 : header.getHeight());
}
if (header != null) {
header.paint(g);
}
}
finally {
g.dispose();
}
}
private void paintGradient(Graphics2D g2d, Color background, int x1, int y1) {
Component view = getView();
if (background != null && view != null) {
int x2 = x1, x3 = getWidth() - x2, x4 = x3;
int y2 = y1, y3 = getHeight() - y2, y4 = y3;
if (myInsets.left > 0 && view.getX() < 0) {
x2 += myInsets.left;
}
if (myInsets.top > 0 && view.getY() < 0) {
y2 += myInsets.top;
}
if (myInsets.right > 0 && view.getX() > getWidth() - view.getWidth()) {
x3 -= myInsets.right;
}
if (myInsets.bottom > 0 && view.getY() > getHeight() - view.getHeight()) {
y3 -= myInsets.bottom;
}
Component parent = myAlways ? null : getParent();
if (parent instanceof JScrollPane) {
JScrollPane pane = (JScrollPane)parent;
JScrollBar vBar = pane.getVerticalScrollBar();
if (vBar != null && vBar.isVisible()) {
if (vBar.getX() < getX()) {
x2 = x1;
}
else {
x3 = x4;
}
}
JScrollBar hBar = pane.getHorizontalScrollBar();
if (hBar != null && hBar.isVisible()) {
if (hBar.getY() < getY()) {
y2 = y1;
}
else {
y3 = y4;
}
}
}
Color transparent = ColorUtil.toAlpha(background, 0);
if (x1 != x2) {
g2d.setPaint(new GradientPaint(x1, y1, background, x2, y1, transparent));
g2d.fillPolygon(new int[]{x1, x2, x2, x1}, new int[]{y1, y2, y3, y4}, 4);
}
if (x3 != x4) {
g2d.setPaint(new GradientPaint(x3, y1, transparent, x4, y1, background));
g2d.fillPolygon(new int[]{x4, x3, x3, x4}, new int[]{y1, y2, y3, y4}, 4);
}
if (y1 != y2) {
g2d.setPaint(new GradientPaint(x1, y1, background, x1, y2, transparent));
g2d.fillPolygon(new int[]{x1, x2, x3, x4}, new int[]{y1, y2, y2, y1}, 4);
}
if (y3 != y4) {
g2d.setPaint(new GradientPaint(x1, y3, transparent, x1, y4, background));
g2d.fillPolygon(new int[]{x1, x2, x3, x4}, new int[]{y4, y3, y3, y4}, 4);
}
}
}
}