Now we define a MenuItem
class which will be used to create each item in the menu. We pass the figure, label string, properties, hover properties, and on select callback function as parameters to this class. The MenuItem
class inherits from the artist.Artist
class.
class MenuItem(artist.Artist):
padx = 5
pady = 5
def __init__(self, fig, labelstr, props=None, hoverprops=None,
on_select=None):
super().__init__()
self.set_figure(fig)
self.labelstr = labelstr
self.props = props if props is not None else ItemProperties()
self.hoverprops = (
hoverprops if hoverprops is not None else ItemProperties())
if self.props.fontsize != self.hoverprops.fontsize:
raise NotImplementedError(
'support for different font sizes not implemented')
self.on_select = on_select
## Setting the transform to IdentityTransform() lets us specify
## coordinates directly in pixels.
self.label = fig.text(0, 0, labelstr, transform=IdentityTransform(),
size=props.fontsize)
self.text_bbox = self.label.get_window_extent(
fig.canvas.get_renderer())
self.rect = patches.Rectangle((0, 0), 1, 1) ## Will be updated later.
self.set_hover_props(False)
fig.canvas.mpl_connect('button_release_event', self.check_select)
def check_select(self, event):
over, _ = self.rect.contains(event)
if not over:
return
if self.on_select is not None:
self.on_select(self)
def set_extent(self, x, y, w, h, depth):
self.rect.set(x=x, y=y, width=w, height=h)
self.label.set(position=(x + self.padx, y + depth + self.pady/2))
self.hover = False
def draw(self, renderer):
self.rect.draw(renderer)
self.label.draw(renderer)
def set_hover_props(self, b):
props = self.hoverprops if b else self.props
self.label.set(color=props.labelcolor)
self.rect.set(facecolor=props.bgcolor, alpha=props.alpha)
def set_hover(self, event):
"""
Update the hover status of event and return whether it was changed.
"""
b, _ = self.rect.contains(event)
changed = (b != self.hover)
if changed:
self.set_hover_props(b)
self.hover = b
return changed