Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Matplotlib 3.8 update event issue fix #3

Merged
Empty file added kivy_garden/__init__.py
Empty file.
160 changes: 103 additions & 57 deletions kivy_garden/matplotlib/backend_kivy.py
Original file line number Diff line number Diff line change
Expand Up @@ -232,7 +232,6 @@ def close(event):
import six
import os
import matplotlib
import matplotlib.transforms as transforms
from matplotlib._pylab_helpers import Gcf
from matplotlib.backend_bases import (
RendererBase,
Expand All @@ -243,12 +242,15 @@ def close(event):
TimerBase,
)
from matplotlib.figure import Figure
from matplotlib.transforms import Bbox, Affine2D
from matplotlib.backend_bases import ShowBase, Event
from matplotlib.transforms import Affine2D
from matplotlib.backend_bases import (ShowBase,
Event,
ResizeEvent,
MouseEvent,
KeyEvent)
from matplotlib.backends.backend_agg import FigureCanvasAgg
from matplotlib.mathtext import MathTextParser
from matplotlib import rcParams
from hashlib import md5
from matplotlib import _path

try:
Expand All @@ -260,7 +262,6 @@ def close(event):
from kivy.graphics.texture import Texture
from kivy.graphics import Rectangle
from kivy.uix.widget import Widget
from kivy.uix.label import Label
from kivy.uix.floatlayout import FloatLayout
from kivy.uix.behaviors import FocusBehavior
from kivy.uix.actionbar import (
Expand All @@ -286,12 +287,8 @@ def close(event):
from kivy.resources import resource_find
from kivy.uix.stencilview import StencilView
from kivy.core.window import Window
from kivy.uix.button import Button
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.relativelayout import RelativeLayout
from kivy.uix.popup import Popup
from kivy.properties import ObjectProperty
from kivy.uix.textinput import TextInput
from kivy.lang import Builder
from kivy.clock import Clock
from distutils.version import LooseVersion
Expand All @@ -300,12 +297,9 @@ def close(event):
_mpl_ge_2_0 = LooseVersion(matplotlib.__version__) >= LooseVersion("2.0.0")

import numpy as np
import io
import textwrap
import uuid
import numbers
from functools import partial
from math import cos, sin, pi

kivy.require("1.9.1")

Expand Down Expand Up @@ -340,7 +334,7 @@ def build(self):


def draw_if_interactive():
"""Handle whether or not the backend is in interactive mode or not."""
"""Handle whether the backend is in interactive mode or not."""
if matplotlib.is_interactive():
figManager = Gcf.get_active()
if figManager:
Expand Down Expand Up @@ -989,13 +983,14 @@ def __init__(self, canvas, **kwargs):
)

