changeset 15:0c9569096feb

Added enso.ui.messages.windows.
author Atul Varma <varmaa@toolness.com>
date Fri, 22 Feb 2008 15:45:29 -0600
parents f9e9fe4d28b1
children 34545dfacdc8
files enso/ui/messages/__init__.py enso/ui/messages/windows.py
diffstat 2 files changed, 208 insertions(+), 1 deletions(-) [+]
line wrap: on
line diff
--- a/enso/ui/messages/__init__.py	Fri Feb 22 15:36:34 2008 -0600
+++ b/enso/ui/messages/__init__.py	Fri Feb 22 15:45:29 2008 -0600
@@ -118,6 +118,13 @@
 """
 
 # ----------------------------------------------------------------------------
+# Imports
+# ----------------------------------------------------------------------------
+
+import logging
+
+
+# ----------------------------------------------------------------------------
 # Message Object
 # ----------------------------------------------------------------------------
 
@@ -318,7 +325,7 @@
         """
 
         # The following message may be used by system tests.
-        infoMsg( "Primary message dismissed." )
+        logging.info( "Primary message dismissed." )
 
         oldMsg = self.__primaryMessage
         if oldMsg.isMini() and not oldMsg.isFinished():
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/enso/ui/messages/windows.py	Fri Feb 22 15:45:29 2008 -0600
@@ -0,0 +1,200 @@
+# Copyright (c) 2008, Humanized, Inc.
+# All rights reserved.
+# 
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
+#
+#    1. Redistributions of source code must retain the above copyright
+#       notice, this list of conditions and the following disclaimer.
+#
+#    2. Redistributions in binary form must reproduce the above copyright
+#       notice, this list of conditions and the following disclaimer in the
+#       documentation and/or other materials provided with the distribution.
+#
+#    3. Neither the name of Enso nor the names of its contributors may
+#       be used to endorse or promote products derived from this
+#       software without specific prior written permission.
+# 
+# THIS SOFTWARE IS PROVIDED BY Humanized, Inc. ``AS IS'' AND ANY
+# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+# DISCLAIMED. IN NO EVENT SHALL Humanized, Inc. BE LIABLE FOR ANY
+# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+# ----------------------------------------------------------------------------
+#
+#   enso.ui.messages.windows
+#
+# ----------------------------------------------------------------------------
+
+"""
+    Implements the various Message windows.
+"""
+
+# ----------------------------------------------------------------------------
+# Imports
+# ----------------------------------------------------------------------------
+
+import cairo
+
+from enso import graphics
+from enso.graphics.transparentwindow import TransparentWindow
+
+from enso.graphics.measurement import pointsToPixels, pixelsToPoints
+from enso.graphics.measurement import inchesToPoints, convertUserSpaceToPoints
+
+
+# ----------------------------------------------------------------------------
+# Generic Message Window
+# ----------------------------------------------------------------------------
+
+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 = int( pointsToPixels(self.__maxSize[0]) + 1)
+        height = int( pointsToPixels(self.__maxSize[1]) + 1)
+
+        xPos = int(round(pointsToPixels(self.__currPos[0])))
+        yPos = int(round(pointsToPixels(self.__currPos[1])))
+
+        # The following are protected to allow subclasses access
+        # to them.
+        self._wind = TransparentWindow( xPos, yPos, width, height )
+        self._context = cairo.Context( self._wind.makeCairoSurface() )
+
+        # We work in points, not pixels
+        convertUserSpaceToPoints( self._context )
+
+
+    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:
+            # Windows work in pixels, not points.
+            width = pointsToPixels( width )
+            height = pointsToPixels( height )
+            self._wind.setSize( int(width), int(height) )
+
+
+    def setPos( self, xPos, yPos ):
+        """
+        Sets the current position of the window to xPos, yPos, which
+        should be in points.
+        """
+
+        assert pointsToPixels( xPos ) <= graphics.getDesktopSize()[0]
+        assert pointsToPixels( yPos ) <= graphics.getDesktopSize()[1]
+
+        self.__currPos = xPos, yPos
+        if self._wind != None:
+            # Windows work in pixels, not points.
+            xPos = pointsToPixels( xPos )
+            yPos = pointsToPixels( yPos )
+            self._wind.setPosition( int(xPos), int(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 )
+        cr.paint()
+        
+    
+def computeWidth( doc ):
+    """
+    Utility function for computing the 'actual' width of a text layout
+    document, by taking the maximum line width.
+    """
+    
+    lines = []
+    for b in doc.blocks:
+        lines.extend( b.lines )
+
+    if len(lines) == 0:
+        return 0
+    else:
+        return max( [ l.xMax for l in lines ] )