def __init__(self, *a, **k): wx.VListBox.__init__(self, *a, **k) syscol = wx.SystemSettings.GetColour self.colors = Storage( textfg=Storage(selected=syscol(wx.SYS_COLOUR_HIGHLIGHTTEXT), normal=syscol(wx.SYS_COLOUR_WINDOWTEXT))) self.bg = Storage(selected=SkinColor(syscol(wx.SYS_COLOUR_HIGHLIGHT)), normal=SkinColor(syscol(wx.SYS_COLOUR_LISTBOX))) self.fonts = Storage(text=default_font()) self.BBind(LEFT_DOWN=self._OnLeftDown)
def __init__(self, parent, data, use_checkbox=True, linkobservers=True): wx.Panel.__init__(self, parent, style=wx.FULL_REPAINT_ON_RESIZE) # self.text_controls = [] oldChildren = set(self.Children) self.data = data self.SetBackgroundStyle(wx.BG_STYLE_CUSTOM) self.selectedbg = SkinColor(syscol(wx.SYS_COLOUR_HIGHLIGHT)) self.bg = SkinColor(wx.WHITE) self.padding = wx.Point(5, 5) # Construct and layout GUI elements self.construct(use_checkbox) self.layout() # Observe the data object for changes if linkobservers: try: data.add_observer(self.on_data_changed) except AttributeError: pass self.on_data_changed(data) # Bind events Bind = self.Bind Bind(wx.EVT_PAINT, self._paint) Bind(wx.EVT_ERASE_BACKGROUND, lambda e: e.Skip(False)) Bind(wx.EVT_MOTION, self.on_motion) Bind(wx.EVT_KILL_FOCUS, self.Parent.on_lost_focus) Bind(wx.EVT_LEFT_DCLICK, self.on_doubleclick) Bind(wx.EVT_RIGHT_UP, self.on_right_up) Bind(wx.EVT_RIGHT_DOWN, self.on_right_down) Bind(wx.EVT_MOUSE_CAPTURE_LOST, self.on_mouse_lost) # Bind special mouse events that fall through to parent controls = [self] + list(set(self.Children) - oldChildren) for win in controls: winBind = win.Bind winBind(wx.EVT_LEFT_DOWN, self.on_left_down) winBind(wx.EVT_RIGHT_DOWN, self.on_right_down) winBind(wx.EVT_RIGHT_UP, self.on_right_up) winBind(wx.EVT_LEFT_DCLICK, self.on_doubleclick) winBind(wx.EVT_KILL_FOCUS, self.Parent.on_lost_focus) self.CalcColors(False) self.UpdateSkin() self.SetDropTarget(AnyListDropTarget(self))
def UpdateSkin(self): """ The usual update skin """ key = self.skinkey s = lambda k, d=None: skin.get('%s.%s' % (key, k), d) self.bg = s('backgrounds.account', lambda: SkinColor(wx.WHITE)) self.majorfont = s('Fonts.Account', default_font) self.minorfont = s('Fonts.StateAndLink', default_font) self.linkfont = CopyFont(self.minorfont, underline=True) self.majorfc = s('FontColors.Account', wx.BLACK) self.statefc = s('FontColors.State', lambda: wx.Colour(125, 125, 125)) self.linkfc = s('FontColors.Link', wx.BLUE) self.closeicon = [None] * 3 self.closeicon[0] = s( 'Icons.Close', skin.get('AppDefaults.removeicon')).ResizedSmaller(16) self.closeicon[1] = s('Icons.CloseHover', self.closeicon[0]).ResizedSmaller(16) self.closeicon[2] = s('Icons.CloseDown', self.closeicon[1]).ResizedSmaller(16) self.liconsize = s('ServiceIconSize', 16) self.padding = s('Padding', lambda: wx.Point(3, 3)) self.stateicon = self.account.statusicon.ResizedSmaller(16) self.licon = self.account.serviceicon.Resized(self.liconsize) if self.initover: self.CalcLayout()
def UpdateSkin(self): """ Updates all the local skin references """ key = self.skinkey s = lambda k, default=sentinel: skin.get(key + '.' + k, default) mode = try_this(lambda: str(s('mode', '')), '') if config.platformName != "mac" and key and mode.lower() != 'native': self.native = False self.repeat = try_this(lambda: str(s('style', '')).lower(), '') == 'repeat' self.padding = s('padding', 0) self.Font = s('font', lambda: default_font()) self.bg = s('backgrounds.normal', None) self.fg = s('backgrounds.fill', lambda: SkinColor(wx.BLUE)) self.normalfc = s('fontcolors.normal', wx.BLACK) self.fillfc = s('fontcolors.fill', wx.WHITE) else: self.native = True self.OnSize()
def UpdateSkin(self): key = self.skinkey s = lambda k, d=None: skin.get('%s.%s' % (key, k), d) self.bg = s('backgrounds.behind', SkinColor(wx.WHITE)) self.spacing = s('spacing', 0) wx.CallAfter(self.WhenListChanges)
def _constructSkinElements(self): 'Creates the buttons that launch menu dropdowns in the bar.' s, p = self.skin, self.panel p.bg = s.get("background", SkinColor(wx.WHITE)) pad = p.padding = s.get("padding", wx.Point(0, 0)) for child in list(p.Children): child.Hide() child.Destroy() v = wx.BoxSizer(wx.VERTICAL) h = wx.BoxSizer(wx.HORIZONTAL) v.Add(h, 1, wx.EXPAND | wx.TOP | wx.BOTTOM, pad.y) p.Sizer = s.get('margins', Margins()).Sizer(v) # create a button for each item in the menubar self.buttons = [] addb = self.buttons.append menus, nummenus = self.Menus, len(self.Menus) for i, (menu, label) in enumerate(menus): del menu.OnDismiss[:] # the API sucks for getting Titles with mnemonic characters label = self.toptitles.get(menu, label) # (self, parent, id = -1, label='', skin='Button', icon=None, # pos=wx.DefaultPosition, size=None, style=wx.HORIZONTAL, # type=None, menu=None, menubarmode=False, onclick = None): button = UberButton(p, -1, skin=s.itemskin, label=label, type="menu", menu=menu, menubarmode=True) addb(button) # store some special attributes in the menu, which it will use for # keyboard/mouse navigation of the menubar menu._next = menus[(i + 1) % nummenus][0] menu._prev = menus[i - 1][0] menu._button = button # add buttons to the size h.AddMany((b, 0, wx.EXPAND | wx.LEFT, pad.x) for b in self.buttons) # bind keyboard accelerators self._bindAccelerators()
def UpdateSkin(self): self.dragimgs = S( bar=skin.get('BuddiesPanel.Dragimages.Bar'), #TODO: stretch? box=skin.get('BuddiesPanel.Dragimages.Box')) for renderer in self.renderers.itervalues(): renderer.UpdateSkin() bg = skin.get('BuddiesPanel.Backgrounds.List', lambda: SkinColor(wx.WHITE)) self.SetBackground(bg) self.RefreshAll()
def CalcColors(self, selected=None): if selected is None: selected = self.IsSelected() # The colors, including the background color, are dependent on if # this item is selected. if selected and self.Parent.show_selected: self.BackgroundColour = selbgcolor elif self.IsHovered(): self.BackgroundColour = hovbgcolor else: self.BackgroundColour = bgcolors[self.Index % len(bgcolors)] self.bg = SkinColor(self.BackgroundColour)
def UpdateSkin(self): s = skin.get self.padding = s('infobox.padding', lambda: wx.Point(4, 4)) self.headerfont = s('infobox.fonts.header', default_font) self.titlefont = s('infobox.fonts.title', default_font) self.majorfont = s('infobox.fonts.major', default_font) self.minorfont = s('infobox.fonts.minor', default_font) self.linkfont = CopyFont(s('infobox.fonts.link', default_font), underline=True) fc = s('infobox.fontcolors') g = fc.get self.titlefc = g('title', BLACK) self.majorfc = g('major', wx.BLACK) self.minorfc = g('minor', wx.Color(128, 128, 128)) self.linkfc = g('link', wx.BLUE) self.hovertitlefc = g('emailhovertitle', self.titlefc) self.hovermajorfc = g('emailhovermajor', self.majorfc) self.hoverminorfc = g('emailhoverminor', self.minorfc) self.hoverlinkfc = g('emailhoverlink', self.linkfc) for link in self.linkage: link.NormalColour = link.HoverColour = link.VisitedColour = self.hoverlinkfc link.Font = self.linkfont self.linkage.Layout() if self.errorlink: self.errorlink.Font = self.Parent.Font self.errorlink.VisitedColour = self.errorlink.HoverColour = self.errorlink.NormalColour = s( 'infobox.linkcolor', lambda: wx.BLUE) self.bg = s('infobox.backgrounds.email', lambda: SkinColor(wx.WHITE)) self.selbg = s('infobox.backgrounds.emailhover', lambda: SkinColor(wx.Color(225, 255, 225))) self.sep = s('infobox.shortseparatorimage', None)
def UpdateSkin(self, first=False): s = skin.get('filetransfers') self.normalbg = s.get('backgrounds.normal', [ SkinColor(wx.Color(238, 238, 238)), SkinColor(wx.Color(255, 255, 255)) ]) self.selectedbg = s.get('backgrounds.selected', SkinColor(wx.Color(180, 180, 180))) self.hoveredbg = s.get('backgrounds.hovered', SkinColor(wx.Color(220, 220, 220))) self.padding = s.get('padding', lambda: Point(5, 5)) self.margins = s.get('margins', lambda: skin.ZeroMargins) if not first: with traceguard: self.details.SetFont( skin.get('filetransfers.fonts.other', default_font)) linkfont = skin.get('filetransfers.fonts.link', default_font) for link in self.links.values(): link.SetFont(linkfont) self.layout() self.Refresh(False)
def UpdateSkin(self): """ The Usual """ key = 'infobox' if skin.get(key,False): s = lambda k,d: skin.get('%s.%s'%(key,k),d) else: s = lambda k,d: d self.padding = s('padding', lambda: wx.Point(2, 2)) self.labelf = s('fonts.title',lambda: default_font()) self.labelfc = s('fontcolors.title', wx.BLACK) self.linkf = CopyFont(s('fonts.link',lambda: default_font()), underline=True) self.linkfc = s('fontcolors.link', wx.BLUE) self.bg = s('backgrounds.email', lambda: SkinColor(wx.WHITE))
def UpdateSkin(self): key = self.skinkey s = lambda k, default: skin.get('%s.%s' % (key, k), default) self.framebg = s('frame', SkinColor(wx.BLACK)) self.framesize = s('framesize', Margins([0, 0, 0, 0])) sz = self.Sizer if sz: sz.Detach(1) sz.Detach(1) sz.Add(wx.Size(self.framesize.left, self.framesize.top), (0, 0)) sz.Add(wx.Size(self.framesize.right, self.framesize.bottom), (2, 2)) wx.CallAfter(self.Layout) wx.CallAfter(self.Refresh)
def UpdateSkin(self): """ The usual. """ key = self.skinkey s = lambda k, d=None: skin.get('%s.%s' % (key, k), d) self.framebg = s('Frame', lambda: SkinColor(wx.BLACK)) self.framesize = s('FrameSize', lambda: Margins([0, 0, 0, 0])) self.iconup = s('icons.show', None) self.icondown = s( 'icons.hide', lambda: wx.BitmapFromImage( wx.ImageFromBitmap(self.iconup).Mirror(False))) self.buttonskin = s('buttonskin', None) self.WhenOrderChanges() if self.Sizer: self.Sizer.SetMargins(self.framesize)
def UpdateSkin(self): """ The usual """ skinget = lambda s, default: skin('%s.%s' % (self.skinkey, s), default) self.padding = skinget('padding', lambda: wx.Point(3, 3)) self.Font = skinget('font', default_font) self.iconsize = skinget('iconsize', 16) self.itemheight = max(self.iconsize, self.Font.LineHeight) + self.padding.y * 2 default_color = SkinColor(wx.Color(225, 255, 225)) self.bg = skinget('backgrounds.normal', default_color) self.selbg = skinget('backgrounds.hover', default_color) self.fontcolor = skinget('fontcolors.normal', wx.BLACK) self.selfontcolor = skinget('fontcolors.hover', wx.BLACK) self.MinSize = wx.Size(-1, self.itemheight * self.ItemCount)
def UpdateSkin(self): self.padding = wx.Point(4, 4) self.headerfont = skin.get('infobox.fonts.header', lambda: default_font()) self.linkfont = CopyFont(skin.get('infobox.fonts.link', lambda: default_font()), underline=True) self.elinkfont = CopyFont(self.linkfont, weight=wx.FONTWEIGHT_BOLD) self.headerfc = skin.get('infobox.fontcolors.navbarheader', lambda: wx.BLACK) self.linkfc = skin.get('infobox.fontcolors.navbarlink', lambda: wx.BLUE) linkposx = self.padding[0] * 2 + 16 linkposy = self.headerfont.Height + 2 * self.padding[1] self.linkage.SetPosition((linkposx, linkposy)) for link in self.linkage: link.NormalColour = link.HoverColour = link.VisitedColour = self.linkfc link.Font = self.linkfont self.linkage.Layout() elink = self.extralinkage if elink: elink.NormalColour = elink.HoverColour = elink.VisitedColour = self.linkfc elink.Font = self.elinkfont elink.Size = elink.BestSize elinkposx = self.Size.width - self.padding[0] - elink.BestSize.width elink.SetPosition((elinkposx, linkposy)) self.bg = skin.get('infobox.backgrounds.header', lambda: SkinColor(wx.Color(225, 255, 225))) # self.sep = skin.get('infobox.longseparatorimage', None) self.Size = self.MinSize = wx.Size( -1, self.headerfont.Height + self.linkfont.Height + self.padding.y * 4) # + self.sep.Size.height
def UpdateSkin(self, first=False): skin_get = skin.get def g(k, default=sentinel): elem = skin_get('FileTransfers.Fonts.%s' % k, default) if elem is None: return default() else: return elem fonts = self.fonts = S() fonts.filename = g('filename', lambda: default_font()) fonts.other = g('other', lambda: fonts.filename) fonts.link = g('link', lambda: fonts.filename) g = lambda k, default=sentinel: (skin_get( 'FileTransfers.FontColors.%s' % k, default) or default()) fontcolors = self.fontcolors = S() fontcolors.filename = g( 'filename', lambda: wx.SystemSettings.GetColour(wx.SYS_COLOUR_WINDOWTEXT)) fontcolors.other = g('other', lambda: fontcolors.filename) fontcolors.link = g('link', lambda: wx.BLUE) fontcolors.filenameselected = g( 'filenameselected', lambda: wx.SystemSettings.GetColour(wx.SYS_COLOUR_HIGHLIGHTTEXT)) fontcolors.otherselected = g('otherselected', lambda: fontcolors.filenameselected) fontcolors.linkselected = g('linkselected', lambda: fontcolors.filenameselected) self.filetype_icon_size = 32 self.bg = skin_get('filetransfers.backgrounds.list', lambda: SkinColor(wx.WHITE)) if not first: wx.CallAfter(self.Layout)
def UpdateSkin(self): """ Update local skin references and updates skins for buttons """ key = self.skinkey self.native = not key if self.native: if self.uxthemeable: self.OpenNativeTheme() self.bg = None else: self.bg = SkinColor( wx.SystemSettings_GetColour(wx.SYS_COLOUR_3DFACE)) self.padding = Point(2, 2) self.margins = Margins([0, 0, 0, 0]) self.buttonskin = None self.menuskin = None else: self.CloseNativeTheme() self.padding = skin.get(key + '.padding', Point(2, 2)) self.margins = skin.get(key + '.margins', Margins([0, 0, 0, 0])) self.bg = skin.get( key + '.background', lambda: SkinColor( wx.SystemSettings_GetColour(wx.SYS_COLOUR_3DFACE))) self.buttonskin = skin.get(key + '.buttonskin', None) self.menuskin = skin.get(key + '.menuskin', None) s = self.Sizer if s: s.Detach(1) s.Detach(1) s.Add(Size(self.margins.left, self.margins.top), (0, 0)) s.Add(Size(self.margins.right, self.margins.bottom), (2, 2)) s.Children[0].SetBorder(self.padding.y) for child in self.content.Children: child.SetBorder(self.padding.x) for object in self.children + self.staticchildren: if isinstance(object, UberButton): object.SetSkinKey(self.buttonskin, True) if object.menu: object.menu.SetSkinKey(self.buttonskin) elif isinstance(object, FontDropDown): object.SetSkinKey(self.buttonskin) object.SetMenuSkinKey(self.menuskin) if hasattr(self, 'overflowbutton'): self.overflowbutton.SetSkinKey(self.buttonskin) self.overflowmenu.SetSkinKey(self.menuskin) if not self.overflowmode and hasattr(self, 'content'): spacersizer = self.spacersizer spacersizer.Detach(0) spacersizer.Add((self.padding.x, 1), 0, EXPAND) wx.CallAfter(self.Layout)
class UberBar(SimplePanel, UberWidget): """ Has at least two uses as a ButtonBar automatically resizes to biggest button, then resizes all other buttons to fit height will have support for other items later but not yet skinning will be passed all items in the bar should think of it as there parent """ def __init__(self, parent, id=wx.ID_ANY, skinkey=None, overflowmode=False, name='UberBar', alignment=None): SimplePanel.__init__(self, parent, FULL_REPAINT_ON_RESIZE) UberWidget.__init__(self, 'toolbar') self.ChildPaints = Delegate() # Initing variables self.alignment = alignment if alignment and not overflowmode else ALIGN_LEFT self.overflowmode = overflowmode self.navimode = False self.active = None self.children = [] self.staticchildren = [] self.overflowed = [] self.focus = None self.lastheight = 0 Bind = self.Bind Bind(wx.EVT_PAINT, self.OnBGPaint) Bind(wx.EVT_SIZE, self.OnReSize) self.keyletters = {} self.tlmargins = Size() self.brmargins = Size() #Start setting up an alternaitve Native Menubar for native mode self.SetSkinKey(skinkey, True) self.content = wx.BoxSizer(HORIZONTAL) sizer = self.Sizer = wx.GridBagSizer() sizer.SetEmptyCellSize(wx.Size(0, 0)) contentFlag = TOP | BOTTOM | (self.alignment | EXPAND if self.alignment == ALIGN_LEFT else self.alignment) sizer.Add(self.content, (1, 1), flag=contentFlag, border=self.padding.y) sizer.Add(Size(self.margins.left, self.margins.top), (0, 0)) sizer.Add(Size(self.margins.right, self.margins.bottom), (2, 2)) sizer.AddGrowableCol(1, 1) sizer.AddGrowableRow(1, 1) # #Set up the menu for the overflowed items if overflow mode if overflowmode: self.overflowmenu = SimpleMenu(self, self.menuskin) self.overflowbutton = UberButton(self, skin=self.buttonskin, type='menu', menu=self.overflowmenu) self.content.Add((self.padding.x, 1), 1, EXPAND) self.content.Add(self.overflowbutton, 0, RIGHT | EXPAND, self.padding.x) self.staticchildren.append(self.overflowbutton) else: spacersizer = self.spacersizer = wx.BoxSizer(wx.HORIZONTAL) spacersizer.Add((self.padding.x, 1), 0, EXPAND) self.content.Add(spacersizer, 0, EXPAND) self.GenWidthRestriction() def UpdateSkin(self): """ Update local skin references and updates skins for buttons """ key = self.skinkey self.native = not key if self.native: if self.uxthemeable: self.OpenNativeTheme() self.bg = None else: self.bg = SkinColor( wx.SystemSettings_GetColour(wx.SYS_COLOUR_3DFACE)) self.padding = Point(2, 2) self.margins = Margins([0, 0, 0, 0]) self.buttonskin = None self.menuskin = None else: self.CloseNativeTheme() self.padding = skin.get(key + '.padding', Point(2, 2)) self.margins = skin.get(key + '.margins', Margins([0, 0, 0, 0])) self.bg = skin.get( key + '.background', lambda: SkinColor( wx.SystemSettings_GetColour(wx.SYS_COLOUR_3DFACE))) self.buttonskin = skin.get(key + '.buttonskin', None) self.menuskin = skin.get(key + '.menuskin', None) s = self.Sizer if s: s.Detach(1) s.Detach(1) s.Add(Size(self.margins.left, self.margins.top), (0, 0)) s.Add(Size(self.margins.right, self.margins.bottom), (2, 2)) s.Children[0].SetBorder(self.padding.y) for child in self.content.Children: child.SetBorder(self.padding.x) for object in self.children + self.staticchildren: if isinstance(object, UberButton): object.SetSkinKey(self.buttonskin, True) if object.menu: object.menu.SetSkinKey(self.buttonskin) elif isinstance(object, FontDropDown): object.SetSkinKey(self.buttonskin) object.SetMenuSkinKey(self.menuskin) if hasattr(self, 'overflowbutton'): self.overflowbutton.SetSkinKey(self.buttonskin) self.overflowmenu.SetSkinKey(self.menuskin) if not self.overflowmode and hasattr(self, 'content'): spacersizer = self.spacersizer spacersizer.Detach(0) spacersizer.Add((self.padding.x, 1), 0, EXPAND) wx.CallAfter(self.Layout) def GentAltCals(self): """ This Goes through and generates the keyboard shortcuts for the menus in menubar mode """ self.keyletters = {} for child in self.children: amp_idx = child.label.find('&') if isinstance(child, UberButton) and amp_idx != -1: self.keyletters[child.label[amp_idx + 1].upper()] = child def Add(self, object, expand=False, calcSize=True): 'Add object ot end of bar.' return self.Insert(len(self.children), object, expand, calcSize=calcSize) def AddMany(self, objects, expand=False): for object in objects: self.Add(object, expand) def AddStatic(self, object, expand=False): 'Add object to end of bar on right of menu in overflow mode.' if self.overflowmode: if isinstance(object, UMenu): object = UberButton(self, -1, object.GetTitle(), self.buttonskin, type='menu', menu=object) elif isinstance(object, UberButton): object.SetSkinKey(self.buttonskin, True) else: raise TypeError( 'Only buttons can be added to UberBar in overflow mode.') self.content.Insert(self.content.GetChildCount() - 1, object, expand, RIGHT | EXPAND, self.padding.x) self.staticchildren.append(object) self.GenWidthRestriction() else: raise AssertionError( 'Static items are only availible in OverFlowMode') def AddMenuItem(self, item): """ Append a SimpleMenuItem to the overflow menu """ if self.overflowmode: self.overflowmenu.AppendItem(item) def AddSpacer(self): """ Inserts a spacer to separate the items at the end of the current set """ if not self.overflowmode: self.content.Add((4 * self.padding.x, 1), 1, EXPAND) self.GenWidthRestriction() def AddStretchSpacer(self, prop=1): self.content.AddStretchSpacer(prop) self.GenWidthRestriction() def InsertSpacer(self, pos): """ Inserts a spacer to separate the items at the pos """ if not self.overflowmode: self.content.Insert(pos, (4 * self.padding.x, 1), 1, EXPAND) self.GenWidthRestriction() def Remove(self, object, calcSize=True): """ untested removes specified object """ if object.menuitem: self.overflowmenu.RemoveItem(object.menuitem) try: self.overflowed.remove(object) except ValueError: pass self.content.Detach(object) self.children.remove(object) if calcSize: self.OnUBSize() def InsertNew(self, pos, thingy, id=-1, label='', **args): """ Inserts a new object so you don't have to create the object beforehand returns the id of new object """ object = thingy(self, id=id, label=label, **args) self.Insert(pos, object) return id def Insert(self, pos, object, expand=False, calcSize=True): 'Add object to certain position on the bar.' # Wrap UMenus in an UberButton if isinstance(object, UMenu): object = UberButton(self, -1, object.GetTitle(), self.buttonskin, type='menu', menu=object) # Prepare overflow values if this is in overflow mode elif self.overflowmode: if not isinstance(object, UberButton): raise TypeError( 'Can only add buttons or menus to an UberBar in overflow mode silly!' ) object.menuitem = None object.shouldshow = True object.Show = OverflowShow # updates skins of uberbuttons if isinstance(object, UberButton): object.SetSkinKey(self.buttonskin, True) if object.menu: object.menu.SetSkinKey(self.buttonskin) elif isinstance(object, FontDropDown): object.SetSkinKey(self.buttonskin) object.SetMenuSkinKey(self.menuskin) # adds the item to content sizer and child list then updates values self.content.Insert(pos, object, expand, LEFT | EXPAND, self.padding.x) self.children.insert(pos, object) if calcSize: self.OnUBSize() def OnBGPaint(self, event): 'Handles wx.EVT_ERASE_BACKGROUND.' dc = wx.AutoBufferedPaintDC(self) #wx.BufferedDC(wx.ClientDC(self)) if self.bg: rect = RectS(self.Size) self.bg.Draw(dc, rect) else: self.DrawNativeLike(dc, 0, 0, wx.RectS(self.Size)) self.ChildPaints(dc) # if self.native: # return event.Skip() def OnUBSize(self, event=None): "Does sizing when button changes it's size." self.GenWidthRestriction() def SetAlignment(self, alignment): """ Can change the alignment of the buttons in the bar, left or center... and maybe right? """ if self.alignment != alignment: self.alignment = alignment self.Sizer.Detach(self.content) self.Sizer.Add(self.content, 1 if alignment == ALIGN_LEFT else 0, self.alignment) self.Sizer.Layout() def OnReSize(self, event=None): 'Updates width restriction information on Resize of bar.' if event is not None: event.Skip() self.GenWidthRestriction() if self.Size.height != self.lastheight: self.lastheight = self.Size.height wx.CallAfter(self.Parent.Layout) def GenWidthRestriction(self, flushoverflow=False): """ When OverFlowMode is off this calculates the minimum size of the bar given the minimum size of the items In OverFlowMode it moves items in and out of the dropdown menu depending on bar size """ if not self.overflowmode: return children = [child for child in self.children if child.shouldshow] #all visible children staticchildren = self.staticchildren #all static overflowed = self.overflowed #all the children already overflowed omenu = self.overflowmenu #the menu, including overflowed items if flushoverflow: for thing in overflowed[:]: #Remove from menu if thing.menuitem: omenu.RemoveItem(thing.menuitem) thing.menuitem = None #show the button wxWindow_Show(thing, thing.shouldshow) #remove from overflow list and set overflowed flag to false overflowed.remove(thing) thing.overflowed = False #remove sizer if it's left as the first item while omenu.spine.items[0].id == -1: omenu.RemoveItem(0) self.Layout() if children: #g the rightmost, non-overflowed child i = len(children) - len(overflowed) - 1 laterchild = children[i] #find how much space there is for the children to show between the start of the bar and the dropdown button cutoffpoint = self.Size.width - ( sum(staticchild.Size.width for staticchild in staticchildren) + (len(staticchildren) + 1) * self.padding.x ) #staticchildren[0].Position.x - self.padding.x #while not all the children are overflowed and the rightmost child is over the cutoffpoint while len(children) > len(overflowed) and (laterchild.Rect.Right >= cutoffpoint): #if it's the first overflowed item and there are other items in the menu # add a separator if not len( overflowed ) and omenu.spine.items and not omenu.spine.items[0].id == -1: omenu.Insert(0, id=-1) #if this item is not overflowed yet, put it in the overflowed list overflowed.insert(0, laterchild) #add the now hidden item to the menu # let the button optionally have a different "overflowed" label and/or action than its usual ones menu_title = getattr(laterchild, 'overflow_label', laterchild.label) menu_cb = getattr(laterchild, 'overflow_callback', laterchild.SendButtonEvent) # add the icon, if it has one if laterchild.icon is not None: menu_title = [laterchild.icon, menu_title] laterchild.menuitem = SimpleMenuItem( menu_title, id=laterchild.Id, method=lambda i, mcb=menu_cb: mcb()) omenu.InsertItem(0, laterchild.menuitem) #hide the item wxWindow_Show(laterchild, False) #move to check next child left i = len(children) - len(overflowed) - 1 laterchild = children[i] #while there's enough room to fit the next overflowed item in the bar while overflowed and (cutoffpoint - (0 if len(overflowed) == len(children) else laterchild.Rect.Right) > overflowed[0].Size.width + self.padding.x): furtherchild = overflowed[0] if furtherchild.menuitem: #remove the menu item omenu.RemoveItem(furtherchild.menuitem) furtherchild.menuitem = None #show the button wxWindow_Show(furtherchild, True) #remove from overflow list overflowed.remove(furtherchild) #choose next laterchild i = len(children) - len(overflowed) - 1 laterchild = children[i] #remove sizer if it's left as the first item while omenu.spine.items[0].id == -1: omenu.RemoveItem(0) self.Layout() self.Top.Layout() def MarkFocus(self, item): "Set the menu's focus to said item." index = self.children.index(item) if self.focus is not None and self.focus != index: self.children[self.focus].ReleaseHover() self.focus = index def UpdateItemLabel(self, id, label): '''Updates the button or menu item for the given id with a new label.''' for item in (self.FindWindowById(id, self), self.overflowmenu.FindItemById(id)): if item is not None: item.SetLabel(label)
ReleaseCapture_win32 = windll.user32.ReleaseCapture def ClearMouseCapture(): if wxMSW: ReleaseCapture_win32() #=============================================================================== wxEVT_ENTER_WINDOW = 10032 wxEVT_LEAVE_WINDOW = 10033 MenuSkinDefaults = { 'framesize': lambda: Margins([0, 0, 0, 0]), 'frame': lambda: SkinColor(wx.BLACK), #@UndefinedVariable 'padding': lambda: wx.Point(2, 2), 'backgrounds.menu': lambda: SkinColor(wx.WHITE), #@UndefinedVariable 'backgrounds.item': lambda: None, 'backgrounds.selection': lambda: SkinColor(wx.BLACK), #@UndefinedVariable 'font': lambda: default_font(), 'fontcolors.normal': lambda: wx.BLACK, #@UndefinedVariable 'fontcolors.selection': lambda: wx.WHITE, #@UndefinedVariable 'separatorimage': lambda: None } class CustomMenuFrame(wx.PopupTransientWindow, NewSkinModule): def __init__(self, parent): wx.PopupTransientWindow.__init__(self, parent) self.SetPosition((-50000, -50000))
RBOTTOM = ALIGN_RIGHT | ALIGN_BOTTOM from gui.textutil import default_font from util.introspect import memoize from util.lrucache import lru_cache from util.primitives.error_handling import try_this from util.primitives.funcs import isiterable, do from util.primitives.mapping import Storage as S from time import time from logging import getLogger; log = getLogger('renderers'); info = log.info from common import pref, prefprop import hooks from gui import skin from gui.skin.skinobjects import SkinColor, Margins syscol = lambda s: SkinColor(SystemSettings_GetColour(s)) from PIL import Image from traceback import print_exc import sys replace_newlines = lru_cache(100)(strings.replace_newlines) def contact_online(contact): 'Whether to display a buddy as online or not in the buddylist.' return contact.online or contact.status == 'mobile' def get_contact_status(contact): if not contact_online(contact):
from gui.uberwidgets.UberButton import UberButton from gui.skin.skinobjects import Margins, SkinColor from gui.prototypes.fontdropdown import FontDropDown import wx from cgui import SimplePanel from util.primitives.funcs import do ToolBarSkinDefaults = { 'padding': lambda: wx.Point(2, 2), 'margins': lambda: Margins([2, 2, 2, 2]), 'background': lambda: SkinColor(wx.SystemSettings_GetColour(wx.SYS_COLOUR_3DFACE)), 'buttonskin': lambda: None, 'menuskin': lambda: None, } class ToolBar(SimplePanel, NewSkinModule): def __init__(self, parent, id=wx.ID_ANY, skinkey=None, name='ToolBar', alignment=None): SimplePanel.__init__(self, parent, wx.FULL_REPAINT_ON_RESIZE)
def makeBrush(brushdesc): ''' Makes a rectangular skin brush given strings like red red white blue vertical green white red rounded red rounded 10 blue shadow 0xffffee 0x123456 ''' if isinstance(brushdesc, list): return SkinStack(makeBrush(e) for e in brushdesc) elif isinstance(brushdesc, int): return SkinColor(colorfor(brushdesc)) elif brushdesc is None: return None elems = brushdesc.split() try: b = elems.index('border') except ValueError: border = None else: border = makeBorder(' '.join(elems[b:])) elems = elems[:b] first = elems[0] if any(first.endswith(e) for e in image_exts): return makeImage(brushdesc) shadow = highlight = rounded = False colors = [] direction = 'vertical' for i, elem in enumerate(elems): elem = elem.lower() if elem in ('h', 'v', 'horizontal', 'vertical'): direction = {'h': 'horizontal', 'v': 'vertical'}.get(elem, elem) elif elem == 'rounded': if len(elems) > i + 1 and isint(elems[i + 1]): rounded = float(elems[i + 1]) else: rounded = DEFAULT_ROUNDED_RADIUS elif elem == 'highlight': highlight = True elif elem == 'shadow': shadow = True elif elem.endswith('%') and isint(elem[:-1]) and colors: # replace the last wxColor in colors with the same color and # a new alpha value, so strings like "blue red 40%" produce # [wx.Colour(0, 0, 255, 255), wx.Colour(255, 0, 0, 102)] # # (I know there is a wxColour.Set method but it didn't work for me) alpha_value = clamp(float(elem[:-1]) / 100.00 * 255.0, 0, 255) rgba = tuple(colors[-1])[:3] + (alpha_value, ) colors[-1] = wx.Colour(*rgba) else: try: colors.append(colorfor(elem)) except ValueError: pass kwargs = dict(rounded=rounded, shadow=shadow, highlight=highlight, border=border) if len(colors) == 0: raise SkinException('no colors specified in "%s"' % brushdesc) elif len(colors) == 1: # one color -> SkinColor return SkinColor(colors[0], **kwargs) else: # multiple colors -> SkinGradient return SkinGradient(direction, colors, **kwargs)
class UberCombo(wx.Window, UberWidget): 'Skinnable Combobox' ForceTextFieldBackground = False def __init__( self, parent, value=None, typeable=False, selectioncallback=None, valuecallback=None, skinkey=None, size=wx.DefaultSize, pos=wx.DefaultPosition, maxmenuheight=None, minmenuwidth=None, editmethod=None, empty_text=None, # text to show in the display when it's not being edited empty_text_hide=True, ): """ value - String in the Box typeable - if true can type in the text field selectioncallback - method called when item is selected Valuecallback - this is called when the text value in the combo changes skinkey - the key string for the skin YAML size - size pos - position maxmenuheight - max size of the menu minmenuwidth - the width of the menu editmethod - trigered when the value is being edited """ wx.Window.__init__(self, parent, -1, pos, size) #Set Callbacks self.selectioncallback = selectioncallback self.valuecallback = valuecallback self._menuClick = False if size: self.Size = wx.Size(*size) self.content = wx.BoxSizer(wx.HORIZONTAL) self.SetSkinKey(skinkey, True) self.selection = None # Create the dropdown button self.dbutton = UberButton(self, -1, skin=self.ddbuttonskin, icon=self.dropdownicon, type='combo') self.dbutton.Bind(wx.EVT_LEFT_DOWN, self.OnDropdownLeftDown) self.dbutton.Bind(wx.EVT_LEFT_DCLICK, self.OnDropdownLeftDown) self.minmenuwidth = minmenuwidth # Create the menu for the combo self.menu = SimpleMenu( self, maxheight=maxmenuheight, width=minmenuwidth if minmenuwidth != None else self.Size.width, skinkey=self.menuskin, callback=lambda *a, **k: (setattr(self, '_menuClick', True), self.OnSelection(*a, **k))) # Create the display for the combobox disp = self.display = ComboDisplay( self, typeable=typeable, #size = (displaywidth,self.Size.height), empty_text=empty_text, empty_text_hide=empty_text_hide) disp.editmethod = editmethod self.content.Add(disp, 1, wx.EXPAND) self.content.Add(self.dbutton, 0, wx.EXPAND) self.Layout() Bind = self.Bind Bind(wx.EVT_PAINT, self.OnPaint) Bind(wx.EVT_SIZE, self.OnSize) Bind(wx.EVT_MENU_CLOSE, disp.OnMouseMove) Bind(EVT_UB_OVER, disp.OnMouseIntoButton) Bind(EVT_UB_OUT, disp.OnMouseOutOfButton) self.SetBackgroundStyle(wx.BG_STYLE_CUSTOM) if value: self.ChangeValue(value) self.Sizer = MarginSizer(self.framesize, self.content) def OnDropdownLeftDown(self, e): self.OpenMenu() DropDownButton = property(lambda self: self.dbutton) def Enable(self, val): # self.cbutton.Enable(val) self.dbutton.Enable(val) self.display.Enable(val) def SetCallbacks(self, selection=sentinel, value=sentinel): 'Sets callbacks for this combobox.' if selection is not sentinel: self.selectioncallback = selection if value is not sentinel: self.valuecallback = value def GetCount(self): 'Returns the number of choices in this combobox.' return self.menu.Count def GetIndex(self, item): return self.menu.GetItemIndex(item) Count = property(GetCount) def __contains__(self, item): return item in self.menu.spine.items def __getitem__(self, n): if not isinstance(n, int): raise TypeError return self.menu.spine.items[n] def __len__(self): return len(self.menu.spine.items) def Add(self, itemname, method=None): """Append a new item to the combo with an optional callback""" self.AppendItem(SimpleMenuItem(itemname, method=method)) def UpdateSkin(self): """ This updates the skin elements from the skin provided can be used to update skins if the window changes, change the skin, or revert to native mode if called with None or no arguments """ key = self.skinkey native = self.native = not key if native: self.padding = Point(2, 2) self.margins = Margins([0, 0, 0, 0]) self.framesize = Margins([0, 0, 0, 0]) bgc = wx.SystemSettings_GetColour(wx.SYS_COLOUR_LISTBOX) self.framebg = SkinColor(wx.BLACK) self.normalbg = SkinColor(bgc, border=wx.Pen(wx.BLACK, 1)) self.activebg = SkinColor(bgc, border=wx.Pen(wx.BLACK, 1)) self.hoverbg = SkinColor(bgc, border=wx.Pen(wx.BLACK, 1)) fc = wx.SystemSettings_GetColour(wx.SYS_COLOUR_WINDOWTEXT) self.normalfc = fc self.activefc = fc self.hoverfc = fc self.Font = default_font() self.menuskin = None self.ddbuttonskin = None self.dropdownicon = None else: s = lambda k, default: skin.get('%s.%s' % (key, k), default) self.padding = s('padding', Point(2, 2)) self.margins = s('margins', Margins([0, 0, 0, 0])) self.framesize = s('framesize', Margins([0, 0, 0, 0])) self.framebg = s('frame', lambda: SkinColor(wx.BLACK)) self.normalbg = s('backgrounds.normal', lambda: SkinColor(wx.WHITE)) self.activebg = s('backgrounds.active', lambda: SkinColor(wx.WHITE)) self.hoverbg = s('backgrounds.hover', lambda: SkinColor(wx.WHITE)) self.normalfc = s('fontcolors.normal', wx.BLACK) self.activefc = s('fontcolors.active', wx.BLACK) self.hoverfc = s('fontcolors.hover', wx.BLACK) self.hintfc = s('fontcolors.hint', lambda: wx.Colour(128, 128, 128)) self.Font = s('font', lambda: default_font) self.menuskin = s('menuskin', '') self.ddbuttonskin = s('dropdownbuttonskin', '') self.dropdownicon = s('dropdownbuttonicon', '') if getattr(self, 'dbutton', None): self.dbutton.SetSkinKey(self.ddbuttonskin) self.dbutton.SetIcon(self.dropdownicon) if getattr(self, 'menu', None): self.menu.SetSkinKey(self.menuskin) if self.Sizer: self.Sizer.SetMargins(self.framesize) def OnPaint(self, event): 'Standard painting stuff.' dc = AutoBufferedPaintDC(self) self.framebg.Draw(dc, RectS(self.Size)) def OnSize(self, event=None): 'Resize the subcomponenets to fit when the combo is resized' self.Layout() self._update_menu_width() def OpenMenu(self): 'Displays menu with correct width and combo as caller' self._update_menu_width() self.menu.Display(self, False) def _update_menu_width(self): widths = [self.Size.width] if self.minmenuwidth is not None: widths.append(self.minmenuwidth) self.menu.SetWidth(max(widths)) def InsertItem(self, index, item): """ Inserts an item the menu at the index """ self.menu.InsertItem(index, item) def AppendItem(self, item): """ Adds item to the end of the menu """ self.menu.AppendItem(item) def Insert(self, index, *a, **kws): """ Inserts a new item into the menu """ self.menu.Insert(index, *a, **kws) def Append(self, *a, **kws): """ Appends a new to the end of the menu """ self.menu.Append(*a, **kws) def AppendSeparator(self): """ Adds a separator to the end of the menu """ self.menu.AppendItem(SimpleMenuItem(id=-1)) def RemoveItem(self, item): """ Removes the givin item from the menu """ self.menu.RemoveItem(item) def RemoveAllItems(self): 'Remove all the items in this combo box.' self.menu.SetItems([]) def SetSelection(self, n): self.SetValue(self.menu.spine.items[n]) def SelectNextItem(self, cycle=False): i = self.GetItemIndex(self.Value) + 1 l = len(self) if i >= l: if cycle: i -= l else: return self.SetSelection(i) def SelectPrevItem(self, cycle=False): i = self.GetItemIndex(self.Value) - 1 if not cycle and i < 0: return self.SetSelection(i) def SetItems(self, menuitems, selectnow=None): self.menu.SetItems(menuitems) if selectnow != None and len(self): self.SetValue(self.menu.spine.items[selectnow]) def SetEditable(self, editable): self.display.Editable = editable def GetEditable(self): self.display.Editable Editable = property(GetEditable, SetEditable) def SetValue(self, value, default=None): """ Sets the value of the textfield to the value in typable mode expects a string otherwhys expects a ComboMenuItem """ assert threading.currentThread().getName() == 'MainThread' self.display.SetValue(value, default) def EditValue(self, newvalue=None): """ Show typing field and select all for replacement. with newvalue as the value of the field """ self.display.TypeField(newvalue) def ChangeValue(self, value, default=None): 'Changes the value of the textfield without firing an event.' self.display.ChangeValue(value, default) def GetValue(self): 'Grabs the value of the display.' return self.display.GetValue() Value = property(GetValue, SetValue) def GetItemIndex(self, item): """ Returns the index of the item """ return self.menu.spine.items.index(item) def GetItems(self): """ Returns a list of the SimpleMenuItems in the menu """ return self.menu.spine.items def GetSelection(self): 'Returns the curently selected item.' return self.selection Selection = property(GetSelection) def GetSelectionIndex(self): 'Returns index of selected items.' return self.menu.spine.items.index(self.selection) def OnSelection(self, item): """ Item selected 'event' calls the Selection Callback if availible then throws a EVT_COMBOBOX to parent """ if self.selection is item: return else: self.selection = item if isinstance(item, int): item = self.menu.spine.items[item] self.display.SetFocus() self.display.SelectAll() if self.selectioncallback: self.selectioncallback(item) else: self.display.SetValue(item) event = wx.CommandEvent(10020, self.GetId()) event.SetInt(try_this(lambda: self.menu.spine.items.index(item), -1)) self.Parent.AddPendingEvent(event) def GetItemBy(self, attr, value): """ Find an item by one of its attribute's values Returns first item or None if no matchin items were found attr - string naming the atribute value - the value you want the atribute of the item to be """ items = self.menu.spine.items for item in items: if value == getattr(item, attr, None): return item def GetStringsAndItems(self): """ Returns a list of string,item tuples a tuplefor each string in each item """ alist = [] items = self.menu.spine.items for item in items: for thing in item.content: if isinstance(thing, basestring): alist.append((thing, item)) return alist @property def TextField(self): return self.display.txtfld @property def defaultvalue(self): return self.display.defaultvalue
def UpdateSkin(self): """ This updates the skin elements from the skin provided can be used to update skins if the window changes, change the skin, or revert to native mode if called with None or no arguments """ key = self.skinkey native = self.native = not key if native: self.padding = Point(2, 2) self.margins = Margins([0, 0, 0, 0]) self.framesize = Margins([0, 0, 0, 0]) bgc = wx.SystemSettings_GetColour(wx.SYS_COLOUR_LISTBOX) self.framebg = SkinColor(wx.BLACK) self.normalbg = SkinColor(bgc, border=wx.Pen(wx.BLACK, 1)) self.activebg = SkinColor(bgc, border=wx.Pen(wx.BLACK, 1)) self.hoverbg = SkinColor(bgc, border=wx.Pen(wx.BLACK, 1)) fc = wx.SystemSettings_GetColour(wx.SYS_COLOUR_WINDOWTEXT) self.normalfc = fc self.activefc = fc self.hoverfc = fc self.Font = default_font() self.menuskin = None self.ddbuttonskin = None self.dropdownicon = None else: s = lambda k, default: skin.get('%s.%s' % (key, k), default) self.padding = s('padding', Point(2, 2)) self.margins = s('margins', Margins([0, 0, 0, 0])) self.framesize = s('framesize', Margins([0, 0, 0, 0])) self.framebg = s('frame', lambda: SkinColor(wx.BLACK)) self.normalbg = s('backgrounds.normal', lambda: SkinColor(wx.WHITE)) self.activebg = s('backgrounds.active', lambda: SkinColor(wx.WHITE)) self.hoverbg = s('backgrounds.hover', lambda: SkinColor(wx.WHITE)) self.normalfc = s('fontcolors.normal', wx.BLACK) self.activefc = s('fontcolors.active', wx.BLACK) self.hoverfc = s('fontcolors.hover', wx.BLACK) self.hintfc = s('fontcolors.hint', lambda: wx.Colour(128, 128, 128)) self.Font = s('font', lambda: default_font) self.menuskin = s('menuskin', '') self.ddbuttonskin = s('dropdownbuttonskin', '') self.dropdownicon = s('dropdownbuttonicon', '') if getattr(self, 'dbutton', None): self.dbutton.SetSkinKey(self.ddbuttonskin) self.dbutton.SetIcon(self.dropdownicon) if getattr(self, 'menu', None): self.menu.SetSkinKey(self.menuskin) if self.Sizer: self.Sizer.SetMargins(self.framesize)
def UpdateSkin(self): key = self.skinkey self.native = native = not key if native: self.OpenNativeTheme() self.padding = wx.Point(2, 2) self.framesize = Margins([1, 1, 1, 1]) #[0,0,0,0] if uxthemed else sz = self.Parent.Sizer if sz: sz.Detach(1) sz.Detach(1) sz.Add(wx.Size(self.framesize.left, self.framesize.top), (0, 0)) sz.Add(wx.Size(self.framesize.right, self.framesize.bottom), (2, 2)) self.framebg = None self.menubg = None self.itembg = None self.selbg = None self.Font = default_font() self.normalfc = wx.SystemSettings_GetColour( wx.SYS_COLOUR_WINDOWTEXT) self.selfc = wx.SystemSettings_GetColour( wx.SYS_COLOUR_HIGHLIGHTTEXT) self.MakeNativeSubmenuIcons() self.separator = None else: self.CloseNativeTheme() s = lambda k, default: skin.get('%s.%s' % (key, k), default) self.padding = s('padding', wx.Point(2, 2)) self.framesize = s('framesize', Margins([0, 0, 0, 0])) sz = self.Parent.Sizer if sz: sz.Detach(1) sz.Detach(1) sz.Add(wx.Size(self.framesize.left, self.framesize.top), (0, 0)) sz.Add(wx.Size(self.framesize.right, self.framesize.bottom), (2, 2)) self.framebg = s('frame', lambda: SkinColor(wx.BLACK)) self.menubg = s('backgrounds.menu', None) self.itembg = s('backgrounds.item', None) self.selbg = s('backgrounds.selection', None) self.Font = s('font', default_font()) self.normalfc = s('fontcolors.normal', lambda: wx.BLACK) self.selfc = s('fontcolors.selection', lambda: wx.BLACK) #TODO: Default? submenuicon = self.submenuicon = s('submenuicon', None) if submenuicon is None: self.MakeNativeSubmenuIcons() else: self.submenuiconhot = s('submenuiconhover', submenuicon) #TODO: Default? self.separator = s('separatorimage', None) for item in self.items: if item.menu: item.menu.spine.SetSkinKey(key)