introduce two type of listeners: instant and for final selections to avoid flooding of Undo stack in text editors

GitOrigin-RevId: db577f0b97f3a4cf56cb5605a063b55ca5c4d4f3
This commit is contained in:
Konstantin Bulenkov
2019-06-09 18:06:38 +03:00
committed by intellij-monorepo-bot
parent a59f605a49
commit 8fbc212297
4 changed files with 48 additions and 15 deletions
@@ -355,21 +355,19 @@ public class ColorPicker extends JPanel implements ColorListener, DocumentListen
}
public static void showColorPickerPopup(@Nullable Color currentColor, @NotNull ColorListener listener) {
LightCalloutPopup dialog = new LightCalloutPopup();
JPanel panel = new ColorPickerBuilder()
LightCalloutPopup popup = new ColorPickerBuilder()
.setOriginalColor(currentColor)
.addSaturationBrightnessComponent()
.addColorAdjustPanel(new MaterialGraphicalColorPipetteProvider())
.addColorValuePanel().withFocus()
//.addSeparator()
//.addCustomComponent(MaterialColorPaletteProvider.INSTANCE)
.addColorListener(listener)
.addColorListener(listener, false)
.focusWhenDisplay(true)
.setFocusCycleRoot(true)
.build();
dialog.show(panel, null, MouseInfo.getPointerInfo().getLocation());
popup.show(MouseInfo.getPointerInfo().getLocation());
}
private JComponent buildTopPanel(boolean enablePipette) throws ParseException {
@@ -48,7 +48,7 @@ class ColorPickerBuilder {
private var focusCycleRoot = false
private var focusedComponentIndex = -1
private val actionMap = mutableMapOf<KeyStroke, Action>()
private val colorListeners = mutableListOf<ColorListener>()
private val colorListeners = mutableListOf<ColorListenerInfo>()
fun setOriginalColor(originalColor: Color?) = apply { this.originalColor = originalColor }
@@ -112,9 +112,13 @@ class ColorPickerBuilder {
fun addKeyAction(keyStroke: KeyStroke, action: Action) = apply { actionMap[keyStroke] = action }
fun addColorListener(colorListener: ColorListener) = apply { colorListeners.add(colorListener) }
fun addColorListener(colorListener: ColorListener) = addColorListener(colorListener, true)
fun build(): JPanel {
fun addColorListener(colorListener: ColorListener, invokeOnEveryColorChange: Boolean) = apply {
colorListeners.add(ColorListenerInfo(colorListener, invokeOnEveryColorChange))
}
fun build(): LightCalloutPopup {
if (componentsToBuild.isEmpty()) {
throw IllegalStateException("The Color Picker should have at least one picking component.")
}
@@ -158,12 +162,16 @@ class ColorPickerBuilder {
panel.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).put(keyStroke, key)
}
colorListeners.forEach { model.addListener(it) }
colorListeners.forEach { model.addListener(it.colorListener, it.invokeOnEveryColorChange) }
return panel
return LightCalloutPopup(panel,
closedCallback = { model.onClose() },
cancelCallBack = { model.onCancel() })
}
}
private class MyFocusTraversalPolicy(val defaultComponent: Component?) : LayoutFocusTraversalPolicy() {
override fun getDefaultComponent(aContainer: Container?): Component? = defaultComponent
}
private data class ColorListenerInfo(val colorListener: ColorListener, val invokeOnEveryColorChange: Boolean)
@@ -15,6 +15,7 @@
*/
package com.intellij.ui.colorpicker
import com.intellij.openapi.application.ApplicationManager
import com.intellij.ui.picker.ColorListener
import java.awt.Color
@@ -23,6 +24,7 @@ val DEFAULT_PICKER_COLOR = Color(0xFF, 0xFF, 0xFF, 0xFF)
class ColorPickerModel(originalColor: Color = DEFAULT_PICKER_COLOR) {
private val listeners = mutableSetOf<ColorListener>()
private val instantListeners = mutableSetOf<ColorListener>()
var color: Color = originalColor
private set
@@ -31,6 +33,22 @@ class ColorPickerModel(originalColor: Color = DEFAULT_PICKER_COLOR) {
color = newColor
Color.RGBtoHSB(color.red, color.green, color.blue, hsb)
instantListeners.forEach { it.colorChanged(color, source) }
}
fun onClose() {
ApplicationManager.getApplication().invokeLater {
listeners.forEach { it.colorChanged(color, this) }
}
}
fun onCancel() {
//todo[kb] at the moment there is no any good way to close the color picker popup. Cancel outside triggers onCancel
onClose()
}
fun applyColorToSource(newColor: Color, source: Any? = null) {
setColor(newColor, source)
listeners.forEach { it.colorChanged(color, source) }
}
@@ -52,7 +70,17 @@ class ColorPickerModel(originalColor: Color = DEFAULT_PICKER_COLOR) {
val brightness get() = hsb[2]
fun addListener(listener: ColorListener) = listeners.add(listener)
fun addListener(listener: ColorListener) = addListener(listener, true)
fun removeListener(listener: ColorListener) = listeners.remove(listener)
fun addListener(listener: ColorListener, invokeOnEveryColorChange: Boolean) {
listeners.add(listener)
if (invokeOnEveryColorChange) {
instantListeners.add(listener)
}
}
fun removeListener(listener: ColorListener) {
listeners.remove(listener)
instantListeners.remove(listener)
}
}
@@ -33,7 +33,7 @@ import javax.swing.JComponent
*
* The popup is automatically dismissed when the user clicks outside.
*/
class LightCalloutPopup(
class LightCalloutPopup(val content: JComponent,
val closedCallback: (() -> Unit)? = null,
val cancelCallBack: (() -> Unit)? = null,
val beforeShownCallback: (() -> Unit)? = null
@@ -50,8 +50,7 @@ class LightCalloutPopup(
*/
@JvmOverloads
fun show(
content: JComponent,
parentComponent: JComponent?,
parentComponent: JComponent? = null,
location: Point,
position: Balloon.Position = Balloon.Position.below
) {