def tsAssign(self, event):
        """
        Derived from: wxPython-src-2.8.10.1\src\common\event.cpp
        """
        self.ts_MouseEventType = event.ts_EventType

        self.ts_X = event.m_x
        self.ts_Y = event.m_y

        self.ts_LeftDown = event.m_leftDown
        self.ts_MiddleDown = event.m_middleDown
        self.ts_RightDown = event.m_rightDown

        self.ts_ControlDown = event.m_controlDown
        self.ts_ShiftDown = event.m_shiftDown
        self.ts_AltDown = event.m_altDown
        self.ts_MetaDown = event.m_metaDown

        self.ts_WheelRotation = event.m_wheelRotation
        self.ts_WheelDelta = event.m_wheelDelta
        self.ts_LinesPerAction = event.m_linesPerAction

        self.ts_ChangeXY = wxPoint(self.ts_X, self.ts_Y) - self.ts_LastXY

        self.ts_LastXY = wxPoint(self.ts_X, self.ts_Y)
    def tsGetStdioPositionAndSize(self):
        '''
        Return position and size of window used for redirected output.
        '''
        if not self.ts_PyOnDemandStdioWindow:
 
            # Establish defaults until attributes finalized
            theRedirectedPos = wxPoint(-1, -1)
            theRedirectedSize = wxSize(450, 300)

        else:

            try:
                self.Display = wxDisplay(self)
                theClientArea = self.Display.theRedirectedStdioArea

                theRedirectedSize = wxSize(theClientArea.width,
                                           theClientArea.height)

                theRedirectedPos = wxPoint(
                    theClientArea.x,
                    theClientArea.y)
            except Exception, getError:
                theRedirectedPos = wxPoint(-1, -1)
                theRedirectedSize = wxSize(450, 300)
                self.logger.debug(
                    '  GetStdioPositionAndSize Exception. %s' % getError)
                msg = 'GetStdioPositionAndSize Exception: %s' % str(getError)
                raise tse.ProgramException(tse.APPLICATION_TRAP, msg)
    def GetPosition(self):
        '''
        Returns the current position of the item, as set in the last Layout.

        Modeled after GetPosition in sizer.h file of wxWidgets.
        '''
        return (wxPoint(self.ts_Rect.x, self.ts_Rect.y))
    def SetItemBounds(self, item, x, y, w, h):
        '''

        Modeled after TBD in sizer.cpp file of wxWidgets.
        '''
        pt = wxPoint(x, y)
        sz = wxSize(item.GetMinSizeWithBorder())
        flag = int(item.GetFlag())

        if flag & wx.EXPAND or \
           flag & wx.SHAPED:
 
            sz = wxSize(w, h)
 
        else:
 
            if flag & wx.ALIGN_CENTER_HORIZONTAL:
 
                pt.x = x + (w - sz.x) // 2
 
            elif flag & wx.ALIGN_RIGHT:
 
                pt.x = x + (w - sz.x)
 

            if flag & wx.ALIGN_CENTER_VERTICAL:
 
                pt.y = y + (h - sz.y) // 2
 
            elif flag & wx.ALIGN_BOTTOM:
 
                pt.y = y + (h - sz.y)

        item.SetDimension(pt, sz)
    def tsGetClientArea(self, pixels=True):
        '''
        Returns the bounding rectangle the client area of the Frame,
        i.e., without menu bars, tool bars, status bars and such.
        '''
        parent = self.ts_Parent
        pos = wxPoint(self.ts_Rect.x, self.ts_Rect.y)
        size = wxSize(self.ts_Rect.width, self.ts_Rect.height)
        style = self.ts_Style
        name = self.ts_Name

        (myRect, myClientRect) = self.tsFrameWindowLayout(
            parent, pos, size, style, name)

        if self.ts_Rect != myRect:

            # My Area changed after by new feature
            fmt1 = 'Wrong layout. myRect (%s) ' % str(myRect)
            fmt2 = 'changed from self.ts_Rect (%s) ' % str(self.ts_Rect)
            fmt3 = 'in tsWxFrame.tsGetClientArea'
            msg = fmt1 + fmt2 + fmt3
            self.logger.wxASSERT_MSG(
                (self.ts_Rect == myRect),
                msg)

            self.ts_Rect = myRect

        if self.ts_ClientRect != myClientRect:

            # Client Area changed after by new feature
            self.ts_ClientRect = myClientRect

        return (self.ts_ClientRect)
    def ShowFullScreen(self, show, style):
        '''
        '''
        # TBD - Under Construction.
        # Extent resize of the top level window to include its children.
        theDisplay = self.Display
 
        theDisplayPos = wxPoint(theDisplay.ClientArea.x,
                                theDisplay.ClientArea.y)

        theDisplaySize = wxSize(theDisplay.ClientArea.width,
                                theDisplay.ClientArea.height)

        self.logger.debug(
            '      ShowFullScreen (screen): pos=%s; size=%s.' % (
                str(theDisplayPos), str(theDisplaySize)))

        self.Rect = wxRect(theDisplayPos.x,
                           theDisplayPos.y,
                           theDisplaySize.width,
                           theDisplaySize.height)

        self.logger.debug(
            '      Need Event to ShowFullScreen (rect): %s.' % (
                str(self.Rect)))

        return (show)
    def GetPositionTuple(self):
        '''
        '''
        if window is None or \
           window.Handle is None:
            # Physical window not yet available
            (y_characters, x_characters) = (0, 0)
        else:
            # Physical window already available
            (y_characters, x_characters) = window.Handle.getyx()

        (x_pixels, y_pixels) = wx.tsGetPixelValues(
            x_characters, y_characters)

        self.tsSetPosition(wxPoint(x_pixels, y_pixels))
        return (x_pixels, y_pixels)
    def tsShow(self):
        '''
        Shows or hides the window. You may need to call Raise for a top
        level window if you want to bring it to top, although this is not
        needed if Show is called immediately after the frame creation.
        Returns True if the window has been shown or hidden or False if
        nothing was done because it already was in the requested state.
        '''
        if self.tsIsShowPermitted:

            if self.ts_Handle is None:

                myRect = wxRect(
                    self.ts_Parent.Rect.Left,
                    (self.ts_Parent.Rect.Bottom - \
                     wx.ThemeToUse['StatusBar']['WindowHeight'] - \
                     wx.pixelHeightPerCharacter),
                    self.ts_Parent.Rect.width,
                    wx.ThemeToUse['StatusBar']['WindowHeight'])

                thePosition = wxPoint(myRect.x, myRect.y)
                theSize = wxSize(myRect.width, myRect.height)

                # TBD - Update Class geometry.
                self.ts_Rect = myRect
                self.logger.debug(
                    'tsShow: myRect=%s; Rect = %s' % (myRect, self.ts_Rect))

                self.ts_BaseRect = self.ts_Rect
                if DEBUG:
                    print('tsShow: myRect=%s; Rect = %s' % (myRect, self.ts_Rect))

                self.Create(self,
                            id=-1,
                            pos=thePosition,
                            size=theSize,
                            style=self.ts_Style,
                            name=self.Name,
                            pixels=True)

            try:
                self.tsRegisterShowOrder()
            except Exception, e:
                self.logger.error('%s; %s' % (__title__, e))

            self.tsUpdate()
    def SetItemBounds(self, item, x, y, w, h ):
        '''
        '''
        pt = wxPoint(x, y)
        sz = item.GetMinSizeWithBorder()
        flag = item.GetFlag()

        if ((flag & wx.EXPAND) or \
            (flag & wx.SHAPED)):

            sz = wxSize(w, h)

        else:

            if (flag & wx.ALIGN_CENTER_HORIZONTAL):

                pt.x = x + (w - sz.width) / 2

            elif (flag & wx.ALIGN_RIGHT):

                pt.x = x + (w - sz.width)

            if (flag & wx.ALIGN_CENTER_VERTICAL):

                pt.y = y + (h - sz.height) / 2

            elif (flag & wx.ALIGN_BOTTOM):

                pt.y = y + (h - sz.height)

        msg = 'GridSizer.SetItemBounds: '  + \
              'item (%s); pt (%s); sz (%s)' % (
                  str(item),
                  str(pt),
                  str(sz))
        if DEBUG:
            print(msg)
        self.logger.debug(msg)

