From 6e299f3bf2365f92a54de8f01532149d4f46844c Mon Sep 17 00:00:00 2001 From: Eric Jeschke Date: Fri, 11 Oct 2024 15:47:25 -1000 Subject: [PATCH] Add background and border attributes to Text canvas object --- doc/WhatsNew.rst | 3 ++ ginga/canvas/types/basic.py | 59 +++++++++++++++++++++++++++++++++---- ginga/qtw/CanvasRenderQt.py | 21 +++---------- 3 files changed, 61 insertions(+), 22 deletions(-) diff --git a/doc/WhatsNew.rst b/doc/WhatsNew.rst index 0e1ea6f90..48c94b253 100644 --- a/doc/WhatsNew.rst +++ b/doc/WhatsNew.rst @@ -22,6 +22,9 @@ Ver 5.2.0 (unreleased) - Toolbar and Info (Synopsis) bars change GUIs according to which viewer is active in the channel +- Text canvas type gets new attributes: bgcolor, bgalpha, bordercolor, + borderpadding, borderalpha, borderlinewidth + Ver 5.1.0 (2024-05-22) ====================== - Fixed an issue where --modules option did not start a global plugin diff --git a/ginga/canvas/types/basic.py b/ginga/canvas/types/basic.py index e63ddb591..e9e340525 100644 --- a/ginga/canvas/types/basic.py +++ b/ginga/canvas/types/basic.py @@ -76,6 +76,24 @@ def get_params_metadata(cls): Param(name='fillalpha', type=float, default=1.0, min=0.0, max=1.0, widget='spinfloat', incr=0.05, description="Opacity of fill"), + Param(name='bgcolor', + valid=colors_plus_none, type=_color, default='white', + description="Color of text background"), + Param(name='bgalpha', type=float, default=0.0, + min=0.0, max=1.0, widget='spinfloat', incr=0.05, + description="Opacity of text background"), + Param(name='bordercolor', + valid=colors_plus_none, type=_color, default='black', + description="Color of text border"), + Param(name='borderlinewidth', type=int, default=0, + min=0, max=20, widget='spinbutton', incr=1, + description="Width of border"), + Param(name='borderpadding', type=int, default=4, + min=0, max=20, widget='spinbutton', incr=1, + description="Padding from text to border"), + Param(name='borderalpha', type=float, default=0.0, + min=0.0, max=1.0, widget='spinfloat', incr=0.05, + description="Opacity of text border"), Param(name='rot_deg', type=float, default=0.0, min=-359.999, max=359.999, widget='spinfloat', incr=1.0, description="Rotation of text"), @@ -92,7 +110,9 @@ def __init__(self, pt, text='EDIT ME', font='Sans Serif', fontsize=None, fontscale=False, fill=True, fontsize_min=6.0, fontsize_max=None, color='yellow', alpha=1.0, fillcolor=None, fillalpha=1.0, - linewidth=0, rot_deg=0.0, showcap=False, **kwdargs): + linewidth=0, rot_deg=0.0, bgcolor='white', bgalpha=0.0, + bordercolor='black', borderpadding=4, + borderlinewidth=0, borderalpha=0.0, showcap=False, **kwdargs): self.kind = 'text' if fillcolor is None: fillcolor = color @@ -104,6 +124,11 @@ def __init__(self, pt, text='EDIT ME', fontsize_min=fontsize_min, fontsize_max=fontsize_max, text=text, rot_deg=rot_deg, + bgcolor=bgcolor, bgalpha=bgalpha, + bordercolor=bordercolor, + borderpadding=borderpadding, + borderlinewidth=borderlinewidth, + borderalpha=borderalpha, showcap=showcap, **kwdargs) OnePointMixin.__init__(self) @@ -170,10 +195,28 @@ def get_llur(self): def draw(self, viewer): cr = viewer.renderer.setup_cr(self) - cr.initialize_from_shape(self, line=True, fill=True, font=True) + cr.initialize_from_shape(self, line=False, fill=False, font=True) x, y = self.get_data_points()[0] cx, cy = viewer.get_canvas_xy(x, y) + + # draw background/border + if self.borderalpha + self.bgalpha > 0.0: + cwd, cht = cr.text_extents(self.text) + pad = self.borderpadding + bbox = np.array([(cx - pad, cy + pad), (cx + cwd + pad, cy + pad), + (cx + cwd + pad, cy - cht - pad), + (cx - pad, cy - cht - pad)]) + x_arr, y_arr = bbox.T + xa, ya = trcalc.rotate_pt(x_arr, y_arr, -self.rot_deg, + xoff=cx, yoff=cy) + cpoints = np.array((xa, ya)).T + cr.set_line(self.bordercolor, alpha=self.borderalpha, + linewidth=self.borderlinewidth) + cr.set_fill(self.bgcolor, alpha=self.bgalpha) + cr.draw_polygon(cpoints, line=cr.line, fill=cr.fill) + + cr.initialize_from_shape(self, line=True, fill=True, font=False) cr.draw_text(cx, cy, self.text, rot_deg=self.rot_deg, font=cr.font, fill=cr.fill, line=cr.line) @@ -188,15 +231,21 @@ def __init__(self, x, y, text='EDIT ME', font='Sans Serif', fontsize=None, fontscale=False, fontsize_min=6.0, fontsize_max=None, fill=True, color='yellow', alpha=1.0, fillcolor=None, fillalpha=1.0, - linewidth=0, rot_deg=0.0, showcap=False, **kwdargs): + linewidth=0, rot_deg=0.0, bgcolor='white', bgalpha=0.0, + bordercolor='black', borderpadding=4, + borderlinewidth=0, borderalpha=0.0, showcap=False, **kwdargs): if fillcolor is None: fillcolor = color TextP.__init__(self, (x, y), text=text, color=color, alpha=alpha, fill=fill, fillcolor=fillcolor, fillalpha=fillalpha, font=font, fontsize=fontsize, fontscale=fontscale, fontsize_min=fontsize_min, fontsize_max=fontsize_max, - linewidth=linewidth, rot_deg=rot_deg, showcap=showcap, - **kwdargs) + linewidth=linewidth, rot_deg=rot_deg, + bgcolor=bgcolor, bgalpha=bgalpha, + bordercolor=bordercolor, borderpadding=borderpadding, + borderlinewidth=borderlinewidth, + borderalpha=borderalpha, + showcap=showcap, **kwdargs) class Polygon(PolygonMixin, CanvasObjectBase): diff --git a/ginga/qtw/CanvasRenderQt.py b/ginga/qtw/CanvasRenderQt.py index 8b445f409..3183735c4 100644 --- a/ginga/qtw/CanvasRenderQt.py +++ b/ginga/qtw/CanvasRenderQt.py @@ -74,11 +74,8 @@ def text_extents(self, text, font=None): if font is None: font = self.font fm = QFontMetrics(font.render.font) - if hasattr(fm, 'horizontalAdvance'): - width = fm.horizontalAdvance(text) - else: - width = fm.width(text) - height = fm.height() + rect = fm.boundingRect(text) + width, height = rect.width(), fm.ascent() # rect.height() return width, height ##### DRAWING OPERATIONS ##### @@ -95,14 +92,7 @@ def draw_text(self, cx, cy, text, rot_deg=0.0, font=None, fill=None, if font is not None: self.ctx.setFont(font.render.font) - # draw bg qfont = self.ctx.font() - # fm = QFontMetrics(qfont) - # qrect = fm.boundingRect(text) - # self.ctx.fillRect(qrect, self.ctx.brush()) - # # draw fg - # self.ctx.drawText(0, 0, text) - #---------- self.ctx.setBrush(QtCore.Qt.NoBrush if fill is None else fill.render.brush) @@ -322,11 +312,8 @@ def get_dimensions(self, shape): def text_extents(self, text, font): qfont = get_font(font.fontname, font.fontsize) fm = QFontMetrics(qfont) - if hasattr(fm, 'horizontalAdvance'): - width = fm.horizontalAdvance(text) - else: - width = fm.width(text) - height = fm.height() + rect = fm.boundingRect(text) + width, height = rect.width(), fm.ascent() # rect.height() return width, height