HandledBox.py :  » GUI » PmwContribD » PmwContribD-r2_0_2 » Python Open Source

Home
Python Open Source
1.3.1.2 Python
2.Ajax
3.Aspect Oriented
4.Blog
5.Build
6.Business Application
7.Chart Report
8.Content Management Systems
9.Cryptographic
10.Database
11.Development
12.Editor
13.Email
14.ERP
15.Game 2D 3D
16.GIS
17.GUI
18.IDE
19.Installer
20.IRC
21.Issue Tracker
22.Language Interface
23.Log
24.Math
25.Media Sound Audio
26.Mobile
27.Network
28.Parser
29.PDF
30.Project Management
31.RSS
32.Search
33.Security
34.Template Engines
35.Test
36.UML
37.USB Serial
38.Web Frameworks
39.Web Server
40.Web Services
41.Web Unit
42.Wiki
43.Windows
44.XML
Python Open Source » GUI » PmwContribD 
PmwContribD » PmwContribD r2_0_2 » HandledBox.py
#!/usr/bin/env python
#
# $Id: HandledBox.py,v 1.4 2001/11/03 11:05:22 doughellmann Exp $
#
# Copyright 2001 Doug Hellmann.
#
#
#                         All Rights Reserved
#
# Permission to use, copy, modify, and distribute this software and
# its documentation for any purpose and without fee is hereby
# granted, provided that the above copyright notice appear in all
# copies and that both that copyright notice and this permission
# notice appear in supporting documentation, and that the name of Doug
# Hellmann not be used in advertising or publicity pertaining to
# distribution of the software without specific, written prior
# permission.
#
# DOUG HELLMANN DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
# INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN
# NO EVENT SHALL DOUG HELLMANN BE LIABLE FOR ANY SPECIAL, INDIRECT OR
# CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
# OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
# NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
# CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#

"""A canvas object subclassed from ShadowBox, which adds handles.

"""

__rcs_info__ = {
    #
    #  Creation Information
    #
    'module_name'  : '$RCSfile: HandledBox.py,v $',
    'rcs_id'       : '$Id: HandledBox.py,v 1.4 2001/11/03 11:05:22 doughellmann Exp $',
    'creator'      : 'Doug Hellmann <doug@hellfly.net>',
    'project'      : 'PmwContribD',
    'created'      : 'Sun, 01-Apr-2001 17:33:38 EDT',

    #
    #  Current Information
    #
    'author'       : '$Author: doughellmann $',
    'version'      : '$Revision: 1.4 $',
    'date'         : '$Date: 2001/11/03 11:05:22 $',
}

#
# Import system modules
#
import Tkinter
import Pmw
import sys, os, string
import Canvas
import math


#
# Import Local modules
#
import colormath
import ShadowBox


#
# Module
#

