git-index: fix line tracker popup layout when scrollbars are necessary
authorAleksey Pivovarov <AMPivovarov@gmail.com>
Mon, 10 Aug 2020 09:36:16 +0000 (12:36 +0300)
committerintellij-monorepo-bot <intellij-monorepo-bot-no-reply@jetbrains.com>
Wed, 12 Aug 2020 13:43:08 +0000 (13:43 +0000)
GitOrigin-RevId: 7a4deadb2e747f9c399ee6703d4d254b006b38d4

plugins/git4idea/src/git4idea/index/GitStageLineStatusTracker.kt
plugins/git4idea/src/git4idea/index/StagePopupVerticalLayout.kt [new file with mode: 0644]

index 49ae732d863ad61a331b6888d6e0918f87bd50fa..207df1fb2606f5ac47a032fc2687637a4261110d 100644 (file)
@@ -35,7 +35,6 @@ import com.intellij.openapi.vfs.VirtualFile
 import com.intellij.ui.EditorTextField
 import com.intellij.ui.JBColor
 import com.intellij.ui.components.JBLabel
-import com.intellij.ui.components.panels.VerticalLayout
 import com.intellij.ui.paint.LinePainter2D
 import com.intellij.ui.scale.JBUIScale
 import com.intellij.util.containers.PeekableIteratorWrapper
@@ -45,6 +44,9 @@ import git4idea.GitUtil
 import git4idea.i18n.GitBundle
 import git4idea.index.actions.GitAddOperation
 import git4idea.index.actions.GitResetOperation
+import net.miginfocom.layout.CC
+import net.miginfocom.layout.LC
+import net.miginfocom.swing.MigLayout
 import org.jetbrains.annotations.CalledInAwt
 import java.awt.*
 import java.util.*
@@ -444,10 +446,13 @@ class GitStageLineStatusTracker(
     }
 
     fun createEditorComponent(editor: Editor, stagedTextField: EditorTextField, vcsTextField: EditorTextField): JComponent {
-      val editorsPanel = JPanel(VerticalLayout(0))
+      val stagedEditorPane = createEditorPane(editor, GitBundle.message("stage.content.staged"), stagedTextField, true)
+      val vcsEditorPane = createEditorPane(editor, GitUtil.HEAD, vcsTextField, false)
+
+      val editorsPanel = JPanel(StagePopupVerticalLayout())
+      editorsPanel.add(stagedEditorPane)
+      editorsPanel.add(vcsEditorPane)
       editorsPanel.background = LineStatusMarkerPopupPanel.getEditorBackgroundColor(editor)
-      editorsPanel.add(createEditorPane(editor, GitBundle.message("stage.content.staged"), stagedTextField, true))
-      editorsPanel.add(createEditorPane(editor, GitUtil.HEAD, vcsTextField, false))
       return editorsPanel
     }
 
diff --git a/plugins/git4idea/src/git4idea/index/StagePopupVerticalLayout.kt b/plugins/git4idea/src/git4idea/index/StagePopupVerticalLayout.kt
new file mode 100644 (file)
index 0000000..cf6d9c2
--- /dev/null
@@ -0,0 +1,68 @@
+// 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 git4idea.index
+
+import java.awt.*
+import kotlin.math.max
+
+/**
+ * Put two scrollable panels in a vertical stack.
+ * If both panels preferred height is bigger than `panel.size / 2`, give them both equal height.
+ */
+internal class StagePopupVerticalLayout : LayoutManager {
+  override fun addLayoutComponent(name: String?, comp: Component) = Unit
+  override fun removeLayoutComponent(comp: Component) = Unit
+
+  override fun preferredLayoutSize(parent: Container): Dimension = computeLayoutSize(parent) { it.preferredSize }
+  override fun minimumLayoutSize(parent: Container): Dimension = computeLayoutSize(parent) { it.minimumSize }
+
+  private fun computeLayoutSize(parent: Container, sizeFun: (Component) -> Dimension): Dimension {
+    var width = 0
+    var height = 0
+    for (component in parent.components) {
+      val size = sizeFun(component)
+      width = max(width, size.width)
+      height += size.height
+    }
+    return Dimension(width, height)
+  }
+
+  override fun layoutContainer(parent: Container) {
+    assert(parent.componentCount == 2)
+    val size = parent.size
+    val panel1 = parent.getComponent(0)
+    val panel2 = parent.getComponent(1)
+
+    val height = size.height
+    val prefHeight1 = panel1.preferredSize.height
+    val prefHeight2 = panel2.preferredSize.height
+
+    val height1: Int
+    val height2: Int
+
+    val isBig1 = prefHeight1 > height / 2
+    val isBig2 = prefHeight2 > height / 2
+    if (isBig1 && isBig2) {
+      // split panel in half
+      height1 = height / 2
+      height2 = height - height1
+    }
+    else if (isBig1) {
+      // scrollbar for panel1
+      height2 = prefHeight2
+      height1 = height - height2
+    }
+    else if (isBig2) {
+      // scrollbar for panel2
+      height1 = prefHeight1
+      height2 = height - height1
+    }
+    else {
+      // no scrollbar necessary
+      height1 = prefHeight1
+      height2 = prefHeight2
+    }
+
+    panel1.bounds = Rectangle(0, 0, size.width, height1)
+    panel2.bounds = Rectangle(0, height1, size.width, height2)
+  }
+}
\ No newline at end of file