##        item.SetDimension(pt, sz)
        item.ts_Window.ts_Rect = wxRect(pt.x, pt.y, sz.width, sz.height)
    def CreateOutputWindow(self, st):
        '''
        Create frame and text control. Append st (text) to output. Show the
        frame and bind the frame OnCloseButtton to the event.
        '''
        # TBD - Under Construction. The class wxTextCtrl is not available.
        if not (self.ts_Frame is None):
            return
 
        try:
            self.ts_Frame = wxFrame(
                self.ts_Parent,
                id=-1,
                title=self.ts_Title,
                pos=wxPoint(self.ts_Rect.x, self.ts_Rect.y),
                size=wxSize(self.ts_Rect.width, self.ts_Rect.height),
                style=self.ts_Style,
                name=self.ts_Name)
        except Exception, frameError:
            self.logger.error(
                '  CreateOutputWindow: frameError. %s' % frameError)
            msg = 'CreateOutputWindow Frame Error: %s' % str(frameError)
            raise tse.ProgramException(tse.APPLICATION_TRAP, msg)
    def tsShow(self):
        '''
        Create and update MenuBar specific native GUI.
        '''
        if self.tsIsShowPermitted:

            if self.ts_Handle is None:

                myRect = wxRect(
                    self.ts_Parent.Rect.x + wx.pixelWidthPerCharacter,
                    self.ts_Parent.Rect.y + wx.pixelHeightPerCharacter,
                    self.ts_Parent.Rect.width - 2* wx.pixelWidthPerCharacter,
                    wx.ThemeToUse['MenuBar']['WindowHeight'])

                thePosition = wxPoint(myRect.x, myRect.y)
                theSize = wxSize(myRect.width, myRect.height)

                # TBD - Update Class geometry.
    ##            self.ts_Rect = myRect
    ##            self.logger.debug(
    ##                '_show: myRect=%s; Rect = %s' % (myRect, self.ts_Rect))

                self.Create(self,
                            id=-1,
                            pos=thePosition,
                            size=theSize,
                            style=self.ts_Style,
                            name=self.Name,
                            pixels=True)

            try:
                self.tsRegisterShowOrder()
            except Exception, e:
                self.logger.error('%s; %s' % (__title__, e))

            self.tsUpdate()
Пример #12
0
    def tsSetStdioWindowAttributes(self, title=None, pos=None, size=None, style=None, name=None):
        """
        Set the title, position, size, style and name of the output window
        if the stdio has been redirected.
        """
        if self.stdioWin:
            # TBD - Cannot set attributes when window does not exist.
            myRect = self.Display.theRedirectedStdioArea
            if title is not None:
                self.stdioWin.title = title
            else:
                self.stdioWin.title = wx.ThemeToUse["Stdio"]["Title"]

            if pos is not None:
                self.stdioWin.pos = pos
            else:
                self.stdioWin.pos = wxPoint(myRect.x, myRect.y)

            if size is not None:
                self.stdioWin.size = size
            else:
                self.stdioWin.size = wxSize(myRect.width, myRect.height)

            if style is not None:
                self.stdioWin.style = style
            elif wx.ThemeToUse["Stdio"]["Title"] == wx.StdioRedirectedTitleStr:
                self.stdioWin.style = wx.DEFAULT_STDIO_STYLE
            else:
                self.stdioWin.style = wx.DEFAULT_FRAME_STYLE

            if name is not None:
                self.stdioWin.name = name
            elif wx.ThemeToUse["Stdio"]["Title"] == wx.StdioRedirectedTitleStr:
                self.stdioWin.name = wx.StdioNameStr
            else:
                self.stdioWin.name = wx.FrameNameStr
    def tsButtonLayout(self, parent, pos, size, style, name):
        '''
        Calculate position and size of button based upon arguments.
        '''
        if (not (self.ts_Handle is None)):

            # Inhibit operation once self.ts_Handle has been
            # assigned a curses window identifier.
            return (self.ts_Rect, self.ts_ClientRect)

        if style is None:
            # Prevent pylint warning.
            pass

        thePosition = self.tsGetClassInstanceFromTuple(pos, wxPoint)
        theSize = self.tsGetClassInstanceFromTuple(size, wxSize)

        theDefaultPosition = self.tsGetClassInstanceFromTuple(
            wx.DefaultPosition, wxPoint)
 
        theDefaultSize = self.tsGetClassInstanceFromTuple(
            wx.DefaultSize, wxSize)

        label = self.ts_ButtonText

        # Ignore UseClientArea because cursor wraps beyond bottom
        # when last character has been output.
        if self.ts_UseClientArea:
            offset = wxPoint(0, 0)
        else:
            offset = wxPoint(0, 0)

        if theSize == theDefaultSize:
            # theDefaultSize

            theLabelSize = theSize
            self.logger.debug(
                '      theLabelSize (begin): %s' % theLabelSize)

            if label is wx.EmptyString:
                # TBD - Adjust for cursor width
                theLabelSize = wxSize(
                    (len(label) + len('[]')) * wx.pixelWidthPerCharacter,
                    wx.pixelHeightPerCharacter)

            elif label.find('\n') == -1:
                # TBD - Remove adjustment for extra cursor width
                theLabelSize = wxSize(
                    (len(label) + len('[ ]')) * wx.pixelWidthPerCharacter,
                    wx.pixelHeightPerCharacter)
            else:
                # TBD - Remove adjustment for extra cursor width
                theLines = label.split('\n')
                maxWidth = 0
                maxHeight = len(theLines)
                for aLine in theLines:
                    if len(aLine) > maxWidth:
                        maxWidth = len(aLine)
                theLabelSize = wxSize(
                    (maxWidth + len('[ ]')) * wx.pixelWidthPerCharacter,
                    maxHeight * wx.pixelHeightPerCharacter)

            self.logger.debug(
                '      theLabelSize (end): %s' % theLabelSize)

            if thePosition == theDefaultPosition:
                # theDefaultPosition

                myRect = wxRect(parent.ClientArea.x,
                                parent.ClientArea.y,
                                theLabelSize.width,
                                theLabelSize.height)

            else:
                # Not theDefaultPosition

                myRect = wxRect(offset.x + thePosition.x,
                                offset.y + thePosition.y,
                                theLabelSize.width,
                                theLabelSize.height)

        else:
            # Not theDefaultSize

            if thePosition == theDefaultPosition:
                # theDefaultPosition

                myRect = wxRect(parent.ClientArea.x,
                                parent.ClientArea.y,
                                theSize.width,
                                theSize.height)

            else:
                # Not theDefaultPosition

                myRect = wxRect(offset.x + thePosition.x,
                                offset.y + thePosition.y,
                                theSize.width,
                                theSize.height)

##        theDisplayRect = self.Display.GetClientArea()
##        if not theDisplayRect.InsideRect(myRect):
##            myRect = wxRect(
##                max(thePosition.x, theDisplayRect.x),
##                max(thePosition.y, theDisplayRect.y),
##                min(theSize.width, theDisplayRect.width),
##                min(theSize.height, theDisplayRect.height - 1))

##        if not theDisplayRect.InsideRect(myRect):
##            myRect = theDisplayRect

        myClientRect = wxRect(myRect.x,
                              myRect.y,
                              myRect.width,
                              myRect.height)

        self.tsTrapIfTooSmall(name, myRect)
        fmt = 'parent=%s; pos=%s; size=%s; ' + \
              'name="%s"; label="%s"; myRect=%s'
        msg = fmt % (parent, str(pos), str(size), name, label, str(myRect))

        self.logger.debug('    tsButtonLayout: %s' % msg)

        return (myRect, myClientRect)
    def tsAdjustScrollPosition(self, evt, orientation):
        '''
        Calculate and set the horizontal or vertical scrolled text position
        corresponding to the relative caret position on the ScrollBarGauge
        at the time the operator clicked the mouse button.
        '''
        ####################################################################
        # Decode the mouse position data associated with mouse click event.
        (mouseId, x, y, z, bstate) = evt.EventData

        ####################################################################
        # Update minimum and maximum number of text rows
        # available for display.