class Handle(ShadowBox.ShadowBox):
    "A visible handle attached to a ShadowBox."
    
    def __init__(self,
                 canvas, 
                 parent,
                 name=None,
                 ulx=0, uly=0, 
                 background='grey', 
                 outline='black',
                 allowMotion=0,
                 width=25,
                 height=20,
                 bd=2,
                 ridgeWidth=0,
                 relief=Tkinter.RIDGE,
                 connectEdge=Tkinter.LEFT,
                 helpMessage=None,
                 balloon=None,
                 ):
        """Create a Handle.

        Arguments

          'canvas' -- The canvas widget on which we draw.

          'parent' -- The parent.

          'name' -- Name of the handle.

          'ulx' -- Upper left X coordinate of the handle.

          'uly' -- Upper left Y coordinate of the handle.

          'background' -- Background color of the handle area.  Defaults to 'grey'.

          'outline' -- Outline color.  Defaults to 'black'.

          'allowMotion' -- Boolean indicating whether drag and drop
          needs to be supported.  Setting to true will cause handle to
          install drag and drop callbacks on canvas.

          'width' -- How wide should the handle be?

          'height' -- How tall should the handle be?

          'bd' -- Border width for shadow and outline.  Defaults to 2.

          'ridgeWidth' -- Width of ridge between outside edge and inside edge.

          'relief' -- Tkinter relief specification.  Defaults to Tkinter.RIDGE.

          'connectEdge' -- Tkinter edge specification.  Defaults to
          Tkinter.LEFT.  Controls which side of the handle is butted
          against the box and controls the drawing of shadows and
          outlines.

          'helpMessage' -- Balloon help to be displayed on mouseover.

          'balloon' -- Balloon help manager.
          
        """
        ShadowBox.ShadowBox.__init__(self, 
                                    canvas = canvas, 
                                    name = name, 
                                    ulx = ulx, 
                                    uly = uly, 
                                    background = background,
                                    outline = outline, 
                                    allowMotion = allowMotion, 
                                    width = width, 
                                    height = height,
                                    bd = bd, 
                                    ridgeWidth = ridgeWidth, 
                                    relief = relief,
                                    helpMessage=helpMessage,
                                    balloon=balloon,
                                    )
        self.edge = connectEdge
        #self.connect_edge(connectEdge)
        self.parent = parent
        if self.relief == Tkinter.RAISED:
            self.mitre_RAISED()
        else:
            pass
        return
    
    def shadow_edge(self):
        "Returns the Tkinter edge specification for shadow edge of handle."
      edge = self.edge
        if edge == Tkinter.LEFT:
            shadow_edge = Tkinter.RIGHT
        elif edge == Tkinter.RIGHT:
            shadow_edge = Tkinter.LEFT
        elif edge == Tkinter.TOP:
            shadow_edge = Tkinter.BOTTOM
        elif edge == Tkinter.BOTTOM:
            shadow_edge = Tkinter.TOP
        else:
            raise 'Unknown edge %s' % edge
        return shadow_edge
                        
    def mitre_RAISED(self):
        "Configure the mitre settings for RAISED mode."
        if self.edge == Tkinter.LEFT:
            self.canvas_objects_dict['right'].config(fill=self.background,
                                                     outline=self.background)
            self.canvas_objects_dict['top_right'].coords( (self.uir,
                                                           self.lur,
                                                           self.uri) )
            self.canvas_objects_dict['right_top'].coords( (self.uir,
                                                           self.ur,
                                                           self.lur) )
            self.canvas_objects_dict['right_top'].config(fill=self.light_shadow,
                                                         outline=self.light_shadow)
            self.canvas_objects_dict['right_bottom'].coords( (self.lir,
                                                              self.ulr,
                                                              self.lr) )
            self.canvas_objects_dict['right_bottom'].config(fill=self.light_shadow,
                                                            outline=self.light_shadow)
            self.canvas_objects_dict['bottom_right'].coords( (self.lir,
                                                              self.lri,
                                                              self.ulr) )
            self.canvas_objects_dict['bottom_right'].tkraise()
            
        elif self.edge == Tkinter.RIGHT:
            self.canvas_objects_dict['left'].config(fill=self.background,
                                                    outline=self.background)
            self.canvas_objects_dict['top_left'].coords( (self.lul, self.uil, self.uli) )
            self.canvas_objects_dict['left_top'].coords( (self.lul, self.ul, self.uil) )
            self.canvas_objects_dict['left_top'].config(fill=self.dark_shadow,
                                                        outline=self.dark_shadow)
            self.canvas_objects_dict['left_bottom'].coords( (self.ll,
                                                             self.ull,
                                                             self.lil) )
            self.canvas_objects_dict['left_bottom'].config(fill=self.dark_shadow,
                                                           outline=self.dark_shadow)
            self.canvas_objects_dict['bottom_left'].coords( (self.ull,
                                                             self.lli,
                                                             self.lil) )
            self.canvas_objects_dict['bottom_left'].tkraise()
            
        elif self.edge == Tkinter.TOP:
            self.canvas_objects_dict['bottom'].config(fill=self.background,
                                                      outline=self.background)
            self.canvas_objects_dict['bottom'].tkraise()
            self.canvas_objects_dict['bottom_left'].coords( (self.ull,
                                                             self.lli,
                                                             self.lil) )
            self.canvas_objects_dict['bottom_left'].config( fill=self.light_shadow,
                                                            outline=self.light_shadow )
            self.canvas_objects_dict['bottom_right'].coords( (self.lir,
                                                              self.lri,
                                                              self.ulr) )
            self.canvas_objects_dict['bottom_right'].config( fill=self.dark_shadow,
                                                             outline=self.dark_shadow)
            self.canvas_objects_dict['bottom_right'].tkraise()
            self.canvas_objects_dict['right_bottom'].coords( (self.lir,
                                                              self.ulr,
                                                              self.lr) )
            self.canvas_objects_dict['right_bottom'].config(fill=self.light_shadow,
                                                            outline=self.light_shadow)
            self.canvas_objects_dict['left_bottom'].coords( (self.ll,
                                                             self.ull,
                                                             self.lil) )
            self.canvas_objects_dict['left_bottom'].config(fill=self.light_shadow,
                                                           outline=self.light_shadow)

        elif self.edge == Tkinter.BOTTOM:
            self.canvas_objects_dict['top'].config(fill=self.background,
                                                   outline=self.background)
            self.canvas_objects_dict['top'].tkraise()
            self.canvas_objects_dict['top_left'].coords( (self.lul, self.uil, self.uli) )
            self.canvas_objects_dict['top_left'].config(fill=self.light_shadow,
                                                        outline=self.light_shadow)
            self.canvas_objects_dict['left_top'].coords( (self.lul, self.ul, self.uil) )
            self.canvas_objects_dict['left_top'].config(fill=self.dark_shadow,
                                                        outline=self.dark_shadow)
            self.canvas_objects_dict['top_right'].coords( (self.uir,
                                                           self.lur,
                                                           self.uri) )
            self.canvas_objects_dict['top_right'].config( fill=self.dark_shadow,
                                                          outline=self.dark_shadow)
            self.canvas_objects_dict['top_right'].tkraise()
            self.canvas_objects_dict['right_top'].coords( (self.uir, self.ur, self.lur) )
            self.canvas_objects_dict['right_top'].config(fill=self.dark_shadow,
                                                         outline=self.dark_shadow)
            
        else:
            pass
        return
    
            
