Skip to content

Commit

Permalink
Improve Balloon widget for #39
Browse files Browse the repository at this point in the history
  • Loading branch information
RedFantom committed Dec 7, 2019
1 parent 8eca0f7 commit 7381668
Showing 1 changed file with 37 additions and 8 deletions.
45 changes: 37 additions & 8 deletions ttkwidgets/frames/balloon.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,9 @@ class Balloon(ttk.Frame):
"""Simple help hover balloon."""

def __init__(self, master=None, headertext="Help", text="Some great help is displayed here.", width=200, timeout=1,
background="#fef9cd", **kwargs):
background="#fef9cd", offset=(2, 2), showheader=True, static=False, **kwargs):
"""
Create a Balloon.
Create a Balloon
:param master: widget to bind the Balloon to
:type master: widget
Expand All @@ -34,6 +34,15 @@ def __init__(self, master=None, headertext="Help", text="Some great help is disp
:type timeout: float
:param background: background color of the Balloon
:type background: str
:param offset: The offset from the mouse position the Ballon shows up
:type offset: Tuple[int, int]
:param showheader: Whether to display the header with image
:type showheader: bool
:param static: Whether to display the tooltip with static
position. When the position is set to static, the balloon
will always appear an offset from the bottom right corner of
the widget.
:type static: bool
:param kwargs: keyword arguments passed on to the :class:`ttk.Frame` initializer
"""
ttk.Frame.__init__(self, master, **kwargs)
Expand All @@ -51,11 +60,16 @@ def __init__(self, master=None, headertext="Help", text="Some great help is disp
self.__headertext = headertext
self.__text = text
self.__width = width
self.__offset = offset
self.__showheader = showheader
self.__static = static

self.master = master
self._id = None
self._timeout = timeout
self.master.bind("<Enter>", self._on_enter)
self.master.bind("<Leave>", self._on_leave)
self.master.bind("<ButtonPress>", self._on_leave)

def __getitem__(self, key):
return self.cget(key)
Expand All @@ -66,7 +80,8 @@ def __setitem__(self, key, value):
def _grid_widgets(self):
"""Place the widgets in the Toplevel."""
self._canvas.grid(sticky="nswe")
self.header_label.grid(row=1, column=1, sticky="nswe", pady=5, padx=5)
if self.__showheader is True:
self.header_label.grid(row=1, column=1, sticky="nswe", pady=5, padx=5)
self.text_label.grid(row=3, column=1, sticky="nswe", pady=6, padx=5)

def _on_enter(self, event):
Expand All @@ -84,9 +99,10 @@ def _on_leave(self, event):

def show(self):
"""
Create the Toplevel widget and its child widgets to show in the spot of the cursor.
Create the Toplevel and its children to show near the cursor
This is the callback for the delayed :obj:`<Enter>` event (see :meth:`~Balloon._on_enter`).
This is the callback for the delayed :obj:`<Enter>` event
(see :meth:`~Balloon._on_enter`).
"""
self._toplevel = tk.Toplevel(self.master)
self._canvas = tk.Canvas(self._toplevel, background=self.__background)
Expand All @@ -97,11 +113,17 @@ def show(self):
self._toplevel.attributes("-topmost", True)
self._toplevel.overrideredirect(True)
self._grid_widgets()
x, y = self.master.winfo_pointerxy()
if self.__static is True:
x, y = self.master.winfo_rootx(), self.master.winfo_rooty()
w, h = self.master.winfo_width(), self.master.winfo_height()
x, y = x + w, y + h
else:
x, y = self.master.winfo_pointerxy()
self._canvas.update()
# Update the Geometry of the Toplevel to update its position and size
self._toplevel.geometry("{0}x{1}+{2}+{3}".format(self._canvas.winfo_width(), self._canvas.winfo_height(),
x + 2, y + 2))
self._toplevel.geometry("{0}x{1}+{2}+{3}".format(
self._canvas.winfo_width(), self._canvas.winfo_height(),
x + self.__offset[0], y + self.__offset[1]))

def cget(self, key):
"""
Expand All @@ -123,6 +145,10 @@ def cget(self, key):
return self._timeout
elif key == "background":
return self.__background
elif key == "offset":
return self.__offset
elif key == "showheader":
return self.__showheader
else:
return ttk.Frame.cget(self, key)

Expand All @@ -138,6 +164,9 @@ def config(self, **kwargs):
self.__width = kwargs.pop("width", self.__width)
self._timeout = kwargs.pop("timeout", self._timeout)
self.__background = kwargs.pop("background", self.__background)
self.__offset = kwargs.pop("offset", self.__offset)
self.__showheader = kwargs.pop("showheader", self.__showheader)
self.__static = kwargs.pop("static", self.__static)
if self._toplevel:
self._on_leave(None)
self.show()
Expand Down

0 comments on commit 7381668

Please sign in to comment.