⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 splitter.py

📁 Wxpython Implemented on Windows CE, Source code
💻 PY
📖 第 1 页 / 共 2 页
字号:
                # draw a new tracker
                self._pendingPos = (newPos1, newPos2)
                self._DrawSashTracker(self._oldX, self._oldY)
            else:
                self._DoSetSashPosition(self._activeSash, newPos1, newPos2, adjustNeighbor)
                self._needUpdating = True


    # -------------------------------------
    # Internal helpers
    
    def _RedrawIfHotSensitive(self, isHot):
        if not wx.VERSION >= _RENDER_VER:
            return
        if wx.RendererNative.Get().GetSplitterParams(self).isHotSensitive:
            self._isHot = isHot
            dc = wx.ClientDC(self)
            self._DrawSash(dc)


    def _OnEnterSash(self):
        self._SetResizeCursor()
        self._RedrawIfHotSensitive(True)


    def _OnLeaveSash(self):
        self.SetCursor(wx.STANDARD_CURSOR)
        self._RedrawIfHotSensitive(False)


    def _SetResizeCursor(self):
        if self._orient == wx.HORIZONTAL:
            self.SetCursor(self._sashCursorWE)
        else:
            self.SetCursor(self._sashCursorNS)


    def _OnSashPositionChanging(self, idx, newPos1, newPos2, adjustNeighbor):
        # TODO: check for possibility of unsplit (pane size becomes zero)

        # make sure that minsizes are honored
        newPos1, newPos2 = self._AdjustSashPosition(idx, newPos1, newPos2, adjustNeighbor)

        # sanity check
        if newPos1 <= 0:
            newPos2 += newPos1
            newPos1 = 0 

        # send the events
        evt = MultiSplitterEvent(
            wx.wxEVT_COMMAND_SPLITTER_SASH_POS_CHANGING, self)
        evt.SetSashIdx(idx)
        evt.SetSashPosition(newPos1)
        if not self._DoSendEvent(evt):
            # the event handler vetoed the change
            newPos1 = -1
        else:
            # or it might have changed the value
            newPos1 = evt.GetSashPosition()

        if adjustNeighbor and newPos1 != -1:
            evt.SetSashIdx(idx+1)
            evt.SetSashPosition(newPos2)
            if not self._DoSendEvent(evt):
                # the event handler vetoed the change
                newPos2 = -1
            else:
                # or it might have changed the value
                newPos2 = evt.GetSashPosition()
            if newPos2 == -1:
                newPos1 = -1

        return (newPos1, newPos2)


    def _AdjustSashPosition(self, idx, newPos1, newPos2=-1, adjustNeighbor=False):
        total = newPos1 + newPos2

        # these are the windows on either side of the sash
        win1 = self._windows[idx]
        win2 = self._windows[idx+1]

        # make adjustments for window min sizes
        minSize = self._GetWindowMin(win1)
        if minSize == -1 or self._minimumPaneSize > minSize:
            minSize = self._minimumPaneSize
        minSize += self._GetBorderSize()
        if newPos1 < minSize:
            newPos1 = minSize
            newPos2 = total - newPos1

        if adjustNeighbor:
            minSize = self._GetWindowMin(win2)
            if minSize == -1 or self._minimumPaneSize > minSize:
                minSize = self._minimumPaneSize
            minSize += self._GetBorderSize()
            if newPos2 < minSize:
                newPos2 = minSize
                newPos1 = total - newPos2
        
        return (newPos1, newPos2)


    def _DoSetSashPosition(self, idx, newPos1, newPos2=-1, adjustNeighbor=False):
        newPos1, newPos2 = self._AdjustSashPosition(idx, newPos1, newPos2, adjustNeighbor)
        if newPos1 == self._sashes[idx]:
            return False
        self._sashes[idx] = newPos1
        if adjustNeighbor:
            self._sashes[idx+1] = newPos2
        return True
        

    def _SetSashPositionAndNotify(self, idx, newPos1, newPos2=-1, adjustNeighbor=False):
        # TODO:  what is the thing about _requestedSashPosition for?

        self._DoSetSashPosition(idx, newPos1, newPos2, adjustNeighbor)

        evt = MultiSplitterEvent(
            wx.wxEVT_COMMAND_SPLITTER_SASH_POS_CHANGED, self)
        evt.SetSashIdx(idx)
        evt.SetSashPosition(newPos1)
        self._DoSendEvent(evt)

        if adjustNeighbor:
            evt.SetSashIdx(idx+1)
            evt.SetSashPosition(newPos2)
            self._DoSendEvent(evt)


    def _GetMotionDiff(self, x, y):
        # find the diff from the old pos
        if self._orient == wx.HORIZONTAL:
            diff = x - self._oldX
        else:
            diff = y - self._oldY
        return diff


    def _SashToCoord(self, idx, sashPos):
        coord = 0
        for i in range(idx):
            coord += self._sashes[i]
            coord += self._GetSashSize()
        coord += sashPos
        return coord


    def _GetWindowMin(self, window):
        if self._orient == wx.HORIZONTAL:
            return window.GetMinWidth()
        else:
            return window.GetMinHeight()
        
            
    def _GetSashSize(self):
        if self.HasFlag(wx.SP_NOSASH):
            return 0
        if wx.VERSION >= _RENDER_VER:
            return wx.RendererNative.Get().GetSplitterParams(self).widthSash
        else:
            return 5


    def _GetBorderSize(self):
        if wx.VERSION >= _RENDER_VER:
            return wx.RendererNative.Get().GetSplitterParams(self).border
        else:
            return 0
        

    def _DrawSash(self, dc):
        if wx.VERSION >= _RENDER_VER:
            if self.HasFlag(wx.SP_3DBORDER):
                wx.RendererNative.Get().DrawSplitterBorder(
                    self, dc, self.GetClientRect())

        # if there are no splits then we're done.
        if len(self._windows) < 2:
            return

        # if we are not supposed to use a sash then we're done.
        if self.HasFlag(wx.SP_NOSASH):
            return

        # Reverse the sense of the orientation, in this case it refers
        # to the direction to draw the sash not the direction that
        # windows are stacked.
        orient = { wx.HORIZONTAL : wx.VERTICAL,
                   wx.VERTICAL : wx.HORIZONTAL }[self._orient]

        flag = 0
        if self._isHot:
            flag = wx.CONTROL_CURRENT

        pos = 0
        for sash in self._sashes[:-1]:
            pos += sash
            if wx.VERSION >= _RENDER_VER:
                wx.RendererNative.Get().DrawSplitterSash(self, dc,
                                                         self.GetClientSize(),
                                                         pos, orient, flag)
            else:
                dc.SetPen(wx.TRANSPARENT_PEN)
                dc.SetBrush(wx.Brush(self.GetBackgroundColour()))
                sashsize = self._GetSashSize()
                if orient == wx.VERTICAL:
                    x = pos
                    y = 0
                    w = sashsize
                    h = self.GetClientSize().height
                else:
                    x = 0
                    y = pos
                    w = self.GetClientSize().width
                    h = sashsize
                dc.DrawRectangle(x, y, w, h)

            pos += self._GetSashSize()


    def _DrawSashTracker(self, x, y):
        # Draw a line to represent the dragging sash, for when not
        # doing live updates
        w, h = self.GetClientSize()
        dc = wx.ScreenDC()

        if self._orient == wx.HORIZONTAL:
            x1 = x
            y1 = 2
            x2 = x
            y2 = h-2
            if x1 > w:
                x1 = w
                x2 = w
            elif x1 < 0:
                x1 = 0
                x2 = 0
        else:
            x1 = 2
            y1 = y
            x2 = w-2
            y2 = y
            if y1 > h:
                y1 = h
                y2 = h
            elif y1 < 0:
                y1 = 0
                y2 = 0

        x1, y1 = self.ClientToScreenXY(x1, y1)
        x2, y2 = self.ClientToScreenXY(x2, y2)
     
        dc.SetLogicalFunction(wx.INVERT)
        dc.SetPen(self._sashTrackerPen)
        dc.SetBrush(wx.TRANSPARENT_BRUSH)
        dc.DrawLine(x1, y1, x2, y2)
        dc.SetLogicalFunction(wx.COPY)
        

    def _SashHitTest(self, x, y, tolerance=5):
        # if there are no splits then we're done.
        if len(self._windows) < 2:
            return -1

        if self._orient == wx.HORIZONTAL:
            z = x
        else:
            z = y

        pos = 0
        for idx, sash in enumerate(self._sashes[:-1]):
            pos += sash
            hitMin = pos - tolerance
            hitMax = pos + self._GetSashSize() + tolerance
            
            if z >= hitMin and z <= hitMax:
                return idx
            
            pos += self._GetSashSize() 

        return -1


    def _SizeWindows(self):
        # no windows yet?
        if not self._windows:
            return

        # are there any pending size settings?
        for window, spos in self._pending.items():
            idx = self._windows.index(window)
            # TODO: this may need adjusted to make sure they all fit
            # in the current client size
            self._sashes[idx] = spos
            del self._pending[window]

        # are there any that still have a -1?
        for idx, spos in enumerate(self._sashes[:-1]):
            if spos == -1:
                # TODO: this should also be adjusted
                self._sashes[idx] = 100
        
        cw, ch = self.GetClientSize()
        border = self._GetBorderSize()
        sash   = self._GetSashSize()
        
        if len(self._windows) == 1:
            # there's only one, it's an easy layout
            self._windows[0].SetDimensions(border, border,
                                           cw - 2*border, ch - 2*border)
        else:
            if 'wxMSW' in wx.PlatformInfo:
                self.Freeze()
            if self._orient == wx.HORIZONTAL:
                x = y = border
                h = ch - 2*border
                for idx, spos in enumerate(self._sashes[:-1]):
                    self._windows[idx].SetDimensions(x, y, spos, h)
                    x += spos + sash
                # last one takes the rest of the space. TODO make this configurable
                last = cw - 2*border - x
                self._windows[idx+1].SetDimensions(x, y, last, h)
                if last > 0:
                    self._sashes[idx+1] = last
            else:
                x = y = border
                w = cw - 2*border
                for idx, spos in enumerate(self._sashes[:-1]):
                    self._windows[idx].SetDimensions(x, y, w, spos)
                    y += spos + sash
                # last one takes the rest of the space. TODO make this configurable
                last = ch - 2*border - y
                self._windows[idx+1].SetDimensions(x, y, w, last)
                if last > 0:
                    self._sashes[idx+1] = last
            if 'wxMSW' in wx.PlatformInfo:
                self.Thaw()
                
        self._DrawSash(wx.ClientDC(self))
        self._needUpdating = False


    def _DoSendEvent(self, evt):
        return not self.GetEventHandler().ProcessEvent(evt) or evt.IsAllowed()
    
#----------------------------------------------------------------------

class MultiSplitterEvent(wx.PyCommandEvent):
    """
    This event class is almost the same as `wx.SplitterEvent` except
    it adds an accessor for the sash index that is being changed.  The
    same event type IDs and event binders are used as with
    `wx.SplitterEvent`.
    """
    def __init__(self, type=wx.wxEVT_NULL, splitter=None):
        wx.PyCommandEvent.__init__(self, type)
        if splitter:
            self.SetEventObject(splitter)
            self.SetId(splitter.GetId())
        self.sashIdx = -1
        self.sashPos = -1
        self.isAllowed = True

    def SetSashIdx(self, idx):
        self.sashIdx = idx

    def SetSashPosition(self, pos):
        self.sashPos = pos

    def GetSashIdx(self):
        return self.sashIdx

    def GetSashPosition(self):
        return self.sashPos

    # methods from wx.NotifyEvent
    def Veto(self):
        self.isAllowed = False
    def Allow(self):
        self.isAllowed = True
    def IsAllowed(self):
        return self.isAllowed
        


#----------------------------------------------------------------------



⌨️ 快捷键说明

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