21b79c426954c270f28d61a64cf51c860b8511ad
[idea/community.git] / platform / vcs-impl / src / com / intellij / openapi / vcs / changes / ChangesViewPanel.kt
1 // 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.
2 package com.intellij.openapi.vcs.changes
3
4 import com.intellij.ide.DataManager
5 import com.intellij.ide.DefaultTreeExpander
6 import com.intellij.openapi.actionSystem.ActionManager
7 import com.intellij.openapi.actionSystem.ActionPlaces.CHANGES_VIEW_TOOLBAR
8 import com.intellij.openapi.actionSystem.ActionToolbar
9 import com.intellij.openapi.actionSystem.DefaultActionGroup
10 import com.intellij.openapi.project.Project
11 import com.intellij.openapi.vcs.changes.ui.ChangesListView
12 import com.intellij.ui.IdeBorderFactory.createBorder
13 import com.intellij.ui.JBColor
14 import com.intellij.ui.ScrollPaneFactory.createScrollPane
15 import com.intellij.ui.SideBorder
16 import com.intellij.util.EditSourceOnDoubleClickHandler.isToggleEvent
17 import com.intellij.util.OpenSourceUtil.openSourcesFrom
18 import com.intellij.util.Processor
19 import com.intellij.util.ui.JBUI.Panels.simplePanel
20 import com.intellij.util.ui.components.BorderLayoutPanel
21 import com.intellij.util.ui.tree.TreeUtil
22 import javax.swing.JComponent
23 import javax.swing.JTree
24 import javax.swing.SwingConstants
25 import kotlin.properties.Delegates.observable
26
27 class ChangesViewPanel(project: Project) : BorderLayoutPanel() {
28   val changesView: ChangesListView = ChangesListView(project, false).apply {
29     treeExpander = object : DefaultTreeExpander(this) {
30       override fun collapseAll(tree: JTree, keepSelectionLevel: Int) {
31         super.collapseAll(tree, 2)
32         TreeUtil.expand(tree, 1)
33       }
34     }
35     doubleClickHandler = Processor { e ->
36       if (isToggleEvent(this, e)) return@Processor false
37
38       openSourcesFrom(DataManager.getInstance().getDataContext(this), true)
39       true
40     }
41     enterKeyHandler = Processor {
42       openSourcesFrom(DataManager.getInstance().getDataContext(this), false)
43       true
44     }
45   }
46
47   val toolbarActionGroup = DefaultActionGroup()
48
49   var isToolbarHorizontal: Boolean by observable(false) { _, oldValue, newValue ->
50     if (oldValue != newValue) {
51       addToolbar(newValue) // this also removes toolbar from previous parent
52     }
53   }
54
55   val toolbar: ActionToolbar =
56     ActionManager.getInstance().createActionToolbar(CHANGES_VIEW_TOOLBAR, toolbarActionGroup, isToolbarHorizontal).apply {
57       setTargetComponent(changesView)
58     }
59
60   var statusComponent by observable<JComponent?>(null) { _, oldValue, newValue ->
61     if (oldValue == newValue) return@observable
62
63     if (oldValue != null) centerPanel.remove(oldValue)
64     if (newValue != null) centerPanel.addToBottom(newValue)
65   }
66
67   private val centerPanel = simplePanel(createScrollPane(changesView))
68
69   init {
70     addToCenter(centerPanel)
71     addToolbar(isToolbarHorizontal)
72   }
73
74   private fun addToolbar(isHorizontal: Boolean) {
75     if (isHorizontal) {
76       toolbar.setOrientation(SwingConstants.HORIZONTAL)
77       centerPanel.border = createBorder(JBColor.border(), SideBorder.TOP)
78       addToTop(toolbar.component)
79     }
80     else {
81       toolbar.setOrientation(SwingConstants.VERTICAL)
82       centerPanel.border = createBorder(JBColor.border(), SideBorder.LEFT)
83       addToLeft(toolbar.component)
84     }
85   }
86 }