vcs: better computation of ChangesTree fixed height
authorAleksey Pivovarov <AMPivovarov@gmail.com>
Tue, 27 Sep 2022 10:58:33 +0000 (12:58 +0200)
committerintellij-monorepo-bot <intellij-monorepo-bot-no-reply@jetbrains.com>
Tue, 27 Sep 2022 20:11:58 +0000 (20:11 +0000)
* Take into account "Tree.rowHeight" property from UI theme (Fixes issue in NewUI on non-Linux systems)
* Prepare for potential bigger-than-text checkboxes

Follow-up: 7cf7aa4316f03a1e83e0d58a1328e6eb9d880052

GitOrigin-RevId: b75bf49cfd4f1a3f644cee19cefb2ee35b185c1b

platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ui/ChangesTree.java
platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ui/ChangesTreeCellRenderer.kt

index 30ca8bbbcd255c7e414bd4aa557974a61371bf49..f7125a8a05600ba9496f044216efa11fb3ac5338 100644 (file)
@@ -1,6 +1,7 @@
 // Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
 package com.intellij.openapi.vcs.changes.ui;
 
+import com.intellij.icons.AllIcons;
 import com.intellij.ide.CommonActionsManager;
 import com.intellij.ide.CopyProvider;
 import com.intellij.ide.DefaultTreeExpander;
@@ -43,10 +44,8 @@ import org.jetbrains.annotations.*;
 import javax.swing.*;
 import javax.swing.event.TreeSelectionEvent;
 import javax.swing.event.TreeSelectionListener;
-import javax.swing.tree.DefaultMutableTreeNode;
-import javax.swing.tree.DefaultTreeModel;
-import javax.swing.tree.TreeNode;
-import javax.swing.tree.TreePath;
+import javax.swing.plaf.TreeUI;
+import javax.swing.tree.*;
 import java.awt.*;
 import java.awt.event.KeyEvent;
 import java.awt.event.MouseEvent;
@@ -137,13 +136,35 @@ public abstract class ChangesTree extends Tree implements DataProvider {
 
     if (Registry.is("vcs.changes.tree.use.fixed.height.renderer")) {
       putClientProperty(DefaultTreeUI.LARGE_MODEL_ALLOWED, true);
-      ChangesBrowserFilePathNode sampleNode = new ChangesBrowserFilePathNode(VcsUtil.getFilePath("ChangesTreeDummy.java"), null);
-      Component component = nodeRenderer.getTreeCellRendererComponent(this, sampleNode, true, true, true, 0, true);
-      setRowHeight(component.getPreferredSize().height);
       setLargeModel(true);
+
+      updateFixedRowHeight();
     }
   }
 
+  private void updateFixedRowHeight() {
+    if (!isLargeModel()) return;
+
+    int fixedRowHeight = UIManager.getInt("Tree.rowHeight");
+    if (fixedRowHeight > 0) return; // leave hardcoded value from BasicTreeUI.installDefaults
+
+    TreeCellRenderer renderer = getCellRenderer();
+    if (renderer == null) return;
+
+    ChangesBrowserNode<?> sampleNode = new FixedHeightSampleChangesBrowserNode();
+    Component component = renderer.getTreeCellRendererComponent(this, sampleNode, true, true, true, 0, true);
+    int rendererHeight = component.getPreferredSize().height;
+    if (rendererHeight <= 0) return;
+
+    setRowHeight(rendererHeight);
+  }
+
+  @Override
+  public void setUI(TreeUI ui) {
+    super.setUI(ui);
+    updateFixedRowHeight();
+  }
+
   /**
    * There is special logic for {@link DnDAware} components in
    * {@link IdeGlassPaneImpl#dispatch(AWTEvent)} that doesn't call
@@ -348,6 +369,7 @@ public abstract class ChangesTree extends Tree implements DataProvider {
       myCheckBoxClickHandler.uninstall(this);
       myCheckBoxClickHandler = null;
     }
+    updateFixedRowHeight();
     repaint();
   }
 
@@ -865,4 +887,23 @@ public abstract class ChangesTree extends Tree implements DataProvider {
       }
     }
   }
+
+  static class FixedHeightSampleChangesBrowserNode extends ChangesBrowserNode<Object> {
+    private static final Object FIXED_HEIGHT_SAMPLE_NODE_VALUE = new Object();
+
+    private FixedHeightSampleChangesBrowserNode() {
+      super(FIXED_HEIGHT_SAMPLE_NODE_VALUE);
+    }
+
+    @Override
+    public void render(@NotNull ChangesBrowserNodeRenderer renderer, boolean selected, boolean expanded, boolean hasFocus) {
+      renderer.append("ChangesTreeDummy.java");
+      renderer.setIcon(AllIcons.FileTypes.Any_type);
+    }
+
+    @Override
+    public String toString() {
+      return "FixedHeightSampleChangesBrowserNode";
+    }
+  }
 }
index 7e89f1444cf4a01af38ae58c45ed21b7720b4d19..fa29c830ddb3972c71ca8f7feed39e68121b6bd2 100644 (file)
@@ -4,7 +4,6 @@ package com.intellij.openapi.vcs.changes.ui
 import com.intellij.openapi.actionSystem.ActionManager
 import com.intellij.ui.CellRendererPanel
 import com.intellij.util.ui.ThreeStateCheckBox
-import com.intellij.util.ui.accessibility.AccessibleContextDelegate
 import com.intellij.util.ui.accessibility.AccessibleContextDelegateWithContextMenu
 import java.awt.BorderLayout
 import java.awt.Component
@@ -54,7 +53,9 @@ open class ChangesTreeCellRenderer(protected val textRenderer: ChangesBrowserNod
       background = null
       isOpaque = false
 
-      isVisible = tree.run { isShowCheckboxes && isInclusionVisible(value) }
+      isVisible = tree.isShowCheckboxes &&
+                  (value is ChangesTree.FixedHeightSampleChangesBrowserNode || // assume checkbox is visible for the sample node
+                   tree.isInclusionVisible(value))
       if (isVisible) {
         state = tree.getNodeStatus(value)
         isEnabled = tree.run { isEnabled && isInclusionEnabled(value) }