terminal: refactor default background/foreground to use JBColor.lazy instead of direct color updating on colors scheme changes

Now, it's as simple as `component.background = TerminalUi.defaultBackground()` to use terminal default background color as component background and update it properly on colors scheme changes.

GitOrigin-RevId: c507f417a7042d22a17afc0a01a80ff67b997787
This commit is contained in:
Sergey Simonchik
2024-03-16 23:05:48 +01:00
committed by intellij-monorepo-bot
parent e3561dcaf6
commit d62dd07a29
7 changed files with 57 additions and 56 deletions
@@ -13,7 +13,6 @@ import com.intellij.openapi.fileEditor.FileDocumentManager
import com.intellij.openapi.project.Project
import com.intellij.openapi.util.Disposer
import com.intellij.openapi.wm.IdeFocusManager
import com.intellij.terminal.BlockTerminalColors
import com.intellij.terminal.JBTerminalSystemSettingsProviderBase
import com.intellij.terminal.TerminalTitle
import com.intellij.terminal.bindApplicationTitle
@@ -261,9 +260,7 @@ class BlockTerminalView(
private inner class BlockTerminalPanel : JPanel(), DataProvider {
init {
bindBackgroundToColorKey(BlockTerminalColors.DEFAULT_BACKGROUND,
this@BlockTerminalView,
outputView.controller.outputModel.editor)
background = TerminalUi.defaultBackground(outputView.controller.outputModel.editor)
}
override fun getData(dataId: String): Any? {
@@ -11,9 +11,9 @@ import com.intellij.openapi.editor.impl.DocumentImpl
import com.intellij.openapi.editor.impl.EditorImpl
import com.intellij.openapi.project.Project
import com.intellij.openapi.util.Disposer
import com.intellij.terminal.BlockTerminalColors
import com.intellij.terminal.JBTerminalSystemSettingsProviderBase
import com.intellij.util.ui.JBUI
import org.jetbrains.plugins.terminal.exp.TerminalUi.useTerminalDefaultBackground
import java.awt.BorderLayout
import java.awt.Dimension
import javax.swing.JComponent
@@ -46,7 +46,7 @@ class SimpleTerminalView(
init {
editor = createEditor()
controller = SimpleTerminalController(settings, session, editor)
component = SimpleTerminalPanel(editor, this)
component = SimpleTerminalPanel(editor)
editor.addFocusListener(object : FocusChangeListener {
override fun focusGained(editor: Editor) {
controller.isFocused = true
@@ -61,9 +61,7 @@ class SimpleTerminalView(
private fun createEditor(): EditorImpl {
val document = DocumentImpl("", true)
val editor = TerminalUiUtils.createOutputEditor(document, project, settings)
bindColorKey(BlockTerminalColors.DEFAULT_BACKGROUND, this, editor) {
editor.setBackgroundColor(it)
}
editor.useTerminalDefaultBackground(this)
editor.settings.isLineMarkerAreaShown = false
editor.scrollPane.verticalScrollBarPolicy = if (withVerticalScroll) {
JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED
@@ -83,9 +81,9 @@ class SimpleTerminalView(
* This wrapper is needed to provide the editor to the DataContext.
* Editor is not proving it itself, because renderer mode is enabled ([EditorImpl.isRendererMode]).
*/
private inner class SimpleTerminalPanel(editor: Editor, parentDisposable: Disposable) : JPanel(), DataProvider {
private inner class SimpleTerminalPanel(editor: Editor) : JPanel(), DataProvider {
init {
bindBackgroundToColorKey(BlockTerminalColors.DEFAULT_BACKGROUND, parentDisposable, editor)
background = TerminalUi.defaultBackground(editor)
border = JBUI.Borders.emptyLeft(TerminalUi.alternateBufferLeftInset)
layout = BorderLayout()
add(editor.component, BorderLayout.CENTER)
@@ -9,10 +9,10 @@ import com.intellij.openapi.editor.EditorFactory
import com.intellij.openapi.editor.impl.DocumentImpl
import com.intellij.openapi.editor.impl.EditorImpl
import com.intellij.openapi.project.Project
import com.intellij.terminal.BlockTerminalColors
import com.intellij.terminal.JBTerminalSystemSettingsProviderBase
import com.intellij.ui.components.JBLayeredPane
import com.intellij.util.concurrency.annotations.RequiresEdt
import org.jetbrains.plugins.terminal.exp.TerminalUi.useTerminalDefaultBackground
import java.awt.Component
import java.awt.Dimension
import javax.swing.JComponent
@@ -69,6 +69,7 @@ class TerminalOutputView(
val document = DocumentImpl("", true)
val editor = TerminalUiUtils.createOutputEditor(document, project, settings)
editor.settings.isUseSoftWraps = true
editor.useTerminalDefaultBackground(this)
stickScrollBarToBottom(editor.scrollPane.verticalScrollBar)
return editor
}
@@ -115,9 +116,6 @@ class TerminalOutputView(
init {
isOpaque = false
add(editor.component, JLayeredPane.DEFAULT_LAYER as Any) // cast to Any needed to call right method overload
bindColorKey(BlockTerminalColors.DEFAULT_BACKGROUND, this@TerminalOutputView, editor) {
editor.setBackgroundColor(it)
}
}
override fun getData(dataId: String): Any? {
@@ -13,7 +13,6 @@ import com.intellij.openapi.fileEditor.FileDocumentManager
import com.intellij.openapi.fileTypes.PlainTextLanguage
import com.intellij.openapi.project.Project
import com.intellij.openapi.wm.IdeFocusManager
import com.intellij.terminal.BlockTerminalColors
import com.intellij.terminal.JBTerminalSystemSettingsProviderBase
import com.intellij.ui.LanguageTextField
import com.intellij.ui.SimpleColoredComponent
@@ -23,6 +22,7 @@ import com.intellij.ui.components.panels.ListLayout
import com.intellij.util.ui.JBInsets
import com.intellij.util.ui.JBUI
import org.jetbrains.plugins.terminal.exp.TerminalPromptController.PromptStateListener
import org.jetbrains.plugins.terminal.exp.TerminalUi.useTerminalDefaultBackground
import org.jetbrains.plugins.terminal.exp.completion.TerminalShellSupport
import org.jetbrains.plugins.terminal.exp.history.CommandHistoryPresenter
import org.jetbrains.plugins.terminal.exp.history.CommandSearchPresenter
@@ -77,7 +77,7 @@ class TerminalPromptView(
}
component.border = JBUI.Borders.compound(outerBorder, innerBorder)
component.bindBackgroundToColorKey(BlockTerminalColors.DEFAULT_BACKGROUND, this, editor)
component.background = TerminalUi.defaultBackground(editor)
component.layout = ListLayout.vertical(TerminalUi.promptToCommandInset)
component.add(promptComponent)
component.add(editorTextField)
@@ -167,9 +167,7 @@ class TerminalPromptView(
val editor = textField.getEditor(true) as EditorImpl
editor.scrollPane.border = JBUI.Borders.empty()
editor.gutterComponentEx.isPaintBackground = false
bindColorKey(BlockTerminalColors.DEFAULT_BACKGROUND, this, editor) {
editor.setBackgroundColor(it)
}
editor.useTerminalDefaultBackground(this)
editor.colorsScheme.apply {
editorFontName = settings.terminalFont.fontName
editorFontSize = settings.terminalFont.size
@@ -195,8 +193,8 @@ class TerminalPromptView(
font = EditorUtil.getEditorFont()
}
}
component.bindBackgroundToColorKey(BlockTerminalColors.DEFAULT_BACKGROUND, this, editor)
component.bindForegroundToColorKey(BlockTerminalColors.DEFAULT_FOREGROUND, this, editor)
component.background = TerminalUi.defaultBackground(editor)
component.foreground = TerminalUi.defaultForeground(editor)
component.myBorder = JBUI.Borders.emptyBottom(2)
component.ipad = JBInsets.emptyInsets()
return component
@@ -1,6 +1,18 @@
// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package org.jetbrains.plugins.terminal.exp
import com.intellij.openapi.Disposable
import com.intellij.openapi.application.ApplicationManager
import com.intellij.openapi.editor.Editor
import com.intellij.openapi.editor.colors.ColorKey
import com.intellij.openapi.editor.colors.EditorColorsListener
import com.intellij.openapi.editor.colors.EditorColorsManager
import com.intellij.openapi.editor.colors.EditorColorsScheme
import com.intellij.openapi.editor.ex.EditorEx
import com.intellij.terminal.BlockTerminalColors
import com.intellij.ui.JBColor
import java.awt.Color
@Suppress("ConstPropertyName")
object TerminalUi {
const val blockTopInset = 8
@@ -22,4 +34,35 @@ object TerminalUi {
const val alternateBufferLeftInset = 4
const val searchComponentWidth = 500
fun defaultBackground(editor: Editor? = null): JBColor {
return createColorBoundToColorKey(BlockTerminalColors.DEFAULT_BACKGROUND, editor) {
it.defaultBackground
}
}
fun defaultForeground(editor: Editor? = null): JBColor {
return createColorBoundToColorKey(BlockTerminalColors.DEFAULT_FOREGROUND, editor) {
it.defaultForeground
}
}
private fun createColorBoundToColorKey(colorKey: ColorKey, editor: Editor? = null, default: (EditorColorsScheme) -> Color): JBColor {
return JBColor.lazy {
val colorsScheme = editor?.colorsScheme ?: EditorColorsManager.getInstance().globalScheme
colorsScheme.getColor(colorKey) ?: default(colorsScheme)
}
}
/**
* Unfortunately, `editor.backgroundColor = terminalDefaultBackground(editor)` doesn't work when
* colors scheme is changed. Because [com.intellij.openapi.editor.impl.EditorImpl.setBackgroundColor]
* doesn't save a passed in color if the color is equal to the default one.
*/
fun EditorEx.useTerminalDefaultBackground(parentDisposable: Disposable) {
backgroundColor = defaultBackground(this)
ApplicationManager.getApplication().messageBus.connect(parentDisposable).subscribe(EditorColorsManager.TOPIC, EditorColorsListener {
backgroundColor = defaultBackground(this)
})
}
}
@@ -10,12 +10,8 @@ import com.intellij.openapi.application.ApplicationManager
import com.intellij.openapi.application.ModalityState
import com.intellij.openapi.diagnostic.logger
import com.intellij.openapi.editor.Document
import com.intellij.openapi.editor.Editor
import com.intellij.openapi.editor.EditorFactory
import com.intellij.openapi.editor.EditorKind
import com.intellij.openapi.editor.colors.ColorKey
import com.intellij.openapi.editor.colors.EditorColorsListener
import com.intellij.openapi.editor.colors.EditorColorsManager
import com.intellij.openapi.editor.event.EditorMouseEvent
import com.intellij.openapi.editor.ex.EditorEx
import com.intellij.openapi.editor.ex.EditorGutterFreePainterAreaState
@@ -232,31 +228,3 @@ object TerminalUiUtils {
const val GREEN_COLOR_INDEX: Int = 2
const val YELLOW_COLOR_INDEX: Int = 3
}
fun Component.bindBackgroundToColorKey(colorKey: ColorKey, parentDisposable: Disposable, editor: Editor? = null) {
bindColorKey(colorKey, parentDisposable, editor) {
background = it
}
}
fun Component.bindForegroundToColorKey(colorKey: ColorKey, parentDisposable: Disposable, editor: Editor? = null) {
bindColorKey(colorKey, parentDisposable, editor) {
foreground = it
}
}
fun bindColorKey(colorKey: ColorKey, parentDisposable: Disposable, editor: Editor? = null, applier: (Color?) -> Unit) {
applier(getColor(editor, colorKey))
ApplicationManager.getApplication().messageBus.connect(parentDisposable).subscribe(EditorColorsManager.TOPIC, EditorColorsListener {
applier(getColor(editor, colorKey))
})
}
private fun getColor(editor: Editor?, colorKey: ColorKey): Color? {
return if (editor != null) {
editor.colorsScheme.getColor(colorKey)
}
else {
EditorColorsManager.getInstance().globalScheme.getColor(colorKey)
}
}
@@ -5,7 +5,6 @@ import com.intellij.openapi.Disposable
import com.intellij.openapi.project.Project
import com.intellij.openapi.util.Disposer
import com.intellij.openapi.wm.IdeFocusManager
import com.intellij.terminal.BlockTerminalColors
import com.intellij.terminal.TerminalTitle
import com.intellij.terminal.ui.TerminalWidget
import com.intellij.terminal.ui.TtyConnectorAccessor
@@ -118,7 +117,7 @@ class TerminalWidgetImpl(private val project: Project,
override val component: JComponent = object : JPanel() {
init {
bindBackgroundToColorKey(BlockTerminalColors.DEFAULT_BACKGROUND, this@TerminalPlaceholder)
background = TerminalUi.defaultBackground()
}
}