Share SHRINK_LONG_RENDERER and the corresponding refactoring

GitOrigin-RevId: cc1d22a52b342a7e7eefd985fde54f9d78e52e16
This commit is contained in:
Sergey Malenkov
2020-02-27 18:30:48 +03:00
committed by intellij-monorepo-bot
parent 14540d3675
commit 8ee521d033
5 changed files with 117 additions and 65 deletions

View File

@@ -47,7 +47,6 @@ import com.intellij.ui.*;
import com.intellij.ui.tree.AsyncTreeModel;
import com.intellij.ui.tree.StructureTreeModel;
import com.intellij.ui.tree.TreeVisitor;
import com.intellij.ui.tree.ui.DefaultTreeUI;
import com.intellij.ui.treeStructure.Tree;
import com.intellij.util.EditSourceOnDoubleClickHandler;
import com.intellij.util.EditSourceOnEnterKeyHandler;
@@ -79,6 +78,7 @@ import static com.intellij.build.BuildView.CONSOLE_VIEW_NAME;
import static com.intellij.openapi.util.text.StringUtil.isEmpty;
import static com.intellij.ui.AnimatedIcon.ANIMATION_IN_RENDERER_ALLOWED;
import static com.intellij.ui.SimpleTextAttributes.GRAYED_ATTRIBUTES;
import static com.intellij.ui.render.RenderingHelper.SHRINK_LONG_RENDERER;
import static com.intellij.util.ObjectUtils.chooseNotNull;
import static com.intellij.util.containers.ContainerUtil.addIfNotNull;
import static com.intellij.util.ui.UIUtil.getTreeSelectionForeground;
@@ -712,6 +712,7 @@ public class BuildTreeConsoleView implements ConsoleView, DataProvider, BuildCon
new TreeSpeedSearch(tree).setComparator(new SpeedSearchComparator(false));
TreeUtil.installActions(tree);
tree.setCellRenderer(new MyNodeRenderer());
tree.putClientProperty(SHRINK_LONG_RENDERER, true);
return tree;
}
@@ -1001,10 +1002,6 @@ public class BuildTreeConsoleView implements ConsoleView, DataProvider, BuildCon
}
private static class MyNodeRenderer extends NodeRenderer {
{
putClientProperty(DefaultTreeUI.SHRINK_LONG_RENDERER, true);
}
private String myDurationText;
private Color myDurationColor;
private int myDurationWidth;

View File

@@ -0,0 +1,97 @@
// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package com.intellij.ui.render;
import com.intellij.openapi.util.Key;
import com.intellij.ui.ComponentWithExpandableItems;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.NotNull;
import javax.swing.JComponent;
import javax.swing.JScrollBar;
import javax.swing.JScrollPane;
import javax.swing.JViewport;
import java.awt.Container;
import java.awt.Rectangle;
import java.util.Collection;
import static com.intellij.openapi.util.SystemInfo.isMac;
import static com.intellij.ui.components.JBScrollPane.IGNORE_SCROLLBAR_IN_INSETS;
public final class RenderingHelper {
/**
* This key can be set to a tree to resize renderer component if it exceed a visible area.
*
* @see JComponent#putClientProperty
*/
public static final Key<Boolean> SHRINK_LONG_RENDERER = Key.create("SHRINK_LONG_RENDERER");
private final Rectangle myViewBounds;
private final int myHintIndex;
private int myRightMargin;
private boolean myShrinkingDisabled;
@ApiStatus.Internal
public RenderingHelper(@NotNull JComponent component) {
myViewBounds = new Rectangle(component.getWidth(), component.getHeight());
myHintIndex = getExpandableHintIndex(component);
Container parent = component.getParent();
if (parent instanceof JViewport) {
myViewBounds.setBounds(-component.getX(), -component.getY(), parent.getWidth(), parent.getHeight());
parent = parent.getParent();
if (parent instanceof JScrollPane) {
JScrollPane pane = (JScrollPane)parent;
JScrollBar hsb = pane.getHorizontalScrollBar();
if (hsb != null && hsb.isVisible()) {
myShrinkingDisabled = isClientPropertyFalse(component, SHRINK_LONG_RENDERER, false);
}
JScrollBar vsb = pane.getVerticalScrollBar();
if (vsb != null && vsb.isVisible() && !vsb.isOpaque() && isClientPropertyFalse(vsb, IGNORE_SCROLLBAR_IN_INSETS, isMac)) {
myRightMargin = vsb.getWidth();
}
}
}
}
public int getX() {
return myViewBounds.x;
}
public int getY() {
return myViewBounds.y;
}
public int getWidth() {
return myViewBounds.width;
}
public int getHeight() {
return myViewBounds.height;
}
public int getRightMargin() {
return myRightMargin;
}
public boolean isRendererShrinkingDisabled(int index) {
return myShrinkingDisabled || isExpandableHintShown(index);
}
public boolean isExpandableHintShown(int index) {
return myHintIndex == index;
}
private static int getExpandableHintIndex(@NotNull JComponent component) {
if (component instanceof ComponentWithExpandableItems) {
ComponentWithExpandableItems<?> c = (ComponentWithExpandableItems<?>)component;
Collection<?> items = c.getExpandableItemsHandler().getExpandedItems();
Object item = items.isEmpty() ? null : items.iterator().next();
if (item instanceof Integer) return (Integer)item;
}
return -1;
}
private static boolean isClientPropertyFalse(@NotNull JComponent component, @NotNull Object key, boolean strict) {
Object property = component.getClientProperty(key);
return strict ? Boolean.FALSE.equals(property) : !Boolean.TRUE.equals(property);
}
}

View File

@@ -9,14 +9,14 @@ import com.intellij.openapi.util.Key;
import com.intellij.ui.BackgroundSupplier;
import com.intellij.ui.DirtyUI;
import com.intellij.ui.ComponentUtil;
import com.intellij.ui.ComponentWithExpandableItems;
import com.intellij.ui.LoadingNode;
import com.intellij.ui.components.JBScrollPane;
import com.intellij.ui.render.RenderingHelper;
import com.intellij.ui.tree.AsyncTreeModel;
import com.intellij.ui.tree.TreePathBackgroundSupplier;
import com.intellij.util.ui.MouseEventAdapter;
import com.intellij.util.ui.UIUtil;
import com.intellij.util.ui.tree.TreeUtil;
import org.jetbrains.annotations.ApiStatus.ScheduledForRemoval;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -37,7 +37,6 @@ import java.util.Collection;
import static com.intellij.openapi.application.ApplicationManager.getApplication;
import static com.intellij.openapi.util.SystemInfo.isMac;
import static com.intellij.openapi.util.registry.Registry.is;
import static com.intellij.ui.components.JBScrollPane.IGNORE_SCROLLBAR_IN_INSETS;
import static com.intellij.ui.paint.RectanglePainter.DRAW;
import static com.intellij.util.ReflectionUtil.getMethod;
import static com.intellij.util.containers.ContainerUtil.createWeakSet;
@@ -45,6 +44,11 @@ import static com.intellij.util.ui.tree.WideSelectionTreeUI.TREE_TABLE_TREE_KEY;
@DirtyUI
public final class DefaultTreeUI extends BasicTreeUI {
/**
* @deprecated use {@link RenderingHelper#SHRINK_LONG_RENDERER} instead
*/
@Deprecated
@ScheduledForRemoval(inVersion = "2020.2")
public static final Key<Boolean> SHRINK_LONG_RENDERER = Key.create("resize renderer component if it exceed a visible area");
private static final Logger LOG = Logger.getInstance(DefaultTreeUI.class);
private static final Collection<Class<?>> SUSPICIOUS = createWeakSet();
@@ -113,16 +117,6 @@ public final class DefaultTreeUI extends BasicTreeUI {
return true;
}
private static int getExpandedRow(@NotNull JTree tree) {
if (tree instanceof ComponentWithExpandableItems) {
ComponentWithExpandableItems<?> component = (ComponentWithExpandableItems<?>)tree;
Collection<?> items = component.getExpandableItemsHandler().getExpandedItems();
Object item = items.isEmpty() ? null : items.iterator().next();
if (item instanceof Integer) return (Integer)item;
}
return -1;
}
@SuppressWarnings("MethodOverridesStaticMethodOfSuperclass")
public static ComponentUI createUI(JComponent component) {
assert component instanceof JTree;
@@ -191,30 +185,8 @@ public final class DefaultTreeUI extends BasicTreeUI {
if (row >= 0) {
Control.Painter painter = getPainter(tree);
Rectangle buffer = new Rectangle();
int expandedRow = getExpandedRow(tree);
RenderingHelper helper = new RenderingHelper(tree);
int maxPaintY = paintBounds.y + paintBounds.height;
int viewportX = 0;
int viewportWidth = tree.getWidth();
int vsbWidth = 0;
boolean hsbVisible = false;
Container parent = tree.getParent();
if (parent instanceof JViewport) {
viewportX = -tree.getX();
viewportWidth = parent.getWidth();
parent = parent.getParent();
if (parent instanceof JBScrollPane) {
JBScrollPane pane = (JBScrollPane)parent;
JScrollBar hsb = pane.getHorizontalScrollBar();
if (hsb != null && hsb.isVisible()) hsbVisible = true;
JScrollBar vsb = pane.getVerticalScrollBar();
if (vsb != null && vsb.isVisible() && !vsb.isOpaque()) {
Boolean property = ComponentUtil.getClientProperty(vsb, IGNORE_SCROLLBAR_IN_INSETS);
if (isMac ? Boolean.FALSE.equals(property) : !Boolean.TRUE.equals(property)) {
vsbWidth = vsb.getWidth(); // to calculate a right margin of a renderer component
}
}
}
}
while (path != null) {
Rectangle bounds = cache.getBounds(path, buffer);
if (bounds == null) break; // something goes wrong
@@ -230,18 +202,18 @@ public final class DefaultTreeUI extends BasicTreeUI {
Color background = getBackground(tree, path, row, selected);
if (background != null) {
g.setColor(background);
g.fillRect(viewportX, bounds.y, viewportWidth, bounds.height);
g.fillRect(helper.getX(), bounds.y, helper.getWidth(), bounds.height);
}
int offset = painter.getRendererOffset(control, depth, leaf);
painter.paint(tree, g, insets.left, bounds.y, offset, bounds.height, control, depth, leaf, expanded, selected && focused);
// TODO: editingComponent, editingRow ???
if (editingComponent == null || editingRow != row) {
int width = viewportX + viewportWidth - insets.left - offset - vsbWidth;
int width = helper.getX() + helper.getWidth() - insets.left - offset - helper.getRightMargin();
if (width > 0) {
Object value = path.getLastPathComponent();
Component component = getRenderer(tree, value, selected, expanded, leaf, row, lead);
if (component != null) {
if (width < bounds.width && (expandedRow == row || hsbVisible && !UIUtil.isClientPropertyTrue(component, SHRINK_LONG_RENDERER))) {
if (width < bounds.width && helper.isRendererShrinkingDisabled(row)) {
width = bounds.width; // disable shrinking a long nodes
}
setBackground(tree, component, background, false);
@@ -251,11 +223,11 @@ public final class DefaultTreeUI extends BasicTreeUI {
if (!isMac && lead && g instanceof Graphics2D) {
if (!selected) {
g.setColor(getBackground(tree, path, row, true));
DRAW.paint((Graphics2D)g, viewportX, bounds.y, viewportWidth, bounds.height, 0);
DRAW.paint((Graphics2D)g, helper.getX(), bounds.y, helper.getWidth(), bounds.height, 0);
}
else if (1 < tree.getSelectionModel().getSelectionCount()) {
g.setColor(UIUtil.getTreeBackground());
DRAW.paint((Graphics2D)g, viewportX + 1, bounds.y + 1, viewportWidth - 2, bounds.height - 2, 0);
DRAW.paint((Graphics2D)g, helper.getX() + 1, bounds.y + 1, helper.getWidth() - 2, bounds.height - 2, 0);
}
}
}

View File

@@ -1,4 +1,4 @@
// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package com.intellij.execution.testframework.sm.runner.ui;
import com.intellij.execution.testframework.TestConsoleProperties;
@@ -15,7 +15,6 @@ import java.awt.*;
import static com.intellij.ide.ui.UISettings.setupAntialiasing;
import static com.intellij.ui.SimpleTextAttributes.GRAYED_ATTRIBUTES;
import static com.intellij.ui.tree.ui.DefaultTreeUI.SHRINK_LONG_RENDERER;
import static com.intellij.util.ui.UIUtil.getTreeSelectionForeground;
/**
@@ -32,7 +31,6 @@ public class TestTreeRenderer extends ColoredTreeCellRenderer {
private int myDurationOffset;
public TestTreeRenderer(final TestConsoleProperties consoleProperties) {
putClientProperty(SHRINK_LONG_RENDERER, true);
myConsoleProperties = consoleProperties;
}

View File

@@ -1,19 +1,4 @@
/*
* Copyright 2000-2009 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.
*/
// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package com.intellij.execution.testframework;
import com.intellij.execution.Location;
@@ -46,6 +31,8 @@ import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import static com.intellij.ui.render.RenderingHelper.SHRINK_LONG_RENDERER;
public abstract class TestTreeView extends Tree implements DataProvider, CopyProvider {
public static final DataKey<TestFrameworkRunningModel> MODEL_DATA_KEY = DataKey.create("testFrameworkModel.dataId");
@@ -85,6 +72,7 @@ public abstract class TestTreeView extends Tree implements DataProvider, CopyPro
});
installHandlers();
setCellRenderer(getRenderer(myModel.getProperties()));
putClientProperty(SHRINK_LONG_RENDERER, true);
putClientProperty(AnimatedIcon.ANIMATION_IN_RENDERER_ALLOWED, true);
}