Ejemplo n.º 1
0
class TextWindow:
    """
    Encapsulates the drawing of a single line of text, with optional
    rounded corners and an optional "override width", which overides the
    default width (margins + text width).
    """
    def __init__(self, height, position):
        """
        Creates the underlying TransparentWindow and Cairo context.

        Position and height should be in pixels.
        """

        # Use the maximum width that we can, i.e., the desktop width.
        width, _ = graphics.getDesktopSize()
        left, top = graphics.getDesktopOffset()

        xPos, yPos = position
        self.__window = TransparentWindow(xPos + left, yPos + top, width,
                                          height)
        self.__context = self.__window.makeCairoContext()

    def getHeight(self):
        """
        LONGTERM TODO: Document this.
        """

        return self.__window.getHeight()

    def draw(self, document):
        """
        Draws the text described by document.

        An updating call; at the end of this method, the displayed
        window should reflect the drawn content.
        """

        width = document.ragWidth + layout.L_MARGIN + layout.R_MARGIN
        height = self.__window.getMaxHeight()
        cr = self.__context

        # Clear the areas where the corners of the rounded rectangle will be.

        cr.save()
        cr.set_source_rgba(0, 0, 0, 0)
        cr.set_operator(cairo.OPERATOR_SOURCE)
        cr.rectangle(width - rounded_rect.CORNER_RADIUS,
                     height - rounded_rect.CORNER_RADIUS,
                     rounded_rect.CORNER_RADIUS, rounded_rect.CORNER_RADIUS)
        cr.rectangle(width - rounded_rect.CORNER_RADIUS, 0,
                     rounded_rect.CORNER_RADIUS, rounded_rect.CORNER_RADIUS)
        cr.paint()

        # Draw the background rounded rectangle.
        corners = []
        if document.roundUpperRight:
            corners.append(rounded_rect.UPPER_RIGHT)
        if document.roundLowerRight:
            corners.append(rounded_rect.LOWER_RIGHT)

        cr.set_source_rgba(*document.background)
        rounded_rect.drawRoundedRect(context=cr,
                                     rect=(0, 0, width, height),
                                     softenedCorners=corners)
        cr.fill_preserve()
        cr.restore()

        # Next, draw the text.
        document.draw(layout.L_MARGIN, document.shrinkOffset, self.__context)

        width = min(self.__window.getMaxWidth(), width)
        height = min(self.__window.getMaxHeight(), height)

        self.__window.setSize(width, height)
        self.__window.update()

    def hide(self):
        """
        Clears the window's surface (making it disappear).
        """

        # LONGTERM TODO: Clearing the surface, i.e., painting it
        # clear, seems like a potential performance bottleneck.

        self.__window.setSize(1, 1)

        # Frankly, I don't know why this works, but after this
        # function, the resulting window is totally clear. I find it
        # odd, since the alpha value is not being set.  It is a
        # wierdness of Cairo. -- Andrew

        self.__context.set_operator(cairo.OPERATOR_CLEAR)
        self.__context.paint()
        self.__context.set_operator(cairo.OPERATOR_OVER)

        self.__window.update()