def _init_toolbar(self):
"""A Toolbar is created with an ActionBar widget in which buttons are
added with a specific behavior given by a callback. The buttons
properties are given by matplotlib.
"""A Toolbar is created with an ActionBar widget in which buttons
are added with a specific behavior given by a callback.
The buttons properties are given by matplotlib.
"""
basedir = os.path.join(rcParams["datapath"], "images")
actionview = ActionView()
actionprevious = ActionPrevious(title="Navigation", with_previous=False)
actionprevious = ActionPrevious(title="Navigation",
with_previous=False)
actionoverflow = ActionOverflow()
actionview.add_widget(actionprevious)
actionview.add_widget(actionoverflow)
Expand Down Expand Up @@ -1217,31 +1212,21 @@ def on_touch_down(self, touch):
newcoord = self.to_widget(touch.x, touch.y, relative=True)
x = newcoord[0]
y = newcoord[1]

if super(FigureCanvasKivy, self).on_touch_down(touch):
return True
if self.collide_point(*touch.pos):
self.motion_notify_event(x, y, guiEvent=None)

self.motion_notify_event(x, y)
touch.grab(self)
if "button" in touch.profile and touch.button in (
"scrollup",
"scrolldown",
):
self.scroll_event(x, y, 5, guiEvent=None)
if 'button' in touch.profile and touch.button in ("scrollup",
"scrolldown"):
self.scroll_event(x, y, 5)
else:
self.button_press_event(
x,
y,
self.get_mouse_button(touch),
dblclick=False,
guiEvent=None,
)
self.button_press_event(x, y, self.get_mouse_button(touch))
if self.entered_figure:
self.enter_notify_event(guiEvent=None, xy=None)
self.enter_notify_event()
else:
if not self.entered_figure:
self.leave_notify_event(guiEvent=None)
self.leave_notify_event()
return False

def on_touch_move(self, touch):
Expand All @@ -1253,12 +1238,12 @@ def on_touch_move(self, touch):
y = newcoord[1]
inside = self.collide_point(touch.x, touch.y)
if inside:
self.motion_notify_event(x, y, guiEvent=None)
self.motion_notify_event(x, y)
if not inside and not self.entered_figure:
self.leave_notify_event(guiEvent=None)
self.leave_notify_event()
self.entered_figure = True
elif inside and self.entered_figure:
self.enter_notify_event(guiEvent=None, xy=(x, y))
self.enter_notify_event()
self.entered_figure = False
return False

Expand All @@ -1284,31 +1269,27 @@ def on_touch_up(self, touch):
x = newcoord[0]
y = newcoord[1]
if touch.grab_current is self:
if "button" in touch.profile and touch.button in (
"scrollup",
"scrolldown",
):
self.scroll_event(x, y, 5, guiEvent=None)
if 'button' in touch.profile and touch.button in ("scrollup",
"scrolldown"):
self.scroll_event(x, y, 5)
else:
self.button_release_event(
x, y, self.get_mouse_button(touch), guiEvent=None
)
self.button_release_event(x, y, self.get_mouse_button(touch))
touch.ungrab(self)
else:
return super(FigureCanvasKivy, self).on_touch_up(touch)
return False

def keyboard_on_key_down(self, window, keycode, text, modifiers):
"""Kivy event to trigger matplotlib `key_press_event`."""
self.key_press_event(keycode[1], guiEvent=None)
self.key_press_event(key=keycode[1])
return super(FigureCanvasKivy, self).keyboard_on_key_down(
window, keycode, text, modifiers
)
window, keycode, text, modifiers)

def keyboard_on_key_up(self, window, keycode):
"""Kivy event to trigger matplotlib `key_release_event`."""
self.key_release_event(keycode[1], guiEvent=None)
return super(FigureCanvasKivy, self).keyboard_on_key_up(window, keycode)
self.key_release_event(key=keycode[1])
return super(FigureCanvasKivy, self).keyboard_on_key_up(
window, keycode)

def _on_mouse_pos(self, *args):
"""Kivy Event to trigger the following matplotlib events:
Expand All @@ -1321,22 +1302,85 @@ def _on_mouse_pos(self, *args):
y = newcoord[1]
inside = self.collide_point(*pos)
if inside:
self.motion_notify_event(x, y, guiEvent=None)
self.motion_notify_event(x, y)
if not inside and not self.entered_figure:
self.leave_notify_event(guiEvent=None)
self.leave_notify_event()
self.entered_figure = True
elif inside and self.entered_figure:
self.enter_notify_event(guiEvent=None, xy=(pos[0], pos[1]))
self.enter_notify_event()
self.entered_figure = False

def enter_notify_event(self, guiEvent=None, xy=None):
event = Event("figure_enter_event", self, guiEvent)
def enter_notify_event(self, gui_event=None):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These changes are making the API backward-incompatible, but since we're moving to a new package, that's also an opportunity to clean up bad things.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well spotted. Didn't think of that, thanks for the hint.

event = Event("figure_enter_event", self, gui_event)
self.callbacks.process("figure_enter_event", event)

