def calcdraw(self, w, h, Rect = Rect): if self._lastcalc == (w, h): return self._lastseq s = self.skin rect = Rect(0, 0, w, h).AddMargins(wx.Rect(*s.margins)) icons = sorted(((icon, getattr(self, icon + '_pos')) for icon in self.icons), key = lambda o: {'f': -1, 'b': 1}.get(o[1][0], 0)) seq = [] last = Rect() badge_size = min(self.badge_max_size, max(self.badge_min_size, int(self.buddy_icon_size * self.badge_ratio))) frame_size = s.icon_frame_size padding = self.padding hpadding = 4 for icon, pos in icons: if getattr(self, 'show_' + icon): pos = pos.lower() size = getattr(self, icon + '_size') left = pos.endswith('left') iconpos = Point(-size * int(not left), 0) if icon == 'buddy_icon': # special case for buddy icon, which can optionally have a frame around it. iconw = size + frame_size.left + frame_size.right frameRect = Rect(0, 0, iconw, size + frame_size.top + frame_size.bottom) frameRect.x, frameRect.y = rect.Pos(wx.Point(-frameRect.width * int(not left), 0))[0], rect.VCenterH(frameRect.height) last = Rect(frameRect.x + frame_size.left, frameRect.y + frame_size.top, size, size) seq += [(getattr(self, 'get_buddy_icon'), last, 0)] seq += [(getattr(self, 'get_frame_icon'), frameRect, 0)] rect = rect.Subtract(**{'left' if left else 'right': iconw + hpadding}) bitmap = getattr(self, 'get_' + icon) else: if not pos.startswith('b'): # non badge r = Rect(rect.Pos(iconpos)[0], rect.VCenterH(size), size, size) rect = rect.Subtract(**{'left' if left else 'right': size + hpadding}) last = r alignment = ALIGN_CENTER bitmap = getattr(self, 'get_' + icon) else: # badge bp = badge_size alignment = LBOTTOM if left else RBOTTOM badgepos = last.Pos(wx.Point(0 if left else -bp, -bp)) r = Rect(badgepos[0], badgepos[1], badge_size, badge_size) bitmap = lambda obj, icon=icon: getattr(self, 'get_' + icon)(obj).ResizedSmaller(badge_size) seq.append((bitmap, r, alignment)) self.inforect = rect self._lastcalc = (w, h) self._lastseq = seq return seq
def Draw(self, dc, rect, selected, obj, depth, expanded, index, hover, Rect = Rect): DrawBitmap = dc.DrawBitmap DrawTruncatedText = dc.DrawTruncatedText idle_string = get_idle_string(obj) extrafont = self.extrafont extra_info = self.extra_info if self.show_extra else None msg = get_contact_status(obj) padding, extra_padding = self.padding, self.extra_padding contact_name = obj.alias mainfont_height = self.mainfont_height # draw all icons for method, r, align in self.calcdraw(rect.width, rect.height): try: b = method(obj) except: print_exc() else: if b: b.Draw(dc, Rect(rect.x + r.x, rect.y + r.y, r.width, r.height), align) rect = rect.AddMargins(wx.Rect(*self.skin.margins)) rect.x, rect.width = self.inforect.x, self.inforect.width # draw the status message (if necessary) if msg and extra_info in ('status', 'both'): th = self.mainfont.LineHeight + extra_padding + self.extrafont_height rect = Rect(rect.x, rect.VCenterH(th), rect.width, rect.height) namerect = Rect(rect.x, rect.y + 1, rect.Width, self.mainfont.LineHeight) inforect = Rect(rect.x, rect.y + self.mainfont.LineHeight + extra_padding, rect.Width, self.extrafont_height) DrawTruncatedText(self.get_contact_info(obj, dc, selected, expanded, hover), inforect, alignment = lmiddle) else: namerect = rect # draw idle time hpadding = 4 if idle_string and extra_info in ('idle', 'both'): # do some measurements to see if # a) idle time needs to be left aligned against the buddy name, or # b) right aligned and cutting off the buddy name (i.e., buddy na...IDLE) namew, nameh, namedescent, __ = dc.GetFullTextExtent(contact_name, self.mainfont) w, h, desc, __ = dc.GetFullTextExtent(idle_string, extrafont) iy = 3 diff = namew + w + hpadding - namerect.width if diff > 0: x, y = namerect.Pos((-w, 0))[0], namerect.Y r = Rect(x, y, w, namerect.Height) namerect = namerect.Subtract(right = w + hpadding) else: r = Rect(namerect.X + namew + hpadding, namerect.Y, w, namerect.Height) self.set_idle_time_dc(obj, dc, selected, expanded, hover) dc.DrawLabel(idle_string, r, ALIGN_LEFT | ALIGN_CENTER_VERTICAL) # draw buddy name self.set_contact_name_dc(obj, dc, selected, expanded, hover) DrawTruncatedText(contact_name, namerect, alignment = lmiddle)