Ejemplo n.º 2
0
class TextWindow:
    """
    Encapsulates the drawing of a single line of text, with optional
    rounded corners and an optional "override width", which overides the
    default width (margins + text width).
    """

    def __init__( self, height, position ):
        """
        Creates the underlying TransparentWindow and Cairo context.

        Position and height should be in pixels.
        """

        # Use the maximum width that we can, i.e., the desktop width.
        width, _ = graphics.getDesktopSize()
        left, top = graphics.getDesktopOffset()

        xPos, yPos = position
        self.__window = TransparentWindow(xPos + left, yPos, width, height )
        self.__context = self.__window.makeCairoContext()


    def getHeight( self ):
        """
        LONGTERM TODO: Document this.
        """

        return self.__window.getHeight()


    def draw( self, document ):
        """
        Draws the text described by document.

        An updating call; at the end of this method, the displayed
        window should reflect the drawn content.
        """

        width = document.ragWidth + layout.L_MARGIN + layout.R_MARGIN
        height = self.__window.getMaxHeight()
        cr = self.__context

        # Clear the areas where the corners of the rounded rectangle will be.

        cr.save()
        cr.set_source_rgba( 0, 0, 0, 0 )
        cr.set_operator( cairo.OPERATOR_SOURCE )
        cr.rectangle( width - rounded_rect.CORNER_RADIUS,
                      height - rounded_rect.CORNER_RADIUS,
                      rounded_rect.CORNER_RADIUS,
                      rounded_rect.CORNER_RADIUS )
        cr.rectangle( width - rounded_rect.CORNER_RADIUS,
                      0,
                      rounded_rect.CORNER_RADIUS,
                      rounded_rect.CORNER_RADIUS )
        cr.paint()

        # Draw the background rounded rectangle.
        corners = []
        if document.roundUpperRight:
            corners.append( rounded_rect.UPPER_RIGHT )
        if document.roundLowerRight:
            corners.append( rounded_rect.LOWER_RIGHT )

        cr.set_source_rgba( *document.background )
        rounded_rect.drawRoundedRect( context = cr,
                                      rect = ( 0, 0, width, height ),
                                      softenedCorners = corners )
        cr.fill_preserve()
        cr.restore()

        # Next, draw the text.
        document.draw( layout.L_MARGIN,
                       document.shrinkOffset,
                       self.__context )

        width = min( self.__window.getMaxWidth(), width )
        height = min( self.__window.getMaxHeight(), height )

        self.__window.setSize( width, height )
        self.__window.update()


    def hide( self ):
        """
        Clears the window's surface (making it disappear).
        """

        # LONGTERM TODO: Clearing the surface, i.e., painting it
        # clear, seems like a potential performance bottleneck.

        self.__window.setSize( 1, 1 )

        # Frankly, I don't know why this works, but after this
        # function, the resulting window is totally clear. I find it
        # odd, since the alpha value is not being set.  It is a
        # wierdness of Cairo. -- Andrew

        self.__context.set_operator (cairo.OPERATOR_CLEAR)
        self.__context.paint ()
        self.__context.set_operator (cairo.OPERATOR_OVER)

        self.__window.update()