##        minTextCols = 0
        maxTextCols = self.ts_MaxTextCols
##        minTextRows = 0
        maxTextRows = self.ts_MaxTextRows
        maxPageCols = self.ts_xScrollLinesPerPage
        maxPageRows = self.ts_yScrollLinesPerPage

        maxPage = wxPoint(maxPageCols, maxPageRows)
        maxText = wxPoint(maxTextCols, maxTextRows)

        if DEBUG:
            fmt0 = 'tsWxScrolledText.tsAdjustScrollPosition=%s; ' % str(self)
            fmt1 = 'className=%s; maxPage=%s; maxText=%s' % (
                self.ts_ClassName, str(maxPage), str(maxText))
            msg = fmt0 + fmt1
            self.logger.debug(msg)
            print('NOTICE: %s\n' % msg)

        ####################################################################
        # Convert mouse position into text row or col position.
        if self.ts_yScrollingEnabled and (orientation == wx.SB_VERTICAL):

            ################################################################
            # Update default text col position and simulated features.
            x_pos = self.ts_xScrollPosition

            # Scroll Text within Vertical ScrollBar Gauge
            yOffset = y - (self.ts_ClientRect.y / wx.pixelHeightPerCharacter)

            ySlope = float(max(0, maxTextRows - maxPageRows)) / (
                float(self.ts_ClientRect.height / wx.pixelHeightPerCharacter))

            y_pos = int(ySlope * float(yOffset))

            if DEBUG:
                fmt0 = 'tsWxScrolledText.' + \
                       'tsAdjustScrollPosition=%s; ' % str(self)
                fmt1 = 'y=%d; ' % y
                fmt2 = 'yOffset=%d; ' % yOffset
                fmt3 = 'ySlope=%f; ' % ySlope
                fmt4 = 'y_pos=%d' % y_pos
                msg = fmt0 + fmt1 + fmt2 + fmt3 + fmt4
                self.logger.debug(msg)
                print('NOTICE: %s\n' % msg)

        if self.ts_xScrollingEnabled and (orientation == wx.SB_HORIZONTAL):

            ################################################################
            # Update default text row position and simulated features.
            y_pos = self.ts_yScrollPosition

            # Scroll Text within Horizontal ScrollBar Gauge
            xOffset = x - (self.ts_ClientRect.x / wx.pixelWidthPerCharacter)

            xSlope = float(max(0, maxTextCols - maxPageCols)) / (
                float(self.ts_ClientRect.width / wx.pixelWidthPerCharacter))

            x_pos = int(xSlope * float(xOffset))

            if DEBUG:
                fmt0 = 'tsWxScrolledText.' + \
                       'tsAdjustScrollPosition=%s; ' % str(self)
                fmt1 = 'x=%d; ' % x
                fmt2 = 'xOffset=%d; ' % xOffset
                fmt3 = 'xSlope=%f; ' % xSlope
                fmt4 = 'x_pos=%d' % x_pos
                msg = fmt0 + fmt1 + fmt2 + fmt3 + fmt4
                self.logger.debug(msg)
                print('NOTICE: %s\n' % msg)

        self.Scroll(x_pos, y_pos)
    def tsGetRedirectedStdioArea(self, pixels=True):
        '''
        Return rectangle position and size of window used for redirected
        output from print, stdout and stderr.

        NOTE: Area includes top, bottom, left and right borders. It must
        support at least one message. Messages may optionally include a
        timestamp. The assumed length of a typical message, without its
        timestamp, but with the left and right borders, is 80 characters.
        The minimum height must therefore provide sufficient lines to
        display the full message and its timestamp.
        '''
        ###############################################################
        #      X=0         1         2         3   X=W-1
        #        01234567890123456789012345678901234
        # Y=0    +---------------------------------+ Frame Border Top
        #   1    |Client Area                      |
        #   2    |   (ex. 35 cols x 6 rows)        |
        #   3    |                                 |
        #   4    |                                 |
        #   5    +---------------------------------+ Frame Border Bottom
        #   H-9  +---------------------------------+ Stdio Border Top
        #   H-8  |Stdio Output (Optionl)           |
        #   H-7  |   (ex. 35 cols x 5 rows)        |
        #   H-6  |                                 |
        #   H-5  +---------------------------------+ Stdio Border Bottom
        #   H-4  +---------------------------------+ Task Border Top
        #   H-3  |Task Bar Output (Optional)       |
        #   H-2  |   (ex. 35 cols x 4 rows)        |
        # Y=H-1  +---------------------------------+ Task Border Bottom
        ###############################################################
        if Display.EnableRedirectArea:

            theTotalArea = self.GetGeometry(pixels=False)

            borderRows = 2
            # borderCols = 2

            if wx.ThemeToUse['Stdio']['Timestamp']:
                minLineWidth = wx.pageWidth + len('2008/07/04 05:44:52.486 -')
            else:
                minLineWidth = wx.pageWidth

            (minDisplayPixelWidth, minDisplayPixelHeight) = \
                                   wx.RedirectedWindowHeight['minDisplay']

            (minDisplayWidth, minDisplayHeight) = (
                 minDisplayPixelWidth // wx.pixelWidthPerCharacter,
                 minDisplayPixelHeight // wx.pixelHeightPerCharacter)

            minHeightPercent = int(
                wx.RedirectedWindowHeight['minHeightPercent'])

            maxHeightPercent = int(
                wx.RedirectedWindowHeight['maxHeightPercent'])

            maxRedirectedWidth = theTotalArea.width

            theTaskArea = self.tsGetTaskArea(pixels=False)

            # thePosition = wxPoint(theTotalArea.x, theTotalArea.y)
            theSize = wxSize(theTotalArea.width, theTotalArea.height)

            theRedirectedAreaOffset = - 1
            if theSize.width < minDisplayWidth:

                if theSize.height < minDisplayHeight:

                    maxRedirectedHeight = max(
                        (borderRows + int(
                            1 + minLineWidth // maxRedirectedWidth)),
                        ((theSize.height *  minHeightPercent) // 100) * \
                        int(1 + minLineWidth // maxRedirectedWidth) + \
                        theRedirectedAreaOffset)

                else:

                    maxRedirectedHeight = max(
                        (borderRows + int(
                            1 + minLineWidth // maxRedirectedWidth)),
                        ((theSize.height *  minHeightPercent) // 100) + \
                        theRedirectedAreaOffset)

            elif theSize.height < minDisplayHeight:

                maxRedirectedHeight = max(
                    (borderRows + int(
                        1 + minLineWidth // maxRedirectedWidth)),
                    ((theSize.height *  minHeightPercent) // 100) + \
                    theRedirectedAreaOffset)

            else:

                maxRedirectedHeight = max(
                    (borderRows + int(
                        1 + minLineWidth // maxRedirectedWidth)),
                    ((theSize.height *  maxHeightPercent) // 100) + \
                    theRedirectedAreaOffset)

            theRedirectedSize = wxSize(maxRedirectedWidth,
                                       maxRedirectedHeight)

            theRedirectedPos = wxPoint(
                theTaskArea.x,
                theTaskArea.y - (theRedirectedSize.height + 0))

            theCharacterArea = wxRect(theRedirectedPos.x,
                                      theRedirectedPos.y,
                                      theRedirectedSize.width,
                                      theRedirectedSize.height)

            thePixelArea = wxRect(
                theCharacterArea.x * wx.pixelWidthPerCharacter,
                theCharacterArea.y * wx.pixelHeightPerCharacter,
                theCharacterArea.width * wx.pixelWidthPerCharacter,
                theCharacterArea.height * wx.pixelHeightPerCharacter)

            if pixels:
                theArea = thePixelArea
            else:
                theArea = theCharacterArea

            if DEBUG and VERBOSE:
                self.tsPrivateLogger(
                    'tsGetRedirectedStdioArea: %s pixels = %s characters' % (
                        thePixelArea, theCharacterArea))

        else:
 
            theArea = None

            if DEBUG and VERBOSE:
                self.tsPrivateLogger(
                    'tsGetRedirectedStdioArea: %s' % theArea)
 
        return (theArea)
 def GetPosition(self):
     """
     Returns the pixel position of the mouse in window coordinates when
     the event happened.
     """
     return wxPoint(self.ts_X, self.ts_Y)
 def Moving(self):
     """
     Returns true if this was a motion event and no mouse buttons were
     pressed.
     """
     return (self.ts_ChangeXY != wxPoint(0, 0)) and (not self.ButtonDown())
    def __init__(self, mouseEventType=wx.EVT_NULL):
        """
        Constructs a wx.MouseEvent.

        Events

        EVT_ENTER_WINDOW  Event sent when the mouse enters the boundaries
        of a window.

        EVT_LEAVE_WINDOW  Sent when the mouse leaves the window bounds

        EVT_LEFT_DOWN   Left mouse button down event. The handler of this
        event should normally call event.Skip() to allow the default
        processing to take place as otherwise the window under mouse
        would not get the focus.

        EVT_LEFT_UP     Left mouse button up event

        EVT_LEFT_DCLICK Left mouse button double click event
        
        EVT_MIDDLE_DOWN Middle mouse button down event

        EVT_MIDDLE_UP   Middle mouse button up event

        EVT_MIDDLE_DCLICK  Middle mouse button double click event

        EVT_RIGHT_DOWN  Right mouse button down event

        EVT_RIGHT_UP    Right mouse button up event

        EVT_RIGHT_DCLICK  Right mouse button double click event

        EVT_MOUSE_AUX1_DOWN     First extra mouse button down event

        EVT_MOUSE_AUX1_UP       First extra mouse button up event

        EVT_MOUSE_AUX1_DCLICK  First extra mouse button double click event

        EVT_MOUSE_AUX2_DOWN     Second extra mouse button down event

        EVT_MOUSE_AUX2_UP       Second extra mouse button up event

        EVT_MOUSE_AUX2_DCLICK  Second extra mouse button double click event

        EVT_MOTION  Event sent when the mouse is moving

        EVT_MOUSEWHEEL Mouse scroll wheel event

        EVT_MOUSE_EVENTS  Binds all mouse events at once.
        """

        theClass = "MouseEvent"

        wx.RegisterFirstCallerClassName(self, theClass)

        wxEvent.Event.__init__(self)
        MouseState.__init__(self)

        if mouseEventType not in validMouseEventTypes:
            msg = "Invalid mouseEventType: %s" % str(mouseEventType)
            self.logger.error(msg)
            raise tse.ProgramException(tse.APPLICATION_TRAP, msg)

        # Duplicated from MouseState
        self.ts_LeftIsDown = False
        self.ts_MiddleIsDown = False
        self.ts_RightIsDown = False
        self.ts_Aux1IsDown = False
        self.ts_Aux2IsDown = False
        self.ts_X = 0
        self.ts_Y = 0

        # Local state
        self.ts_Button = False
        self.ts_ButtonDClick = False
        self.ts_ButtonDown = False
        self.ts_ButtonIsDown = False
        self.ts_ButtonUp = False
        self.ts_Dragging = False
        self.ts_Entering = False
        self.ts_Leaving = False

        self.ts_LeftDClick = False
        self.ts_LeftDown = False
        self.ts_LeftIsDown = False
        self.ts_LeftUp = False

        self.ts_MetaDown = False

        self.ts_MiddleDClick = False
        self.ts_MiddleDown = False
        self.ts_MiddleIsDown = False
        self.ts_MiddleUp = False

        self.ts_Moving = False

        self.ts_RightDClick = False
        self.ts_RightDown = False
        self.ts_RightIsDown = False
        self.ts_RightUp = False

        self.ts_LinesPerAction = 0
        self.ts_MouseEventType = mouseEventType
        self.ts_WheelDelta = 0
        self.ts_WheelRotation = 0

        self.ts_LastXY = wxPoint(self.ts_X, self.ts_Y)
        self.ts_ChangeXY = wxPoint(self.ts_X, self.ts_Y) - self.ts_LastXY

        self.tsBeginClassRegistration(theClass, wx.ID_ANY)

        ##        self.thisown = theClass

        self.tsEndClassRegistration(theClass)
 def GetLogicalPosition(self, dc):
     """
     Returns the logical mouse position in pixels (i.e.
     """
     delta = wxPoint(self.ts_X, self.ts_Y) - dc
     return delta
    def tsStaticBoxLayout(self, parent, pos, size, style, name):
        '''
        Calculate position and size of button based upon arguments.
        '''
        if (not (self.ts_Handle is None)):

            # Inhibit operation once self.ts_Handle has been
            # assigned a curses window identifier.
            return (self.ts_Rect, self.ts_ClientRect)
 
        if style is None:
            # Prevent pylint warning.
            pass

        thePosition = self.tsGetClassInstanceFromTuple(pos, wxPoint)
        theSize = self.tsGetClassInstanceFromTuple(size, wxSize)

        theBorder = self.tsIsBorderThickness(style, pixels=True)

        theDefaultPosition = self.tsGetClassInstanceFromTuple(
            wx.DefaultPosition, wxPoint)
 
        theDefaultSize = self.tsGetClassInstanceFromTuple(
            wx.DefaultSize, wxSize)

        # Ignore UseClientArea because cursor wraps beyond bottom
        # when last character has been output.
        offset = wxPoint(theBorder.width, theBorder.height)

        if thePosition == theDefaultPosition and \
             theSize == theDefaultSize:

            # The Default Position and the Parent's Default Client Size
            myRect = wxRect(parent.ClientArea.x,
                            parent.ClientArea.y,
                            parent.ClientArea.width,
                            parent.ClientArea.height)

        elif thePosition == theDefaultPosition:

            # Parent's Default Client Position and the Specified Size
            myRect = wxRect(parent.ClientArea.x,
                            parent.ClientArea.y,
                            theSize.width,
                            theSize.height)

        else:

            # The Specified Position and the Specified Size

            myRect = wxRect(thePosition.x,
                            thePosition.y,
                            theSize.width,
                            theSize.height)

        myClientRect = wxRect((myRect.x + offset.x),
                              (myRect.y + offset.y),
                              (myRect.width - (2 * offset.x)),
                              (myRect.height - (2 * offset.y)))

        msg = 'parent=%s; pos=%s; size=%s; name=%s; myRect=%s' % \
              (parent, pos, size, name, myRect)

        self.logger.debug('    tsStaticBoxLayout: %s' % msg)

        return (myRect, myClientRect)
    def SetDimension(self, *args):
        '''
        Set the position and size of the space allocated for this item by
        the sizer, and adjust the position and size of the item (window or
        subsizer) to be within that space taking alignment and borders into
        account.

        Modeled after SetDimension in sizer.cpp file of wxWidgets.
        '''
##        for i in range(len(args)):
##            print('txWxSizerItem.SetDimension:args[%d]= %s' % (
##                i, str(args[i])))
        if len(args) == 4:
            # len(args) == 4; Invoked via SetDimension(x, y, w, h)
            myPosition = wxPoint(args[0], args[1])
            mySize = wxSize(args[2], args[3])

        else:

            # len(args) == 2; Invoked via SetDimension(pos, size)
            myPosition = args[0]
            mySize = args[1]


        if self.ts_Flag & wx.SHAPED:
 
            # adjust aspect ratio
            rwidth = int(mySize.height * self.ts_Ratio)
            if rwidth > mySize.width:
 
                # fit horizontally
                rheight = int(mySize.width / self.ts_Ratio)
                # add vertical space
                if self.ts_Flag & wx.ALIGN_CENTER_VERTICAL:
                    myPosition.y += (mySize.height - rheight) / 2

                elif self.ts_Flag & wx.ALIGN_BOTTOM:
                    myPosition.y += (mySize.height - rheight)
                # use reduced dimensions
                mySize.height = rheight
 
            elif rwidth < mySize.width:
 
                # add horizontal space
                if self.ts_Flag & wx.ALIGN_CENTER_HORIZONTAL:
                    myPosition.x += (mySize.width - rwidth) / 2

                elif self.ts_Flag & wx.ALIGN_RIGHT:
                    myPosition.x += (mySize.width - rwidth)
                mySize.width = rwidth
 
        # This is what GetPosition() returns. Since we calculate
        # borders afterwards, GetPosition() will be the left/top
        # corner of the surrounding border.
        myBorder = self.tsGetBorderCharacterDimensions(
            thickness=self.ts_Border)

        if (self.ts_Flag & wx.WEST):
 
            myPosition.x += myBorder.width
            mySize.width -= myBorder.width
 
        if (self.ts_Flag & wx.EAST):
 
            mySize.width -= myBorder.width
 
        if (self.ts_Flag & wx.NORTH):
 
            myPosition.y += myBorder.height
            mySize.height -= myBorder.height
 
        if (self.ts_Flag & wx.SOUTH):
 
            mySize.height -= myBorder.height

        if (mySize.width < 0):
            mySize.width = 0

        if (mySize.height < 0):
            mySize.height = 0

        self.ts_Rect = wxRect(myPosition.x,
                              myPosition.y,
                              mySize.width,
                              mySize.height)

        if (self.ts_Kind == wx.Item_None):

            self.logger.wxFAIL_MSG(
                'Cannot set size of uninitialized sizer item in ' + \
                'wx.SizerItem.SetDimension')

        elif (self.ts_Kind == wx.Item_Window):
            # Use wxSIZE_FORCE_EVENT here since a sizer item might
            # have changed alignment or some other property which would
            # not change the size of the window. In such a case, no
            # wxSizeEvent would normally be generated and thus the
            # control wouldn't get layed out correctly here.
            if True:
                self.ts_Window.SetSize(mySize)
#                    mySize,
#                    wx.SIZE_ALLOW_MINUS_ONE | wx.SIZE_FORCE_EVENT)
            else:
                self.ts_Window.SetSize(mySize)
#                    mySize,
#                    wx.SIZE_ALLOW_MINUS_ONE)

        elif (self.ts_Kind == wx.Item_Sizer):

            self.ts_Sizer.SetDimension(myPosition, mySize)

        elif (self.ts_Kind == wx.Item_Spacer):

            self.ts_Spacer.SetSize(mySize)

        else: # Item_Max

            self.logger.wxFAIL_MSG('Unexpected wxSizerItem.ts_Kind=Item_Max')
    def tsScrollBarButtonLayout(self, parent, pos, size, style, name):
        '''
        Calculate position and size of button based upon arguments.
        '''
        if (not (self.ts_Handle is None)):

            # Inhibit operation once self.ts_Handle has been
            # assigned a curses window identifier.
            return (self.ts_Rect, self.ts_ClientRect)

        if style is None:
            # Prevent pylint warning.
            pass

        if DEBUG:
            fmt1 = 'tsScrollBarButtonLayout: '
            fmt2 = 'parent=%s; ' % str(parent)
            fmt3 = 'pos=%s; ' % str(pos)
            fmt4 = 'size=%s; ' % str(size)
            fmt5 = 'style=0x%X' % style
            msg =  fmt1 + fmt2 + fmt3 + fmt4 + fmt5
            self.logger.debug(msg)

        if wx.ThemeToUse['ScrollBar']['ArrowBorder']:

            arrowWidth = 3 * wx.pixelWidthPerCharacter
            arrowHeight = 3 * wx.pixelHeightPerCharacter
            # arrowStyle = wx.BORDER_SIMPLE

        else:

            arrowWidth = 1 * wx.pixelWidthPerCharacter
            arrowHeight = 1 * wx.pixelHeightPerCharacter
            # arrowStyle = wx.BORDER_NONE

        thePosition = self.tsGetClassInstanceFromTuple(pos, wxPoint)
        theSize = self.tsGetClassInstanceFromTuple(size, wxSize)

        theDefaultPosition = self.tsGetClassInstanceFromTuple(
            wx.DefaultPosition, wxPoint)

        theDefaultSize = self.tsGetClassInstanceFromTuple(
            wx.DefaultSize, wxSize)

        label = self.ts_ButtonText

        # Ignore UseClientArea because cursor wraps beyond bottom
        # when last character has been output.
        if self.ts_UseClientArea:
            offset = wxPoint(wx.pixelWidthPerCharacter,
                             wx.pixelHeightPerCharacter)
        else:
            offset = wxPoint(0, 0)

        if theSize == theDefaultSize:
            # theDefaultSize

            theLabelSize = theSize
            self.logger.debug(
                '      theLabelSize (begin): %s' % theLabelSize)

            if (label == wx.EmptyString) or \
               (len(label) == 1):
                # TBD - Adjust for cursor width
                theLabelSize = wxSize(
                    arrowWidth * wx.pixelWidthPerCharacter,
                    arrowHeight * wx.pixelHeightPerCharacter)

            elif label.find('\n') == -1:
                # TBD - Remove adjustment for extra cursor width
                theLabelSize = wxSize(
                    (len(label) + arrowWidth - 1) * wx.pixelWidthPerCharacter,
                    arrowHeight * wx.pixelHeightPerCharacter)
            else:
                # TBD - Remove adjustment for extra cursor width
                theLines = label.split('\n')
                maxWidth = 0
                maxHeight = len(theLines) + arrowHeight - 1
                for aLine in theLines:
                    if len(aLine) > maxWidth:
                        maxWidth = len(aLine) + arrowWidth - 1
                theLabelSize = wxSize(
                    maxWidth * wx.pixelWidthPerCharacter,
                    maxHeight * wx.pixelHeightPerCharacter)

            self.logger.debug(
                '      theLabelSize (end): %s' % theLabelSize)

            if thePosition == theDefaultPosition:
                # theDefaultPosition

                myRect = wxRect(parent.ClientArea.x,
                                parent.ClientArea.y,
                                theLabelSize.width,
                                theLabelSize.height)

            else:
                # Not theDefaultPosition

                myRect = wxRect(offset.x + thePosition.x,
                                offset.y + thePosition.y,
                                theLabelSize.width,
                                theLabelSize.height)

        else:

            # Not theDefaultSize

            if thePosition == theDefaultPosition:
                # theDefaultPosition

                myRect = wxRect(parent.ClientArea.x,
                                parent.ClientArea.y,
                                theSize.width,
                                theSize.height)

            else:
                # Not theDefaultPosition

                myRect = wxRect(offset.x + thePosition.x,
                                offset.y + thePosition.y,
                                theSize.width,
                                theSize.height)

        myClientRect = wxRect(myRect.x,
                              myRect.y,
                              myRect.width,
                              myRect.height)

        self.tsTrapIfTooSmall(name, myRect)
        fmt = 'parent=%s; pos=%s; size=%s; ' + \
            'name="%s"; label="%s"; myRect=%s'
        msg = fmt % (parent, str(pos), str(size), name, label, str(myRect))

        self.logger.debug('    tsScrollBarButtonLayout: %s' % msg)

        return (myRect, myClientRect)
    def CalcMin(self):
        '''
        This method is where the sizer will do the actual calculation of its
        childrens minimal sizes. You should not need to call this directly
        as it is called by Layout

        Modeled after TBD in sizer.cpp file of wxWidgets.
        '''
        nitems = self.CalcRowsCols()
        if DEBUG:
            print(
                'GridSizes.CalcMin: nitems=%d; Rows=%d; Cols=%d' % (
                    nitems, self.ts_Rows, self.ts_Cols))

        if (nitems == 0):
            return (wxSize(0, 0))

        sizerClientArea = self.FindSizerClientArea()
        self.ts_Rect = sizerClientArea
        self.ts_Position = wxPoint(sizerClientArea.x, sizerClientArea.y)
        self.ts_Size = wxSize(sizerClientArea.width, sizerClientArea.height)
        if DEBUG:
            print(
                'GridSizer.CalcMin: sizerClientArea=%s' % str(sizerClientArea))

        sz = wxSize(
            ((sizerClientArea.width - (
                (self.ts_Cols - 1) * self.ts_HGap)) / self.ts_Cols),
            ((sizerClientArea.height - (
                (self.ts_Rows - 1) * self.ts_VGap)) / self.ts_Rows))

        if DEBUG:
            print(
                'GridSizer.CalcMin: sz=%s; sizerClientArea=%s' % (
                    str(sz),
                    str(sizerClientArea)))

        # Find the max width and height for any component
        w = 0
        h = 0
        for i in range(0, self.ts_Children.GetCount()):
            node = self.ts_Children.GetIndex(i)

            item =  node.GetUserData()
            if DEBUG:
                msg = 'GridSizer.CalcMin: item[%d]=%s' % (i, str(item))
                print(msg)

            if (item.ts_Kind == wx.Item_Sizer):
                item.ts_Sizer.Layout()

##            parent = item.ts_Window.ts_Parent
##            clientArea = parent.ClientArea

##            theRect = parent.Rect
##            theClientArea = parent.ClientArea
##            print('GridSizer.CalcMin: Rect=%s; ClientArea=%s' % (
##                str(theRect),
##                str(theClientArea)))

##            tempSize = item.CalcMin()
##            sz = tempSize
##            sz = wxSize((min(tempSize.width,
##                            ((self.ts_ContainingWindowClientArea.width /
##                              self.ts_Cols) - self.ts_Hgap))),
##                        (min(tempSize.width,
##                             ((self.ts_ContainingWindowClientArea.height /
##                               self.ts_Rows) - self.ts_Vgap))))

            w = wx.Max( w, sz.x )
            h = wx.Max( h, sz.y )

        # In case we have a nested sizer with a two step algo , give it
        # a chance to adjust to that (we give it width component)
        didChangeMinSize = False
        for i in range(0, self.ts_Children.GetCount()):
            node = self.ts_Children.GetIndex(i)

            item =  node.GetUserData()
            didChangeMinSize |= item.InformFirstDirection(
                wx.HORIZONTAL, w, -1 )

        # And redo iteration in case min size changed
        if(didChangeMinSize):

            w = h = 0
            for i in range(0, self.ts_Children.GetCount()):
                node = self.ts_Children.GetIndex(i)

                item =  node.GetUserData()
                sz = item.GetMinSizeWithBorder()

                w = wx.Max( w, sz.x )
                h = wx.Max( h, sz.y )

        return (wxSize(self.ts_Cols * w + (self.ts_Cols-1) * self.ts_HGap,
                       self.ts_Rows * h + (self.ts_Rows-1) * self.ts_VGap))
    def __init__(self,
                 parent,
                 id=wx.ID_ANY,
                 label=wx.EmptyString,
                 pos=wx.DefaultPosition,
                 size=wx.DefaultSize,
                 choices=wx.PyEmptyStringArray,
                 majorDimension=0,
                 style=wx.RA_HORIZONTAL,
                 validator=wx.DefaultValidator,
                 name=wx.RadioBoxNameStr):
        '''
        Create a Control. Normally you should only call this from a
        subclass __init__ as a plain old wx.Control is not very useful.
        '''
        # Also, remember that wx.RA_SPECIFY_COLS means that we arrange buttons
        # in left to right order and GetMajorDim() is the number of columns
        # while wx.RA_SPECIFY_ROWS means that the buttons are arranged top to
        # bottom and GetMajorDim() is the number of rows.
        theClass = 'RadioBox'

        # Capture initial caller parametsrs before they are changed
        self.caller_parent = parent
        self.caller_id = id
        self.caller_label = label
        self.caller_pos = pos
        self.caller_size = size
        self.caller_choices = choices
        self.caller_majorDimension = majorDimension
        self.caller_style = style
        self.caller_validator = validator
        self.caller_name = name

        wx.RegisterFirstCallerClassName(self, theClass)

        Control.__init__(self,
                         parent,
                         id=id,
                         pos=pos,
                         size=size,
                         style=style,
                         validator=validator,
                         name=name)

        self.tsBeginClassRegistration(theClass, id)

        if DEBUG:
            self.logger.debug('               self: %s' % self)
            self.logger.debug('             parent: %s' % parent)
            self.logger.debug('                 id: %s' % self.ts_Id)
            self.logger.debug('         AssignedId: %s' % self.ts_AssignedId)
            self.logger.debug('              label: %s' % label)
            self.logger.debug('                pos: %s' % str(pos))
            self.logger.debug('               size: %s' % str(size))
            self.logger.debug('            choices: %s' % choices)
            self.logger.debug('     majorDimension: %s' % majorDimension)
            self.logger.debug('              style: 0x%X' % style)
#            self.logger.debug('          validator: 0x%X' % validator)
            self.logger.debug('               name: %s' % name)

        self.ts_Default = False

        self.ts_Name = name
        self.ts_Parent = parent

        theTopLevelClass = self
        self.SetTopLevelAncestor(theTopLevelClass)

        if parent is None:
            self.ts_GrandParent = None
        else:
            self.ts_GrandParent = parent.Parent

        if False:
            # Leaves artifacts of different color than parent background.
            self.ts_BackgroundColour = wx.ThemeToUse[
                'BackgroundColour'].lower()
            self.ts_ForegroundColour = wx.ThemeToUse[
                'ForegroundColour'].lower()
        else:
            self.ts_BackgroundColour = self.Parent.ts_BackgroundColour
            self.ts_ForegroundColour = self.Parent.ts_ForegroundColour

        self.ts_Choices = choices
        self.ts_Count = len(choices)
        self.ts_Label = label
        self.ts_MajorDimension = max(majorDimension, self.ts_Count)
        self.ts_Style = style
        self.ts_Validator = validator

        myRect, myClientRect = self.tsRadioBoxLayout(
            parent, pos, size, style, name)
        self.ts_Rect = myRect
        self.ts_ClientRect = myClientRect

        bestSize = self.tsBestSize()
##        style = 0

        self.ts_ItemLabel = []
        self.ts_ItemEnabled = []
        self.ts_ItemHelpText = []
        self.ts_ItemToolTip = []
        self.ts_ItemShown = []
        self.ts_ItemWindow = []

        # TBD - Verify scaling.
        if self.ts_Style & wx.RA_HORIZONTAL:
            itemWidth = bestSize.width // (self.ts_MajorDimension + 1)
        else:
            itemWidth = bestSize.width

        for item in range(self.ts_Count):
            self.ts_ItemLabel.append(self.ts_Choices[item])
            self.ts_ItemHelpText.append(self.ts_ItemLabel[item])
            self.ts_ItemToolTip.append(self.ts_ItemLabel[item])
            self.ts_ItemShown.append(True)

            if item == 0:
                self.ts_ItemEnabled.append(True)
            else:
                self.ts_ItemEnabled.append(False)

            # TBD - Under Construction.
            if self.ts_Style & wx.RA_HORIZONTAL:
                # Horizontal layout
                posTBD = wxPoint(
                    self.Rect.x + (item * itemWidth + 2) * wx.pixelWidthPerCharacter,
                    self.Rect.y + (2) * wx.pixelHeightPerCharacter)
            else:
                # Vertical layout
                posTBD = wxPoint(
                    self.Rect.x + (2) * wx.pixelWidthPerCharacter,
                    self.Rect.y + (item + 2) * wx.pixelHeightPerCharacter)

##            sizeTBD = wxSize(
##                (len('(*)  ') + len(
##                    self.ts_ItemLabel[item])) * wx.pixelWidthPerCharacter,
##                wx.pixelHeightPerCharacter)

            sizeTBD = wxSize(
                (len('(*)  ') + len(self.tsStripAcceleratorTextLabel(
                    self.ts_ItemLabel[item]))) * wx.pixelWidthPerCharacter,
                wx.pixelHeightPerCharacter)

            self.ts_ItemWindow.append(wxRadioButton(
                self,
                id=wx.ID_ANY,
                label=self.ts_ItemLabel[item],
                pos=posTBD,
                size=sizeTBD,
                style=(self.ts_Style & wx.ALIGN_LEFT | \
                       self.ts_Style & wx.ALIGN_RIGHT | \
                       wx.NO_BORDER),
                validator=wx.DefaultValidator,
                name=self.ts_ItemLabel[item]))

            self.ts_ItemWindow[item].SetValue(self.ts_ItemEnabled[item])

        if self.ts_Style & wx.RA_HORIZONTAL:
            self.ts_ColumnCount = self.ts_MajorDimension
            self.ts_RowCount = 1

        elif self.ts_Style & wx.RA_VERTICAL:
            self.ts_ColumnCount = 1
            self.ts_RowCount = self.ts_MajorDimension

        else:
            # TBD - Temporary dimension
            self.ts_ColumnCount = self.ts_MajorDimension
            rows, cols = divmod(self.ts_Count, self.ts_MajorDimension)
            if cols == 0:
                self.ts_RowCount = rows
            else:
                self.ts_RowCount = rows + 1

        self.ts_Selection = 0
        self.ts_StringSelection = 0

        # Automatically Bind all mouse events ASAP (now).
        # Will register event in the SystemEventTable.
        event = EVT_COMMAND_LEFT_CLICK
        handler = self.tsOnLeftClick
        source = self
        self.Bind(event,
                  handler,
                  source,
                  useSystemEventTable=True)

        # Automatically Bind all Radio Button events ASAP (now).
        # Will register event in the SystemEventTable.
        event = EVT_RADIOBUTTON
        handler = self.tsOnRadioButtonClick
        source = self
        self.Bind(event,
                  handler,
                  source,
                  useSystemEventTable=True)

        self.tsEndClassRegistration(theClass)
from tsWxGTUI_Py2x.tsLibGUI.tsWxSize import Size as wxSize
from tsWxGTUI_Py2x.tsLibGUI.tsWxSizer import Sizer
from tsWxGTUI_Py2x.tsLibGUI.tsWxSizerItem import SizerItem as wxSizerItem

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

##DEBUG = True
DEBUG = wx.Debug_GUI_Launch | \
        wx.Debug_GUI_Progress | \
        wx.Debug_GUI_Termination | \
        wx.Debug_GUI_Exceptions

##VERBOSE = True
VERBOSE = wx.Debug_GUI_Configuration

DEFAULT_POS = wxPoint(wx.DefaultPosition)
DEFAULT_SIZE = wxSize(wx.DefaultSize)

#---------------------------------------------------------------------------
 
class GridSizer(Sizer):
    '''
    A grid sizer is a sizer which lays out its children in a two-dimensional
    table with all cells having the same size. In other words, the width of
    each cell within the grid is the width of the widest item added to the
    sizer and the height of each grid cell is the height of the tallest item.
    An optional vertical and/or horizontal gap between items can also be
    specified (in pixels.)

    Items are placed in the cells of the grid in the order they are added,
    in row-major order. In other words, the first row is filled first, then
    def __init__(self,
                 parent,
                 id=wx.ID_ANY,
                 label=wx.EmptyString,
                 pos=wx.DefaultPosition,
                 size=wx.DefaultSize,
                 style=wx.DEFAULT_PANEL_STYLE,
                 name=wx.PanelNameStr):
        '''
        Construct and show a generic Window.
        '''
        theClass = 'Panel'

        # Capture initial caller parametsrs before they are changed
        self.caller_parent = parent
        self.caller_id = id
        self.caller_label = label
        self.caller_pos = pos
        self.caller_size = size
        self.caller_style = style
        self.caller_name = name

        wx.RegisterFirstCallerClassName(self, theClass)

        if parent is None:

            # Top Level Windows (Frames & Dialogs) have no parent
            panelPos = pos
            panelSize = size

        else:

            parentClientArea = parent.ClientArea
            if pos == wx.DefaultPosition:
                panelPos = wxPoint(parentClientArea.x,
                                   parentClientArea.y)
            else:
                panelPos = pos

            if size == wx.DefaultSize:
                panelSize = wxSize(parentClientArea.width,
                                   parentClientArea.height)
            else:
                panelSize = size

        Window.__init__(self,
                        parent,
                        id=id,
                        pos=panelPos,
                        size=panelSize,
                        style=style,
                        name=name)

        self.tsBeginClassRegistration(theClass, id)

        if False:
            self.ts_Rect = wxRect(-1, -1, -1, -1)
            self.ts_ClientRect = self.ts_Rect
        else:
            (myRect, myClientRect) = self.tsPanelLayout(
                parent, panelPos, panelSize, style, name)
            self.ts_Rect = myRect
            self.ts_ClientRect = myClientRect

        thePosition = self.Position
        theSize = self.Size

        if DEBUG:
            self.logger.debug('               self: %s' % self)
            self.logger.debug('             parent: %s' % parent)
            self.logger.debug('                 id: %s' % id)
            self.logger.debug('         AssignedId: %s' % self.ts_AssignedId)
            self.logger.debug('              label: %s' % label)
            self.logger.debug('                pos: %s' % thePosition)
            self.logger.debug('               size: %s' % theSize)
            self.logger.debug('              style: 0x%X' % style)
            self.logger.debug('               name: %s' % name)

        self.ts_Label = label
        self.ts_Name = name
        self.ts_Parent = parent

        theTopLevelClass = self
        self.SetTopLevelAncestor(theTopLevelClass)

        if parent is None:
            self.ts_GrandParent = None
        else:
            self.ts_GrandParent = parent.Parent

        self.ts_BackgroundColour = wx.ThemeToUse['BackgroundColour'].lower()
        self.ts_ForegroundColour = wx.ThemeToUse['ForegroundColour'].lower()

        # Facilitate differentiation of this panel from its parent by
        # transposing the parent's foreground and background colors.
        if style == wx.BORDER_SUNKEN:

            self.ts_BackgroundColour = wx.COLOR_BLACK
            self.ts_ForegroundColour = wx.COLOR_WHITE

        elif style == wx.BORDER_RAISED:

            self.ts_BackgroundColour = wx.COLOR_WHITE
            self.ts_ForegroundColour = wx.COLOR_BLACK

        else:

            self.ts_BackgroundColour = self.ts_Parent.ts_BackgroundColour
            self.ts_ForegroundColour = self.ts_Parent.ts_ForegroundColour

        self.ts_Style = style

        # Automatically Bind all mouse events ASAP (now).
        # Will register event in the SystemEventTable.
        event = EVT_SET_FOCUS
        handler = self.SetFocusFromKbd
        source = self
        self.Bind(event,
                  handler,
                  source,
                  useSystemEventTable=True)

        self.tsEndClassRegistration(theClass)
    def RecalcSizes(self):
        '''
        Using the sizes calculated by CalcMin reposition and resize all the
        items managed by this sizer. You should not need to call this
        directly as it is called by Layout.

        Modeled after RecalcSizes in sizer.cpp file of wxWidgets.
        '''
        nitems = self.CalcRowsCols()
        self.logger.debug(
            'GridSizes.RecalcSizes: nitems=%d; Rows=%d; Cols=%d' % (
            nitems, self.ts_Rows, self.ts_Cols))

        if (nitems == 0):
            return

        # find the space allotted to this sizer

        if True:

            # Use CalcMin Output and Integer Arithmetic
            pt = self.GetPosition()
            sz = self.GetSize()

            w = (sz.width - (
                (self.ts_Cols - 1) * self.ts_HGap)) / self.ts_Cols

            h = (sz.height - (
                (self.ts_Rows - 1) * self.ts_VGap)) / self.ts_Rows

        else:

            # TBD - Use CalcMin Output and Floating Point Arithmetic
            pt = self.GetPosition()
            sz = self.GetSize()

            w = (sz.width - (
                (self.ts_Cols - 1) * self.ts_HGap)) / self.ts_Cols

            h = (sz.height - (
                (self.ts_Rows - 1) * self.ts_VGap)) / self.ts_Rows

##            ptOrig = self.GetPosition()
##            xOrig = ptOrig.x
##            yOrig = ptOrig.y

##            szOrig = self.GetSize()
##            widthOrig = szOrig.width
##            heightOrig = szOrig.height

##            hGapOrig = self.ts_HGap
##            vGapOrig = self.ts_VGap
##            x = int(float(szOrig.x) + (float(wx.pixelWidthPerCharacter) / 2.0))
##            sz = wxSize(szOrig.x +
##            pt = ptOrig

##            w = (sz.width - ((self.ts_Cols - 1) * self.ts_HGap)) / self.ts_Cols

##            h = (sz.height - ((self.ts_Rows - 1) * self.ts_VGap)) / self.ts_Rows

        y = pt.y
        for r in range(self.ts_Rows):

            x = pt.x
            for c in range(self.ts_Cols):

                i = (r * self.ts_Cols) + c
                if (i < nitems):

                    node = self.ts_Children.indexedNodeList[i]

                    self.logger.wxASSERT_MSG(
                        (node is not None),
                        'GridSizer.RecalcSizes Failed to find node')

                    if True:
                        theItem = node.GetUserData()
                        thePoint = wxPoint(x, y)
                        theSize = wxSize(w, h)
                        theItem.SetDimension(thePoint, theSize)
                        theLabel = theItem.ts_Window.ts_Label
                        if DEBUG:
                            print(
                                'r=%d; c=%d; i=%d; pt=%s; sz=%s; label=%s' % (
                                    r, c, i, str(thePoint),
                                    str(theSize), theLabel))
                    self.SetItemBounds(node.GetUserData(), x, y, w, h)

                x = x + w + self.ts_HGap

            y = y + h + self.ts_VGap
    def __init__(
        self,
        parent,
        id=wx.ID_ANY,
        bitmap=None,
        splashStyle=0,
        milliseconds=0,
        pos=wx.DefaultPosition,
        size=wx.DefaultSize,
        style=wx.DEFAULT_SPLASHSCREEN_STYLE,
    ):
        """
        Construct class.
        """
        theClass = "SplashScreen"

        # Capture initial caller parametsrs before they are changed
        self.caller_bitmap = bitmap
        self.caller_splashStyle = splashStyle
        self.caller_milliseconds = milliseconds
        self.caller_parent = parent
        self.caller_id = id
        self.caller_pos = pos
        self.caller_size = size
        self.caller_style = style

        wx.RegisterFirstCallerClassName(self, theClass)

        TopLevelWindow.__init__(self)

        self.tsBeginClassRegistration(theClass, id)

        ##        size = wxSize(500, 300)
        Frame.__init__(
            self,
            parent,
            id=wx.ID_ANY,
            title=wx.EmptyString,
            pos=pos,
            size=size,
            style=wx.BORDER_SIMPLE,  # wx.DEFAULT_SPLASHSCREEN_STYLE,
            name=wx.SplashScreenNameStr,
        )

        splashWindow = self
        splashWindow.ts_ForegroundColour = wx.COLOR_RED
        splashWindow.ts_BackgroundColour = wx.COLOR_WHITE

        self.ts_SplashStyle = splashStyle
        self.ts_SplashWindow = splashWindow
        self.ts_SplashTimeout = milliseconds

        self.ts_bitmap = wxTextCtrl(
            splashWindow,
            id=-1,
            value=wx.EmptyString,
            pos=wxPoint(
                splashWindow.ts_ClientRect.x + wx.pixelWidthPerCharacter,
                splashWindow.ts_ClientRect.y + wx.pixelHeightPerCharacter,
            ),
            size=wxSize(
                splashWindow.ts_ClientRect.width - (2 * wx.pixelWidthPerCharacter),
                splashWindow.ts_ClientRect.height - (2 * wx.pixelHeightPerCharacter),
            ),
            style=0,  # wx.TE_MULTILINE |wx.TE_READONLY,
            validator=wx.DefaultValidator,
            name=wx.TextCtrlNameStr,
        )

        self.ts_bitmap.AppendText(bitmap)
        self.ts_bitmap.Show()

        self.SetFocus()

        ##        print('SplashScreen: Show')
        ##        self.Show()
        ##        print('SplashScreen: Sleep(%d)' % self.ts_SplashTimeout)
        ##        time.sleep(self.ts_SplashTimeout / 1000)
        ##        print('SplashScreen: Hide')
        ##        self.Hide()

        self.tsEndClassRegistration(theClass)
 def GetPosition(self):
     '''
     Obtains the position (in client coordinates) at which the key
     was pressed.
     '''
     return (wxPoint(self.ts_x, self.ts_y))
    def tsCreateButtonBar(self, panel, xPos=0, yPos=0):
        '''
        Create the collection of Frame Buttons located on the Frame Title
        Line.

        Based on "wxPython In Action" by Noel Rappin and Robin Dunn,
        Manning Publications Co. (See downloaded source code located in
        Chapter-05, goodExampple.py.)
        '''
        theLabels = []
        theButtons = []
        uninstalledAcceleratorEntries = []
        for theLabel, theEvent, theHandler, theName in self.tsButtonData():
            theLabels += [theLabel]
            pos = wxPoint(xPos, yPos)
            button = self.tsBuildOneButton(panel,
                                           label=theLabel,
                                           event=theEvent,
                                           handler=theHandler,
                                           pos=pos,
                                           name=theName)

##            if theLabel == CloseButtonLabel:

##                theButton = self.ts_OnFrameCloseButton = button

##              event = EVT_COMMAND_LEFT_CLICK # EVT_CLOSE
##              handler = self.tsFrameOnCloseClick
##              source = self.ts_OnFrameCloseButton
##              button.Bind(event,
##                          handler,
##                          source,
##                          useSystemEventTable=True)

##            elif theLabel == MaximizeButtonLabel:

##                theButton = self.ts_OnFrameMaximizeButton = button

##              event = EVT_COMMAND_LEFT_CLICK # EVT_MAXIMIZE
##              handler = self.tsFrameOnMaximizeClick
##              source = self.ts_OnFrameMaximizeButton
##              button.Bind(event,
##                          handler,
##                          source,
##                          useSystemEventTable=True)

##            elif theLabel == IconizeButtonLabel:

##                theButton = self.ts_OnFrameIconizeButton = button

##              event = EVT_COMMAND_LEFT_CLICK # EVT_ICONIZE
##              handler = self.tsFrameOnIconizeClick
##              source = self.ts_OnFrameIconizeButton
##              button.Bind(event,
##                          handler,
##                          source,
##                          useSystemEventTable=True)

##            elif theLabel == RestoreDownButtonLabel:

##                theButton = self.ts_OnFrameRestoreDownButton = button

##              event = EVT_COMMAND_LEFT_CLICK # EVT_RESTOREDOWN
##              handler = self.tsFrameOnRestoreDownClick
##              source = self.ts_OnFrameRestoreDownButton
##              button.Bind(event,
##                          handler,
##                          source,
##                          useSystemEventTable=True)

##            else:

##              msg = 'Invalid value for theLabel="%s"' % theLabel
##              print('ERROR: %s' % msg)

            try:
                fmt1 = '\n\n tsCreateButtonBar: '
                fmt2 = '\n\t self.GetLabel="%s"; ' % self.GetLabel()
                fmt3 = '\n\t self="%s"; ' % str(self)
                fmt4 = '\n\t theLabel="%s"; ' % str(theLabel)
                fmt5 = '\n\t theEvent="%s"; ' % str(theEvent)
                fmt6 = '\n\t theButton="%s"; ' % str(theButton)
                fmt7 = '\n\t theHandler="%s"; ' % str(theHandler)
                fmt8 = '\n\t theName="%s"; ' % str(theName)
                fmt9 = '\n\t theButton="%s"' % str(button)
                msg = fmt1 + fmt2 + fmt3 + fmt4 + \
                    fmt5 + fmt6 + fmt7 + fmt8 + fmt9
                print(msg)
            except Exception, errorCode:
                fmt1 = 'tsCreateButtonBar: '
                fmt2 = 'errorCode="%s"' % str(errorCode)
                print('ERROR: "%s"' % errorCode)

##            # Bind mouse event ASAP (now).
##            # Will register event in the SystemEventTable
##            # if useSystemEventTable=True.
##            self.Bind(theEvent,
##                      theHandler,
##                      button,
##                      useSystemEventTable=True)

            theButtons += [button]

##            myRect = button.Rect
##            xPos += myRect.width - 1 * wx.pixelWidthPerCharacter
##            self.logger.debug('tsCreateButtonBar: myRect=%s' % str(myRect))
            xPos += button.GetSize().width - 1 * wx.pixelWidthPerCharacter