def leave_notify_event(self, guiEvent=None):
event = Event("figure_leave_event", self, guiEvent)
def leave_notify_event(self, gui_event=None):
event = Event("figure_leave_event", self, gui_event)
self.callbacks.process("figure_leave_event", event)

def resize_event(self):
event = ResizeEvent('resize_event', self)
self.callbacks.process('resize_event', event)

def motion_notify_event(self, x, y, gui_event=None):
event = MouseEvent(
'motion_notify_event',
canvas=self,
x=x,
y=y,
guiEvent=gui_event)
self.callbacks.process('motion_notify_event', event)

def button_press_event(self, x, y, button,
dblclick=False, gui_event=None):
event = MouseEvent(
'button_press_event',
canvas=self,
x=x,
y=y,
button=button,
dblclick=dblclick,
guiEvent=gui_event)
self.callbacks.process('button_press_event', event)

def button_release_event(self, x, y, button,
dblclick=False, gui_event=None):
event = MouseEvent(
'button_release_event',
canvas=self,
x=x,
y=y,
button=button,
dblclick=dblclick,
guiEvent=gui_event)
self.callbacks.process('button_release_event', event)

def scroll_event(self, x, y, step, gui_event=None):
event = MouseEvent(
'scroll_event',
canvas=self,
x=x,
y=y,
step=step,
guiEvent=gui_event)
self.callbacks.process('scroll_event', event)

def key_press_event(self, key, gui_event=None):
event = KeyEvent(
'key_press_event',
canvas=self,
key=key,
guiEvent=gui_event)
self.callbacks.process('key_press_event', event)

def key_release_event(self, key, gui_event=None):
event = KeyEvent(
'key_release_event',
canvas=self,
key=key,
guiEvent=gui_event)
self.callbacks.process('key_release_event', event)

def _on_pos_changed(self, *args):
self.draw()

Expand All @@ -1346,6 +1390,8 @@ def _on_size_changed(self, *args):
size.
"""
w, h = self.size
if w <= 0 or h <= 0:
return
dpival = self.figure.dpi
winch = float(w) / dpival
hinch = float(h) / dpival
Expand Down
12 changes: 0 additions & 12 deletions kivy_garden/matplotlib/backend_kivyagg.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,18 +73,7 @@ def my_callback(event):

__all__ = "FigureCanvasKivyAgg"

import six

import matplotlib
from matplotlib._pylab_helpers import Gcf
from matplotlib.backend_bases import (
RendererBase,
GraphicsContextBase,
FigureManagerBase,
FigureCanvasBase,
)
from matplotlib.figure import Figure
from matplotlib.transforms import Bbox
from matplotlib.backends.backend_agg import FigureCanvasAgg
from matplotlib.backend_bases import register_backend, ShowBase

Expand All @@ -96,7 +85,6 @@ def my_callback(event):
from kivy.app import App
from kivy.graphics.texture import Texture
from kivy.graphics import Rectangle, Color
from kivy.uix.widget import Widget
from kivy.properties import ObjectProperty
from kivy.base import EventLoop
from kivy.uix.floatlayout import FloatLayout
Expand Down
Empty file.
1 change: 1 addition & 0 deletions kivy_garden/matplotlib/tests/test_backend_kivy.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ def test_matplotlib_use_backend():
import matplotlib
import matplotlib.pyplot as plt

plt.close('all')
matplotlib.use("module://kivy_garden.matplotlib.backend_kivy")

plt.plot([1, 2, 3, 4])
Expand Down
1 change: 1 addition & 0 deletions kivy_garden/matplotlib/tests/test_backend_kivyagg.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ def test_matplotlib_use_backend():
import matplotlib
import matplotlib.pyplot as plt

plt.close('all')
matplotlib.use("module://kivy_garden.matplotlib.backend_kivyagg")

plt.plot([1, 2, 3, 4])
Expand Down
Loading
Loading