Ejemplo n.º 3
0
class MessageWindow(object):
    """
    A generic message window class, combining the TransparentWindow
    functionality with a Cairo context to create a usable message
    window class, with sizing, positioning, and drawing methods.
    """
    def __init__(self, maxSize):
        """
        Initialize the message window.
        """

        self.__maxSize = maxSize
        self.__currSize = (1, 1)
        self.__currPos = (0, 0)

        self._wind = None
        self._context = None

        # The TransparentWindow should not be instantiated here.
        # As the position/size is not yet known, TransparentWindow
        # is created with default position and size and that causes
        # ugly flickering on Linux when the window is really drawn later.
        # We should instead create TransparentWindow in lazy manner
        # shortly before it needs to be drawn.
        # self.__setupWindow()

    def __setupWindow(self):
        """
        Creates the MessageWindow's underlying TransparentWindow and
        Cairo Context objects, once and for all.
        """
        # Lazy initialization of TransparentWindow
        if self._wind is None:
            width = self.__maxSize[0]
            height = self.__maxSize[1]

            xPos = self.__currPos[0]
            yPos = self.__currPos[1]

            # The following are protected to allow subclasses access
            # to them.
            self._wind = TransparentWindow(xPos, yPos, width, height)
            self._context = self._wind.makeCairoContext()

    def getSize(self):
        return self.__currSize

    def getMaxSize(self):
        return self.__maxSize

    def getPos(self):
        return self.__currPos

    def _getContext(self):
        self.__setupWindow()
        return self._context

    # LONGTERM TODO: Consider replacing setSize,setPos with setBox, and
    # establish a clipping function isOnScreen for use in the contract.

    def setSize(self, width, height, refresh=True):
        """
        Sets the current size of the message window the width, height.

        Using the function appropriately vastly improves performance,
        as it reduces the visible size of the window and the number of
        pixels that must be copied on window updates.
        """

        assert width <= self.getMaxSize()[0],\
            "Window width (%d) is larger than maximum window width (%d)"\
            % (width, self.getMaxSize()[0])
        assert height <= self.getMaxSize()[1],\
            "Window height (%d) is larger than maximum window height (%d)"\
            % (height, self.getMaxSize()[1])

        self.__currSize = width, height

        if self._wind is not None and refresh:
            self._wind.setSize(width, height)

    def setPos(self, xPos, yPos):
        """
        Sets the current position of the window to xPos, yPos, which
        should be in points.
        """
        self.__currPos = xPos, yPos
        if self._wind is not None:
            self._wind.setPosition(xPos, yPos)

    def hide(self):
        """
        Sets the underlying TransparentWindow's size to (1,1) so that
        the window essentially vanishes.  This effectively "hides" the
        window, causing it to cease interfering with performance of
        windows that are "underneath" the message window.
        """

        # LONGTERM TODO: This method should eventually be
        # re-implmeneted or removed; merely setting the size of the
        # window to 1x1 pixels can still result in performance
        # degredation (see trac ticket #290).

        self.__setupWindow()
        # This is prtobably only needed on Win32:
        #self._wind.setSize( 1, 1 )
        self._wind.update()

    def show(self):
        """
        Sets the underlying TransparentWindow's size to the stored
        "current size" variable, essentially re-correlating the actual
        displayed rectangle on the screen to the size required by the
        MessageWindow's underlying content.
        """
        self.__setupWindow()

        width, height = self.getSize()
        self.setSize(width, height, False)
        self._wind.update()

    def clearWindow(self):
        """
        "Clears" the underlying cairo context.
        """

        # Works by blanking the whole surface.
        # The cairo paint() method does the whole (clipped) cairo
        # surface.

        self.__setupWindow()

        cr = self._context
        cr.set_source_rgba(0, 0, 0, 0)
        cr.set_operator(
            cairo.OPERATOR_SOURCE
        )  # IGNORE:E1101 @UndefinedVariable Keep PyLint and PyDev happy
        cr.paint()
Ejemplo n.º 4
0
class MessageWindow:
    """
    A generic message window class, combining the TransparentWindow
    functionality with a Cairo context to create a usable message
    window class, with sizing, positioning, and drawing methods.
    """
    def __init__(self, maxSize):
        """
        Initialize the message window.
        """

        self.__maxSize = maxSize
        self.__currSize = (1, 1)
        self.__currPos = (0, 0)

        self.__setupWindow()

    def __setupWindow(self):
        """
        Creates the MessageWindow's underlying TransparentWindow and
        Cairo Context objects, once and for all.
        """

        width = self.__maxSize[0]
        height = self.__maxSize[1]

        xPos = self.__currPos[0]
        yPos = self.__currPos[1]

        # The following are protected to allow subclasses access
        # to them.
        self._wind = TransparentWindow(xPos, yPos, width, height)
        self._context = self._wind.makeCairoContext()

    def getSize(self):
        return self.__currSize

    def getMaxSize(self):
        return self.__maxSize

    def getPos(self):
        return self.__currPos

    # LONGTERM TODO: Consider replacing setSize,setPos with setBox, and
    # establish a clipping function isOnScreen for use in the contract.

    def setSize(self, width, height):
        """
        Sets the current size of the message window the width, height.

        Using the function appropriately vastly improves performance,
        as it reduces the visible size of the window and the number of
        pixels that must be copied on window updates.
        """

        assert width <= self.getMaxSize()[0]
        assert height <= self.getMaxSize()[1]

        self.__currSize = width, height

        if self._wind != None:
            self._wind.setSize(width, height)

    def setPos(self, xPos, yPos):
        """
        Sets the current position of the window to xPos, yPos, which
        should be in points.
        """

        self.__currPos = xPos, yPos
        if self._wind != None:
            self._wind.setPosition(xPos, yPos)

    def hide(self):
        """
        Sets the underlying TransparentWindow's size to (1,1) so that
        the window essentially vanishes.  This effectively "hides" the
        window, causing it to cease interfering with performance of
        windows that are "underneath" the message window.
        """

        # LONGTERM TODO: This method should eventually be
        # re-implmeneted or removed; merely setting the size of the
        # window to 1x1 pixels can still result in performance
        # degredation (see trac ticket #290).

        self._wind.setSize(1, 1)
        self._wind.update()

    def show(self):
        """
        Sets the underlying TransparentWindow's size to the stored
        "current size" variable, essentially re-correlating the actual
        displayed rectangle on the screen to the size required by the
        MessageWindow's underlying content.
        """

        self.setSize(*self.getSize())
        self._wind.update()

    def clearWindow(self):
        """
        "Clears" the underlying cairo context.
        """

        # Works by blanking the whole surface.
        # The cairo paint() method does the whole (clipped) cairo
        # surface.
        cr = self._context
        cr.set_source_rgba(0, 0, 0, 0)
        cr.paint()
