mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-03-22 15:19:59 +07:00
[PyCharm] PY-66520 Jupyter (refactor): Nested scrolling rewritten, layers and ancestor listeners removed, timeout tweaked.
GitOrigin-RevId: 2596450201eaaa08855d3041f12e5dc12ad553b1
This commit is contained in:
committed by
intellij-monorepo-bot
parent
dfdce84cf9
commit
3106110b50
@@ -1,6 +1,5 @@
|
||||
package com.intellij.notebooks.visualization.ui
|
||||
|
||||
import com.intellij.execution.console.LanguageConsoleImpl
|
||||
import com.intellij.notebooks.ui.editor.actions.command.mode.NotebookEditorMode
|
||||
import com.intellij.notebooks.ui.editor.actions.command.mode.setMode
|
||||
import com.intellij.notebooks.visualization.*
|
||||
@@ -14,38 +13,33 @@ import com.intellij.openapi.editor.Caret
|
||||
import com.intellij.openapi.editor.Editor
|
||||
import com.intellij.openapi.editor.event.*
|
||||
import com.intellij.openapi.editor.ex.util.EditorScrollingPositionKeeper
|
||||
import com.intellij.openapi.editor.impl.EditorComponentImpl
|
||||
import com.intellij.openapi.editor.impl.EditorImpl
|
||||
import com.intellij.openapi.fileEditor.impl.text.TextEditorComponent
|
||||
import com.intellij.openapi.util.Disposer
|
||||
import com.intellij.openapi.util.use
|
||||
import com.intellij.ui.AncestorListenerAdapter
|
||||
import java.awt.*
|
||||
import java.awt.BorderLayout
|
||||
import java.awt.Component
|
||||
import java.awt.GraphicsEnvironment
|
||||
import java.awt.Point
|
||||
import java.awt.event.InputEvent
|
||||
import java.awt.event.MouseEvent
|
||||
import java.awt.event.MouseWheelEvent
|
||||
import java.util.concurrent.atomic.AtomicBoolean
|
||||
import javax.swing.JComponent
|
||||
import javax.swing.JLayer
|
||||
import javax.swing.JPanel
|
||||
import javax.swing.SwingUtilities
|
||||
import javax.swing.event.AncestorEvent
|
||||
import javax.swing.plaf.LayerUI
|
||||
import kotlin.math.max
|
||||
import kotlin.math.min
|
||||
|
||||
class DecoratedEditor private constructor(private val editorImpl: EditorImpl, private val manager: NotebookCellInlayManager) : NotebookEditor {
|
||||
class DecoratedEditor private constructor(
|
||||
private val editorImpl: EditorImpl,
|
||||
private val manager: NotebookCellInlayManager,
|
||||
) : NotebookEditor {
|
||||
|
||||
/** Used to hold current cell under mouse, to update the folding state and "run" button state. */
|
||||
private var mouseOverCell: EditorCellView? = null
|
||||
|
||||
private val selectionModel = EditorCellSelectionModel(manager)
|
||||
|
||||
private var selectionUpdateScheduled: AtomicBoolean = AtomicBoolean(false)
|
||||
|
||||
/**
|
||||
* Correct parent for the editor component - our special scroll-supporting layer.
|
||||
* We cannot wrap editorComponent at creation, so we are changing its parent du
|
||||
*/
|
||||
private var editorComponentParent: JLayer<JComponent>? = null
|
||||
private var selectionUpdateScheduled = AtomicBoolean(false)
|
||||
|
||||
init {
|
||||
if (!GraphicsEnvironment.isHeadless()) {
|
||||
@@ -79,17 +73,9 @@ class DecoratedEditor private constructor(private val editorImpl: EditorImpl, pr
|
||||
}, editorImpl.disposable)
|
||||
|
||||
editorImpl.caretModel.addCaretListener(object : CaretListener {
|
||||
override fun caretAdded(event: CaretEvent) {
|
||||
scheduleSelectionUpdate()
|
||||
}
|
||||
|
||||
override fun caretPositionChanged(event: CaretEvent) {
|
||||
scheduleSelectionUpdate()
|
||||
}
|
||||
|
||||
override fun caretRemoved(event: CaretEvent) {
|
||||
scheduleSelectionUpdate()
|
||||
}
|
||||
override fun caretAdded(event: CaretEvent) = scheduleSelectionUpdate()
|
||||
override fun caretPositionChanged(event: CaretEvent) = scheduleSelectionUpdate()
|
||||
override fun caretRemoved(event: CaretEvent) = scheduleSelectionUpdate()
|
||||
})
|
||||
|
||||
updateSelectionByCarets()
|
||||
@@ -98,46 +84,36 @@ class DecoratedEditor private constructor(private val editorImpl: EditorImpl, pr
|
||||
}
|
||||
|
||||
private fun wrapEditorComponent(editor: EditorImpl) {
|
||||
val parent = editor.component.parent
|
||||
if (parent == null || parent == editorComponentParent) {
|
||||
val nestedScrollingSupport = NestedScrollingSupportImpl()
|
||||
|
||||
editorImpl.component.addAncestorListener(object : AncestorListenerAdapter() {
|
||||
override fun ancestorAdded(event: AncestorEvent?) {
|
||||
wrapEditorComponent(editorImpl)
|
||||
NotebookAWTMouseDispatcher(editor.scrollPane).apply {
|
||||
|
||||
eventDispatcher.addListener { event ->
|
||||
if (event is MouseEvent) {
|
||||
getEditorPoint(event)?.let { (_, point) ->
|
||||
updateMouseOverCell(point)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
return
|
||||
eventDispatcher.addListener { event ->
|
||||
if (event is MouseWheelEvent) {
|
||||
nestedScrollingSupport.processMouseWheelEvent(event)
|
||||
}
|
||||
else if (event is MouseEvent) {
|
||||
if (event.id == MouseEvent.MOUSE_CLICKED || event.id == MouseEvent.MOUSE_RELEASED || event.id == MouseEvent.MOUSE_PRESSED) {
|
||||
nestedScrollingSupport.processMouseEvent(event, editor.scrollPane)
|
||||
}
|
||||
else if (event.id == MouseEvent.MOUSE_MOVED) {
|
||||
nestedScrollingSupport.processMouseMotionEvent(event)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Disposer.register(editor.disposable, this)
|
||||
}
|
||||
|
||||
if(parent is LanguageConsoleImpl.ConsoleEditorsPanel) return
|
||||
|
||||
val view = editorImpl.scrollPane.viewport.view
|
||||
if (view is EditorComponentImpl) {
|
||||
editorImpl.scrollPane.viewport.view = EditorComponentWrapper(editorImpl, view)
|
||||
}
|
||||
|
||||
editorComponentParent = createCellUnderMouseSupportLayer(editorImpl.component)
|
||||
val secondLayer = NestedScrollingSupport.addNestedScrollingSupport(editorComponentParent!!)
|
||||
|
||||
parent.remove(editor.component)
|
||||
val newComponent = secondLayer
|
||||
|
||||
if (parent is TextEditorComponent) {
|
||||
parent.__add(newComponent, GridBagConstraints().also {
|
||||
it.gridx = 0
|
||||
it.gridy = 0
|
||||
it.weightx = 1.0
|
||||
it.weighty = 1.0
|
||||
it.fill = GridBagConstraints.BOTH
|
||||
})
|
||||
}
|
||||
else if (parent is LanguageConsoleImpl.ConsoleEditorsPanel) {
|
||||
parent.add(newComponent)
|
||||
}
|
||||
else {
|
||||
parent.add(newComponent, BorderLayout.CENTER)
|
||||
}
|
||||
editor.scrollPane.viewport.view = EditorComponentWrapper(editor, editor.contentComponent)
|
||||
}
|
||||
|
||||
/** The main thing while we need it - to perform updating of underlying components within keepScrollingPositionWhile. */
|
||||
@@ -193,27 +169,6 @@ class DecoratedEditor private constructor(private val editorImpl: EditorImpl, pr
|
||||
}
|
||||
}
|
||||
|
||||
private fun createCellUnderMouseSupportLayer(view: JComponent) = JLayer(view, object : LayerUI<JComponent>() {
|
||||
|
||||
override fun installUI(c: JComponent) {
|
||||
super.installUI(c)
|
||||
(c as JLayer<*>).layerEventMask = AWTEvent.MOUSE_MOTION_EVENT_MASK
|
||||
}
|
||||
|
||||
override fun uninstallUI(c: JComponent) {
|
||||
super.uninstallUI(c)
|
||||
(c as JLayer<*>).layerEventMask = 0
|
||||
}
|
||||
|
||||
override fun eventDispatched(e: AWTEvent, l: JLayer<out JComponent?>?) {
|
||||
if (e is MouseEvent) {
|
||||
getEditorPoint(e)?.let { (_, point) ->
|
||||
updateMouseOverCell(point)
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
private fun getEditorPoint(e: MouseEvent): Pair<Component, Point>? {
|
||||
val component = if (SwingUtilities.isDescendingFrom(e.component, editorImpl.contentComponent)) {
|
||||
editorImpl.contentComponent
|
||||
|
||||
@@ -1,203 +1,194 @@
|
||||
package com.intellij.notebooks.visualization.ui
|
||||
|
||||
import com.intellij.openapi.util.registry.Registry
|
||||
import com.intellij.ui.ComponentUtil
|
||||
import java.awt.AWTEvent
|
||||
import java.awt.Component
|
||||
import java.awt.event.MouseEvent
|
||||
import java.awt.event.MouseWheelEvent
|
||||
import javax.swing.JComponent
|
||||
import javax.swing.JLayer
|
||||
import javax.swing.JScrollPane
|
||||
import javax.swing.SwingUtilities
|
||||
import javax.swing.plaf.LayerUI
|
||||
import kotlin.reflect.KClass
|
||||
import kotlin.time.Duration
|
||||
import kotlin.time.Duration.Companion.milliseconds
|
||||
import kotlin.time.DurationUnit
|
||||
|
||||
/**
|
||||
* Decorates component to handle nested scrolling areas gracefully.
|
||||
* As it described in [Mozilla documentation](https://wiki.mozilla.org/Gecko:Mouse_Wheel_Scrolling#Mouse_wheel_transaction)
|
||||
* Processes Mouse (wheel, motion, click) to handle nested scrolling areas gracefully. Used together with [NotebookAWTMouseDispatcher].
|
||||
* Nested scrolling idea described in [Mozilla documentation](https://wiki.mozilla.org/Gecko:Mouse_Wheel_Scrolling#Mouse_wheel_transaction)
|
||||
*/
|
||||
object NestedScrollingSupport {
|
||||
class NestedScrollingSupportImpl {
|
||||
|
||||
private val asyncComponents = mutableSetOf<KClass<*>>()
|
||||
private var _currentMouseWheelOwner: Component? = null
|
||||
private var currentMouseWheelOwner: Component?
|
||||
get() {
|
||||
return resetOwnerIfTimeoutExceeded()
|
||||
}
|
||||
set(value) {
|
||||
_currentMouseWheelOwner = value
|
||||
}
|
||||
|
||||
fun registerAsyncComponent(type: KClass<*>) {
|
||||
asyncComponents.add(type)
|
||||
private var timestamp = 0L
|
||||
|
||||
private var dispatchingEvent: MouseEvent? = null
|
||||
|
||||
private fun isNewEventCreated(e: MouseWheelEvent) = dispatchingEvent != e
|
||||
|
||||
private fun isDispatchingInProgress() = dispatchingEvent != null
|
||||
|
||||
fun processMouseWheelEvent(e: MouseWheelEvent) {
|
||||
val component = e.component
|
||||
if (isDispatchingInProgress()) {
|
||||
if (!isNewEventCreated(e)) {
|
||||
return
|
||||
}
|
||||
else if (_currentMouseWheelOwner != null) {
|
||||
// Prevents [JBScrollPane] from propagating wheel events to the parent component if there is an active scroll
|
||||
e.consume()
|
||||
return
|
||||
}
|
||||
}
|
||||
resetOwnerIfTimeoutExceeded()
|
||||
val owner = resetOwnerIfEventIsOutside(e)
|
||||
if (owner != null) {
|
||||
if (component != owner) {
|
||||
redispatchEvent(SwingUtilities.convertMouseEvent(component, e, owner))
|
||||
e.consume()
|
||||
}
|
||||
else {
|
||||
dispatchEvent(e)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun addNestedScrollingSupport(view: JComponent): JLayer<JComponent> {
|
||||
return JLayer(view, object : LayerUI<JComponent>() {
|
||||
fun processMouseEvent(e: MouseEvent, scrollPane: JScrollPane) {
|
||||
if (e.id == MouseEvent.MOUSE_CLICKED || e.id == MouseEvent.MOUSE_RELEASED || e.id == MouseEvent.MOUSE_PRESSED) {
|
||||
updateOwner(scrollPane)
|
||||
}
|
||||
}
|
||||
|
||||
private var _currentMouseWheelOwner: Component? = null
|
||||
private var currentMouseWheelOwner: Component?
|
||||
get() {
|
||||
return resetOwnerIfTimeoutExceeded()
|
||||
}
|
||||
set(value) {
|
||||
_currentMouseWheelOwner = value
|
||||
}
|
||||
fun processMouseMotionEvent(e: MouseEvent) {
|
||||
val owner = currentMouseWheelOwner
|
||||
if (owner != null && isTimeoutExceeded(100.milliseconds) && !isEventInsideOwner(owner, e)) {
|
||||
resetOwner()
|
||||
}
|
||||
}
|
||||
|
||||
private var timestamp = 0L
|
||||
private fun dispatchEvent(event: MouseEvent) {
|
||||
val owner = event.component
|
||||
if (isAsync(owner)) return
|
||||
|
||||
private var dispatchingEvent: MouseEvent? = null
|
||||
|
||||
override fun installUI(c: JComponent) {
|
||||
super.installUI(c)
|
||||
(c as JLayer<*>).layerEventMask = AWTEvent.MOUSE_WHEEL_EVENT_MASK or AWTEvent.MOUSE_EVENT_MASK or AWTEvent.MOUSE_MOTION_EVENT_MASK
|
||||
if (owner is JLayer<*>) {
|
||||
val aa = owner.parent
|
||||
if (aa is JLayer<*>) {
|
||||
dispatchEventSync(event, aa.parent)
|
||||
}
|
||||
|
||||
override fun uninstallUI(c: JComponent) {
|
||||
super.uninstallUI(c)
|
||||
(c as JLayer<*>).layerEventMask = 0
|
||||
else {
|
||||
dispatchEventSync(event, aa)
|
||||
}
|
||||
}
|
||||
else {
|
||||
dispatchEventSync(event, owner)
|
||||
}
|
||||
}
|
||||
|
||||
override fun processMouseWheelEvent(e: MouseWheelEvent, l: JLayer<out JComponent>) {
|
||||
val component = e.component
|
||||
if (isDispatchingInProgress()) {
|
||||
if (!isNewEventCreated(e)) {
|
||||
return
|
||||
}
|
||||
else if (_currentMouseWheelOwner != null) {
|
||||
// Prevents [JBScrollPane] from propagating wheel events to the parent component if there is an active scroll
|
||||
e.consume()
|
||||
return
|
||||
}
|
||||
}
|
||||
resetOwnerIfTimeoutExceeded()
|
||||
val owner = resetOwnerIfEventIsOutside(e)
|
||||
if (owner != null) {
|
||||
if (component != owner) {
|
||||
redispatchEvent(SwingUtilities.convertMouseEvent(component, e, owner))
|
||||
e.consume()
|
||||
}
|
||||
else {
|
||||
dispatchEvent(e)
|
||||
}
|
||||
}
|
||||
private fun dispatchEventSync(event: MouseEvent, owner: Component) {
|
||||
val oldDispatchingEvent = dispatchingEvent
|
||||
dispatchingEvent = event
|
||||
try {
|
||||
owner.dispatchEvent(event)
|
||||
if (event.isConsumed && _currentMouseWheelOwner == null) {
|
||||
updateOwner(owner)
|
||||
}
|
||||
|
||||
private fun isNewEventCreated(e: MouseWheelEvent) = dispatchingEvent != e
|
||||
|
||||
private fun isDispatchingInProgress() = dispatchingEvent != null
|
||||
|
||||
private fun isAsync(owner: Component): Boolean {
|
||||
return asyncComponents.contains(owner::class)
|
||||
else {
|
||||
updateOwner(_currentMouseWheelOwner)
|
||||
}
|
||||
}
|
||||
finally {
|
||||
dispatchingEvent = oldDispatchingEvent
|
||||
}
|
||||
}
|
||||
|
||||
private fun dispatchEvent(event: MouseEvent) {
|
||||
val owner = event.component
|
||||
if (!isAsync(owner)) {
|
||||
dispatchEventSync(event, owner)
|
||||
}
|
||||
}
|
||||
private fun redispatchEvent(event: MouseEvent) {
|
||||
val oldDispatchingEvent = dispatchingEvent
|
||||
dispatchingEvent = null
|
||||
try {
|
||||
val owner = event.component
|
||||
owner.dispatchEvent(event)
|
||||
}
|
||||
finally {
|
||||
dispatchingEvent = oldDispatchingEvent
|
||||
}
|
||||
}
|
||||
|
||||
private fun dispatchEventSync(event: MouseEvent, owner: Component): Boolean {
|
||||
val oldDispatchingEvent = dispatchingEvent
|
||||
dispatchingEvent = event
|
||||
try {
|
||||
owner.dispatchEvent(event)
|
||||
if (event.isConsumed && _currentMouseWheelOwner == null) {
|
||||
updateOwner(owner)
|
||||
}
|
||||
else {
|
||||
updateOwner(_currentMouseWheelOwner)
|
||||
}
|
||||
return event.isConsumed
|
||||
}
|
||||
finally {
|
||||
dispatchingEvent = oldDispatchingEvent
|
||||
}
|
||||
}
|
||||
private fun resetOwnerIfTimeoutExceeded(): Component? {
|
||||
val currentOwner = _currentMouseWheelOwner
|
||||
if (currentOwner == null) {
|
||||
return null
|
||||
}
|
||||
val scrollOwnerTimeout = Registry.intValue("jupyter.editor.scroll.mousewheel.timeout", 750).milliseconds
|
||||
return if (isTimeoutExceeded(scrollOwnerTimeout)) {
|
||||
resetOwner()
|
||||
null
|
||||
}
|
||||
else {
|
||||
currentOwner
|
||||
}
|
||||
}
|
||||
|
||||
private fun redispatchEvent(event: MouseEvent): Boolean {
|
||||
val oldDispatchingEvent = dispatchingEvent
|
||||
dispatchingEvent = null
|
||||
try {
|
||||
val owner = event.component
|
||||
owner.dispatchEvent(event)
|
||||
return event.isConsumed
|
||||
}
|
||||
finally {
|
||||
dispatchingEvent = oldDispatchingEvent
|
||||
}
|
||||
}
|
||||
private fun resetOwnerIfEventIsOutside(e: MouseWheelEvent): Component? {
|
||||
val currentOwner = _currentMouseWheelOwner
|
||||
return if (currentOwner != null && isEventInsideOwner(currentOwner, e)) {
|
||||
currentOwner
|
||||
}
|
||||
else {
|
||||
resetOwner()
|
||||
e.component
|
||||
}
|
||||
}
|
||||
|
||||
private fun resetOwnerIfTimeoutExceeded(): Component? {
|
||||
val currentOwner = _currentMouseWheelOwner
|
||||
if (currentOwner == null) {
|
||||
return null
|
||||
}
|
||||
val scrollOwnerTimeout = Registry.intValue("jupyter.editor.scroll.mousewheel.timeout", 1000).milliseconds
|
||||
return if (isTimeoutExceeded(scrollOwnerTimeout)) {
|
||||
resetOwner()
|
||||
null
|
||||
}
|
||||
else {
|
||||
currentOwner
|
||||
}
|
||||
}
|
||||
private fun isEventInsideOwner(owner: Component, e: MouseEvent): Boolean {
|
||||
val component = e.component
|
||||
return if (component == null) {
|
||||
false
|
||||
}
|
||||
else {
|
||||
val p = SwingUtilities.convertPoint(component, e.point, owner)
|
||||
return owner.contains(p)
|
||||
}
|
||||
}
|
||||
|
||||
private fun resetOwnerIfEventIsOutside(e: MouseWheelEvent): Component? {
|
||||
val currentOwner = _currentMouseWheelOwner
|
||||
return if (currentOwner != null && isEventInsideOwner(currentOwner, e)) {
|
||||
currentOwner
|
||||
}
|
||||
else {
|
||||
resetOwner()
|
||||
e.component
|
||||
}
|
||||
}
|
||||
private fun isTimeoutExceeded(timeout: Duration): Boolean {
|
||||
return timestamp + timeout.toInt(DurationUnit.NANOSECONDS) < System.nanoTime()
|
||||
}
|
||||
|
||||
private fun isEventInsideOwner(owner: Component, e: MouseEvent): Boolean {
|
||||
val component = e.component
|
||||
return if (component == null) {
|
||||
false
|
||||
}
|
||||
else {
|
||||
val p = SwingUtilities.convertPoint(component, e.point, owner)
|
||||
return owner.contains(p)
|
||||
}
|
||||
}
|
||||
private fun updateOwner(component: Component?) {
|
||||
if (component != null) {
|
||||
replaceOwner(component)
|
||||
}
|
||||
else {
|
||||
resetOwner()
|
||||
}
|
||||
}
|
||||
|
||||
private fun isTimeoutExceeded(timeout: Duration): Boolean {
|
||||
return timestamp + timeout.toInt(DurationUnit.NANOSECONDS) < System.nanoTime()
|
||||
}
|
||||
private fun replaceOwner(component: Component) {
|
||||
_currentMouseWheelOwner = component
|
||||
timestamp = System.nanoTime()
|
||||
}
|
||||
|
||||
private fun updateOwner(component: Component?) {
|
||||
if (component != null) {
|
||||
replaceOwner(component)
|
||||
}
|
||||
else {
|
||||
resetOwner()
|
||||
}
|
||||
}
|
||||
private fun resetOwner() {
|
||||
timestamp = 0
|
||||
_currentMouseWheelOwner = null
|
||||
}
|
||||
|
||||
private fun replaceOwner(component: Component) {
|
||||
currentMouseWheelOwner = component
|
||||
timestamp = System.nanoTime()
|
||||
}
|
||||
private fun isAsync(owner: Component): Boolean {
|
||||
return asyncComponents.contains(owner::class)
|
||||
}
|
||||
|
||||
private fun resetOwner() {
|
||||
timestamp = 0
|
||||
currentMouseWheelOwner = null
|
||||
}
|
||||
companion object {
|
||||
internal val asyncComponents = mutableSetOf<KClass<*>>()
|
||||
|
||||
override fun processMouseEvent(e: MouseEvent, l: JLayer<out JComponent>) {
|
||||
if (e.id == MouseEvent.MOUSE_CLICKED || e.id == MouseEvent.MOUSE_RELEASED || e.id == MouseEvent.MOUSE_PRESSED) {
|
||||
val scrollPane = ComponentUtil.getParentOfType(JScrollPane::class.java, l.findComponentAt(e.point))
|
||||
updateOwner(scrollPane)
|
||||
}
|
||||
}
|
||||
|
||||
override fun processMouseMotionEvent(e: MouseEvent, l: JLayer<out JComponent>) {
|
||||
val owner = currentMouseWheelOwner
|
||||
if (owner != null && isTimeoutExceeded(100.milliseconds) && !isEventInsideOwner(owner, e)) {
|
||||
resetOwner()
|
||||
}
|
||||
}
|
||||
})
|
||||
fun registerAsyncComponent(type: KClass<*>) {
|
||||
asyncComponents.add(type)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
package com.intellij.notebooks.visualization.ui
|
||||
|
||||
import com.intellij.openapi.Disposable
|
||||
import com.intellij.util.EventDispatcher
|
||||
import java.awt.AWTEvent
|
||||
import java.awt.Component
|
||||
import java.awt.Toolkit
|
||||
import java.awt.event.AWTEventListener
|
||||
import java.awt.event.ComponentEvent
|
||||
import java.awt.event.InputEvent
|
||||
|
||||
/**
|
||||
* Dispatches mouse events (click, move, wheel) which have [target] component or any of its children.
|
||||
*
|
||||
* @property target the root Component for which the events will be collected.
|
||||
*/
|
||||
class NotebookAWTMouseDispatcher(private val target: Component) : Disposable, AWTEventListener {
|
||||
|
||||
val eventDispatcher = EventDispatcher.create(AWTEventListener::class.java)
|
||||
|
||||
init {
|
||||
Toolkit.getDefaultToolkit().addAWTEventListener(this,
|
||||
AWTEvent.MOUSE_WHEEL_EVENT_MASK or
|
||||
AWTEvent.MOUSE_EVENT_MASK or
|
||||
AWTEvent.MOUSE_MOTION_EVENT_MASK)
|
||||
}
|
||||
|
||||
override fun dispose() {
|
||||
Toolkit.getDefaultToolkit().removeAWTEventListener(this)
|
||||
}
|
||||
|
||||
override fun eventDispatched(event: AWTEvent) {
|
||||
if (event !is ComponentEvent) return
|
||||
|
||||
var component: Component? = event.component
|
||||
while (component != null) {
|
||||
if (component == target) {
|
||||
if (event is InputEvent && !event.isConsumed) {
|
||||
eventDispatcher.getMulticaster().eventDispatched(event)
|
||||
}
|
||||
}
|
||||
component = component.getParent()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -334,7 +334,7 @@ public final class EditorEmbeddedComponentManager {
|
||||
}
|
||||
});
|
||||
|
||||
renderer.addMouseWheelListener(myEditor.getContentComponent()::dispatchEvent);
|
||||
// renderer.addMouseWheelListener(myEditor.getContentComponent()::dispatchEvent);
|
||||
|
||||
renderer.setInlay(inlay);
|
||||
myEditor.getContentComponent().add(renderer);
|
||||
|
||||
Reference in New Issue
Block a user