import wx import gui.utils.colorUtils as colorUtils import gui.utils.drawUtils as drawUtils SB_ITEM_NORMAL = 0 SB_ITEM_SELECTED = 1 SB_ITEM_HIGHLIGHTED = 2 SB_ITEM_DISABLED = 4 BTN_NORMAL = 1 BTN_PRESSED = 2 BTN_HOVER = 4 BTN_DISABLED = 8 class PFBaseButton(object): def __init__(self, normalBitmap = wx.NullBitmap,label = "", callback = None, hoverBitmap = None, disabledBitmap = None, show = True): self.normalBmp = normalBitmap self.dropShadowOpacity = 0.2 self.dropShadowBmp = drawUtils.CreateDropShadowBitmap(self.normalBmp, self.dropShadowOpacity) self.hoverBmp = hoverBitmap self.disabledBmp = disabledBitmap self.label = label self.show = show self.callback = callback self.state = BTN_NORMAL # state : BTN_STUFF def Show(self, show): self.show = show def Hide(self): self.show = False def IsVisible(self): return self.show def SetCallback(self, callback): self.callback = callback def GetCallback(self): return self.callback def DoCallback(self): if self.callback: self.callback() def SetState(self, state = BTN_NORMAL): self.state = state def GetState(self): return self.state def GetSize(self): w = self.normalBmp.GetWidth() h = self.normalBmp.GetHeight() return (w,h) def GetBitmap(self): return self.normalBmp def SetBitmap(self, bitmap): self.normalBmp = bitmap self.dropShadowBmp = drawUtils.CreateDropShadowBitmap(self.normalBmp, self.dropShadowOpacity) def GetLabel(self): return self.label def GetHoverBitmap(self): if self.hoverBmp == None: return self.normalBmp return self.hoverBmp def GetDisabledBitmap(self): if self.disabledBmp == None: return self.normalBmp return self.disabledBmp def GetDropShadowBitmap(self): return self.dropShadowBmp class PFToolbar(object): def __init__(self, parent): self.Parent = parent self.buttons =[] self.toolbarX = 0 self.toolbarY = 0 self.padding = 2 self.hoverLabel = "" def SetPosition(self, pos): self.toolbarX, self.toolbarY = pos def AddButton(self, btnBitmap, label = "", clickCallback = None, hoverBitmap = None, disabledBitmap = None, show = True): btn = PFBaseButton(btnBitmap, label, clickCallback, hoverBitmap, disabledBitmap, show) self.buttons.append(btn) return btn def ClearState(self): for button in self.buttons: button.SetState() self.hoverLabel = "" def MouseMove(self, event): doRefresh = False changeCursor = False bx = self.toolbarX self.hoverLabel = "" for button in self.buttons: if not button.IsVisible(): continue state = button.GetState() if self.HitTest( (bx, self.toolbarY), event.GetPosition(), button.GetSize()): changeCursor = True if not state & BTN_HOVER: button.SetState(state | BTN_HOVER) self.hoverLabel = button.GetLabel() self.Parent.SetCursor(wx.StockCursor(wx.CURSOR_HAND)) doRefresh = True else: if state & BTN_HOVER: button.SetState(state ^ BTN_HOVER) doRefresh = True bwidth, bheight = button.GetSize() bx += bwidth + self.padding if not changeCursor: self.Parent.SetCursor(wx.StockCursor(wx.CURSOR_ARROW)) return doRefresh def MouseClick(self, event): mx,my = event.GetPosition() bx = self.toolbarX for button in self.buttons: if not button.IsVisible(): continue state = button.GetState() if state & BTN_PRESSED: button.SetState(state ^ BTN_PRESSED ) if self.HitTest( (bx, self.toolbarY), event.GetPosition(), button.GetSize()): return button else: return False bwidth, bheight = button.GetSize() bx += bwidth + self.padding bx = self.toolbarX for button in self.buttons: if not button.IsVisible(): continue state = button.GetState() if self.HitTest( (bx, self.toolbarY), event.GetPosition(), button.GetSize()): if event.LeftDown() or event.LeftDClick(): button.SetState(state | BTN_PRESSED) return button elif event.LeftUp(): button.SetState(state | (not BTN_PRESSED)) return button bwidth, bheight = button.GetSize() bx += bwidth + self.padding return None def GetWidth(self): bx = 0 for button in self.buttons: if not button.IsVisible(): continue bwidth, bheight = button.GetSize() bx += bwidth + self.padding return bx def GetHeight(self): height = 0 for button in self.buttons: if not button.IsVisible(): continue bwidth, bheight = button.GetSize() height = max(height, bheight) return height def HitTest(self, target, position, area): x, y = target px, py = position aX, aY = area if (px > x and px < x + aX) and (py > y and py < y + aY): return True return False def Render(self, pdc): bx = self.toolbarX for button in self.buttons: if not button.IsVisible(): continue by = self.toolbarY tbx = bx btnState = button.GetState() bmp = button.GetDisabledBitmap() dropShadowBmp = button.GetDropShadowBitmap() if btnState & BTN_NORMAL: bmp = button.GetBitmap() if btnState & BTN_HOVER: bmp = button.GetHoverBitmap() if btnState & BTN_PRESSED: bmp = button.GetBitmap() by += self.padding / 2 tbx += self.padding / 2 bmpWidth = bmp.GetWidth() pdc.DrawBitmap(dropShadowBmp,bx + self.padding / 2, self.toolbarY + self.padding / 2) pdc.DrawBitmap(bmp, tbx, by) bx += bmpWidth + self.padding class SFBrowserItem(wx.Window): def __init__(self, parent, id = wx.ID_ANY, pos = wx.DefaultPosition, size = (0,16), style = 0): wx.Window.__init__(self, parent, id, pos, size, style) self.highlighted = False self.selected = False self.bkBitmap = None self.canBeDragged = False self.toolbar = PFToolbar(self) self.Bind(wx.EVT_PAINT, self.OnPaint) self.Bind(wx.EVT_ERASE_BACKGROUND, self.OnEraseBackground) self.Bind(wx.EVT_LEFT_UP, self.OnLeftUp) if "wxMSW" in wx.PlatformInfo: self.Bind(wx.EVT_LEFT_DCLICK, self.OnLeftDown) self.Bind(wx.EVT_LEFT_DOWN,self.OnLeftDown) self.Bind(wx.EVT_ENTER_WINDOW, self.OnEnterWindow) self.Bind(wx.EVT_LEAVE_WINDOW, self.OnLeaveWindow) self.Bind(wx.EVT_MOTION, self.OnMotion) def Refresh(self): self.RenderBackground() wx.Window.Refresh(self) def OnPaint(self, event): mdc = wx.BufferedPaintDC(self) self.RenderBackground() mdc.DrawBitmap(self.bkBitmap, 0,0) self.DrawItem(mdc) self.toolbar.Render(mdc) def DrawItem(self, mdc): pass def OnEraseBackground(self, event): pass def MouseLeftUp(self, event): pass def MouseLeftDown(self, event): pass def MouseMove(self, event): pass def SetDraggable(self, mode = True): self.canBeDragged = mode def OnLeftUp(self, event): if self.HasCapture(): self.ReleaseMouse() if not self.canBeDragged: mposx, mposy = wx.GetMousePosition() rect = self.GetRect() rect.top = rect.left = 0 cx,cy = self.ScreenToClient((mposx,mposy)) if not rect.Contains((cx,cy)): self.SetHighlighted(False) self.toolbar.ClearState() self.Refresh() return btn = self.toolbar.MouseClick(event) if btn is not None: if btn is not False: if btn.GetState() & BTN_NORMAL: btn.DoCallback() self.Refresh() else: self.Refresh() return self.MouseLeftUp(event) def OnLeftDown(self, event): self.CaptureMouse() btn = self.toolbar.MouseClick(event) if btn is not None: if btn.GetState() & BTN_PRESSED: self.Refresh() return self.MouseLeftDown(event) def OnEnterWindow(self, event): self.SetHighlighted(True) self.toolbar.ClearState() self.Refresh() event.Skip() def OnLeaveWindow(self, event): self.SetHighlighted(False) self.toolbar.ClearState() self.Refresh() event.Skip() def OnMotion(self, event): if self.toolbar.MouseMove(event): self.Refresh() self.MouseMove(event) event.Skip() def GetType(self): return -1 def SetSelected(self, select = True): self.selected = select def SetHighlighted(self, highlight = True): self.highlighted = highlight def GetState(self): if self.highlighted and not self.selected: state = SB_ITEM_HIGHLIGHTED elif self.selected: if self.highlighted: state = SB_ITEM_SELECTED | SB_ITEM_HIGHLIGHTED else: state = SB_ITEM_SELECTED else: state = SB_ITEM_NORMAL return state def RenderBackground(self): rect = self.GetRect() windowColor = wx.SystemSettings_GetColour(wx.SYS_COLOUR_WINDOW) state = self.GetState() sFactor = 0.2 mFactor = None eFactor = 0 if state == SB_ITEM_HIGHLIGHTED: mFactor = 0.45 eFactor = 0.30 elif state == SB_ITEM_SELECTED | SB_ITEM_HIGHLIGHTED: eFactor = 0.3 elif state == SB_ITEM_SELECTED: eFactor = 0.15 else: sFactor = 0.0 if self.bkBitmap: if self.bkBitmap.eFactor == eFactor and self.bkBitmap.sFactor == sFactor and self.bkBitmap.mFactor == mFactor \ and rect.width == self.bkBitmap.GetWidth() and rect.height == self.bkBitmap.GetHeight() : return else: del self.bkBitmap self.bkBitmap = drawUtils.RenderGradientBar(windowColor, rect.width, rect.height, sFactor, eFactor, mFactor) self.bkBitmap.state = state self.bkBitmap.sFactor = sFactor self.bkBitmap.eFactor = eFactor self.bkBitmap.mFactor = mFactor