Ejemplo n.º 5
0
class MessageWindow:
    """
    A generic message window class, combining the TransparentWindow
    functionality with a Cairo context to create a usable message
    window class, with sizing, positioning, and drawing methods.
    """
    
    def __init__( self, maxSize ):
        """
        Initialize the message window.
        """
        
        self.__maxSize = maxSize
        self.__currSize = ( 1, 1 )
        self.__currPos = ( 0, 0 )

        self.__setupWindow()


    def __setupWindow( self ):
        """
        Creates the MessageWindow's underlying TransparentWindow and
        Cairo Context objects, once and for all.
        """
        
        width = self.__maxSize[0]
        height = self.__maxSize[1]

        xPos = self.__currPos[0]
        yPos = self.__currPos[1]

        # The following are protected to allow subclasses access
        # to them.
        self._wind = TransparentWindow( xPos, yPos, width, height )
        self._context = self._wind.makeCairoContext()


    def getSize( self ):
        return self.__currSize
    def getMaxSize( self ):
        return self.__maxSize
    def getPos( self ):
        return self.__currPos


    # LONGTERM TODO: Consider replacing setSize,setPos with setBox, and
    # establish a clipping function isOnScreen for use in the contract.

    def setSize( self, width, height ):
        """
        Sets the current size of the message window the width, height.

        Using the function appropriately vastly improves performance,
        as it reduces the visible size of the window and the number of
        pixels that must be copied on window updates.
        """

        assert width <= self.getMaxSize()[0] 
        assert height <= self.getMaxSize()[1]

        self.__currSize = width, height

        if self._wind != None:
            self._wind.setSize( width, height )


    def setPos( self, xPos, yPos ):
        """
        Sets the current position of the window to xPos, yPos, which
        should be in points.
        """

        assert xPos <= graphics.getDesktopSize()[0]
        assert yPos <= graphics.getDesktopSize()[1]

        self.__currPos = xPos, yPos
        if self._wind != None:
            self._wind.setPosition( xPos, yPos )

            
    def hide( self ):
        """
        Sets the underlying TransparentWindow's size to (1,1) so that
        the window essentially vanishes.  This effectively "hides" the
        window, causing it to cease interfering with performance of
        windows that are "underneath" the message window.
        """

        # LONGTERM TODO: This method should eventually be
        # re-implmeneted or removed; merely setting the size of the
        # window to 1x1 pixels can still result in performance
        # degredation (see trac ticket #290).

        self._wind.setSize( 1, 1 )
        self._wind.update()

        
    def show( self ):
        """
        Sets the underlying TransparentWindow's size to the stored
        "current size" variable, essentially re-correlating the actual
        displayed rectangle on the screen to the size required by the
        MessageWindow's underlying content.
        """
        
        self.setSize( *self.getSize() )
        self._wind.update()


    def clearWindow( self ):
        """
        "Clears" the underlying cairo context.
        """

        # Works by blanking the whole surface.
        # The cairo paint() method does the whole (clipped) cairo
        # surface.
        cr = self._context
        cr.set_source_rgba( 0, 0, 0, 0 )
        cr.paint()