bumblebee-status/bumblebee_status/util/popup.py

118 lines
3.1 KiB
Python
Raw Permalink Normal View History

2020-04-11 13:35:04 +02:00
"""Pop-up menus."""
import logging
2020-05-15 10:07:07 +02:00
import tkinter as tk
import tkinter.font as tkFont
2020-04-11 13:35:04 +02:00
import functools
2020-04-11 13:35:04 +02:00
class menu(object):
2020-05-15 10:07:07 +02:00
"""Draws a hierarchical popup menu
:param config: Global config singleton, passed on from modules
2020-05-15 10:07:07 +02:00
:param parent: If given, this menu is a leave of the "parent" menu
:param leave: If set to True, close this menu when mouse leaves the area (defaults to True)
"""
def __init__(self, config, parent=None, leave=True):
self.running = True
self.parent = parent
self._root = parent.root() if parent else tk.Tk()
self._root.withdraw()
self._menu = tk.Menu(self._root, tearoff=0)
self._menu.bind("<FocusOut>", self.__on_focus_out)
self._font_size = tkFont.Font(size=config.popup_font_size())
2020-04-11 13:35:04 +02:00
if leave:
2020-05-15 10:07:07 +02:00
self._menu.bind("<Leave>", self.__on_focus_out)
elif not parent:
self.add_menuitem("close", self.__on_focus_out)
self.add_separator()
2020-05-15 10:07:07 +02:00
self._menu.bind("<ButtonRelease-1>", self.release)
2020-05-15 10:07:07 +02:00
"""Returns the root node of this menu
:return: root node
"""
2020-04-11 13:35:04 +02:00
def root(self):
return self._root
2020-05-15 10:07:07 +02:00
"""Returns the menu
:return: menu
"""
2020-04-11 13:35:04 +02:00
def menu(self):
return self._menu
2020-05-15 10:07:07 +02:00
def __on_focus_out(self, event=None):
self.running = False
2020-04-11 13:35:04 +02:00
self._root.destroy()
2020-05-15 10:07:07 +02:00
def __on_click(self, callback):
2020-04-11 13:35:04 +02:00
self._root.destroy()
callback()
def release(self, event=None):
self.running=False
if self.parent:
self.parent.release(event)
2020-05-15 10:07:07 +02:00
"""Adds a cascading submenu to the current menu
:param menuitem: label to display for the submenu
:param submenu: submenu to show
"""
2020-04-11 13:35:04 +02:00
def add_cascade(self, menuitem, submenu):
self._menu.add_cascade(label=menuitem, menu=submenu.menu(), font=self._font_size)
2020-04-11 13:35:04 +02:00
2020-05-15 10:07:07 +02:00
"""Adds an item to the current menu
:param menuitem: label to display for the entry
:param callback: method to invoke on click
"""
2020-04-11 13:35:04 +02:00
def add_menuitem(self, menuitem, callback):
self._menu.add_command(
label=menuitem, command=functools.partial(self.__on_click, callback), font=self._font_size,
)
2020-04-11 13:35:04 +02:00
2020-05-23 05:53:21 +02:00
"""Adds a separator to the menu in the current location"""
def add_separator(self):
self._menu.add_separator()
2020-05-15 10:07:07 +02:00
"""Shows this menu
:param event: i3wm event that triggered the menu (dict that contains "x" and "y" fields)
:param offset_x: x-axis offset from mouse position for the menu (defaults to 0)
:param offset_y: y-axis offset from mouse position for the menu (defaults to 0)
"""
2020-04-11 13:35:04 +02:00
def show(self, event, offset_x=0, offset_y=0):
try:
self._menu.tk_popup(event["x"] + offset_x, event["y"] + offset_y)
2020-04-11 13:35:04 +02:00
finally:
self._menu.grab_release()
while self.running == True:
try:
self._root.update_idletasks()
self._root.update()
except:
self.running = False
try:
self._root.destroy()
except:
pass
2020-04-11 13:35:04 +02:00
2020-04-11 13:35:04 +02:00
# vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4