class Label(Bin): """a widget that displays a limited amount of read-only text""" #: pango.FontDescription to use for the label font_desc = "Sans Serif 10" #: image attachment. one of top, right, bottom, left image_position = "left" #: font size size = None fill = False padding = 0 x_align = 0 def __init__(self, text="", markup="", spacing=5, image=None, image_position=None, size=None, font_desc=None, overflow=False, color="#000", background_color=None, **kwargs): # TODO - am initiating table with fill = false but that yields suboptimal label placement and the 0,0 points to whatever parent gave us Bin.__init__(self, **kwargs) #: image to put next to the label self.image = image # the actual container that contains the label and/or image self.container = Box(spacing=spacing, fill=False, x_align=self.x_align, y_align=self.y_align) if image_position is not None: self.image_position = image_position self.display_label = _DisplayLabel(text=text, markup=markup, color=color, size=size) self.display_label.x_align = 0 # the default is 0.5 which makes label align incorrectly on wrapping if font_desc or self.font_desc: self.display_label.font_desc = font_desc or self.font_desc self.display_label.size = size or self.size self.background_color = background_color #: either the pango `wrap <http://www.pygtk.org/pygtk2reference/pango-constants.html#pango-wrap-mode-constants>`_ #: or `ellipsize <http://www.pygtk.org/pygtk2reference/pango-constants.html#pango-ellipsize-mode-constants>`_ constant. #: if set to False will refuse to become smaller self.overflow = overflow self.add_child(self.container) self._position_contents() self.connect_after("on-render", self.__on_render) def get_mouse_sprites(self): return None @property def text(self): """label text. This attribute and :attr:`markup` are mutually exclusive.""" return self.display_label.text @property def markup(self): """pango markup to use in the label. This attribute and :attr:`text` are mutually exclusive.""" return self.display_label.markup @property def color(self): """label color""" return self.display_label.color def __setattr__(self, name, val): if name in ("text", "markup", "color", "size"): if self.display_label.__dict__.get( name, "hamster_graphics_no_value_really") == val: return setattr(self.display_label, name, val) elif name in ("spacing"): setattr(self.container, name, val) else: if self.__dict__.get(name, "hamster_graphics_no_value_really") == val: return Bin.__setattr__(self, name, val) if name in ('x_align', 'y_align') and hasattr(self, "container"): setattr(self.container, name, val) elif name == "alloc_w" and hasattr(self, "display_label") and getattr( self, "overflow") is not False: self._update_max_width() elif name == "min_width" and hasattr(self, "display_label"): self.display_label.width = val - self.horizontal_padding elif name == "overflow" and hasattr(self, "display_label"): if val is False: self.display_label.wrap = None self.display_label.ellipsize = None elif isinstance( val, pango.WrapMode) and val in (pango.WrapMode.WORD, pango.WrapMode.WORD_CHAR, pango.WrapMode.CHAR): self.display_label.wrap = val self.display_label.ellipsize = None elif isinstance(val, pango.EllipsizeMode) and val in ( pango.EllipsizeMode.START, pango.EllipsizeMode.MIDDLE, pango.EllipsizeMode.END): self.display_label.wrap = None self.display_label.ellipsize = val self._update_max_width() elif name in ("font_desc", "size"): setattr(self.display_label, name, val) if name in ("text", "markup", "image", "image_position", "overflow", "size"): if hasattr(self, "overflow"): self._position_contents() self.container.queue_resize() def _update_max_width(self): # updates labels max width, respecting image and spacing if self.overflow is False: self.display_label.max_width = -1 else: w = (self.alloc_w or 0) - self.horizontal_padding - self.container.spacing if self.image and self.image_position in ("left", "right"): w -= self.image.width - self.container.spacing self.display_label.max_width = w self.container.queue_resize() def _position_contents(self): if self.image and (self.text or self.markup): self.image.expand = False self.container.orient_horizontal = self.image_position in ("left", "right") if self.image_position in ("top", "left"): if self.container.sprites != [self.image, self.display_label]: self.container.clear() self.container.add_child(self.image, self.display_label) else: if self.container.sprites != [self.display_label, self.image]: self.container.clear() self.container.add_child(self.display_label, self.image) elif self.image or (self.text or self.markup): sprite = self.image or self.display_label if self.container.sprites != [sprite]: self.container.clear() self.container.add_child(sprite) def __on_render(self, sprite): w, h = self.width, self.height w2, h2 = self.get_height_for_width_size() w, h = max(w, w2), max(h, h2) self.graphics.rectangle(0, 0, w, h) if self.background_color: self.graphics.fill(self.background_color) else: self.graphics.new_path()
class Label(Bin): """a widget that displays a limited amount of read-only text""" #: pango.FontDescription to use for the label font_desc = "Sans Serif 10" #: image attachment. one of top, right, bottom, left image_position = "left" #: font size size = None fill = False padding = 0 x_align = 0 def __init__(self, text = "", markup = "", spacing = 5, image = None, image_position = None, size = None, font_desc = None, overflow = False, color = "#000", background_color = None, **kwargs): # TODO - am initiating table with fill = false but that yields suboptimal label placement and the 0,0 points to whatever parent gave us Bin.__init__(self, **kwargs) #: image to put next to the label self.image = image # the actual container that contains the label and/or image self.container = Box(spacing = spacing, fill = False, x_align = self.x_align, y_align = self.y_align) if image_position is not None: self.image_position = image_position self.display_label = _DisplayLabel(text = text, markup = markup, color=color, size = size) self.display_label.x_align = 0 # the default is 0.5 which makes label align incorrectly on wrapping if font_desc or self.font_desc: self.display_label.font_desc = font_desc or self.font_desc self.display_label.size = size or self.size self.background_color = background_color #: either the pango `wrap <http://www.pygtk.org/pygtk2reference/pango-constants.html#pango-wrap-mode-constants>`_ #: or `ellipsize <http://www.pygtk.org/pygtk2reference/pango-constants.html#pango-ellipsize-mode-constants>`_ constant. #: if set to False will refuse to become smaller self.overflow = overflow self.add_child(self.container) self._position_contents() self.connect_after("on-render", self.__on_render) def get_mouse_sprites(self): return None @property def text(self): """label text. This attribute and :attr:`markup` are mutually exclusive.""" return self.display_label.text @property def markup(self): """pango markup to use in the label. This attribute and :attr:`text` are mutually exclusive.""" return self.display_label.markup @property def color(self): """label color""" return self.display_label.color def __setattr__(self, name, val): if name in ("text", "markup", "color", "size"): if self.display_label.__dict__.get(name, "hamster_graphics_no_value_really") == val: return setattr(self.display_label, name, val) elif name in ("spacing"): setattr(self.container, name, val) else: if self.__dict__.get(name, "hamster_graphics_no_value_really") == val: return Bin.__setattr__(self, name, val) if name in ('x_align', 'y_align') and hasattr(self, "container"): setattr(self.container, name, val) elif name == "alloc_w" and hasattr(self, "display_label") and getattr(self, "overflow") is not False: self._update_max_width() elif name == "min_width" and hasattr(self, "display_label"): self.display_label.width = val - self.horizontal_padding elif name == "overflow" and hasattr(self, "display_label"): if val is False: self.display_label.wrap = None self.display_label.ellipsize = None elif isinstance(val, pango.WrapMode) and val in (pango.WrapMode.WORD, pango.WrapMode.WORD_CHAR, pango.WrapMode.CHAR): self.display_label.wrap = val self.display_label.ellipsize = None elif isinstance(val, pango.EllipsizeMode) and val in (pango.EllipsizeMode.START, pango.EllipsizeMode.MIDDLE, pango.EllipsizeMode.END): self.display_label.wrap = None self.display_label.ellipsize = val self._update_max_width() elif name in ("font_desc", "size"): setattr(self.display_label, name, val) if name in ("text", "markup", "image", "image_position", "overflow", "size"): if hasattr(self, "overflow"): self._position_contents() self.container.queue_resize() def _update_max_width(self): # updates labels max width, respecting image and spacing if self.overflow is False: self.display_label.max_width = -1 else: w = (self.alloc_w or 0) - self.horizontal_padding - self.container.spacing if self.image and self.image_position in ("left", "right"): w -= self.image.width - self.container.spacing self.display_label.max_width = w self.container.queue_resize() def _position_contents(self): if self.image and (self.text or self.markup): self.image.expand = False self.container.orient_horizontal = self.image_position in ("left", "right") if self.image_position in ("top", "left"): if self.container.sprites != [self.image, self.display_label]: self.container.clear() self.container.add_child(self.image, self.display_label) else: if self.container.sprites != [self.display_label, self.image]: self.container.clear() self.container.add_child(self.display_label, self.image) elif self.image or (self.text or self.markup): sprite = self.image or self.display_label if self.container.sprites != [sprite]: self.container.clear() self.container.add_child(sprite) def __on_render(self, sprite): w, h = self.width, self.height w2, h2 = self.get_height_for_width_size() w, h = max(w, w2), max(h, h2) self.graphics.rectangle(0, 0, w, h) if self.background_color: self.graphics.fill(self.background_color) else: self.graphics.new_path()