class HandledBox(ShadowBox.ShadowBox):
    """A ShadowBox with handles on it.
    """
    def __init__(self,
                 canvas, 
                 name=None,
                 ulx=0, uly=0, 
                 background='grey', 
                 outline='black',
                 allowMotion=0,
                 width=25,
                 height=20,
                 bd=2,
                 ridgeWidth=0,
                 relief=Tkinter.RAISED,
                 ipad=6,
                 helpMessage=None,
                 balloon=None,
                 handleWidth=10,
                 handleHeight=10,
                 ):
        """Create a HandledBox.

        Arguments

          'canvas' -- Canvas on which all of this is being drawn.

          'name' -- Name of the HandledBox.

          'ulx' -- Upper left X coordinate.

          'uly' -- Upper left Y coordinate.

          'background' -- Background color of the box.  Defaults to 'grey'.

          'outline' -- Outline color for the box.  Defaults to 'black'.

          'allowMotion' -- Boolean controlling whether the icon should
          allow the user to move it.

          'width' -- How wide is the box?

          'height' -- How high is the box?

          'bd' -- Border width for shadow and outline area.  Defaults to 2.

          'ridgeWidth' -- Width of ridge around edge of box.

          'relief' -- Tkinter relief mode specification.  Defaults to
          Tkinter.RAISED.

          'ipad' -- Internal padding value.

          'helpMessage' -- Balloon help message to be shown on mouseover.

          'balloon' -- Balloon help manager.

          'handleWidth' -- How wide are handles attached to this box?

          'handleHeight' -- How tall are handles attached to this box?
          
        """
        self.__handles = {}
        self.ipad = ipad
        self.balloon = balloon
        self.handle_width = handleWidth
        self.handle_height = handleHeight
        ShadowBox.ShadowBox.__init__(self, 
                                    canvas = canvas, 
                                    name = name, 
                                    ulx = ulx, 
                                    uly = uly, 
                                    background = background,
                                    outline = outline, 
                                    allowMotion = allowMotion, 
                                    width = width, 
                                    height = height,
                                    bd = bd, 
                                    ridgeWidth = ridgeWidth, 
                                    relief = relief,
                                    helpMessage=helpMessage,
                                    balloon=balloon)
        self.__handle_offsets = {
            #Tkinter.LEFT:self.bd,
            #Tkinter.RIGHT:self.bd,
            #Tkinter.TOP:self.bd,
            #Tkinter.BOTTOM:self.bd,
            Tkinter.LEFT:self.ipad,
            Tkinter.RIGHT: self.height - self.ipad,
            Tkinter.TOP:self.ipad,
            Tkinter.BOTTOM: self.width - self.ipad,
            }
        return
    
    def handle(self, handle_name):
        "Retrieve a named handle."
        return self.__handles[handle_name]

    def add_handle(self, handle_name=None, edge=Tkinter.LEFT, 
                   helpMessage=None, relief=Tkinter.RAISED):
        """Add a handle to the box.

        Arguments

          handle_name -- Name of the handle.

          edge -- Edge of the box on which the handle should appear.
          Defaults to Tkinter.LEFT.

          helpMessage -- Balloon help to be displayed on mouseover.

          relief -- Relief mode specification for the handle.
        
        Add a named handle to the specified edge.  A separate
        CanvasObject which can be treated as the handle will be 
        returned.
        """
        if self.__handles.has_key(handle_name):
            raise ValueError('There is already a handle named %s' % handle_name)
        else:
            shadow_thickness = math.floor((self.bd - self.ridge_width) / 2)
            handle_width = self.handle_width
            handle_height = self.handle_height
            if (relief in [ Tkinter.RAISED, Tkinter.SUNKEN ]):
                shadow_offset = shadow_thickness
            else:
                shadow_offset = math.ceil(shadow_thickness/2)
            
            if edge == Tkinter.LEFT:
                ulx = self.ulx - handle_width + shadow_offset
                uly = self.uly + self.__handle_offsets[edge]
                #ulx = self.ulx - handle_width
                #uly = self.uly + self.__handle_offsets[edge]
                self.__handle_offsets[edge] = \
                    self.__handle_offsets[edge] + self.ipad + handle_height
                    
            elif edge == Tkinter.TOP:
                #ulx = self.ulx + self.__handle_offsets[edge] + shadow_thickness
                ulx = self.ulx + self.__handle_offsets[edge]
                uly = self.uly - handle_height + shadow_offset
                self.__handle_offsets[edge] = \
                    self.__handle_offsets[edge] + self.ipad + handle_width
                    
            elif edge == Tkinter.RIGHT:
                ulx = self.ulx + self.width - shadow_offset
                uly = self.uly + self.__handle_offsets[edge] - handle_height
                self.__handle_offsets[edge] = \
                    self.__handle_offsets[edge] - self.ipad - handle_height
                    
            elif edge == Tkinter.BOTTOM:
                ulx = self.ulx + self.__handle_offsets[edge] - handle_width
                uly = self.uly + self.height - shadow_offset
                self.__handle_offsets[edge] = \
                    self.__handle_offsets[edge] - self.ipad - handle_width
                
            new_handle = Handle(self.canvas, 
                                parent = self,
                                name = '%s_%s' % (self.name, handle_name),
                                ulx = ulx, 
                                uly = uly,
                                allowMotion = 0,
                                background = self.background,
                                #background = 'lightblue',
                                bd = shadow_thickness,
                                ridgeWidth = shadow_thickness,
                                relief = relief,
                                width = handle_width,
                                height = handle_height,
                                connectEdge = edge,
                                helpMessage = helpMessage,
                                balloon = self.balloon
                                )
            new_handle.parent = self                            
            #
            # Here we need to insert the tag for
            # the HandledBox (self) before the tag for the
            # new handle (new_handle) so that when the
            # mouse moves onto the handle, the help message
            # for the handle is displayed; and when the
            # mouse moves onto the HandledBox main area,
            # the help message for the HandledBox is displayed.
            #
            # If we assume that the last tag added to the
            # handle was the one for HandledBox, we can
            # just insert our tag before the last one in
            # the tuple.
            #
            # We do all of this fanciness to the main_outline
            # component of the handle.  This isn't safe, especially
            # if we subclass the handle and start creating things
            # with other canvas objects on top of the main_outline
            #
            tags = new_handle.main_outline.gettags()
            newtags = tags[:-1] + (self.unique_name, tags[-1])
            new_handle.main_outline.config(tags=newtags)
            #
            # Now we throw the HandledBox tag back on the
            # end of the tag list, so that when we pick
            # up the box and move it with the mouse all
            # of the parts of the handles move with it.
            #
            new_handle.addtag(self.unique_name)
            
            #
            # Store the handle so we can retrieve it later.
            #
            self.__handles[new_handle.name] = new_handle
            #print 'storing handle "%s" (%s) for %s' % (handle_name, new_handle.name, self.name)
            
            #
            # Return the handle so the caller can bind
            # to it right away.
            #
            return new_handle

