fishyboteso/fishy/libs/tkhtmlview/__init__.py
2020-05-20 16:49:01 +05:30

130 lines
4.3 KiB
Python

"""
tkinter HTML text widgets
"""
import sys
import tkinter as tk
from . import html_parser
VERSION = "0.1.0.post1"
class _ScrolledText(tk.Text):
# ----------------------------------------------------------------------------------------------
def __init__(self, master=None, **kw):
self.frame = tk.Frame(master)
self.vbar = tk.Scrollbar(self.frame)
kw.update({'yscrollcommand': self.vbar.set})
self.vbar.pack(side=tk.RIGHT, fill=tk.Y)
self.vbar['command'] = self.yview
tk.Text.__init__(self, self.frame, **kw)
self.pack(side=tk.LEFT, fill=tk.BOTH, expand=True)
text_meths = vars(tk.Text).keys()
methods = vars(tk.Pack).keys() | vars(tk.Grid).keys() | vars(tk.Place).keys()
methods = methods.difference(text_meths)
for m in methods:
if m[0] != '_' and m != 'config' and m != 'configure':
setattr(self, m, getattr(self.frame, m))
def __str__(self):
return str(self.frame)
class HTMLScrolledText(_ScrolledText):
# ----------------------------------------------------------------------------------------------
"""
HTML scrolled text widget
"""
def __init__(self, *args, html=None, **kwargs):
# ------------------------------------------------------------------------------------------
super().__init__(*args, **kwargs)
self._w_init(kwargs)
self.html_parser = html_parser.HTMLTextParser()
if isinstance(html, str):
self.set_html(html)
def _w_init(self, kwargs):
# ------------------------------------------------------------------------------------------
if not 'wrap' in kwargs.keys():
self.config(wrap='word')
if not 'background' in kwargs.keys():
if sys.platform.startswith('win'):
self.config(background='SystemWindow')
else:
self.config(background='white')
def fit_height(self):
# ------------------------------------------------------------------------------------------
"""
Fit widget height to wrapped lines
"""
for h in range(1, 4):
self.config(height=h)
self.master.update()
if self.yview()[1] >= 1:
break
else:
self.config(height=0.5 + 3 / self.yview()[1])
def set_html(self, html, strip=True):
# ------------------------------------------------------------------------------------------
"""
Set HTML widget text. If strip is enabled (default) it ignores spaces and new lines.
"""
prev_state = self.cget('state')
self.config(state=tk.NORMAL)
self.delete('1.0', tk.END)
self.tag_delete(self.tag_names)
self.html_parser.w_set_html(self, html, strip=strip)
self.config(state=prev_state)
class HTMLText(HTMLScrolledText):
# ----------------------------------------------------------------------------------------------
"""
HTML text widget
"""
def _w_init(self, kwargs):
# ------------------------------------------------------------------------------------------
super()._w_init(kwargs)
self.vbar.pack_forget()
def fit_height(self):
# ------------------------------------------------------------------------------------------
super().fit_height()
# self.master.update()
self.vbar.pack_forget()
class HTMLLabel(HTMLText):
# ----------------------------------------------------------------------------------------------
"""
HTML label widget
"""
def _w_init(self, kwargs):
# ------------------------------------------------------------------------------------------
super()._w_init(kwargs)
if not 'background' in kwargs.keys():
if sys.platform.startswith('win'):
self.config(background='SystemButtonFace')
else:
self.config(background='#d9d9d9')
if not 'borderwidth' in kwargs.keys():
self.config(borderwidth=0)
if not 'padx' in kwargs.keys():
self.config(padx=3)
def set_html(self, *args, **kwargs):
# ------------------------------------------------------------------------------------------
super().set_html(*args, **kwargs)
self.config(state=tk.DISABLED)