customwidgets.py

来自「bittorrent source by python. please enj」· Python 代码 · 共 519 行 · 第 1/2 页

PY
519
字号
# The contents of this file are subject to the BitTorrent Open Source License# Version 1.1 (the License).  You may not copy or use this file, in either# source code or executable form, except in compliance with the License.  You# may obtain a copy of the License at http://www.bittorrent.com/license/.## Software distributed under the License is distributed on an AS IS basis,# WITHOUT WARRANTY OF ANY KIND, either express or implied.  See the License# for the specific language governing rights and limitations under the# License.# Written by Greg Hazel, ModerateDownloadGauge written by Matt Chisholmimport osfrom BitTorrent.translation import _import wxfrom BitTorrent.platform import bttimefrom BitTorrent.DictWithLists import DictWithListsfrom BitTorrent.obsoletepythonsupport import setfrom BitTorrent.sparse_set import SparseSetif os.name == 'nt':    import win32gui    import win32condef _ScaleBlit(bmp, dc, dst_rect):    sX = float(dst_rect.width) / float(bmp.GetWidth())    sY = float(dst_rect.height) / float(bmp.GetHeight())    dc.SetUserScale(sX, sY)    old_mode = None    if os.name == 'nt':        h_dst = dc.GetHDC()        try:            old_mode = win32gui.SetStretchBltMode(h_dst, win32con.HALFTONE)        except:            pass    if sX == 0:        w = 0    else:        w = dst_rect.x/sX    if sY == 0:        h = 0    else:        h = dst_rect.y/sY                dc.DrawBitmap(bmp, w, h, True)    if os.name == 'nt':        try:            win32gui.SetStretchBltMode(h_dst, old_mode)        except:            pass    dc.SetUserScale(1, 1)class DoubleBufferedMixin(object):    def __init__(self):        self.bind_events()        self.buffer_size = wx.Size(-1, -1)        self.last_size = self._calc_size()        self.init_buffer()    def _calc_size(self):        return self.GetClientSize()    def init_buffer(self):        size = self._calc_size()        if ((self.buffer_size.width < size.width) or            (self.buffer_size.height < size.height)):            self.buffer = wx.EmptyBitmap(size.width, size.height)            dc = wx.MemoryDC()            dc.SelectObject(self.buffer)            dc.SetBackground(wx.Brush(self.GetBackgroundColour()))            dc.Clear()            dc.SelectObject(wx.NullBitmap)            self.buffer_size = size            return True        return False    def bind_events(self):        self.Bind(wx.EVT_ERASE_BACKGROUND, lambda e : None)        self.Bind(wx.EVT_SIZE, self.OnSize)        self.Bind(wx.EVT_PAINT, self.OnPaint)    def redraw(self):        dc = wx.MemoryDC()        dc.SelectObject(self.buffer)        size = self._calc_size()        self.last_size = size        self.draw(dc, size=size)        dc.SelectObject(wx.NullBitmap)        self.Refresh()    def OnSize(self, event):        reallocated = self.init_buffer()        if reallocated or self.last_size != self._calc_size():            self.redraw()        else:            self.Refresh()    def OnPaint(self, event):        dc = wx.BufferedPaintDC(self, self.buffer)class ScaledBufferMixin(DoubleBufferedMixin):    def __init__(self, w_step=200, h_step=15):        self.w_step = w_step        self.h_step = h_step        # don't go crazy        self.w_max = 1000        self.h_max = 1000        DoubleBufferedMixin.__init__(self)    def _round(self, d, step):        return max(int(d / step), 1) * step    def _calc_size(self):        size = self.GetClientSize()        # * 2 for the high quality        w = self._round(size.width*2, self.w_step)        h = self._round(size.height, self.h_step)        w = max(w, self.buffer_size.width)        w = min(w, self.w_max)        h = max(h, self.buffer_size.height)        h = min(h, self.h_max)        return wx.Size(w, h)    def OnPaint(self, event):        dc = wx.PaintDC(self)        _ScaleBlit(self.buffer, dc, self.GetClientRect(), strip_border=1)class ListCtrlPassThrough(object):    def __init__(self, listctrl):        # I'll be nice and ignore you.        if not isinstance(listctrl, wx.ListCtrl):            return        self.listctrl = listctrl        self.Bind(wx.EVT_LEFT_DOWN, self.LeftDown)        self.Bind(wx.EVT_LEFT_DCLICK, self.LeftDClick)        self.Bind(wx.EVT_CONTEXT_MENU, self.ContextMenu)    def _resolve_position(self):        p = self.GetPosition()        p -= self.listctrl._get_origin_offset()        return p    def _resolve_index(self):        p = self._resolve_position()        try:            i, flags = self.listctrl.HitTest(p)        except TypeError:            # unpack non-sequence            return        return i    def ContextMenu(self, event):        self.listctrl.DoPopup(self._resolve_position())    def LeftDClick(self, event):        i = self._resolve_index()        if i is None:            return        e = wx.ListEvent(wx.wxEVT_COMMAND_LIST_ITEM_ACTIVATED)        e.m_itemIndex = i        self.listctrl.ProcessEvent(e)    def LeftDown(self, event):        i = self._resolve_index()        if i is None:            return        if not event.ControlDown():            if event.ShiftDown():                if '__WXMSW__' in wx.PlatformInfo:                    self.listctrl.DeselectAll()                f = self.listctrl.GetFocusedItem()                if f > -1:                    for j in xrange(min(i,f), max(i,f)):                        self.listctrl.Select(j)                    self.listctrl.Select(f)            else:                self.listctrl.DeselectAll()        self.listctrl.Select(i)        self.listctrl.SetFocus()        self.listctrl.Focus(i)class NullGauge(object):    def NullMethod(*a):        pass    __init__ = NullMethod    def __getattr__(self, attr):        return self.NullMethodclass SimpleDownloadGauge(ListCtrlPassThrough, ScaledBufferMixin, wx.Window):    def __init__(self, parent,                 completed_color=None,                 remaining_color=None,                 border_color=None,                 border=True,                 size=(0,0),                 top_line=True,                 **k):        original = {            "smooth": True,            "border color": wx.NamedColour("light gray"),            "completed color": wx.Colour(0, 230, 50),            "line color"     : wx.Colour(0, 178, 39),            "remaining color": wx.NamedColour("white"),            "transferring color": wx.NamedColour("yellow"),            "missing color": wx.NamedColour("red"),            "rare colors": [wx.Colour(235, 235, 255),                            wx.Colour(215, 215, 255),                            wx.Colour(195, 195, 255),                            wx.Colour(175, 175, 255),                            wx.Colour(155, 155, 255),                            wx.Colour(135, 135, 255),                            wx.Colour(115, 115, 255),                            wx.Colour(95, 95, 255),                            wx.Colour(75, 75, 255),                            wx.Colour(55, 55, 255),                            wx.Colour(50, 50, 255)]            }        new_green = {            "smooth": True,            "border color": wx.Colour(111, 111, 111),            "completed color": wx.Colour(14, 183, 19),            "line color"     : wx.Colour(255, 255, 0),            "remaining color": wx.NamedColour("white"),            "transferring color": wx.Colour(94, 243, 99),            "missing color": wx.Colour(255, 0, 0),            "rare colors": [wx.Colour(185, 185, 185),                            wx.Colour(195, 195, 195),                            wx.Colour(205, 205, 205),                            wx.Colour(215, 215, 215),                            wx.Colour(225, 225, 225),                            wx.Colour(235, 235, 235),                            wx.Colour(245, 245, 245),                            wx.Colour(255, 255, 255)]            }        new_blue = {            "smooth": True,            "border color": wx.NamedColour("light gray"),            "completed color": wx.NamedColour("blue"),

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?