if __name__ == '__main__':
    import TestCases.CanvasTestApp
    import AnimatedFileIcon
    import AnimatedFolder
    
    class DoubleClickFolder(AnimatedFolder.AnimatedFolder):
        def __init__(self, canvas, 
                    name=None,
                    ulx=0, uly=0, 
                    foreground='AntiqueWhite', 
                    lightshadow='tan3', 
                    darkshadow='tan1',
                    outline='black',
                    allowMotion=0,
                    width=25,
                    height=20,
                    ):
            AnimatedFolder.AnimatedFolder.__init__(self, canvas,
                    name=name,
                    ulx=ulx, uly=uly,
                    foreground=foreground,
                    lightshadow=lightshadow,
                    darkshadow=darkshadow,
                    outline=outline,
                    allowMotion=allowMotion,
                    width=width,
                    height=height,
                    defaultSequence='<Double-1>',
                    command=self.callback)
        def callback(self, event):
            print '%s got a callback' % self
            print 'and is %s' % self.state
            
    class HandledBoxTest(TestCases.CanvasTestApp.CanvasTestApp):
        appname = 'Test handled box'
        handle_message_type = 'userevent'
        def showHandleInfo(self, event, handle=None):
            self.showMessage(self.handle_message_type, 'Over %s' % handle.name)
            
        def hideHandleInfo(self, event):
            #print 'in hideHandleInfo (%s)' % event
            self.showMessage(self.handle_message_type)
            
        def createCanvasObjects(self):
            
            box = HandledBox(self.canvas, name='bigtest', 
                      ulx=50, uly=30,
                      width=150, 
                      height=150,
                      relief=Tkinter.RIDGE,
                      bd=15,
                      ridgeWidth=5,
                      allowMotion=1,
                      #background='lightblue',
                      balloon = self.balloon(),
                      helpMessage = 'help for handled box',
                      handleWidth=15,
                      handleHeight=15,
                      )
            
            for side in [ Tkinter.LEFT, Tkinter.RIGHT, Tkinter.TOP, Tkinter.BOTTOM ]:
                for style in [ Tkinter.SUNKEN, Tkinter.RIDGE, Tkinter.GROOVE, Tkinter.RAISED ] :
                    name = '%s_%s' % (side, style)
                    h = box.add_handle(name, 
                            helpMessage = 'help for %s' % name, 
                            edge = side,
                            relief = style)
                    
            #
            # Put a circle in the middle of the box
            #
            ((ulx, uly), (lrx, lry)) = box.ibbox()
            circle = Canvas.Oval(self.canvas, ulx + 1, uly + 1, lrx - 2, lry - 2,
                            fill='green',
                            outline='black',
                            width=2) 
            box.add_object(circle)

            ignore = """
            box2 = HandledBox(self.canvas, name='bigtest', 
                      ulx=200, uly=50,
                      width=85, 
                      height=110,
                      relief=Tkinter.RIDGE,
                      bd=10,
                      ridgeWidth=6,
                      allowMotion=1,
                      #background='lightblue',
                      balloon = self.balloon(),
                      helpMessage = 'help for 2nd handled box',
                      handleWidth=15,
                      handleHeight=15,
                      )
            
            for n in range(0, 2):
                for side in [ Tkinter.LEFT, Tkinter.RIGHT, Tkinter.TOP, Tkinter.BOTTOM ]:
                    name = '%s_%d' % (side, n)
                    h = box2.add_handle(name, helpMessage = 'help for %s' % name, edge = side)
                    
            #
            # Put a circle in the middle of the box
            #
            ((ulx, uly), (lrx, lry)) = box2.ibbox()
            icon = AnimatedFileIcon.AnimatedFileIcon(self.canvas, 
                            ulx=ulx + 1, 
                            uly=uly + 1,
                            width = lrx - ulx - 2,
                            height = lry - uly - 2,
                            )
            box2.add_object(icon)

            box3 = HandledBox(self.canvas, name='bigtest', 
                      ulx=200, uly=200,
                      width=110, 
                      height=85,
                      relief=Tkinter.RIDGE,
                      bd=20,
                      ridgeWidth=5,
                      allowMotion=1,
                      #background='lightblue',
                      balloon = self.balloon(),
                      helpMessage = 'help for 2nd handled box',
                      handleWidth=15,
                      handleHeight=15,
                      )
            
            for n in range(0, 2):
                for side in [ Tkinter.LEFT, Tkinter.RIGHT, Tkinter.TOP, Tkinter.BOTTOM ]:
                    name = '%s_%d' % (side, n)
                    h = box3.add_handle(name, helpMessage = 'help for %s' % name, edge = side)
                    
            #
            # Put a circle in the middle of the box
            #
            ((ulx, uly), (lrx, lry)) = box3.ibbox()
            icon = DoubleClickFolder(self.canvas, 
                            ulx=ulx + 1, 
                            uly=uly + 1,
                            width = lrx - ulx - 2,
                            height = lry - uly - 2,
                            name = 'the folder',
                            )
            box3.add_object(icon)
            """
            
        def folderClickCB(self, event, icon):
            print 'clicked on folder %s (%s)' % (icon, icon.name)
            print 'icon is now in %s state' % (icon.get_state())
            #print 'closing'
            icon.set_state('closed')
            print ''
    HandledBoxTest().run()
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.