def tsGetClientArea(self, pixels=True):
        '''
        Returns the bounding rectangle the client area of the StaticBox.
        '''
        myRect = self.ts_Rect

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

        thickness = self.tsIsBorderThickness(
            style=self.ts_Style, pixels=pixels)

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

        self.ts_ClientRect = myClientRect

        if pixels:

            return (myClientRect)

        else:

            return (wxRect(
                (myClientRect.x // wx.pixelWidthPerCharacter),
                (myClientRect.y // wx.pixelWidthPerCharacter),
                (myClientRect.width // wx.pixelWidthPerCharacter),
                (myClientRect.height // wx.pixelWidthPerCharacter)))
    def tsStaticLineLayout(self, parent, pos, size, style, name):
        '''
        Calculate position and size of StaticLine 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)
 
        thePosition = self.tsGetClassInstanceFromTuple(pos, wxPoint)
        theSize = self.tsGetClassInstanceFromTuple(size, wxSize)

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

        if theSize == theDefaultSize:
            # theDefaultSize

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

        else:
            # Not theDefaultSize

            myRect = wxRect(thePosition.x,
                            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, self.GetLabel(), str(myRect))

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

        return (myRect, myClientRect)
    def GetGeometry(self, pixels=True):
        '''
        Returns the bounding rectangle of the display whose index was
        passed to the constructor.
        '''
        if Display.TheTerminal is None:

            (displayX,
             displayY,
             displayWidth,
             displayHeight) = (0, 0, 0, 0)

        else:

            if True:
                geometry = Display.TheTerminal.ts_stdscrGeometry
                (displayX,
                 displayY,
                 displayWidth,
                 displayHeight) = (geometry.x,
                                   geometry.y,
                                   geometry.width,
                                   geometry.height)
            else:
                (displayX,
                 displayY,
                 displayWidth,
                 displayHeight) = Display.TheTerminal.ts_stdscrGeometry


        theCharacterArea = wxRect(
            displayX,
            displayY,
            displayWidth,
            displayHeight)

        thePixelArea = wxRect(
            displayX * wx.pixelWidthPerCharacter,
            displayY * wx.pixelHeightPerCharacter,
            displayWidth * wx.pixelWidthPerCharacter,
            displayHeight * wx.pixelHeightPerCharacter)
 
        if pixels:
            theArea = thePixelArea
        else:
            theArea = theCharacterArea

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

        return (theArea)
    def IsDisplayAvailable():
        '''
        Tests if it is possible to create a GUI in the current environment.
        This will mean different things on the different platforms.

        * On X Windows systems this function will return False if it is not
        able to open a connection to the X display, which can happen if
        $DISPLAY is not set, or is not set correctly.
 
        * On Mac OS X a False return value will mean that wx is not able to
        access the window manager, which can happen if logged in remotely
        or if running from the normal version of python instead of the
        framework version, (i.e., pythonw.)
 
        * On MS Windows...
        '''
        if PyApp._TheGeometry == wxRect(-1, -1, -1, -1):
            termname = None
        else:
            try:
                termname = tsGTUI.GraphicalTextUserInterface.TermName
            except AttributeError:
                termname = None

        displayAvailable = termname is not None
 
        return (displayAvailable)
    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 IsOk(self):
        '''
        Return true if the object was initialized successfully.
        '''
        try:

            ok = Display.TheTerminal.ts_stdscrGeometry != wxRect(0, 0, 0, 0)

        except AttributeError:

            ok = False

        return (ok)
    def __nonzero__(self):
        '''
        Return True if and initialized display exists; else return False.
        '''
        if Display.TheTerminal is None:
            result = False

        elif Display.TerminalPixelRectangle == wxRect(0, 0, 0, 0):
            result = False

        else:
            result = True

        return (result)
    def tsStatusBarLayout(self, parent, pos, size, style, name):
        '''
        Calculate position and size of status bar. Ignore based upon arguments.
        '''
        ###############################################################
        #      X=0         1         2         3   X=W-1
        #        01234567890123456789012345678901234
        # Y=0    +- Frame Title ---------[-][=][X]-+ Frame Border Top
        #   1    +---------------------------------+ Menu Bar Border Top
        #   2    |Menu Bar (Optional)              |
        #   3    |   (ex. 35 cols x 4 rows)        |
        #   4    +- - - - - - - - - - - - - - - - -+ Menu Bar Border Bottom
        #   4    + - - - - - - - - - - - - - - - - + Tool Bar Border Top
        #   5    |Tool Bar (Optional)              |
        #   6    |   (ex. 35 cols x 4 rows)        |
        #   7    +- - - - - - - - - - - - - - - - -+ Tool Bar Border Bottom
        #   7    + - - - - - - - - - - - - - - - - + Client Border Top
        #   8    |Client Area                      |
        #   9    |   (ex. 35 cols x 5 rows)        |
        #   H-5  |                                 |
        #   H-4  +- - - - - - - - - - - - - - - - -+ Client Border Bottom
        #   H-4  + - - - - - - - - - - - - - - - - + Status Border Top
        #   H-3  |Status Line (Optional)           |
        #   H-2  |   (ex. 35 cols x 4 rows)        |
        # Y=H-1  +---------------------------------| Status Border Bottom
        #
        # NOTE: Overlapping rows denoted by "- - - -" and " - - - ".
        ###############################################################
        # Apply override of parental StatusBar position.
        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)
            return (self.ts_Rect)

        thePixelSize = parent.Rect.Size
        thePixelSize.height = self.ts_minHeight

        if parent.Rect.Size != self.display.ClientArea.Size:
            offset = thePixelSize.height - 1 * wx.pixelHeightPerCharacter
        else:
            offset = thePixelSize.height - 2 * wx.pixelHeightPerCharacter

        myRect = wxRect(parent.Rect.x,
                        parent.Rect.y + parent.Rect.height - offset,
                        thePixelSize.width,
                        thePixelSize.height)

        return (myRect)
    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 CalcMin(self):
        '''
        Calculate the total minimum width and height needed by all items
        in the sizer according to this sizer layout algorithm.

        This method is abstract and has to be overwritten by any derived
        class.

        Here, the sizer will do the actual calculation of its childrens
        minimal sizes.

        Implemented in wxGridBagSizer, and wxBoxSizer.
        '''
        width = 0
        height = 0
        for i in range(0, self.ts_Children.GetCount()):
            node = self.ts_Children.GetIndex(i)

            item = node.GetUserData()

            size = wxSize(0, 0)
            if (isinstance(self, Window)):
                try:
                    parent = self.ts_Parent
                    theClientRect = parent.ClientArea
                except AttributeError:
                    parent = None
                    theClientRect = wxRect(0, 0, 0, 0)

                width = theClientRect.width
                height = theClientRect.height
                minSize = wxSize(width, height)

                self.logger.debug(
                    'CalcMin: item=%s; minSize=%s; width=%s; height=%s' % (
                    str(item), str(minSize), str(width), str(height)))

                size = minSize
                self.logger.debug('CalcMin: size=%s' % size)

            return (size)
    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()
    def tsGetTaskArea(self, pixels=True):
        '''
        Return rectangle position and size of window used for task bar.
        '''
        ###############################################################
        #      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.EnableTaskBarArea:
 
            theTaskAreaHeight = wx.ThemeToUse['TaskBar']['WindowHeight'] // \
                                wx.pixelHeightPerCharacter

            theTotalArea = self.GetGeometry(pixels=False)

            theTaskAreaOffset = theTaskAreaHeight
            theCharacterArea = wxRect(
                theTotalArea.x,
                theTotalArea.y + theTotalArea.height - theTaskAreaOffset,
                theTotalArea.width,
                theTaskAreaHeight)

            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(
                    'tsGetTaskArea: %s pixels = %s characters' % (
                        thePixelArea, theCharacterArea))

        else:
 
            theArea = None

            if DEBUG and VERBOSE:
                self.tsPrivateLogger(
                    'tsGetTaskArea: %s' % theArea)

        return (theArea)
    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 tsTextEntryDialogLayout(self, parent, pos, size, style, name):
        '''
        Calculate position and size of dialog based upon arguments.
        '''
        # Example Layout (wxPython TextEntryDialog)
        #
        #   Key:
        #       Caption = "Eh?"
        #       Message = "What is your favorite programming language?"
        #       Value   = "Python is the best!"
        #       Buttons = "OK" and "Cancel"
        #
        #   Layout:
        #       Title    = Caption
        #       VSizer1  = Message Line(s)
        #       VSizer2  = Value Line(s)
        #       VSizer3  = Horizontal Separator (TextLine)
        #       VSizer4  = Button(s)
        #       HSizer1  = Spacer (variable size)
        #       HSizer2  = OK Button (fixed size)
        #       HSizer3  = Cancel Button (fixed size)
        #
        # wxPython-Style (pixel-mode)
        #
        # +---------------------------------------------------------+
        # | Caption                                              [X]|
        # +---------------------------------------------------------+
        # | What is your favorite programming language?             |
        # |  +---------------------------------------------------+  |
        # |  |Python is the best!                                |  |
        # |  +---------------------------------------------------+  |
        # | ------------------------------------------------------- |
        # |                              +----------+ +----------+  |
        # |                              [    OK    ] [  Cancel  ]  |
        # |                              +----------+ +----------+  |
        # +---------------------------------------------------------+
        #
        # tsWxGTUI-Style (character-mode)
        #
        # +- Caption -------------------------------------- [?][X] -+
        # +---------------------------------------------------------+
        # | What is your favorite programming language?             |
        # |  +---------------------------------------------------+  |
        # |  |Python is the best!                                |  |
        # |  +---------------------------------------------------+  |
        # | ------------------------------------------------------- |
        # |                              [    OK    ] [  Cancel  ]  |
        # +---------------------------------------------------------+
        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)

        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)

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

            if parent is None:

                myRect = wxRect(self.display.ClientArea.x,
                                self.display.ClientArea.y,
                                self.display.ClientArea.width,
                                self.display.ClientArea.height)
                myRect = self.display.ClientArea

            else:

                myRect = parent.GetClientArea(pixels=True)

        elif thePosition == theDefaultPosition:

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

        elif theSize == theDefaultSize:

            theDisplaySize = wxSize(
                self.display.ClientArea.width,
                self.display.ClientArea.height)

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

        else:

            myRect = wxRect(thePosition.x,
                            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 + theBorder.width,
                              myRect.y + theBorder.height,
                              myRect.width - 2 * theBorder.width,
                              myRect.height - 2 * theBorder.height)

        self.tsTrapIfTooSmall(name, myRect)
        msg = 'parent=%s; pos=%s; size=%s; name=%s; title=%s; myRect=%s' % \
              (parent, pos, size, name, self.Title, myRect)

        self.logger.debug('tsTextEntryDialog.' + \
                          'tsTextEntryDialogLayout: %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 GetClientArea(self, pixels=True):
        '''
        Returns the bounding rectangle the client area of the display,
        i.e., without taskbars and such.
        '''
        ###############################################################
        #      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 DEBUG and VERBOSE:
            self.tsPrivateLogger(
                '  GetClientArea:Display.EnableRedirectArea=%s' % \
                Display.EnableRedirectArea)
 
            self.tsPrivateLogger(
                '  GetClientArea:Display.EnableTaskBarArea=%s' % \
                Display.EnableTaskBarArea)

        theCharacterArea = self.GetGeometry(pixels=False)

        if Display.EnableTaskBarArea:

            theTaskArea = self.tsGetTaskArea(pixels=False)

            theCharacterArea.height -= theTaskArea.height

        if Display.EnableRedirectArea:

            theRedirectedStdioArea = self.tsGetRedirectedStdioArea(
                pixels=False)

            theCharacterArea.height -= theRedirectedStdioArea.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(
                'GetClientArea: %s pixels = %s characters' % (
                    thePixelArea, theCharacterArea))

        return (theArea)
    def __init__(self,
                 parent,
                 id=wx.ID_ANY,
                 pos=wx.DefaultPosition,
                 size=wx.DefaultSize,
                 style=wx.DEFAULT_MENUBAR_STYLE,
                 name=wx.MenuBarNameStr):
        '''
        Construct and show a generic Window.
        '''
        theClass = 'MenuBar'

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

        wx.RegisterFirstCallerClassName(self, theClass)

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

        self.tsBeginClassRegistration(theClass, id)

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

        self.ts_theEntry = []
        self.ts_theEntryCount = wx.ID_ANY
        self.ts_MenuCount = 0
        self.ts_Menus = None

        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('              title: %s' % title)
            self.logger.debug('                pos: %s' % self.Position)
            self.logger.debug('               size: %s' % self.Size)
            self.logger.debug('              style: 0x%X' % style)
            self.logger.debug('               name: %s' % name)

        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()

        self.ts_Style = style

        self.ts_TheWrapper = None

        self.ts_UserInputEnable = False

        self.tsEndClassRegistration(theClass)
    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 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 __init__(self):
        '''
        Create a new application object, starting the bootstrap process.
        '''

        theClass = 'PyApp'

        wx.RegisterFirstCallerClassName(self, theClass)

        # Initiate bootstrap process

        EvtHandler.__init__(self)

        applicationId = wx.ID_ANY

        self.tsBeginClassRegistration(theClass, applicationId)

        self.ts_theTerminal = tsGTUI.GraphicalTextUserInterface(theClass)
        try:
            if True:
                PyApp._TheGeometry = self.ts_theTerminal.StdscrGeometryPixels
            else:
                (theScreenX,
                 theScreenY,
                 theScreenWidth,
                 theScreenHeight) = self.ts_theTerminal.StdscrGeometry

                PyApp._TheGeometry = wxRect(
                    theScreenX * wx.pixelWidthPerCharacter,
                    theScreenY * wx.pixelHeightPerCharacter,
                    theScreenWidth * wx.pixelWidthPerCharacter,
                    theScreenHeight * wx.pixelHeightPerCharacter)

        except AttributeError:
            PyApp._TheGeometry = wxRect(-1, -1, -1, -1)

        self.ts_Active = True
        self.ts_AppName = None
        self.ts_AssertMode = False
        self.ts_ClassName = theClass
        self.ts_EventLoop = None
        self.ts_Exit = False
        self.ts_ExitMainLoop = False
        self.ts_ExitOnFrameDelete = True
        self.ts_IdleEvents = False
        self.ts_IsActive = False
        self.ts_LayoutDirection = wx.Layout_Default

        self.ts_PrintMode = wx.UseDefaultValue

##        self.ts_thisown = None

        # Create a Frame that encompasses entire curses screen (stdscr).
        # It is the default for handling mouse clicks outside of those
        # top-level windows (frames and dialogs), and their children,
        # that do not fully occupy the curses screen.
        theParent = None
        self.ts_TheTopUserWindow = None
        self.ts_TheTopWindow = wxScreen(
            theParent,
            id=wx.ID_ANY,
            title='Screen',
            pos=wx.DefaultPosition,
            size=wx.DefaultSize,
            style=wx.DEFAULT_FRAME_STYLE,
            name=wx.ScreenNameStr)

        # Set default Window that will receive Keyboard Text Entry Input.
        # Must bypass use of self.tsRegisterKeyboardInputOrder()
        try:

            tsWxGTUI_DataBase.KeyboardInputRecipients[
                'lifoList'] = self.ts_TheTopWindow

        except Exception, errorCode:

            msg = 'txWxPyApp.__init__: errorCode=""%s"' % str(errorCode)
            self.logger.error(msg)
            print('ERROR: %s\n' % msg)
            raise tse.ProgramException(tse.APPLICATION_TRAP, msg)
    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 tsScrollBarGaugeLayout(self, parent, pos, size, style, name):
        '''
        Calculate position and size of gauge 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)
 
        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_Name

        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 False and thePosition == theDefaultPosition:
                # theDefaultPosition

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

            else:
                # Not theDefaultPosition

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

        else:
            # Not theDefaultSize

            if False and thePosition == theDefaultPosition:
                # theDefaultPosition

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

            else:
                # Not theDefaultPosition

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

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

        if ((self.Parent.ts_Style & wx.SB_HORIZONTAL) or \
            (self.Parent.ts_Style & wx.HSCROLL)):

            self.ts_GaugeThumbLines = (
                self.ts_ClientRect.width // wx.pixelWidthPerCharacter)

        else:

            self.ts_GaugeThumbLines = (
                self.ts_ClientRect.height // wx.pixelHeightPerCharacter)

        self.ts_Rect = myRect
        self.ts_ClientRect = myClientRect

        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('    tsScrollBarGaugeLayout: %s' % msg)

        return (myRect, myClientRect)
    def __init__(self, title):
        '''
        Construct a wx.PyOnDemandOutputWindow object.
        '''
        theClass = 'PyOnDemandStdioWindow'

        wx.RegisterFirstCallerClassName(self, theClass)

##        applicationId = wx.ID_ANY

##        self.tsBeginClassRegistration(theClass, applicationId)

        indent = '--' * 5
        self.logger = tsLogger.TsLogger(
            threshold=tsLogger.DEBUG,
            start=time.time(),
            name=tsLogger.StandardOutputFile)

        self.logger.debug(
            '%s Begin %s (0x%X) after logger import.' % (
                indent, theClass, id(self)))

        # Establish defaults until attributes finalized
        self.ts_ClassName = theClass
        self.ts_Frame = None
        self.ts_Parent = None
        self.ts_Text = None
        self.ts_Title = title

        if wx.ThemeToUse['Stdio']['Title'] == wx.StdioRedirectedTitleStr:

            self.ts_PyOnDemandStdioWindow = True

            self.ts_Name = wx.StdioNameStr
            self.ts_Style = wx.DEFAULT_STDIO_STYLE
            self.ts_logFile = self.tsCreateScrollableRedirectionLog()
            self.ts_Margin = wx.tsGetClassInstanceFromTuple(
                wx.ThemeToUse['Stdio']['Margin'], wxSize)

        else:

            self.ts_PyOnDemandStdioWindow = False

            self.ts_Name = wx.FrameNameStr
            self.ts_Style = wx.DEFAULT_FRAME_STYLE
            self.ts_logFile = None
            self.ts_Margin = wx.tsGetClassInstanceFromTuple(
                wx.ThemeToUse['Stdio']['Margin'], wxSize)

        (thePosition, theSize) = self.tsGetStdioPositionAndSize()
        self.ts_Rect = wxRect(thePosition.x,
                              thePosition.y,
                              theSize.width,
                              theSize.height)

        self.ts_ClientRect = wxRect(
            thePosition.x + wx.pixelWidthPerCharacter,
            thePosition.y + wx.pixelHeightPerCharacter,
            theSize.width - 2 * wx.pixelWidthPerCharacter,
            theSize.height - 2 * wx.pixelHeightPerCharacter)

        self.ts_Cache = wx.EmptyString

        #self.OnCloseClicked = None
        #self.OnHelpClicked = None
        #self.OnMaximizeClicked = None
        #self.OnMinimizeClicked = None
        #self.OnRestoreDownClicked = None
        self.OnClose = None
        self.OnHelp = None
        self.OnMaximize = None
        self.OnMinimize = None
        self.OnRestoreDown = None
    def tsTextCtrlLayout(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)

        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)

        label = self.ts_Text

        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(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(thePosition.x,
                                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(thePosition.x,
                                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 + theBorder.width,
                              myRect.y + theBorder.height,
                              myRect.width - 2 * theBorder.width,
                              myRect.height - 2 * theBorder.height)

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

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

        return (myRect, myClientRect)
    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 tsRadioButtonLayout(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

        if theSize == theDefaultSize:
            # theDefaultSize
            ##            print('default size layout label="%s"; pos=%s size=%s' % (
            ##                label, pos, size))

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

            maxWidth = self.ts_Parent.ts_ClientRect.width - (2 * wx.pixelWidthPerCharacter)

            if label is wx.EmptyString:
                # TBD - Adjust for cursor width
                theLabelSize = wxSize(maxWidth, 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 False and thePosition == theDefaultPosition:
                # theDefaultPosition

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

            else:
                # Not theDefaultPosition

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

        else:
            # Not theDefaultSize
            ##            print('not default size layout label="%s"; pos=%s size=%s' % (
            ##                label, pos, size))

            if False and thePosition == theDefaultPosition:
                # theDefaultPosition

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

            else:
                # Not theDefaultPosition

                myRect = wxRect(thePosition.x, 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("    tsRadioButtonLayout: %s" % msg)

        return (myRect, myClientRect)
    def __init__(self, *args, **kwargs):
        '''
        Constructor for Sizer, Spacer and Window variants of SizerItem.

        Design for wxPython 2.8.12 supported no arguments and no key word
        arguments. The application first had to instantiate the SizerItem
        Class and then use various Set methods to configure the kind of
        SizerItem.

        Design for wxWidgets 2.9.2.2 supported optional arguments and key
        word arguments. The application could instantiate the SizerItem
        Class in the manner of wxPython 2.8.12 or optionally instantiate
        the Sizer, Spacer or Window variant via the appropriate args and
        kwargs.

        Since there is no wxPython 2.9.2.2, the following implementation
        attempts to cover all wxWidgets 2.9.2.2 instantiation forms.
        '''
        theClass = 'SizerItem'

        wx.RegisterFirstCallerClassName(self, theClass)

        Object.__init__(self)

        self.tsBeginClassRegistration(theClass, wx.ID_ANY)

        # Begin setup to avoid triggering pylint errors and warnings.
        # Set Default Values

        # ***** Begin Default Attributes
        self.ts_Border = 0
        self.ts_Flag = 0
        self.ts_ID = self.ts_LastSizerItemId = wx.ID_NONE
        self.ts_Kind = wx.Item_None
        self.ts_MinSize = wxSize(0, 0)
        self.ts_MinSizeWithBorder = wxSize(0, 0)
        self.ts_Proportion = 0
        self.ts_Ratio = 0.0
        self.ts_Rect = wxRect(0, 0, 0, 0)
        self.ts_Show = False
        self.ts_Size = wxSize(0, 0)
        self.ts_Sizer = None
        self.ts_Spacer = None
        self.ts_UserData = None
        self.ts_Window = None
        # ***** End Default Attributes

        # End setup to avoid triggering pylint errors and warnings.

        if (len(args) == 0) and \
           (len(kwargs) == 0):

            # Instatiate SizerItem Class without using args or kwargs
            # associated with Sizer, Spacer or Window variants.
            self.__init_No_Args_No_KwArgs__()

        elif (len(args) > 0) and \
             (isinstance(args[0], wxWindow)):

            # Instatiate SizerItem Class using args or kwargs
            # associated with Window variant.

            self.__init_Item_Window__(args, kwargs)

        elif (len(args) > 0) and \
             (isinstance(args[0], wxSizerSpacer)):

            # Instatiate SizerItem Class using args or kwargs
            # associated with Spacer variants.

            self.__init_Item_Spacer__(args, kwargs)

        else:

            # Instatiate SizerItem Class using args or kwargs
            # associated with Sizer variants.

            self.__init_Item_Sizer__(args, kwargs)

        self.tsEndClassRegistration(theClass)
    def RecalcSizes(self):
        '''
        Recalculate (if necessary) the position and size of each item and
        then call item.SetDimension to do the actual positioning and sizing
        of the items within the space alloted to this sizer.
        '''
        self.ts_RecalcArea = []

        for i in range(0, self.ts_Children.GetCount()):

            if (self.ts_Orientation == wx.HORIZONTAL):

                # Horizontal Layout
                orientation = 'HORIZONTAL'
                if (i == 0):

                    self.ts_RecalcArea += [wxRect(
                        self.ts_ClientArea.x,
                        self.ts_ClientArea.y,
                        self.ts_CalcMinArea[i].width,
                        self.ts_CalcMinArea[i].height)]

                else:

                    self.ts_RecalcArea += [wxRect(
                        (self.ts_RecalcArea[i - 1].x + \
                         self.ts_RecalcArea[i - 1].width),
                        self.ts_RecalcArea[i - 1].y,
                        self.ts_CalcMinArea[i].width,
                        self.ts_CalcMinArea[i].height)]

            else:

                # Vertical Layout
                orientation = '  VERTICAL'

                if (i == 0):

                    self.ts_RecalcArea += [wxRect(
                        self.ts_ClientArea.x,
                        self.ts_ClientArea.y,
                        self.ts_CalcMinArea[i].width,
                        self.ts_CalcMinArea[i].height)]

                else:

                    self.ts_RecalcArea += [wxRect(
                        self.ts_RecalcArea[i - 1].x,
                        (self.ts_RecalcArea[i - 1].y + \
                         self.ts_RecalcArea[i - 1].height),
                        self.ts_CalcMinArea[i].width,
                        self.ts_CalcMinArea[i].height)]

            msg = '%s RecalcSizes[%d]: Rect=%s; ' % (
                orientation,
                i,
                self.ts_RecalcArea[i])

            print(msg)

            self.ts_CalcMinWindow[i].ts_Rect = self.ts_RecalcArea[i]
    def _tsCreateFields(self):
        '''
        '''
        widths = self.ts_StatusWidths

        number = self.ts_nFields

        baseRect = self.Rect

        # RSG - 07/31/2008
        if True:
            # TBD - Why did change to tsWxTextCtrl introduce need for this.
            baseRect.x -= wx.pixelWidthPerCharacter
            baseRect.y -= wx.pixelHeightPerCharacter
        else:
            # TBD - Why round up?
            # Compensates for centering that splits a single character
            baseRect.x += wx.pixelWidthPerCharacter // 2
        # RSG - 07/31/2008
 
        remainderWidth = 0

        overlay = wx.ThemeToUse['StatusBar']['Overlay']
        if overlay and number > 1:
            overlayAdjustment = wx.pixelWidthPerCharacter
        else:
            overlayAdjustment = 0

        cells = []
        for index in range(number):
            characterWidth, pixelRemainder = divmod(
                widths[index], wx.pixelWidthPerCharacter)
            remainderWidth += pixelRemainder
            cells.append(characterWidth * wx.pixelWidthPerCharacter)
            if index < number - 1:
                cells[index] += overlayAdjustment
                if overlay:
                    remainderWidth += (wx.pixelWidthPerCharacter // 2) - 1
            else:
                cells[index] += remainderWidth
            if DEBUG:
                fmt = '_tsCreateFields: ' + \
                      'widths(%d)=%3d; ' + \
                      'cells=%3d; ' + \
                      'remainderWidth=%3d'
                self.logger.debug(fmt % (
                    index, widths[index], cells[index], remainderWidth))

        self.ts_FieldRect = []
        self.ts_Fields = []
        self.ts_StatusStyles = []
        self.ts_StatusWidths = []
        for index in range(number):
            self.ts_Fields.append(None)
            self.ts_StatusStyles.append(self.ts_Style)
            self.ts_StatusWidths.append(cells[index])
            if index == 0:
                self.ts_FieldRect.append(
                    wxRect(baseRect.x,
                           baseRect.y,
                           self.ts_StatusWidths[index],
                           baseRect.height))

##            elif index == 1:
##                if True or overlay:
##                    self.ts_FieldRect.append(
##                        wxRect(self.ts_FieldRect[index - 1].x + \
##                               self.ts_StatusWidths[index - 1],
##                               self.ts_FieldRect[index - 1].y,
##                               self.ts_StatusWidths[index],
##                               self.ts_FieldRect[index - 1].height))

##                else:
##                    self.ts_FieldRect.append(
##                        wxRect(self.ts_FieldRect[index - 1].x + \
##                               self.ts_StatusWidths[index - 1] + remainderWidth,
##                               self.ts_FieldRect[index - 1].y,
##                               self.ts_StatusWidths[index],
##                               self.ts_FieldRect[index - 1].height))

            else:
                if overlay:
                    self.ts_FieldRect.append(
                        wxRect(self.ts_FieldRect[index - 1].x + \
                               self.ts_StatusWidths[index - 1] - overlayAdjustment,
                               self.ts_FieldRect[index - 1].y,
                               self.ts_StatusWidths[index],
                               self.ts_FieldRect[index - 1].height))
                else:
                    self.ts_FieldRect.append(
                        wxRect(self.ts_FieldRect[index - 1].x + \
                           self.ts_StatusWidths[index - 1] - overlayAdjustment,
                           self.ts_FieldRect[index - 1].y,
                           self.ts_StatusWidths[index],
                           self.ts_FieldRect[index - 1].height))
 
            if DEBUG:
                fmt = '_tsCreateFields: ' + \
                      'ts_FieldRect(%d)=%s; '
                self.logger.debug(fmt % (
                    index, str(self.ts_FieldRect[index])))

        # TBD - Can creating TextCtrl be deferred until Show?
        if True:
            self._tsCreateStatusText()